// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Flags: --allow-natives-syntax --experimental-wasm-threads

load('test/mjsunit/wasm/wasm-module-builder.js');


// In  this test we start a worker which enters wasm and stays there in a loop.
// The main thread stays in JS and checks that its thread-in-wasm flag is not
// set. The main thread calls setTimeout after every check to give the worker a
// chance to be scheculed.
const sync_address = 12;
(function TestPostModule() {
  let builder = new WasmModuleBuilder();
  let sig_index = builder.addType(kSig_v_v);
  let import_id = builder.addImport('m', 'func', sig_index);
  builder.addFunction('wait', kSig_v_v)
      .addBody([
        // Calling the imported function sets the thread-in-wasm flag of the
        // main thread.
        kExprCallFunction, import_id,  // --
        kExprLoop, kWasmStmt,          // --
        kExprI32Const, sync_address,   // --
        kExprI32LoadMem, 0, 0,         // --
        kExprI32Eqz,
        kExprBrIf, 0,                  // --
        kExprEnd,
      ])
      .exportFunc();

  builder.addFunction('signal', kSig_v_v)
      .addBody([
        kExprI32Const, sync_address,  // --
        kExprI32Const, 1,             // --
        kExprI32StoreMem, 0, 0,       // --
        ])
      .exportFunc();
  builder.addImportedMemory("m", "imported_mem", 0, 1, "shared");

  let module = builder.toModule();
  let memory = new WebAssembly.Memory({initial: 1, maximum: 1, shared: true});

  let workerScript = `
    onmessage = function(msg) {
      try {
        let worker_instance = new WebAssembly.Instance(msg.module,
            {m: {imported_mem: msg.memory,
                 func: _ => 5}});
        postMessage("start running");
        worker_instance.exports.wait();
        postMessage("finished");
      } catch(e) {
        postMessage('ERROR: ' + e);
      }
    }
  `;

  let worker = new Worker(workerScript, {type: 'string'});
  worker.postMessage({module: module, memory: memory});

  let main_instance = new WebAssembly.Instance(
      module, {m: {imported_mem: memory, func: _ => 7}});

  let counter = 0;
  function CheckThreadNotInWasm() {
    // We check the thread-in-wasm flag many times and reschedule ourselves in
    // between to increase the chance that we read the flag set by the worker.
    assertFalse(%IsThreadInWasm());
    counter++;
    if (counter < 100) {
      setTimeout(CheckThreadNotInWasm, 0);
    } else {
      main_instance.exports.signal(sync_address);
      assertEquals('finished', worker.getMessage());
      worker.terminate();
    }
  }

  assertFalse(%IsThreadInWasm());
  assertEquals('start running', worker.getMessage());
  CheckThreadNotInWasm();
})();
