| // 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 |
| |
| load('test/mjsunit/wasm/wasm-module-builder.js'); |
| |
| // The number of locals must be greater than the constant defined here: |
| // https://cs.chromium.org/chromium/src/v8/src/compiler/x64/code-generator-x64.cc?l=3146 |
| const kNumLocals = 128; |
| |
| function varuint32(val) { |
| let bytes = []; |
| for (let i = 0; i < 4; ++i) { |
| bytes.push(0x80 | ((val >> (7 * i)) & 0x7f)); |
| } |
| bytes.push((val >> (7 * 4)) & 0x7f); |
| return bytes; |
| } |
| |
| // Generate a function that calls the "get" import `kNumLocals` times, and |
| // stores each result in a local, then calls the "call" import `kNumLocals` |
| // times with the stored local values. |
| // |
| // The intention is to create a function that has a large stack frame. |
| let body = []; |
| |
| for (let i = 0; i < kNumLocals; ++i) { |
| body.push(kExprCallFunction, 0, kExprSetLocal, ...varuint32(i)); |
| } |
| |
| for (let i = 0; i < kNumLocals; ++i) { |
| body.push(kExprGetLocal, ...varuint32(i), kExprCallFunction, 1); |
| } |
| |
| let builder = new WasmModuleBuilder(); |
| builder.addImport('mod', 'get', kSig_i_v); |
| builder.addImport('mod', 'call', kSig_v_i); |
| builder. |
| addFunction('main', kSig_v_v). |
| addLocals({i32_count: kNumLocals}). |
| addBody(body). |
| exportAs('main'); |
| let m1_bytes = builder.toBuffer(); |
| let m1 = new WebAssembly.Module(m1_bytes); |
| |
| // Serialize the module and postMessage it to another thread. |
| let serialized_m1 = %SerializeWasmModule(m1); |
| |
| let worker_onmessage = function(msg) { |
| let {serialized_m1, m1_bytes} = msg; |
| |
| let m1_clone = %DeserializeWasmModule(serialized_m1, m1_bytes); |
| let imports = {mod: {get: () => 3, call: () => {}}}; |
| let i2 = new WebAssembly.Instance(m1_clone, imports); |
| i2.exports.main(); |
| postMessage('done'); |
| } |
| let workerScript = "onmessage = " + worker_onmessage.toString(); |
| |
| let worker = new Worker(workerScript, {type: 'string'}); |
| worker.postMessage({serialized_m1, m1_bytes}); |
| |
| // Wait for worker to finish. |
| print(worker.getMessage()); |