Commit 7a6e6bb1 authored by Andreas Haas's avatar Andreas Haas Committed by Commit Bot

[wasm] Make WebAssembly.compile() asynchronous

titzer@ originally created this
CL (https://codereview.chromium.org/2757903002). I fixed crashing tests
and adressed some comments of the reviewers.

R=bradnelson@chromium.org, clemensh@chromium.org, mtrofin@chromium.org
BUG=v8:6003

Change-Id: I4ab6d503909402d24043657a896200032e6d1023
Reviewed-on: https://chromium-review.googlesource.com/464887Reviewed-by: 's avatarClemens Hammacher <clemensh@chromium.org>
Reviewed-by: 's avatarMircea Trofin <mtrofin@chromium.org>
Commit-Queue: Andreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#44333}
parent a472eccd
......@@ -1189,7 +1189,7 @@ void Code::CodePrint(std::ostream& os) { // NOLINT
void Foreign::ForeignPrint(std::ostream& os) { // NOLINT
os << "foreign address : " << foreign_address();
os << "foreign address : " << reinterpret_cast<void*>(foreign_address());
os << "\n";
}
......
This diff is collapsed.
......@@ -250,7 +250,6 @@ var failWithMessage;
failWithMessage = function failWithMessage(message) {
print("oh, we failed: " + message);
throw new MjsUnitAssertionError(message);
}
......
// Copyright 2017 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: --expose-wasm --allow-natives-syntax
load("test/mjsunit/wasm/wasm-constants.js");
load("test/mjsunit/wasm/wasm-module-builder.js");
let ok_buffer = (() => {
var builder = new WasmModuleBuilder();
builder.addFunction("f", kSig_i_v)
.addBody([kExprI32Const, 42])
.exportAs("f");
return builder.toBuffer();
})();
// The OK buffer validates and can be made into a module.
assertTrue(WebAssembly.validate(ok_buffer));
let ok_module = new WebAssembly.Module(ok_buffer);
assertTrue(ok_module instanceof WebAssembly.Module);
// The bad buffer does not validate and cannot be made into a module.
let bad_buffer = new ArrayBuffer(0);
assertFalse(WebAssembly.validate(bad_buffer));
assertThrows(() => new WebAssembly.Module(bad_buffer), WebAssembly.CompileError);
function checkModule(module) {
assertTrue(module instanceof WebAssembly.Module);
}
function checkCompileError(ex) {
assertTrue(ex instanceof WebAssembly.CompileError);
}
let kNumCompiles = 3;
// Three compilations of the OK module should succeed.
for (var i = 0; i < kNumCompiles; i++) {
assertPromiseResult(WebAssembly.compile(ok_buffer), checkModule,
(ex) => assertUnreachable);
}
// Three compilations of the bad module should fail.
for (var i = 0; i < kNumCompiles; i++) {
assertPromiseResult(WebAssembly.compile(bad_buffer),
(module) => assertUnreachable,
checkCompileError);
}
// Copyright 2017 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 --validate-asm
// Compilation limits for WASM are not enforced for asm->wasm.
%SetWasmCompileControls(0, false);
function AsmModule() {
"use asm";
function xxx() { return 43; }
function yyy() { return 43; }
function zzz() { return 43; }
function main() { return 43; }
return {main: main};
}
assertEquals(43, AsmModule(
undefined, undefined, new ArrayBuffer(1024)).main());
assertTrue(%IsAsmWasmCode(AsmModule));
// Copyright 2017 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-constants.js");
load("test/mjsunit/wasm/wasm-module-builder.js");
%SetWasmCompileControls(100000, true);
%SetWasmCompileControls(100000, false);
let buffer = (() => {
let builder = new WasmModuleBuilder();
builder.addFunction("f", kSig_i_v)
.addBody([kExprI32Const, 42])
.exportAs("f");
return builder.toBuffer();
})();
let ok_module = new WebAssembly.Module(buffer);
assertTrue(ok_module instanceof WebAssembly.Module);
assertEquals(42, new WebAssembly.Instance(ok_module).exports.f());
failWithMessage = msg => %AbortJS(msg);
async function SuccessfulTest() {
print("SuccessfulTest...");
%SetWasmCompileControls(buffer.byteLength, true);
%SetWasmInstantiateControls();
let m = new WebAssembly.Module(buffer);
let i = new WebAssembly.Instance(m);
assertEquals(i.exports.f(), 42);
}
async function FailSyncCompile() {
print("FailSyncCompile...");
%SetWasmCompileControls(buffer.byteLength - 1, true);
assertThrows(() => new WebAssembly.Module(buffer), RangeError);
print(" wait");
try {
let m = await WebAssembly.compile(buffer);
print(" cont");
assertTrue(m instanceof WebAssembly.Module);
} catch (e) {
print(" catch");
assertUnreachable();
}
}
async function FailSyncInstantiate() {
print("FailSyncInstantiate...");
%SetWasmCompileControls(buffer.byteLength - 1, true);
assertThrows(() => new WebAssembly.Instance(ok_module), RangeError);
print(" wait");
try {
let i = await WebAssembly.instantiate(ok_module);
print(" cont");
assertTrue(i instanceof WebAssembly.Instance);
} catch (e) {
print(" catch: " + e);
assertUnreachable();
}
}
async function FailAsyncCompile() {
print("FailAsyncCompile...");
%SetWasmCompileControls(buffer.byteLength - 1, false);
assertThrows(() => new WebAssembly.Module(buffer), RangeError);
print(" wait");
try {
let m = await WebAssembly.compile(buffer);
print(" cont");
assertUnreachable();
} catch (e) {
print(" catch: " + e);
assertTrue(e instanceof RangeError);
}
}
async function FailAsyncInstantiate() {
print("FailAsyncInstantiate...");
%SetWasmCompileControls(buffer.byteLength - 1, false);
assertThrows(() => new WebAssembly.Instance(buffer), RangeError);
print(" wait");
try {
let m = await WebAssembly.instantiate(buffer);
print(" cont");
assertUnreachable();
} catch (e) {
print(" catch: " + e);
assertTrue(e instanceof RangeError);
}
}
async function TestAll() {
await SuccessfulTest();
await FailSyncCompile();
await FailSyncInstantiate();
await FailAsyncCompile();
await FailAsyncInstantiate();
}
%IncrementWaitCount();
TestAll().then(
() => { %DecrementWaitCount(); },
() => { %DecrementWaitCount(); }
);
This diff is collapsed.
// Copyright 2017 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.
//
// TODO(eholk): Once we have stable test IDs, use those as the key instead.
// See https://github.com/WebAssembly/spec/issues/415
//
// Flags: --expose-wasm --allow-natives-syntax
const known_failures = {
"'WebAssembly.Module.customSections' method":
'https://bugs.chromium.org/p/v8/issues/detail?id=5815',
......@@ -78,7 +81,7 @@ load("test/wasm-js/test/harness/wasm-constants.js");
load("test/wasm-js/test/harness/wasm-module-builder.js");
load("test/wasm-js/test/js-api/jsapi.js");
last_promise.then(_ => {
assertPromiseResult(last_promise, _ => {
if (failures.length > 0) {
let unexpected = false;
print("Some tests FAILED:");
......
// Copyright 2017 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 --validate-asm
load("test/mjsunit/wasm/wasm-constants.js");
load("test/mjsunit/wasm/wasm-module-builder.js");
let buffer = (() => {
var builder = new WasmModuleBuilder();
builder.addFunction("f", kSig_i_v)
.addBody([kExprI32Const, 42])
.exportAs("f");
return builder.toBuffer();
})();
// allow up to the buffer size
%SetWasmCompileControls(buffer.byteLength, true);
%SetWasmInstantiateControls();
var m = new WebAssembly.Module(buffer);
var i = new WebAssembly.Instance(m);
assertEquals(i.exports.f(), 42);
// the buffer can't compile synchronously, but we allow async compile
%SetWasmCompileControls(buffer.byteLength - 1, true);
// test first that we can't sync-instantiate this module anymore
try {
i = new WebAssembly.Instance(m);
} catch (e) {
assertTrue(e instanceof RangeError);
}
//...but we can async-instantiate it
WebAssembly.instantiate(m)
.then(instance => i = instance,
assertUnreachable);
%RunMicrotasks();
assertTrue(i instanceof WebAssembly.Instance);
try {
m = new WebAssembly.Module(buffer);
assertUnreachable();
} catch (e) {
assertTrue(e instanceof RangeError);
}
WebAssembly.compile(buffer)
.then(res => m = res,
m = null);
%RunMicrotasks();
assertTrue(m instanceof WebAssembly.Module)
WebAssembly.instantiate(buffer)
.then(res => m = res.module,
m = null);
%RunMicrotasks();
assertTrue(m instanceof WebAssembly.Module);
// Async compile works, but using the sync instantiate doesn't
i = undefined;
m = undefined;
var ex = undefined;
WebAssembly.compile(buffer)
.then(mod => {
m = mod;
try {
i = new WebAssembly.Instance(m);
} catch (e) {
ex = e;
}
},
e => ex = e);
%RunMicrotasks();
assertTrue(ex instanceof RangeError);
assertEquals(i, undefined);
assertTrue(m instanceof WebAssembly.Module);
// Now block async compile works.
%SetWasmCompileControls(buffer.byteLength - 1, false);
WebAssembly.compile(buffer)
.then(ex = null,
e => ex = e);
%RunMicrotasks();
assertTrue(ex instanceof RangeError);
WebAssembly.instantiate(buffer)
.then(ex = null,
e => ex = e);
%RunMicrotasks();
assertTrue(ex instanceof RangeError);
// Verify that, for asm-wasm, these controls are ignored.
%SetWasmCompileControls(0, false);
function assertValidAsm(func) {
assertTrue(%IsAsmWasmCode(func));
}
function assertWasm(expected, func) {
assertEquals(
expected, func(undefined, undefined, new ArrayBuffer(1024)).caller());
assertValidAsm(func);
}
function TestAsmWasmIsUnaffected() {
"use asm";
function caller() {
return 43;
}
return {caller: caller};
}
assertWasm(43, TestAsmWasmIsUnaffected);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment