// 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: --wasm-shared-engine --no-wasm-disable-structured-cloning --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();
})();
