Changeset 207825 in webkit


Ignore:
Timestamp:
Oct 25, 2016 10:23:53 AM (8 years ago)
Author:
jfbastien@apple.com
Message:

WebAssembly JS API: implement Module

This implementation allows us to:

  • Syncrhonously create a WebAssembly.Module with a typed array.
  • Creates a compilation plan.
  • Parse the Module and creates corresponding code.
  • Throw WebAssembly.CompileError with mildly helpful [*] error messages on failure.

Consult the API documentation for expected behavior: https://github.com/WebAssembly/design/blob/master/JS.md#webassemblymodule-constructor

For now the implementation discards the generated code.

The next steps will be:

  • Expose a Module's exports.
  • Implement WebAssembly.Instance, which allows instantiating and running a compiled Module.
  • Beef up the testing infrastructure under JSTests/wasm so that more complex modules can be created and tested (instead of writing the bits by hand).

This patch also:

  • Adds assert.instanceof in assert.js.
  • Refactors Wasm::Parser and friends to accept const uint8_t* as well as a Vector, to avoid copying when invoked synchronously.
  • Remove useless Structure from some of the wasm constructors: they're already on the JSGlobalObject, visited properly and all.
  • Fix off-by-one error in parsing: Parser::parseUInt32 failed if the integer was exactly at end of file.

[*] On error messages while parsing: I filed https://bugs.webkit.org/show_bug.cgi?id=163919

WebAssembly JS API: implement Module
https://bugs.webkit.org/show_bug.cgi?id=163903

Reviewed by Keith Miller.

JSTests:

  • wasm/assert.js: use underscore in name, and remove when exporting to avoid clasing with builtin names

(const._notUndef):
(const._isUndef):
(const._eq):
(const._ge):
(const._throws):

  • wasm/js-api/test_basic_api.js: test the WebAssembly.Module API

(const.c.in.constructorProperties.switch):

Source/JavaScriptCore:

  • runtime/ExceptionHelpers.cpp:

(JSC::defaultSourceAppender): make this public so that WebAssembly can use it: it generates those fancy (evaluating '...') messages at the end

  • runtime/ExceptionHelpers.h:
  • runtime/JSGlobalObject.cpp:

(JSC::JSGlobalObject::init): remove the useless Structure from the WebAssembly objects (it's already in this file, no need to hold two references and visit them twice)

  • testWasm.cpp:

(runWasmTests): update API

  • wasm/WasmB3IRGenerator.cpp:

(JSC::Wasm::parseAndCompile): use updated API

  • wasm/WasmB3IRGenerator.h:
  • wasm/WasmFunctionParser.h:

(JSC::Wasm::FunctionParser<Context>::FunctionParser): use updated API
(JSC::Wasm::FunctionParser<Context>::parseExpression): use updated API

  • wasm/WasmModuleParser.cpp:

(JSC::Wasm::ModuleParser::parse): generate error messages

  • wasm/WasmModuleParser.h:

(JSC::Wasm::ModuleParser::ModuleParser):
(JSC::Wasm::ModuleParser::failed):
(JSC::Wasm::ModuleParser::errorMessage):
(JSC::Wasm::ModuleParser::functionInformation):
(JSC::Wasm::ModuleParser::memory):

  • wasm/WasmParser.h: use update non-public API

(JSC::Wasm::Parser::parseVarUInt32):
(JSC::Wasm::Parser::parseVarUInt64):
(JSC::Wasm::Parser::source):
(JSC::Wasm::Parser::length):
(JSC::Wasm::Parser::Parser):
(JSC::Wasm::Parser::consumeCharacter):
(JSC::Wasm::Parser::consumeString):
(JSC::Wasm::Parser::parseUInt32):
(JSC::Wasm::Parser::parseUInt7):

  • wasm/WasmPlan.cpp:

(JSC::Wasm::Plan::Plan):
(JSC::Wasm::Plan::~Plan):

  • wasm/WasmPlan.h:

(JSC::Wasm::Plan::failed):
(JSC::Wasm::Plan::errorMessage):
(JSC::Wasm::Plan::resultSize):
(JSC::Wasm::Plan::result):
(JSC::Wasm::Plan::memory):

  • wasm/js/JSWebAssemblyCompileError.cpp:

(JSC::createWebAssemblyCompileError): makes it easier to throw a WebAssembly.CompileError from Module

  • wasm/js/JSWebAssemblyCompileError.h:
  • wasm/js/WebAssemblyCompileErrorConstructor.cpp:

(JSC::WebAssemblyCompileErrorConstructor::create):
(JSC::WebAssemblyCompileErrorConstructor::finishCreation):

  • wasm/js/WebAssemblyCompileErrorConstructor.h:
  • wasm/js/WebAssemblyInstanceConstructor.cpp:

(JSC::WebAssemblyInstanceConstructor::create):
(JSC::WebAssemblyInstanceConstructor::finishCreation):
(JSC::WebAssemblyInstanceConstructor::visitChildren):

  • wasm/js/WebAssemblyInstanceConstructor.h:
  • wasm/js/WebAssemblyMemoryConstructor.cpp:

(JSC::WebAssemblyMemoryConstructor::create):
(JSC::WebAssemblyMemoryConstructor::finishCreation):
(JSC::WebAssemblyMemoryConstructor::visitChildren):

  • wasm/js/WebAssemblyMemoryConstructor.h:
  • wasm/js/WebAssemblyModuleConstructor.cpp:

(JSC::constructJSWebAssemblyModule):
(JSC::WebAssemblyModuleConstructor::create):
(JSC::WebAssemblyModuleConstructor::finishCreation):
(JSC::WebAssemblyModuleConstructor::visitChildren):

  • wasm/js/WebAssemblyModuleConstructor.h:
  • wasm/js/WebAssemblyRuntimeErrorConstructor.cpp:

(JSC::WebAssemblyRuntimeErrorConstructor::create):
(JSC::WebAssemblyRuntimeErrorConstructor::finishCreation):

  • wasm/js/WebAssemblyRuntimeErrorConstructor.h:
  • wasm/js/WebAssemblyTableConstructor.cpp:

(JSC::WebAssemblyTableConstructor::create):
(JSC::WebAssemblyTableConstructor::finishCreation):
(JSC::WebAssemblyTableConstructor::visitChildren):

  • wasm/js/WebAssemblyTableConstructor.h:
Location:
trunk
Files:
30 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r207824 r207825  
     12016-10-25  JF Bastien  <jfbastien@apple.com>
     2
     3        WebAssembly JS API: implement Module
     4
     5        This implementation allows us to:
     6         - Syncrhonously create a WebAssembly.Module with a typed array.
     7         - Creates a compilation plan.
     8         - Parse the Module and creates corresponding code.
     9         - Throw WebAssembly.CompileError with mildly helpful [*] error messages on
     10           failure.
     11
     12        Consult the API documentation for expected behavior: https://github.com/WebAssembly/design/blob/master/JS.md#webassemblymodule-constructor
     13
     14        For now the implementation discards the generated code.
     15
     16        The next steps will be:
     17         - Expose a Module's exports.
     18         - Implement WebAssembly.Instance, which allows instantiating and running a
     19           compiled Module.
     20         - Beef up the testing infrastructure under JSTests/wasm so that more complex
     21           modules can be created and tested (instead of writing the bits by hand).
     22
     23        This patch also:
     24         - Adds assert.instanceof in assert.js.
     25         - Refactors Wasm::Parser and friends to accept const uint8_t* as well as a
     26           Vector, to avoid copying when invoked synchronously.
     27         - Remove useless Structure from some of the wasm constructors: they're already
     28           on the JSGlobalObject, visited properly and all.
     29         - Fix off-by-one error in parsing: Parser::parseUInt32 failed if the integer
     30           was exactly at end of file.
     31
     32         [*] On error messages while parsing: I filed https://bugs.webkit.org/show_bug.cgi?id=163919
     33
     34        WebAssembly JS API: implement Module
     35        https://bugs.webkit.org/show_bug.cgi?id=163903
     36
     37        Reviewed by Keith Miller.
     38
     39        * wasm/assert.js: use underscore in name, and remove when exporting to avoid clasing with builtin names
     40        (const._notUndef):
     41        (const._isUndef):
     42        (const._eq):
     43        (const._ge):
     44        (const._throws):
     45        * wasm/js-api/test_basic_api.js: test the WebAssembly.Module API
     46        (const.c.in.constructorProperties.switch):
     47
    1482016-10-25  Keith Miller  <keith_miller@apple.com>
    249
  • trunk/JSTests/wasm/assert.js

    r207572 r207825  
    2424 */
    2525
    26 export const notUndef = (v) => {
     26const _notUndef = (v) => {
    2727    if (typeof v === "undefined")
    2828        throw new Error("Shouldn't be undefined");
    2929};
    3030
    31 export const isUndef = (v) => {
     31const _isUndef = (v) => {
    3232    if (typeof v !== "undefined")
    3333        throw new Error("Should be undefined");
    3434};
    3535
    36 export const eq = (lhs, rhs) => {
     36const _eq = (lhs, rhs) => {
    3737    if (lhs !== rhs)
    3838        throw new Error(`Not the same: "${lhs}" and "${rhs}"`);
    3939};
    4040
    41 export const ge = (lhs, rhs) => {
    42     notUndef(lhs);
    43     notUndef(rhs);
     41const _ge = (lhs, rhs) => {
     42    _notUndef(lhs);
     43    _notUndef(rhs);
    4444    if (!(lhs >= rhs))
    4545        throw new Error(`Expected: "${lhs}" < "${rhs}"`);
    4646};
    4747
    48 export const throws = (func, type, message, ...args) => {
     48const _throws = (func, type, message, ...args) => {
    4949    try {
    5050        func(...args);
     
    5656    throw new Error(`Expected to throw a ${type.name} with message "${message}"`);
    5757};
     58
     59const _instanceof = (obj, type) => obj instanceof type;
     60
     61// Use underscore names to avoid clashing with builtin names.
     62export {
     63    _notUndef as notUndef,
     64    _isUndef as isUndef,
     65    _eq as eq,
     66    _ge as ge,
     67    _throws as throws,
     68    _instanceof as instanceof,
     69};
  • trunk/JSTests/wasm/js-api/test_basic_api.js

    r207650 r207825  
    11import * as assert from '../assert.js';
    22import * as utilities from '../utilities.js';
     3
     4const version = 0xC;
     5const emptyModule = Uint8Array.of(0x0, 0x61, 0x73, 0x6d, version, 0x00, 0x00, 0x00);
    36
    47const checkOwnPropertyDescriptor = (obj, prop, expect) => {
     
    1518};
    1619const constructorProperties = {
    17     "Module":       { typeofvalue: "function", writable: true, configurable: true, enumerable: false, length: 1, isError: false },
    18     "Instance":     { typeofvalue: "function", writable: true, configurable: true, enumerable: false, length: 1, isError: false },
    19     "Memory":       { typeofvalue: "function", writable: true, configurable: true, enumerable: false, length: 1, isError: false },
    20     "Table":        { typeofvalue: "function", writable: true, configurable: true, enumerable: false, length: 1, isError: false },
    21     "CompileError": { typeofvalue: "function", writable: true, configurable: true, enumerable: false, length: 1, isError: true },
    22     "RuntimeError": { typeofvalue: "function", writable: true, configurable: true, enumerable: false, length: 1, isError: true },
     20    "Module":       { typeofvalue: "function", writable: true, configurable: true, enumerable: false, length: 1 },
     21    "Instance":     { typeofvalue: "function", writable: true, configurable: true, enumerable: false, length: 1 },
     22    "Memory":       { typeofvalue: "function", writable: true, configurable: true, enumerable: false, length: 1 },
     23    "Table":        { typeofvalue: "function", writable: true, configurable: true, enumerable: false, length: 1 },
     24    "CompileError": { typeofvalue: "function", writable: true, configurable: true, enumerable: false, length: 1 },
     25    "RuntimeError": { typeofvalue: "function", writable: true, configurable: true, enumerable: false, length: 1 },
    2326};
    2427
     
    4548    checkOwnPropertyDescriptor(WebAssembly[c], "prototype", { typeofvalue: "object", writable: false, configurable: false, enumerable: false });
    4649    assert.throws(() => WebAssembly[c](), TypeError, `calling WebAssembly.${c} constructor without new is invalid`);
    47     if (constructorProperties[c].isError) {
     50    switch (c) {
     51    case "Module":
     52        for (const invalid of [undefined, "", 1, {}, []])
     53            assert.throws(() => new WebAssembly[c](invalid), TypeError, `first argument to WebAssembly.Module must be an ArrayBufferView or an ArrayBuffer (evaluating 'new WebAssembly[c](invalid)')`);
     54        for (const buffer of [new ArrayBuffer(), new DataView(new ArrayBuffer()), new Int8Array(), new Uint8Array(), new Uint8ClampedArray(), new Int16Array(), new Uint16Array(), new Int32Array(), new Uint32Array(), new Float32Array(), new Float64Array()])
     55            // FIXME the following should be WebAssembly.CompileError. https://bugs.webkit.org/show_bug.cgi?id=163768
     56            assert.throws(() => new WebAssembly[c](buffer), Error, `Module is 0 bytes, expected at least 8 bytes (evaluating 'new WebAssembly[c](buffer)')`);
     57        assert.instanceof(new WebAssembly[c](emptyModule), WebAssembly.Module);
     58        // FIXME test neutered TypedArray and TypedArrayView. https://bugs.webkit.org/show_bug.cgi?id=163899
     59        break;
     60    case "Instance":
     61        // FIXME Implement and test these APIs further. For now they just throw. https://bugs.webkit.org/show_bug.cgi?id=159775
     62        assert.throws(() => new WebAssembly[c](), Error, `WebAssembly doesn't yet implement the ${c} constructor property`);
     63        break;
     64    case "Memory":
     65        // FIXME Implement and test these APIs further. For now they just throw. https://bugs.webkit.org/show_bug.cgi?id=159775
     66        assert.throws(() => new WebAssembly[c](), Error, `WebAssembly doesn't yet implement the ${c} constructor property`);
     67        break;
     68    case "Table":
     69        // FIXME Implement and test these APIs further. For now they just throw. https://bugs.webkit.org/show_bug.cgi?id=159775
     70        assert.throws(() => new WebAssembly[c](), Error, `WebAssembly doesn't yet implement the ${c} constructor property`);
     71        break;
     72    case "CompileError":
     73    case "RuntimeError": {
    4874        const e = new WebAssembly[c];
    4975        assert.eq(e instanceof WebAssembly[c], true);
     
    5581        const e2 = new WebAssembly[c](sillyString);
    5682        assert.eq(e2.message, sillyString);
     83    } break;
     84    default: throw new Error(`Implementation error: unexpected constructor property "${c}"`);
    5785    }
    5886}
    5987
    6088// FIXME Implement and test these APIs further. For now they just throw. https://bugs.webkit.org/show_bug.cgi?id=159775
    61 
    6289for (const f in functionProperties) {
    6390    assert.throws(() => WebAssembly[f](), Error, `WebAssembly doesn't yet implement the ${f} function property`);
    6491}
    65 
    66 for (const c in constructorProperties) {
    67     if (!constructorProperties[c].isError)
    68         assert.throws(() => new WebAssembly[c](), Error, `WebAssembly doesn't yet implement the ${c} constructor property`);
    69 }
  • trunk/Source/JavaScriptCore/ChangeLog

    r207824 r207825  
     12016-10-25  JF Bastien  <jfbastien@apple.com>
     2
     3        WebAssembly JS API: implement Module
     4
     5        This implementation allows us to:
     6         - Syncrhonously create a WebAssembly.Module with a typed array.
     7         - Creates a compilation plan.
     8         - Parse the Module and creates corresponding code.
     9         - Throw WebAssembly.CompileError with mildly helpful [*] error messages on
     10           failure.
     11
     12        Consult the API documentation for expected behavior: https://github.com/WebAssembly/design/blob/master/JS.md#webassemblymodule-constructor
     13
     14        For now the implementation discards the generated code.
     15
     16        The next steps will be:
     17         - Expose a Module's exports.
     18         - Implement WebAssembly.Instance, which allows instantiating and running a
     19           compiled Module.
     20         - Beef up the testing infrastructure under JSTests/wasm so that more complex
     21           modules can be created and tested (instead of writing the bits by hand).
     22
     23        This patch also:
     24         - Adds assert.instanceof in assert.js.
     25         - Refactors Wasm::Parser and friends to accept const uint8_t* as well as a
     26           Vector, to avoid copying when invoked synchronously.
     27         - Remove useless Structure from some of the wasm constructors: they're already
     28           on the JSGlobalObject, visited properly and all.
     29         - Fix off-by-one error in parsing: Parser::parseUInt32 failed if the integer
     30           was exactly at end of file.
     31
     32         [*] On error messages while parsing: I filed https://bugs.webkit.org/show_bug.cgi?id=163919
     33
     34        WebAssembly JS API: implement Module
     35        https://bugs.webkit.org/show_bug.cgi?id=163903
     36
     37        Reviewed by Keith Miller.
     38
     39        * runtime/ExceptionHelpers.cpp:
     40        (JSC::defaultSourceAppender): make this public so that WebAssembly can use it: it generates those fancy (evaluating '...') messages at the end
     41        * runtime/ExceptionHelpers.h:
     42        * runtime/JSGlobalObject.cpp:
     43        (JSC::JSGlobalObject::init): remove the useless Structure from the WebAssembly objects (it's already in this file, no need to hold two references and visit them twice)
     44        * testWasm.cpp:
     45        (runWasmTests): update API
     46        * wasm/WasmB3IRGenerator.cpp:
     47        (JSC::Wasm::parseAndCompile): use updated API
     48        * wasm/WasmB3IRGenerator.h:
     49        * wasm/WasmFunctionParser.h:
     50        (JSC::Wasm::FunctionParser<Context>::FunctionParser): use updated API
     51        (JSC::Wasm::FunctionParser<Context>::parseExpression): use updated API
     52        * wasm/WasmModuleParser.cpp:
     53        (JSC::Wasm::ModuleParser::parse): generate error messages
     54        * wasm/WasmModuleParser.h:
     55        (JSC::Wasm::ModuleParser::ModuleParser):
     56        (JSC::Wasm::ModuleParser::failed):
     57        (JSC::Wasm::ModuleParser::errorMessage):
     58        (JSC::Wasm::ModuleParser::functionInformation):
     59        (JSC::Wasm::ModuleParser::memory):
     60        * wasm/WasmParser.h: use update non-public API
     61        (JSC::Wasm::Parser::parseVarUInt32):
     62        (JSC::Wasm::Parser::parseVarUInt64):
     63        (JSC::Wasm::Parser::source):
     64        (JSC::Wasm::Parser::length):
     65        (JSC::Wasm::Parser::Parser):
     66        (JSC::Wasm::Parser::consumeCharacter):
     67        (JSC::Wasm::Parser::consumeString):
     68        (JSC::Wasm::Parser::parseUInt32):
     69        (JSC::Wasm::Parser::parseUInt7):
     70        * wasm/WasmPlan.cpp:
     71        (JSC::Wasm::Plan::Plan):
     72        (JSC::Wasm::Plan::~Plan):
     73        * wasm/WasmPlan.h:
     74        (JSC::Wasm::Plan::failed):
     75        (JSC::Wasm::Plan::errorMessage):
     76        (JSC::Wasm::Plan::resultSize):
     77        (JSC::Wasm::Plan::result):
     78        (JSC::Wasm::Plan::memory):
     79        * wasm/js/JSWebAssemblyCompileError.cpp:
     80        (JSC::createWebAssemblyCompileError): makes it easier to throw a WebAssembly.CompileError from Module
     81        * wasm/js/JSWebAssemblyCompileError.h:
     82        * wasm/js/WebAssemblyCompileErrorConstructor.cpp:
     83        (JSC::WebAssemblyCompileErrorConstructor::create):
     84        (JSC::WebAssemblyCompileErrorConstructor::finishCreation):
     85        * wasm/js/WebAssemblyCompileErrorConstructor.h:
     86        * wasm/js/WebAssemblyInstanceConstructor.cpp:
     87        (JSC::WebAssemblyInstanceConstructor::create):
     88        (JSC::WebAssemblyInstanceConstructor::finishCreation):
     89        (JSC::WebAssemblyInstanceConstructor::visitChildren):
     90        * wasm/js/WebAssemblyInstanceConstructor.h:
     91        * wasm/js/WebAssemblyMemoryConstructor.cpp:
     92        (JSC::WebAssemblyMemoryConstructor::create):
     93        (JSC::WebAssemblyMemoryConstructor::finishCreation):
     94        (JSC::WebAssemblyMemoryConstructor::visitChildren):
     95        * wasm/js/WebAssemblyMemoryConstructor.h:
     96        * wasm/js/WebAssemblyModuleConstructor.cpp:
     97        (JSC::constructJSWebAssemblyModule):
     98        (JSC::WebAssemblyModuleConstructor::create):
     99        (JSC::WebAssemblyModuleConstructor::finishCreation):
     100        (JSC::WebAssemblyModuleConstructor::visitChildren):
     101        * wasm/js/WebAssemblyModuleConstructor.h:
     102        * wasm/js/WebAssemblyRuntimeErrorConstructor.cpp:
     103        (JSC::WebAssemblyRuntimeErrorConstructor::create):
     104        (JSC::WebAssemblyRuntimeErrorConstructor::finishCreation):
     105        * wasm/js/WebAssemblyRuntimeErrorConstructor.h:
     106        * wasm/js/WebAssemblyTableConstructor.cpp:
     107        (JSC::WebAssemblyTableConstructor::create):
     108        (JSC::WebAssemblyTableConstructor::finishCreation):
     109        (JSC::WebAssemblyTableConstructor::visitChildren):
     110        * wasm/js/WebAssemblyTableConstructor.h:
     111
    11122016-10-25  Keith Miller  <keith_miller@apple.com>
    2113
  • trunk/Source/JavaScriptCore/runtime/ExceptionHelpers.cpp

    r206476 r207825  
    102102}
    103103
    104 static String defaultSourceAppender(const String& originalMessage, const String& sourceText, RuntimeType, ErrorInstance::SourceTextWhereErrorOccurred occurrence)
     104String defaultSourceAppender(const String& originalMessage, const String& sourceText, RuntimeType, ErrorInstance::SourceTextWhereErrorOccurred occurrence)
    105105{
    106106    if (occurrence == ErrorInstance::FoundApproximateSource)
  • trunk/Source/JavaScriptCore/runtime/ExceptionHelpers.h

    r206525 r207825  
    3737
    3838typedef JSObject* (*ErrorFactory)(ExecState*, const String&, ErrorInstance::SourceAppender);
     39
     40String defaultSourceAppender(const String&, const String&, RuntimeType, ErrorInstance::SourceTextWhereErrorOccurred);
    3941
    4042JSObject* createTerminatedExecutionException(VM*);
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp

    r207650 r207825  
    833833        auto* prototype = Prototype::create(vm, this, Prototype::createStructure(vm, this, base)); \
    834834        auto* structure = JSObj::createStructure(vm, this, prototype); \
    835         auto* constructor = Constructor::create(vm, Constructor::createStructure(vm, this, this->functionPrototype()), prototype, structure); \
     835        auto* constructor = Constructor::create(vm, Constructor::createStructure(vm, this, this->functionPrototype()), prototype); \
    836836        prototype->putDirectWithoutTransition(vm, vm.propertyNames->constructor, constructor, DontEnum); \
    837837        m_ ## lowerName ## Prototype.set(vm, this, prototype); \
  • trunk/Source/JavaScriptCore/testWasm.cpp

    r207781 r207825  
    291291
    292292        Plan plan(*vm, vector);
    293         if (plan.result.size() != 2 || !plan.result[0] || !plan.result[1]) {
    294             dataLogLn("Module failed to compile correctly.");
    295             CRASH();
    296         }
    297 
    298         // Test this doesn't crash.
    299         CHECK(isIdentical(invoke<float>(*plan.result[1]->jsEntryPoint, { boxf(0.0), boxf(1.5) }), -1.5f));
    300         CHECK(isIdentical(invoke<float>(*plan.result[1]->jsEntryPoint, { boxf(100.1234), boxf(12.5) }), 87.6234f));
    301         CHECK(isIdentical(invoke<float>(*plan.result[0]->jsEntryPoint, { boxf(0.0), boxf(1.5) }), -1.5f));
    302         CHECK(isIdentical(invoke<float>(*plan.result[0]->jsEntryPoint, { boxf(100.1234), boxf(12.5) }), 87.6234f));
     293        if (plan.failed() || plan.resultSize() != 2 || !plan.result(0) || !plan.result(1)) {
     294            dataLogLn("Module failed to compile correctly.");
     295            CRASH();
     296        }
     297
     298        // Test this doesn't crash.
     299        CHECK(isIdentical(invoke<float>(*plan.result(1)->jsEntryPoint, { boxf(0.0), boxf(1.5) }), -1.5f));
     300        CHECK(isIdentical(invoke<float>(*plan.result(1)->jsEntryPoint, { boxf(100.1234), boxf(12.5) }), 87.6234f));
     301        CHECK(isIdentical(invoke<float>(*plan.result(0)->jsEntryPoint, { boxf(0.0), boxf(1.5) }), -1.5f));
     302        CHECK(isIdentical(invoke<float>(*plan.result(0)->jsEntryPoint, { boxf(100.1234), boxf(12.5) }), 87.6234f));
    303303    }
    304304
     
    320320
    321321        Plan plan(*vm, vector);
    322         if (plan.result.size() != 2 || !plan.result[0] || !plan.result[1]) {
    323             dataLogLn("Module failed to compile correctly.");
    324             CRASH();
    325         }
    326 
    327         // Test this doesn't crash.
    328         CHECK(isIdentical(invoke<float>(*plan.result[1]->jsEntryPoint, { boxf(0.0), boxf(1.5) }), 1.5f));
    329         CHECK(isIdentical(invoke<float>(*plan.result[1]->jsEntryPoint, { boxf(100.1234), boxf(12.5) }), 112.6234f));
    330         CHECK(isIdentical(invoke<float>(*plan.result[0]->jsEntryPoint, { boxf(0.0), boxf(1.5) }), 1.5f));
    331         CHECK(isIdentical(invoke<float>(*plan.result[0]->jsEntryPoint, { boxf(100.1234), boxf(12.5) }), 112.6234f));
     322        if (plan.failed() || plan.resultSize() != 2 || !plan.result(0) || !plan.result(1)) {
     323            dataLogLn("Module failed to compile correctly.");
     324            CRASH();
     325        }
     326
     327        // Test this doesn't crash.
     328        CHECK(isIdentical(invoke<float>(*plan.result(1)->jsEntryPoint, { boxf(0.0), boxf(1.5) }), 1.5f));
     329        CHECK(isIdentical(invoke<float>(*plan.result(1)->jsEntryPoint, { boxf(100.1234), boxf(12.5) }), 112.6234f));
     330        CHECK(isIdentical(invoke<float>(*plan.result(0)->jsEntryPoint, { boxf(0.0), boxf(1.5) }), 1.5f));
     331        CHECK(isIdentical(invoke<float>(*plan.result(0)->jsEntryPoint, { boxf(100.1234), boxf(12.5) }), 112.6234f));
    332332    }
    333333
     
    354354
    355355        Plan plan(*vm, vector);
    356         if (plan.result.size() != 2 || !plan.result[0] || !plan.result[1]) {
    357             dataLogLn("Module failed to compile correctly.");
    358             CRASH();
    359         }
    360 
    361         // Test this doesn't crash.
    362         CHECK_EQ(invoke<int>(*plan.result[1]->jsEntryPoint, { box(0) }), 0);
    363         CHECK_EQ(invoke<int>(*plan.result[1]->jsEntryPoint, { box(100) }), 1200);
    364         CHECK_EQ(invoke<int>(*plan.result[1]->jsEntryPoint, { box(1) }), 12);
    365         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(1), box(2), box(3), box(4), box(5), box(6), box(7), box(8), box(9), box(10), box(11), box(12) }), 78);
    366         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(1), box(2), box(3), box(4), box(5), box(6), box(7), box(8), box(9), box(10), box(11), box(100) }), 166);
     356        if (plan.failed() || plan.resultSize() != 2 || !plan.result(0) || !plan.result(1)) {
     357            dataLogLn("Module failed to compile correctly.");
     358            CRASH();
     359        }
     360
     361        // Test this doesn't crash.
     362        CHECK_EQ(invoke<int>(*plan.result(1)->jsEntryPoint, { box(0) }), 0);
     363        CHECK_EQ(invoke<int>(*plan.result(1)->jsEntryPoint, { box(100) }), 1200);
     364        CHECK_EQ(invoke<int>(*plan.result(1)->jsEntryPoint, { box(1) }), 12);
     365        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(1), box(2), box(3), box(4), box(5), box(6), box(7), box(8), box(9), box(10), box(11), box(12) }), 78);
     366        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(1), box(2), box(3), box(4), box(5), box(6), box(7), box(8), box(9), box(10), box(11), box(100) }), 166);
    367367    }
    368368
     
    388388
    389389        Plan plan(*vm, vector);
    390         if (plan.result.size() != 1 || !plan.result[0]) {
    391             dataLogLn("Module failed to compile correctly.");
    392             CRASH();
    393         }
    394 
    395         // Test this doesn't crash.
    396         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(0) }), 1);
    397         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(1) }), 1);
    398         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(2) }), 2);
    399         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(4) }), 24);
     390        if (plan.failed() || plan.resultSize() != 1 || !plan.result(0)) {
     391            dataLogLn("Module failed to compile correctly.");
     392            CRASH();
     393        }
     394
     395        // Test this doesn't crash.
     396        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(0) }), 1);
     397        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(1) }), 1);
     398        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(2) }), 2);
     399        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(4) }), 24);
    400400    }
    401401
     
    417417
    418418        Plan plan(*vm, vector);
    419         if (plan.result.size() != 2 || !plan.result[0] || !plan.result[1]) {
    420             dataLogLn("Module failed to compile correctly.");
    421             CRASH();
    422         }
    423 
    424         // Test this doesn't crash.
    425         CHECK_EQ(invoke<int>(*plan.result[1]->jsEntryPoint, { box(0), box(0) }), 0);
    426         CHECK_EQ(invoke<int>(*plan.result[1]->jsEntryPoint, { box(100), box(0) }), 100);
    427         CHECK_EQ(invoke<int>(*plan.result[1]->jsEntryPoint, { box(1), box(15) }), 16);
    428         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(0) }), 0);
    429         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(100) }), 200);
    430         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(1) }), 2);
     419        if (plan.resultSize() != 2 || !plan.result(0) || !plan.result(1)) {
     420            dataLogLn("Module failed to compile correctly.");
     421            CRASH();
     422        }
     423
     424        // Test this doesn't crash.
     425        CHECK_EQ(invoke<int>(*plan.result(1)->jsEntryPoint, { box(0), box(0) }), 0);
     426        CHECK_EQ(invoke<int>(*plan.result(1)->jsEntryPoint, { box(100), box(0) }), 100);
     427        CHECK_EQ(invoke<int>(*plan.result(1)->jsEntryPoint, { box(1), box(15) }), 16);
     428        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(0) }), 0);
     429        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(100) }), 200);
     430        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(1) }), 2);
    431431    }
    432432
     
    448448
    449449        Plan plan(*vm, vector);
    450         if (plan.result.size() != 2 || !plan.result[0] || !plan.result[1]) {
    451             dataLogLn("Module failed to compile correctly.");
    452             CRASH();
    453         }
    454 
    455         // Test this doesn't crash.
    456         CHECK_EQ(invoke<int>(*plan.result[1]->jsEntryPoint, { box(0) }), 0);
    457         CHECK_EQ(invoke<int>(*plan.result[1]->jsEntryPoint, { box(100) }), 100);
    458         CHECK_EQ(invoke<int>(*plan.result[1]->jsEntryPoint, { box(1) }), 1);
    459         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(0) }), 0);
    460         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(100) }), 100);
    461         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(1) }), 1);
     450        if (plan.failed() || plan.resultSize() != 2 || !plan.result(0) || !plan.result(1)) {
     451            dataLogLn("Module failed to compile correctly.");
     452            CRASH();
     453        }
     454
     455        // Test this doesn't crash.
     456        CHECK_EQ(invoke<int>(*plan.result(1)->jsEntryPoint, { box(0) }), 0);
     457        CHECK_EQ(invoke<int>(*plan.result(1)->jsEntryPoint, { box(100) }), 100);
     458        CHECK_EQ(invoke<int>(*plan.result(1)->jsEntryPoint, { box(1) }), 1);
     459        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(0) }), 0);
     460        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(100) }), 100);
     461        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(1) }), 1);
    462462    }
    463463
     
    481481
    482482        Plan plan(*vm, vector);
    483         if (plan.result.size() != 1 || !plan.result[0]) {
    484             dataLogLn("Module failed to compile correctly.");
    485             CRASH();
    486         }
    487 
    488         // Test this doesn't crash.
    489         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(0), box(10) }), 0);
    490         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(100), box(2) }), 100);
    491         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(1), box(100) }), 1);
     483        if (plan.failed() || plan.resultSize() != 1 || !plan.result(0)) {
     484            dataLogLn("Module failed to compile correctly.");
     485            CRASH();
     486        }
     487
     488        // Test this doesn't crash.
     489        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(0), box(10) }), 0);
     490        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(100), box(2) }), 100);
     491        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(1), box(100) }), 1);
    492492    }
    493493
     
    511511
    512512        Plan plan(*vm, vector);
    513         if (plan.result.size() != 1 || !plan.result[0]) {
    514             dataLogLn("Module failed to compile correctly.");
    515             CRASH();
    516         }
    517 
    518         // Test this doesn't crash.
    519         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(0), box(10) }), 0);
    520         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(100), box(2) }), 100);
    521         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(1), box(100) }), 1);
     513        if (plan.failed() || plan.resultSize() != 1 || !plan.result(0)) {
     514            dataLogLn("Module failed to compile correctly.");
     515            CRASH();
     516        }
     517
     518        // Test this doesn't crash.
     519        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(0), box(10) }), 0);
     520        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(100), box(2) }), 100);
     521        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(1), box(100) }), 1);
    522522    }
    523523
     
    551551
    552552        Plan plan(*vm, vector);
    553         if (plan.result.size() != 1 || !plan.result[0]) {
    554             dataLogLn("Module failed to compile correctly.");
    555             CRASH();
    556         }
    557         ASSERT(plan.memory->size());
     553        if (plan.failed() || plan.resultSize() != 1 || !plan.result(0)) {
     554            dataLogLn("Module failed to compile correctly.");
     555            CRASH();
     556        }
     557        ASSERT(plan.memory()->size());
    558558
    559559        // Test this doesn't crash.
    560560        unsigned length = 5;
    561561        unsigned offset = sizeof(uint32_t);
    562         uint32_t* memory = static_cast<uint32_t*>(plan.memory->memory());
    563         invoke<void>(*plan.result[0]->jsEntryPoint, { box(100), box(offset), box(length) });
     562        uint32_t* memory = static_cast<uint32_t*>(plan.memory()->memory());
     563        invoke<void>(*plan.result(0)->jsEntryPoint, { box(100), box(offset), box(length) });
    564564        offset /= sizeof(uint32_t);
    565565        CHECK_EQ(memory[offset - 1], 0u);
     
    570570        length = 10;
    571571        offset = 5 * sizeof(uint32_t);
    572         invoke<void>(*plan.result[0]->jsEntryPoint, { box(5), box(offset), box(length) });
     572        invoke<void>(*plan.result(0)->jsEntryPoint, { box(5), box(offset), box(length) });
    573573        offset /= sizeof(uint32_t);
    574574        CHECK_EQ(memory[offset - 1], 100u);
     
    606606
    607607        Plan plan(*vm, vector);
    608         if (plan.result.size() != 1 || !plan.result[0]) {
    609             dataLogLn("Module failed to compile correctly.");
    610             CRASH();
    611         }
    612         ASSERT(plan.memory->size());
     608        if (plan.failed() || plan.resultSize() != 1 || !plan.result(0)) {
     609            dataLogLn("Module failed to compile correctly.");
     610            CRASH();
     611        }
     612        ASSERT(plan.memory()->size());
    613613
    614614        // Test this doesn't crash.
    615615        unsigned length = 5;
    616616        unsigned offset = 1;
    617         uint8_t* memory = static_cast<uint8_t*>(plan.memory->memory());
    618         invoke<void>(*plan.result[0]->jsEntryPoint, { box(100), box(offset), box(length) });
     617        uint8_t* memory = static_cast<uint8_t*>(plan.memory()->memory());
     618        invoke<void>(*plan.result(0)->jsEntryPoint, { box(100), box(offset), box(length) });
    619619        CHECK_EQ(memory[offset - 1], 0u);
    620620        CHECK_EQ(memory[offset + length], 0u);
     
    624624        length = 10;
    625625        offset = 5;
    626         invoke<void>(*plan.result[0]->jsEntryPoint, { box(5), box(offset), box(length) });
     626        invoke<void>(*plan.result(0)->jsEntryPoint, { box(5), box(offset), box(length) });
    627627        CHECK_EQ(memory[offset - 1], 100u);
    628628        CHECK_EQ(memory[offset + length], 0u);
     
    650650
    651651        Plan plan(*vm, vector);
    652         if (plan.result.size() != 1 || !plan.result[0]) {
    653             dataLogLn("Module failed to compile correctly.");
    654             CRASH();
    655         }
    656         ASSERT(plan.memory->size());
    657 
    658         // Test this doesn't crash.
    659         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(0), box(10) }), 0);
    660         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(100), box(2) }), 100);
    661         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(1), box(100) }), 1);
     652        if (plan.failed() || plan.resultSize() != 1 || !plan.result(0)) {
     653            dataLogLn("Module failed to compile correctly.");
     654            CRASH();
     655        }
     656        ASSERT(plan.memory()->size());
     657
     658        // Test this doesn't crash.
     659        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(0), box(10) }), 0);
     660        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(100), box(2) }), 100);
     661        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(1), box(100) }), 1);
    662662    }
    663663
     
    681681
    682682        Plan plan(*vm, vector);
    683         if (plan.result.size() != 1 || !plan.result[0]) {
    684             dataLogLn("Module failed to compile correctly.");
    685             CRASH();
    686         }
    687 
    688         // Test this doesn't crash.
    689         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(0) }), 0);
    690         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(100) }), 100);
    691         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(1) }), 1);
     683        if (plan.failed() || plan.resultSize() != 1 || !plan.result(0)) {
     684            dataLogLn("Module failed to compile correctly.");
     685            CRASH();
     686        }
     687
     688        // Test this doesn't crash.
     689        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(0) }), 0);
     690        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(100) }), 100);
     691        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(1) }), 1);
    692692    }
    693693
     
    711711
    712712        Plan plan(*vm, vector);
    713         if (plan.result.size() != 1 || !plan.result[0]) {
    714             dataLogLn("Module failed to compile correctly.");
    715             CRASH();
    716         }
    717 
    718         // Test this doesn't crash.
    719         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(0), box(10) }), 0);
    720         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(100), box(2) }), 100);
    721         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(1), box(100) }), 1);
    722         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(-12), box(plan.memory->size() - sizeof(uint64_t)) }), -12);
     713        if (plan.failed() || plan.resultSize() != 1 || !plan.result(0)) {
     714            dataLogLn("Module failed to compile correctly.");
     715            CRASH();
     716        }
     717
     718        // Test this doesn't crash.
     719        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(0), box(10) }), 0);
     720        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(100), box(2) }), 100);
     721        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(1), box(100) }), 1);
     722        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(-12), box(plan.memory()->size() - sizeof(uint64_t)) }), -12);
    723723    }
    724724
     
    742742
    743743        Plan plan(*vm, vector);
    744         if (plan.result.size() != 1 || !plan.result[0]) {
    745             dataLogLn("Module failed to compile correctly.");
    746             CRASH();
    747         }
    748 
    749         // Test this doesn't crash.
    750         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(0), box(10) }), 0);
    751         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(100), box(2) }), 100);
    752         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(1), box(100) }), 1);
     744        if (plan.failed() || plan.resultSize() != 1 || !plan.result(0)) {
     745            dataLogLn("Module failed to compile correctly.");
     746            CRASH();
     747        }
     748
     749        // Test this doesn't crash.
     750        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(0), box(10) }), 0);
     751        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(100), box(2) }), 100);
     752        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(1), box(100) }), 1);
    753753    }
    754754
     
    782782
    783783        Plan plan(*vm, vector);
    784         if (plan.result.size() != 1 || !plan.result[0]) {
    785             dataLogLn("Module failed to compile correctly.");
    786             CRASH();
    787         }
    788         ASSERT(plan.memory->size());
     784        if (plan.failed() || plan.resultSize() != 1 || !plan.result(0)) {
     785            dataLogLn("Module failed to compile correctly.");
     786            CRASH();
     787        }
     788        ASSERT(plan.memory()->size());
    789789
    790790        // Test this doesn't crash.
    791791        unsigned length = 5;
    792792        unsigned offset = sizeof(uint32_t);
    793         uint32_t* memory = static_cast<uint32_t*>(plan.memory->memory());
    794         invoke<void>(*plan.result[0]->jsEntryPoint, { box(100), box(offset), box(length) });
     793        uint32_t* memory = static_cast<uint32_t*>(plan.memory()->memory());
     794        invoke<void>(*plan.result(0)->jsEntryPoint, { box(100), box(offset), box(length) });
    795795        offset /= sizeof(uint32_t);
    796796        CHECK_EQ(memory[offset - 1], 0u);
     
    801801        length = 10;
    802802        offset = 5 * sizeof(uint32_t);
    803         invoke<void>(*plan.result[0]->jsEntryPoint, { box(5), box(offset), box(length) });
     803        invoke<void>(*plan.result(0)->jsEntryPoint, { box(5), box(offset), box(length) });
    804804        offset /= sizeof(uint32_t);
    805805        CHECK_EQ(memory[offset - 1], 100u);
     
    837837
    838838        Plan plan(*vm, vector);
    839         if (plan.result.size() != 1 || !plan.result[0]) {
    840             dataLogLn("Module failed to compile correctly.");
    841             CRASH();
    842         }
    843         ASSERT(plan.memory->size());
     839        if (plan.failed() || plan.resultSize() != 1 || !plan.result(0)) {
     840            dataLogLn("Module failed to compile correctly.");
     841            CRASH();
     842        }
     843        ASSERT(plan.memory()->size());
    844844
    845845        // Test this doesn't crash.
    846846        unsigned length = 5;
    847847        unsigned offset = 1;
    848         uint8_t* memory = static_cast<uint8_t*>(plan.memory->memory());
    849         invoke<void>(*plan.result[0]->jsEntryPoint, { box(100), box(offset), box(length) });
     848        uint8_t* memory = static_cast<uint8_t*>(plan.memory()->memory());
     849        invoke<void>(*plan.result(0)->jsEntryPoint, { box(100), box(offset), box(length) });
    850850        CHECK_EQ(memory[offset - 1], 0u);
    851851        CHECK_EQ(memory[offset + length], 0u);
     
    855855        length = 10;
    856856        offset = 5;
    857         invoke<void>(*plan.result[0]->jsEntryPoint, { box(5), box(offset), box(length) });
     857        invoke<void>(*plan.result(0)->jsEntryPoint, { box(5), box(offset), box(length) });
    858858        CHECK_EQ(memory[offset - 1], 100u);
    859859        CHECK_EQ(memory[offset + length], 0u);
     
    881881
    882882        Plan plan(*vm, vector);
    883         if (plan.result.size() != 1 || !plan.result[0]) {
    884             dataLogLn("Module failed to compile correctly.");
    885             CRASH();
    886         }
    887         ASSERT(plan.memory->size());
    888 
    889         // Test this doesn't crash.
    890         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(0), box(10) }), 0);
    891         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(100), box(2) }), 100);
    892         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(1), box(100) }), 1);
     883        if (plan.failed() || plan.resultSize() != 1 || !plan.result(0)) {
     884            dataLogLn("Module failed to compile correctly.");
     885            CRASH();
     886        }
     887        ASSERT(plan.memory()->size());
     888
     889        // Test this doesn't crash.
     890        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(0), box(10) }), 0);
     891        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(100), box(2) }), 100);
     892        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(1), box(100) }), 1);
    893893    }
    894894
     
    912912
    913913        Plan plan(*vm, vector);
    914         if (plan.result.size() != 1 || !plan.result[0]) {
    915             dataLogLn("Module failed to compile correctly.");
    916             CRASH();
    917         }
    918 
    919         // Test this doesn't crash.
    920         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(0) }), 0);
    921         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(100) }), 100);
    922         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(1) }), 1);
     914        if (plan.failed() || plan.resultSize() != 1 || !plan.result(0)) {
     915            dataLogLn("Module failed to compile correctly.");
     916            CRASH();
     917        }
     918
     919        // Test this doesn't crash.
     920        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(0) }), 0);
     921        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(100) }), 100);
     922        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(1) }), 1);
    923923    }
    924924
     
    942942
    943943        Plan plan(*vm, vector);
    944         if (plan.result.size() != 1 || !plan.result[0]) {
    945             dataLogLn("Module failed to compile correctly.");
    946             CRASH();
    947         }
    948 
    949         // Test this doesn't crash.
    950         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(0), box(1) }), 1);
    951         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(1), box(0) }), 1);
    952         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(2), box(1) }), 1);
    953         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(1), box(2) }), 1);
    954         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(2), box(2) }), 0);
    955         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(1), box(1) }), 0);
    956         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(2), box(6) }), 1);
    957         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(100), box(6) }), 1);
     944        if (plan.failed() || plan.resultSize() != 1 || !plan.result(0)) {
     945            dataLogLn("Module failed to compile correctly.");
     946            CRASH();
     947        }
     948
     949        // Test this doesn't crash.
     950        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(0), box(1) }), 1);
     951        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(1), box(0) }), 1);
     952        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(2), box(1) }), 1);
     953        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(1), box(2) }), 1);
     954        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(2), box(2) }), 0);
     955        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(1), box(1) }), 0);
     956        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(2), box(6) }), 1);
     957        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(100), box(6) }), 1);
    958958    }
    959959
     
    983983
    984984        Plan plan(*vm, vector);
    985         if (plan.result.size() != 1 || !plan.result[0]) {
    986             dataLogLn("Module failed to compile correctly.");
    987             CRASH();
    988         }
    989 
    990         // Test this doesn't crash.
    991         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(0), box(1) }), 1);
    992         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(1), box(0) }), 0);
    993         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(2), box(1) }), 0);
    994         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(1), box(2) }), 1);
    995         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(2), box(2) }), 0);
    996         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(1), box(1) }), 0);
    997         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(2), box(6) }), 1);
    998         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(100), box(6) }), 0);
     985        if (plan.failed() || plan.resultSize() != 1 || !plan.result(0)) {
     986            dataLogLn("Module failed to compile correctly.");
     987            CRASH();
     988        }
     989
     990        // Test this doesn't crash.
     991        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(0), box(1) }), 1);
     992        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(1), box(0) }), 0);
     993        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(2), box(1) }), 0);
     994        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(1), box(2) }), 1);
     995        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(2), box(2) }), 0);
     996        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(1), box(1) }), 0);
     997        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(2), box(6) }), 1);
     998        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(100), box(6) }), 0);
    999999    }
    10001000
     
    10101010
    10111011        Plan plan(*vm, vector);
    1012         if (plan.result.size() != 1 || !plan.result[0]) {
    1013             dataLogLn("Module failed to compile correctly.");
    1014             CRASH();
    1015         }
    1016 
    1017         // Test this doesn't crash.
    1018         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { }), 5);
     1012        if (plan.failed() || plan.resultSize() != 1 || !plan.result(0)) {
     1013            dataLogLn("Module failed to compile correctly.");
     1014            CRASH();
     1015        }
     1016
     1017        // Test this doesn't crash.
     1018        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { }), 5);
    10191019    }
    10201020
     
    10311031
    10321032        Plan plan(*vm, vector);
    1033         if (plan.result.size() != 1 || !plan.result[0]) {
    1034             dataLogLn("Module failed to compile correctly.");
    1035             CRASH();
    1036         }
    1037 
    1038         // Test this doesn't crash.
    1039         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { }), 11);
     1033        if (plan.failed() || plan.resultSize() != 1 || !plan.result(0)) {
     1034            dataLogLn("Module failed to compile correctly.");
     1035            CRASH();
     1036        }
     1037
     1038        // Test this doesn't crash.
     1039        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { }), 11);
    10401040    }
    10411041
     
    10511051
    10521052        Plan plan(*vm, vector);
    1053         if (plan.result.size() != 1 || !plan.result[0]) {
    1054             dataLogLn("Module failed to compile correctly.");
    1055             CRASH();
    1056         }
    1057 
    1058         // Test this doesn't crash.
    1059         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { }), 11);
     1053        if (plan.failed() || plan.resultSize() != 1 || !plan.result(0)) {
     1054            dataLogLn("Module failed to compile correctly.");
     1055            CRASH();
     1056        }
     1057
     1058        // Test this doesn't crash.
     1059        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { }), 11);
    10601060    }
    10611061
     
    10711071
    10721072        Plan plan(*vm, vector);
    1073         if (plan.result.size() != 1 || !plan.result[0]) {
    1074             dataLogLn("Module failed to compile correctly.");
    1075             CRASH();
    1076         }
    1077 
    1078         // Test this doesn't crash.
    1079         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { }), 11);
     1073        if (plan.failed() || plan.resultSize() != 1 || !plan.result(0)) {
     1074            dataLogLn("Module failed to compile correctly.");
     1075            CRASH();
     1076        }
     1077
     1078        // Test this doesn't crash.
     1079        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { }), 11);
    10801080    }
    10811081
     
    10901090
    10911091        Plan plan(*vm, vector);
    1092         if (plan.result.size() != 1 || !plan.result[0]) {
    1093             dataLogLn("Module failed to compile correctly.");
    1094             CRASH();
    1095         }
    1096 
    1097         // Test this doesn't crash.
    1098         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(0), box(1) }), 1);
    1099         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(100), box(1) }), 101);
    1100         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(-1), box(1)}), 0);
    1101         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(std::numeric_limits<int>::max()), box(1) }), std::numeric_limits<int>::min());
     1092        if (plan.failed() || plan.resultSize() != 1 || !plan.result(0)) {
     1093            dataLogLn("Module failed to compile correctly.");
     1094            CRASH();
     1095        }
     1096
     1097        // Test this doesn't crash.
     1098        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(0), box(1) }), 1);
     1099        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(100), box(1) }), 101);
     1100        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(-1), box(1)}), 0);
     1101        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(std::numeric_limits<int>::max()), box(1) }), std::numeric_limits<int>::min());
    11021102    }
    11031103
     
    11191119
    11201120        Plan plan(*vm, vector);
    1121         if (plan.result.size() != 1 || !plan.result[0]) {
    1122             dataLogLn("Module failed to compile correctly.");
    1123             CRASH();
    1124         }
    1125 
    1126         // Test this doesn't crash.
    1127         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(0) }), 0);
    1128         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(10) }), 10);
     1121        if (plan.failed() || plan.resultSize() != 1 || !plan.result(0)) {
     1122            dataLogLn("Module failed to compile correctly.");
     1123            CRASH();
     1124        }
     1125
     1126        // Test this doesn't crash.
     1127        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(0) }), 0);
     1128        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(10) }), 10);
    11291129    }
    11301130
     
    11551155
    11561156        Plan plan(*vm, vector);
    1157         if (plan.result.size() != 1 || !plan.result[0]) {
    1158             dataLogLn("Module failed to compile correctly.");
    1159             CRASH();
    1160         }
    1161 
    1162         // Test this doesn't crash.
    1163         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(0) }), 0);
    1164         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(1) }), 1);
    1165         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(2)}), 3);
    1166         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(100) }), 5050);
     1157        if (plan.failed() || plan.resultSize() != 1 || !plan.result(0)) {
     1158            dataLogLn("Module failed to compile correctly.");
     1159            CRASH();
     1160        }
     1161
     1162        // Test this doesn't crash.
     1163        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(0) }), 0);
     1164        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(1) }), 1);
     1165        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(2)}), 3);
     1166        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(100) }), 5050);
    11671167    }
    11681168
     
    11991199
    12001200        Plan plan(*vm, vector);
    1201         if (plan.result.size() != 1 || !plan.result[0]) {
    1202             dataLogLn("Module failed to compile correctly.");
    1203             CRASH();
    1204         }
    1205 
    1206         // Test this doesn't crash.
    1207         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(0), box(1) }), 0);
    1208         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(1), box(0) }), 0);
    1209         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(2), box(1) }), 2);
    1210         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(1), box(2) }), 2);
    1211         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(2), box(2) }), 4);
    1212         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(2), box(6) }), 12);
    1213         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(100), box(6) }), 600);
    1214         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(100), box(100) }), 10000);
     1201        if (plan.failed() || plan.resultSize() != 1 || !plan.result(0)) {
     1202            dataLogLn("Module failed to compile correctly.");
     1203            CRASH();
     1204        }
     1205
     1206        // Test this doesn't crash.
     1207        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(0), box(1) }), 0);
     1208        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(1), box(0) }), 0);
     1209        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(2), box(1) }), 2);
     1210        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(1), box(2) }), 2);
     1211        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(2), box(2) }), 4);
     1212        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(2), box(6) }), 12);
     1213        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(100), box(6) }), 600);
     1214        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(100), box(100) }), 10000);
    12151215    }
    12161216
     
    12521252
    12531253        Plan plan(*vm, vector);
    1254         if (plan.result.size() != 1 || !plan.result[0]) {
    1255             dataLogLn("Module failed to compile correctly.");
    1256             CRASH();
    1257         }
    1258 
    1259         // Test this doesn't crash.
    1260         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(0), box(1) }), 1);
    1261         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(1), box(0) }), 0);
    1262         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(2), box(1) }), 0);
    1263         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(1), box(2) }), 1);
    1264         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(2), box(2) }), 0);
    1265         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(1), box(1) }), 0);
    1266         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(2), box(6) }), 1);
    1267         CHECK_EQ(invoke<int>(*plan.result[0]->jsEntryPoint, { box(100), box(6) }), 0);
     1254        if (plan.failed() || plan.resultSize() != 1 || !plan.result(0)) {
     1255            dataLogLn("Module failed to compile correctly.");
     1256            CRASH();
     1257        }
     1258
     1259        // Test this doesn't crash.
     1260        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(0), box(1) }), 1);
     1261        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(1), box(0) }), 0);
     1262        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(2), box(1) }), 0);
     1263        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(1), box(2) }), 1);
     1264        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(2), box(2) }), 0);
     1265        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(1), box(1) }), 0);
     1266        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(2), box(6) }), 1);
     1267        CHECK_EQ(invoke<int>(*plan.result(0)->jsEntryPoint, { box(100), box(6) }), 0);
    12681268    }
    12691269
  • trunk/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp

    r207824 r207825  
    719719}
    720720
    721 std::unique_ptr<FunctionCompilation> parseAndCompile(VM& vm, Vector<uint8_t>& source, Memory* memory, FunctionInformation info, const Vector<FunctionInformation>& functions, unsigned optLevel)
     721std::unique_ptr<FunctionCompilation> parseAndCompile(VM& vm, const uint8_t* functionStart, size_t functionLength, Memory* memory, const Signature* signature, const Vector<FunctionInformation>& functions, unsigned optLevel)
    722722{
    723723    auto result = std::make_unique<FunctionCompilation>();
     
    725725    Procedure procedure;
    726726    B3IRGenerator context(memory, procedure, result->unlinkedCalls);
    727     FunctionParser<B3IRGenerator> parser(context, source, info, functions);
     727    FunctionParser<B3IRGenerator> parser(context, functionStart, functionLength, signature, functions);
    728728    if (!parser.parse())
    729729        RELEASE_ASSERT_NOT_REACHED();
     
    737737
    738738    result->code = std::make_unique<Compilation>(vm, procedure, optLevel);
    739     result->jsEntryPoint = createJSWrapper(vm, info.signature, result->code->code(), memory);
     739    result->jsEntryPoint = createJSWrapper(vm, signature, result->code->code(), memory);
    740740    return result;
    741741}
  • trunk/Source/JavaScriptCore/wasm/WasmB3IRGenerator.h

    r207693 r207825  
    3838class Memory;
    3939
    40 std::unique_ptr<FunctionCompilation> parseAndCompile(VM&, Vector<uint8_t>&, Memory*, FunctionInformation, const Vector<FunctionInformation>&, unsigned optLevel = 1);
     40std::unique_ptr<FunctionCompilation> parseAndCompile(VM&, const uint8_t*, size_t, Memory*, const Signature*, const Vector<FunctionInformation>&, unsigned optLevel = 1);
    4141
    4242} } // namespace JSC::Wasm
  • trunk/Source/JavaScriptCore/wasm/WasmFunctionParser.h

    r207781 r207825  
    4545    typedef typename Context::ControlType ControlType;
    4646
    47     FunctionParser(Context&, const Vector<uint8_t>& sourceBuffer, const FunctionInformation&, const Vector<FunctionInformation>& functions);
     47    FunctionParser(Context&, const uint8_t* functionStart, size_t functionLength, const Signature*, const Vector<FunctionInformation>& functions);
    4848
    4949    bool WARN_UNUSED_RETURN parse();
     
    6060    Vector<ExpressionType, 1> m_expressionStack;
    6161    Vector<ControlType> m_controlStack;
    62     const Signature& m_signature;
     62    const Signature* m_signature;
    6363    const Vector<FunctionInformation>& m_functions;
    6464    unsigned m_unreachableBlocks { 0 };
     
    6666
    6767template<typename Context>
    68 FunctionParser<Context>::FunctionParser(Context& context, const Vector<uint8_t>& sourceBuffer, const FunctionInformation& info, const Vector<FunctionInformation>& functions)
    69     : Parser(sourceBuffer, info.start, info.end)
     68FunctionParser<Context>::FunctionParser(Context& context, const uint8_t* functionStart, size_t functionLength, const Signature* signature, const Vector<FunctionInformation>& functions)
     69    : Parser(functionStart, functionLength)
    7070    , m_context(context)
    71     , m_signature(*info.signature)
     71    , m_signature(signature)
    7272    , m_functions(functions)
    7373{
    7474    if (verbose)
    75         dataLogLn("Parsing function starting at: ", info.start, " ending at: ", info.end);
    76     m_context.addArguments(m_signature.arguments);
     75        dataLogLn("Parsing function starting at: ", (uintptr_t)functionStart, " of length: ", functionLength);
     76    m_context.addArguments(m_signature->arguments);
    7777}
    7878
     
    310310    case OpType::Return: {
    311311        Vector<ExpressionType, 1> returnValues;
    312         if (m_signature.returnType != Void)
     312        if (m_signature->returnType != Void)
    313313            returnValues.append(m_expressionStack.takeLast());
    314314
  • trunk/Source/JavaScriptCore/wasm/WasmModuleParser.cpp

    r207693 r207825  
    4242bool ModuleParser::parse()
    4343{
    44     if (m_sourceLength < 8)
    45         return false;
    46     if (!consumeCharacter(0))
    47         return false;
    48     if (!consumeString("asm"))
    49         return false;
     44    const size_t minSize = 8;
     45    if (length() < minSize) {
     46        m_errorMessage = "Module is " + String::number(length()) + " bytes, expected at least " + String::number(minSize) + " bytes";
     47        return false;
     48    }
     49    if (!consumeCharacter(0) || !consumeString("asm")) {
     50        m_errorMessage = "Modules doesn't start with '\\0asm'";
     51        return false;
     52    }
    5053
    5154    // Skip the version number for now since we don't do anything with it.
    5255    uint32_t versionNumber;
    53     if (!parseUInt32(versionNumber))
    54         return false;
    55 
    56     if (versionNumber != magicNumber)
    57         return false;
     56    if (!parseUInt32(versionNumber)) {
     57        // FIXME improve error message https://bugs.webkit.org/show_bug.cgi?id=163919
     58        m_errorMessage = "couldn't parse version number";
     59        return false;
     60    }
     61
     62    if (versionNumber != magicNumber) {
     63        // FIXME improve error message https://bugs.webkit.org/show_bug.cgi?id=163919
     64        m_errorMessage = "unexpected version number";
     65        return false;
     66    }
    5867
    5968
     
    6271
    6372    Sections::Section previousSection = Sections::Unknown;
    64     while (m_offset < m_sourceLength) {
     73    while (m_offset < length()) {
    6574        if (verbose)
    6675            dataLogLn("Starting to parse next section at offset: ", m_offset);
    6776
    6877        uint8_t sectionByte;
    69         if (!parseUInt7(sectionByte))
    70             return false;
     78        if (!parseUInt7(sectionByte)) {
     79            // FIXME improve error message https://bugs.webkit.org/show_bug.cgi?id=163919
     80            m_errorMessage = "couldn't get section byte";
     81            return false;
     82        }
    7183
    7284        if (verbose)
     
    7991        } else {
    8092            uint32_t sectionNameLength;
    81             if (!parseVarUInt32(sectionNameLength))
    82                 return false;
     93            if (!parseVarUInt32(sectionNameLength)) {
     94                // FIXME improve error message https://bugs.webkit.org/show_bug.cgi?id=163919
     95                m_errorMessage = "couldn't get section name length";
     96                return false;
     97            }
    8398
    8499            // Make sure we can read up to the section's size.
    85             if (m_offset + sectionNameLength + WTF::LEBDecoder::max32BitLEBByteLength >= m_sourceLength)
    86                 return false;
     100            if (m_offset + sectionNameLength + WTF::LEBDecoder::max32BitLEBByteLength >= length()) {
     101                // FIXME improve error message https://bugs.webkit.org/show_bug.cgi?id=163919
     102                m_errorMessage = "section length is bigger than actual size";
     103                return false;
     104            }
    87105
    88106            // We don't support any custom sections yet.
     
    91109        }
    92110
    93         if (!Sections::validateOrder(previousSection, section))
    94             return false;
     111        if (!Sections::validateOrder(previousSection, section)) {
     112            // FIXME improve error message https://bugs.webkit.org/show_bug.cgi?id=163919
     113            m_errorMessage = "invalid section order";
     114            return false;
     115        }
    95116
    96117        uint32_t sectionLength;
    97         if (!parseVarUInt32(sectionLength))
    98             return false;
     118        if (!parseVarUInt32(sectionLength)) {
     119            // FIXME improve error message https://bugs.webkit.org/show_bug.cgi?id=163919
     120            m_errorMessage = "couldn't get section length";
     121            return false;
     122        }
    99123
    100124        unsigned end = m_offset + sectionLength;
     
    105129            if (verbose)
    106130                dataLogLn("Parsing Memory.");
    107             if (!parseMemory())
    108                 return false;
     131            if (!parseMemory()) {
     132                // FIXME improve error message https://bugs.webkit.org/show_bug.cgi?id=163919
     133                m_errorMessage = "couldn't parse memory";
     134                return false;
     135            }
    109136            break;
    110137        }
     
    113140            if (verbose)
    114141                dataLogLn("Parsing types.");
    115             if (!parseFunctionTypes())
    116                 return false;
     142            if (!parseFunctionTypes()) {
     143                // FIXME improve error message https://bugs.webkit.org/show_bug.cgi?id=163919
     144                m_errorMessage = "couldn't parse types";
     145                return false;
     146            }
    117147            break;
    118148        }
     
    121151            if (verbose)
    122152                dataLogLn("Parsing function signatures.");
    123             if (!parseFunctionSignatures())
    124                 return false;
     153            if (!parseFunctionSignatures()) {
     154                // FIXME improve error message https://bugs.webkit.org/show_bug.cgi?id=163919
     155                m_errorMessage = "couldn't parse function signatures";
     156                return false;
     157            }
    125158            break;
    126159        }
     
    129162            if (verbose)
    130163                dataLogLn("Parsing function definitions.");
    131             if (!parseFunctionDefinitions())
    132                 return false;
     164            if (!parseFunctionDefinitions()) {
     165                // FIXME improve error message https://bugs.webkit.org/show_bug.cgi?id=163919
     166                m_errorMessage = "couldn't parse function definitions";
     167                return false;
     168            }
    133169            break;
    134170        }
     
    147183            dataLogLn("Finished parsing section.");
    148184
    149         if (end != m_offset)
    150             return false;
     185        if (end != m_offset) {
     186            // FIXME improve error message https://bugs.webkit.org/show_bug.cgi?id=163919
     187            m_errorMessage = "parsing ended before the end of the section";
     188            return false;
     189        }
    151190
    152191        previousSection = section;
     
    154193
    155194    // TODO
     195    m_failed = false;
    156196    return true;
    157197}
  • trunk/Source/JavaScriptCore/wasm/WasmModuleParser.h

    r207693 r207825  
    4040    static const unsigned magicNumber = 0xc;
    4141
     42    ModuleParser(const uint8_t* sourceBuffer, size_t sourceLength)
     43        : Parser(sourceBuffer, sourceLength)
     44    {
     45    }
    4246    ModuleParser(const Vector<uint8_t>& sourceBuffer)
    43         : Parser(sourceBuffer, 0, sourceBuffer.size())
     47        : Parser(sourceBuffer.data(), sourceBuffer.size())
    4448    {
    4549    }
    4650
    4751    bool WARN_UNUSED_RETURN parse();
     52    bool WARN_UNUSED_RETURN failed() const { return m_failed; }
     53    const String& errorMessage() const
     54    {
     55        RELEASE_ASSERT(failed());
     56        return m_errorMessage;
     57    }
    4858
    49     const Vector<FunctionInformation>& functionInformation() const { return m_functions; }
    50     std::unique_ptr<Memory>& memory() { return m_memory; }
     59    const Vector<FunctionInformation>& functionInformation() const
     60    {
     61        RELEASE_ASSERT(!failed());
     62        return m_functions;
     63    }
     64    std::unique_ptr<Memory>& memory()
     65    {
     66        RELEASE_ASSERT(!failed());
     67        return m_memory;
     68    }
    5169
    5270private:
     
    6078    Vector<Signature> m_signatures;
    6179    std::unique_ptr<Memory> m_memory;
     80    bool m_failed { true };
     81    String m_errorMessage;
    6282};
    6383
  • trunk/Source/JavaScriptCore/wasm/WasmParser.h

    r207693 r207825  
    3939class Parser {
    4040protected:
    41     Parser(const Vector<uint8_t>&, size_t start, size_t end);
     41    Parser(const uint8_t*, size_t);
    4242
    4343    bool WARN_UNUSED_RETURN consumeCharacter(char);
     
    4747    bool WARN_UNUSED_RETURN parseUInt7(uint8_t& result);
    4848    bool WARN_UNUSED_RETURN parseUInt32(uint32_t& result);
    49     bool WARN_UNUSED_RETURN parseVarUInt32(uint32_t& result) { return WTF::LEBDecoder::decodeUInt32(m_source.data(), m_sourceLength, m_offset, result); }
    50     bool WARN_UNUSED_RETURN parseVarUInt64(uint64_t& result) { return WTF::LEBDecoder::decodeUInt64(m_source.data(), m_sourceLength, m_offset, result); }
    51 
     49    bool WARN_UNUSED_RETURN parseVarUInt32(uint32_t& result) { return WTF::LEBDecoder::decodeUInt32(m_source, m_sourceLength, m_offset, result); }
     50    bool WARN_UNUSED_RETURN parseVarUInt64(uint64_t& result) { return WTF::LEBDecoder::decodeUInt64(m_source, m_sourceLength, m_offset, result); }
    5251
    5352    bool WARN_UNUSED_RETURN parseValueType(Type& result);
    5453
    55     const Vector<uint8_t>& m_source;
     54    const uint8_t* source() const { return m_source; }
     55    size_t length() const { return m_sourceLength; }
     56
     57    size_t m_offset = 0;
     58
     59private:
     60    const uint8_t* m_source;
    5661    size_t m_sourceLength;
    57     size_t m_offset;
    5862};
    5963
    60 ALWAYS_INLINE Parser::Parser(const Vector<uint8_t>& sourceBuffer, size_t start, size_t end)
     64ALWAYS_INLINE Parser::Parser(const uint8_t* sourceBuffer, size_t sourceLength)
    6165    : m_source(sourceBuffer)
    62     , m_sourceLength(end)
    63     , m_offset(start)
     66    , m_sourceLength(sourceLength)
    6467{
    65     ASSERT(end <= sourceBuffer.size());
    66     ASSERT(start < end);
    6768}
    6869
    6970ALWAYS_INLINE bool Parser::consumeCharacter(char c)
    7071{
    71     if (m_offset >= m_sourceLength)
     72    if (m_offset >= length())
    7273        return false;
    73     if (c == m_source[m_offset]) {
     74    if (c == source()[m_offset]) {
    7475        m_offset++;
    7576        return true;
     
    8182{
    8283    unsigned start = m_offset;
    83     if (m_offset >= m_sourceLength)
     84    if (m_offset >= length())
    8485        return false;
    85     for (unsigned i = 0; str[i]; i++) {
     86    for (size_t i = 0; str[i]; i++) {
    8687        if (!consumeCharacter(str[i])) {
    8788            m_offset = start;
     
    9495ALWAYS_INLINE bool Parser::parseUInt32(uint32_t& result)
    9596{
    96     if (m_sourceLength < 4 || m_offset >= m_sourceLength - 4)
     97    if (length() < 4 || m_offset > length() - 4)
    9798        return false;
    98     result = *reinterpret_cast<const uint32_t*>(m_source.data() + m_offset);
     99    result = *reinterpret_cast<const uint32_t*>(source() + m_offset);
    99100    m_offset += 4;
    100101    return true;
     
    103104ALWAYS_INLINE bool Parser::parseUInt7(uint8_t& result)
    104105{
    105     if (m_offset >= m_sourceLength)
     106    if (m_offset >= length())
    106107        return false;
    107     result = m_source[m_offset++];
     108    result = source()[m_offset++];
    108109    return result < 0x80;
    109110}
  • trunk/Source/JavaScriptCore/wasm/WasmPlan.cpp

    r207693 r207825  
    3838
    3939static const bool verbose = false;
     40   
     41Plan::Plan(VM& vm, Vector<uint8_t> source)
     42    : Plan(vm, source.data(), source.size())
     43{
     44}
    4045
    41 Plan::Plan(VM& vm, Vector<uint8_t> source)
     46Plan::Plan(VM& vm, const uint8_t* source, size_t sourceLength)
    4247{
    4348    if (verbose)
    4449        dataLogLn("Starting plan.");
    45     ModuleParser moduleParser(source);
     50    ModuleParser moduleParser(source, sourceLength);
    4651    if (!moduleParser.parse()) {
    47         dataLogLn("Parsing module failed.");
     52        dataLogLn("Parsing module failed: ", moduleParser.errorMessage());
     53        m_errorMessage = moduleParser.errorMessage();
    4854        return;
    4955    }
     
    5561        if (verbose)
    5662            dataLogLn("Processing funcion starting at: ", info.start, " and ending at: ", info.end);
    57         result.append(parseAndCompile(vm, source, moduleParser.memory().get(), info, moduleParser.functionInformation()));
     63        const uint8_t* functionStart = source + info.start;
     64        size_t functionLength = info.end - info.start;
     65        ASSERT(functionLength <= sourceLength);
     66        m_result.append(parseAndCompile(vm, functionStart, functionLength, moduleParser.memory().get(), info.signature, moduleParser.functionInformation()));
    5867    }
    5968
    6069    // Patch the call sites for each function.
    61     for (std::unique_ptr<FunctionCompilation>& functionPtr : result) {
     70    for (std::unique_ptr<FunctionCompilation>& functionPtr : m_result) {
    6271        FunctionCompilation* function = functionPtr.get();
    6372        for (auto& call : function->unlinkedCalls)
    64             MacroAssembler::repatchCall(call.callLocation, CodeLocationLabel(result[call.functionIndex]->code->code()));
     73            MacroAssembler::repatchCall(call.callLocation, CodeLocationLabel(m_result[call.functionIndex]->code->code()));
    6574    }
    6675
    67     memory = WTFMove(moduleParser.memory());
     76    m_memory = WTFMove(moduleParser.memory());
     77    m_failed = false;
    6878}
     79
     80Plan::~Plan() { }
    6981
    7082} } // namespace JSC::Wasm
  • trunk/Source/JavaScriptCore/wasm/WasmPlan.h

    r207693 r207825  
    3737class Memory;
    3838
    39 // TODO: This should create a Wasm Module not a list of functions.
    4039class Plan {
    4140public:
    42     JS_EXPORT_PRIVATE Plan(VM&, Vector<uint8_t> source);
     41    JS_EXPORT_PRIVATE Plan(VM&, Vector<uint8_t>);
     42    JS_EXPORT_PRIVATE Plan(VM&, const uint8_t*, size_t);
     43    JS_EXPORT_PRIVATE ~Plan();
    4344
    44     Vector<std::unique_ptr<FunctionCompilation>> result;
    45     std::unique_ptr<Memory> memory;
     45    bool WARN_UNUSED_RETURN failed() const { return m_failed; }
     46    const String& errorMessage() const
     47    {
     48        RELEASE_ASSERT(failed());
     49        return m_errorMessage;
     50    }
     51    size_t resultSize() const
     52    {
     53        RELEASE_ASSERT(!failed());
     54        return m_result.size();
     55    }
     56    const FunctionCompilation* result(size_t n) const
     57    {
     58        RELEASE_ASSERT(!failed());
     59        return m_result.at(n).get();
     60    }
     61    const Memory* memory() const
     62    {
     63        RELEASE_ASSERT(!failed());
     64        return m_memory.get();
     65    }
     66
     67private:
     68    Vector<std::unique_ptr<FunctionCompilation>> m_result;
     69    std::unique_ptr<Memory> m_memory;
     70    bool m_failed { true };
     71    String m_errorMessage;
    4672};
    4773
  • trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyCompileError.cpp

    r207650 r207825  
    4848const ClassInfo JSWebAssemblyCompileError::s_info = { "WebAssembly.CompileError", &Base::s_info, 0, CREATE_METHOD_TABLE(JSWebAssemblyCompileError) };
    4949
     50   
     51JSObject* createWebAssemblyCompileError(ExecState* exec, const String& message)
     52{
     53    ASSERT(!message.isEmpty());
     54    JSGlobalObject* globalObject = exec->lexicalGlobalObject();
     55    return ErrorInstance::create(exec, globalObject->vm(), globalObject->WebAssemblyCompileErrorStructure(), message, defaultSourceAppender, TypeNothing, true);
     56}
     57
    5058} // namespace JSC
    5159
  • trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyCompileError.h

    r207650 r207825  
    4848};
    4949
     50JSObject* createWebAssemblyCompileError(ExecState*, const String&);
     51
    5052} // namespace JSC
    5153
  • trunk/Source/JavaScriptCore/wasm/js/WebAssemblyCompileErrorConstructor.cpp

    r207650 r207825  
    4949    auto& vm = state->vm();
    5050    auto scope = DECLARE_THROW_SCOPE(vm);
    51     JSValue message = state->argumentCount() ? state->argument(0) : jsUndefined();
     51    JSValue message = state->argument(0);
    5252    auto* structure = InternalFunction::createSubclassStructure(state, state->newTarget(), asInternalFunction(state->callee())->globalObject()->WebAssemblyCompileErrorStructure());
    5353    RETURN_IF_EXCEPTION(scope, encodedJSValue());
     
    6262}
    6363
    64 WebAssemblyCompileErrorConstructor* WebAssemblyCompileErrorConstructor::create(VM& vm, Structure* structure, WebAssemblyCompileErrorPrototype* thisPrototype, Structure* thisStructure)
     64WebAssemblyCompileErrorConstructor* WebAssemblyCompileErrorConstructor::create(VM& vm, Structure* structure, WebAssemblyCompileErrorPrototype* thisPrototype)
    6565{
    6666    auto* constructor = new (NotNull, allocateCell<WebAssemblyCompileErrorConstructor>(vm.heap)) WebAssemblyCompileErrorConstructor(vm, structure);
    67     constructor->finishCreation(vm, thisPrototype, thisStructure);
     67    constructor->finishCreation(vm, thisPrototype);
    6868    return constructor;
    6969}
     
    7474}
    7575
    76 void WebAssemblyCompileErrorConstructor::finishCreation(VM& vm, WebAssemblyCompileErrorPrototype* prototype, Structure*)
     76void WebAssemblyCompileErrorConstructor::finishCreation(VM& vm, WebAssemblyCompileErrorPrototype* prototype)
    7777{
    7878    Base::finishCreation(vm, ASCIILiteral("CompileError"));
  • trunk/Source/JavaScriptCore/wasm/js/WebAssemblyCompileErrorConstructor.h

    r207650 r207825  
    4040    static const unsigned StructureFlags = Base::StructureFlags | HasStaticPropertyTable;
    4141
    42     static WebAssemblyCompileErrorConstructor* create(VM&, Structure*, WebAssemblyCompileErrorPrototype*, Structure*);
     42    static WebAssemblyCompileErrorConstructor* create(VM&, Structure*, WebAssemblyCompileErrorPrototype*);
    4343    static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
    4444
     
    4646
    4747protected:
    48     void finishCreation(VM&, WebAssemblyCompileErrorPrototype*, Structure*);
     48    void finishCreation(VM&, WebAssemblyCompileErrorPrototype*);
    4949
    5050private:
  • trunk/Source/JavaScriptCore/wasm/js/WebAssemblyInstanceConstructor.cpp

    r207650 r207825  
    5858}
    5959
    60 WebAssemblyInstanceConstructor* WebAssemblyInstanceConstructor::create(VM& vm, Structure* structure, WebAssemblyInstancePrototype* thisPrototype, Structure* thisStructure)
     60WebAssemblyInstanceConstructor* WebAssemblyInstanceConstructor::create(VM& vm, Structure* structure, WebAssemblyInstancePrototype* thisPrototype)
    6161{
    6262    auto* constructor = new (NotNull, allocateCell<WebAssemblyInstanceConstructor>(vm.heap)) WebAssemblyInstanceConstructor(vm, structure);
    63     constructor->finishCreation(vm, thisPrototype, thisStructure);
     63    constructor->finishCreation(vm, thisPrototype);
    6464    return constructor;
    6565}
     
    7070}
    7171
    72 void WebAssemblyInstanceConstructor::finishCreation(VM& vm, WebAssemblyInstancePrototype* prototype, Structure* structure)
     72void WebAssemblyInstanceConstructor::finishCreation(VM& vm, WebAssemblyInstancePrototype* prototype)
    7373{
    7474    Base::finishCreation(vm, ASCIILiteral("Instance"));
    7575    putDirectWithoutTransition(vm, vm.propertyNames->prototype, prototype, DontEnum | DontDelete | ReadOnly);
    7676    putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(1), ReadOnly | DontEnum | DontDelete);
    77     m_InstanceStructure.set(vm, this, structure);
    7877}
    7978
     
    10099    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
    101100    Base::visitChildren(thisObject, visitor);
    102     visitor.append(&thisObject->m_InstanceStructure);
    103101}
    104102
  • trunk/Source/JavaScriptCore/wasm/js/WebAssemblyInstanceConstructor.h

    r207650 r207825  
    4040    static const unsigned StructureFlags = Base::StructureFlags | HasStaticPropertyTable;
    4141
    42     static WebAssemblyInstanceConstructor* create(VM&, Structure*, WebAssemblyInstancePrototype*, Structure*);
     42    static WebAssemblyInstanceConstructor* create(VM&, Structure*, WebAssemblyInstancePrototype*);
    4343    static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
    4444
    4545    DECLARE_INFO;
    4646
    47     Structure* InstanceStructure() const { return m_InstanceStructure.get(); }
    48 
    4947protected:
    50     void finishCreation(VM&, WebAssemblyInstancePrototype*, Structure*);
     48    void finishCreation(VM&, WebAssemblyInstancePrototype*);
    5149
    5250private:
     
    5553    static CallType getCallData(JSCell*, CallData&);
    5654    static void visitChildren(JSCell*, SlotVisitor&);
    57 
    58     WriteBarrier<Structure> m_InstanceStructure;
    5955};
    6056
  • trunk/Source/JavaScriptCore/wasm/js/WebAssemblyMemoryConstructor.cpp

    r207650 r207825  
    5858}
    5959
    60 WebAssemblyMemoryConstructor* WebAssemblyMemoryConstructor::create(VM& vm, Structure* structure, WebAssemblyMemoryPrototype* thisPrototype, Structure* thisStructure)
     60WebAssemblyMemoryConstructor* WebAssemblyMemoryConstructor::create(VM& vm, Structure* structure, WebAssemblyMemoryPrototype* thisPrototype)
    6161{
    6262    auto* constructor = new (NotNull, allocateCell<WebAssemblyMemoryConstructor>(vm.heap)) WebAssemblyMemoryConstructor(vm, structure);
    63     constructor->finishCreation(vm, thisPrototype, thisStructure);
     63    constructor->finishCreation(vm, thisPrototype);
    6464    return constructor;
    6565}
     
    7070}
    7171
    72 void WebAssemblyMemoryConstructor::finishCreation(VM& vm, WebAssemblyMemoryPrototype* prototype, Structure* structure)
     72void WebAssemblyMemoryConstructor::finishCreation(VM& vm, WebAssemblyMemoryPrototype* prototype)
    7373{
    7474    Base::finishCreation(vm, ASCIILiteral("Memory"));
    7575    putDirectWithoutTransition(vm, vm.propertyNames->prototype, prototype, DontEnum | DontDelete | ReadOnly);
    7676    putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(1), ReadOnly | DontEnum | DontDelete);
    77     m_MemoryStructure.set(vm, this, structure);
    7877}
    7978
     
    10099    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
    101100    Base::visitChildren(thisObject, visitor);
    102     visitor.append(&thisObject->m_MemoryStructure);
    103101}
    104102
  • trunk/Source/JavaScriptCore/wasm/js/WebAssemblyMemoryConstructor.h

    r207650 r207825  
    4040    static const unsigned StructureFlags = Base::StructureFlags | HasStaticPropertyTable;
    4141
    42     static WebAssemblyMemoryConstructor* create(VM&, Structure*, WebAssemblyMemoryPrototype*, Structure*);
     42    static WebAssemblyMemoryConstructor* create(VM&, Structure*, WebAssemblyMemoryPrototype*);
    4343    static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
    4444
    4545    DECLARE_INFO;
    4646
    47     Structure* MemoryStructure() const { return m_MemoryStructure.get(); }
    48 
    4947protected:
    50     void finishCreation(VM&, WebAssemblyMemoryPrototype*, Structure*);
     48    void finishCreation(VM&, WebAssemblyMemoryPrototype*);
    5149
    5250private:
     
    5553    static CallType getCallData(JSCell*, CallData&);
    5654    static void visitChildren(JSCell*, SlotVisitor&);
    57 
    58     WriteBarrier<Structure> m_MemoryStructure;
    5955};
    6056
  • trunk/Source/JavaScriptCore/wasm/js/WebAssemblyModuleConstructor.cpp

    r207650 r207825  
    2929#if ENABLE(WEBASSEMBLY)
    3030
     31#include "ExceptionHelpers.h"
    3132#include "FunctionPrototype.h"
     33#include "JSArrayBuffer.h"
    3234#include "JSCInlines.h"
     35#include "JSTypedArrays.h"
     36#include "JSWebAssemblyCompileError.h"
     37#include "JSWebAssemblyModule.h"
     38#include "WasmPlan.h"
    3339#include "WebAssemblyModulePrototype.h"
    3440
     
    4652static EncodedJSValue JSC_HOST_CALL constructJSWebAssemblyModule(ExecState* state)
    4753{
    48     VM& vm = state->vm();
     54    auto& vm = state->vm();
    4955    auto scope = DECLARE_THROW_SCOPE(vm);
    50     return JSValue::encode(throwException(state, scope, createError(state, ASCIILiteral("WebAssembly doesn't yet implement the Module constructor property"))));
     56    JSValue val = state->argument(0);
     57    JSArrayBuffer* arrayBuffer = val.getObject() ? jsDynamicCast<JSArrayBuffer*>(val.getObject()) : nullptr;
     58    JSArrayBufferView* arrayBufferView = val.getObject() ? jsDynamicCast<JSArrayBufferView*>(val.getObject()) : nullptr;
     59    if (!(arrayBuffer || arrayBufferView))
     60        return JSValue::encode(throwException(state, scope, createTypeError(state, ASCIILiteral("first argument to WebAssembly.Module must be an ArrayBufferView or an ArrayBuffer"), defaultSourceAppender, runtimeTypeForValue(val))));
     61
     62    if (arrayBufferView ? arrayBufferView->isNeutered() : arrayBuffer->impl()->isNeutered())
     63        return JSValue::encode(throwException(state, scope, createTypeError(state, ASCIILiteral("underlying TypedArray has been detatched from the ArrayBuffer"), defaultSourceAppender, runtimeTypeForValue(val))));
     64
     65    size_t byteOffset = arrayBufferView ? arrayBufferView->byteOffset() : 0;
     66    size_t byteSize = arrayBufferView ? arrayBufferView->length() : arrayBuffer->impl()->byteLength();
     67    const auto* base = arrayBufferView ? static_cast<uint8_t*>(arrayBufferView->vector()) : static_cast<uint8_t*>(arrayBuffer->impl()->data());
     68
     69    Wasm::Plan plan(vm, base + byteOffset, byteSize);
     70    if (plan.failed())
     71        return JSValue::encode(throwException(state, scope, createWebAssemblyCompileError(state, plan.errorMessage())));
     72
     73    // FIXME take content from Plan.
     74
     75    auto* structure = InternalFunction::createSubclassStructure(state, state->newTarget(), asInternalFunction(state->callee())->globalObject()->WebAssemblyModuleStructure());
     76    RETURN_IF_EXCEPTION(scope, encodedJSValue());
     77    return JSValue::encode(JSWebAssemblyModule::create(vm, structure));
    5178}
    5279
     
    5885}
    5986
    60 WebAssemblyModuleConstructor* WebAssemblyModuleConstructor::create(VM& vm, Structure* structure, WebAssemblyModulePrototype* thisPrototype, Structure* thisStructure)
     87WebAssemblyModuleConstructor* WebAssemblyModuleConstructor::create(VM& vm, Structure* structure, WebAssemblyModulePrototype* thisPrototype)
    6188{
    6289    auto* constructor = new (NotNull, allocateCell<WebAssemblyModuleConstructor>(vm.heap)) WebAssemblyModuleConstructor(vm, structure);
    63     constructor->finishCreation(vm, thisPrototype, thisStructure);
     90    constructor->finishCreation(vm, thisPrototype);
    6491    return constructor;
    6592}
     
    7097}
    7198
    72 void WebAssemblyModuleConstructor::finishCreation(VM& vm, WebAssemblyModulePrototype* prototype, Structure* structure)
     99void WebAssemblyModuleConstructor::finishCreation(VM& vm, WebAssemblyModulePrototype* prototype)
    73100{
    74101    Base::finishCreation(vm, ASCIILiteral("Module"));
    75102    putDirectWithoutTransition(vm, vm.propertyNames->prototype, prototype, DontEnum | DontDelete | ReadOnly);
    76103    putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(1), ReadOnly | DontEnum | DontDelete);
    77     m_ModuleStructure.set(vm, this, structure);
    78104}
    79105
     
    100126    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
    101127    Base::visitChildren(thisObject, visitor);
    102     visitor.append(&thisObject->m_ModuleStructure);
    103128}
    104129
  • trunk/Source/JavaScriptCore/wasm/js/WebAssemblyModuleConstructor.h

    r207650 r207825  
    4040    static const unsigned StructureFlags = Base::StructureFlags | HasStaticPropertyTable;
    4141
    42     static WebAssemblyModuleConstructor* create(VM&, Structure*, WebAssemblyModulePrototype*, Structure*);
     42    static WebAssemblyModuleConstructor* create(VM&, Structure*, WebAssemblyModulePrototype*);
    4343    static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
    4444
    4545    DECLARE_INFO;
    4646
    47     Structure* ModuleStructure() const { return m_ModuleStructure.get(); }
    48 
    4947protected:
    50     void finishCreation(VM&, WebAssemblyModulePrototype*, Structure*);
     48    void finishCreation(VM&, WebAssemblyModulePrototype*);
    5149
    5250private:
     
    5553    static CallType getCallData(JSCell*, CallData&);
    5654    static void visitChildren(JSCell*, SlotVisitor&);
    57 
    58     WriteBarrier<Structure> m_ModuleStructure;
    5955};
    6056
  • trunk/Source/JavaScriptCore/wasm/js/WebAssemblyRuntimeErrorConstructor.cpp

    r207650 r207825  
    6262}
    6363
    64 WebAssemblyRuntimeErrorConstructor* WebAssemblyRuntimeErrorConstructor::create(VM& vm, Structure* structure, WebAssemblyRuntimeErrorPrototype* thisPrototype, Structure* thisStructure)
     64WebAssemblyRuntimeErrorConstructor* WebAssemblyRuntimeErrorConstructor::create(VM& vm, Structure* structure, WebAssemblyRuntimeErrorPrototype* thisPrototype)
    6565{
    6666    auto* constructor = new (NotNull, allocateCell<WebAssemblyRuntimeErrorConstructor>(vm.heap)) WebAssemblyRuntimeErrorConstructor(vm, structure);
    67     constructor->finishCreation(vm, thisPrototype, thisStructure);
     67    constructor->finishCreation(vm, thisPrototype);
    6868    return constructor;
    6969}
     
    7474}
    7575
    76 void WebAssemblyRuntimeErrorConstructor::finishCreation(VM& vm, WebAssemblyRuntimeErrorPrototype* prototype, Structure*)
     76void WebAssemblyRuntimeErrorConstructor::finishCreation(VM& vm, WebAssemblyRuntimeErrorPrototype* prototype)
    7777{
    7878    Base::finishCreation(vm, ASCIILiteral("RuntimeError"));
  • trunk/Source/JavaScriptCore/wasm/js/WebAssemblyRuntimeErrorConstructor.h

    r207650 r207825  
    4040    static const unsigned StructureFlags = Base::StructureFlags | HasStaticPropertyTable;
    4141
    42     static WebAssemblyRuntimeErrorConstructor* create(VM&, Structure*, WebAssemblyRuntimeErrorPrototype*, Structure*);
     42    static WebAssemblyRuntimeErrorConstructor* create(VM&, Structure*, WebAssemblyRuntimeErrorPrototype*);
    4343    static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
    4444
     
    4646
    4747protected:
    48     void finishCreation(VM&, WebAssemblyRuntimeErrorPrototype*, Structure*);
     48    void finishCreation(VM&, WebAssemblyRuntimeErrorPrototype*);
    4949
    5050private:
  • trunk/Source/JavaScriptCore/wasm/js/WebAssemblyTableConstructor.cpp

    r207650 r207825  
    5858}
    5959
    60 WebAssemblyTableConstructor* WebAssemblyTableConstructor::create(VM& vm, Structure* structure, WebAssemblyTablePrototype* thisPrototype, Structure* thisStructure)
     60WebAssemblyTableConstructor* WebAssemblyTableConstructor::create(VM& vm, Structure* structure, WebAssemblyTablePrototype* thisPrototype)
    6161{
    6262    auto* constructor = new (NotNull, allocateCell<WebAssemblyTableConstructor>(vm.heap)) WebAssemblyTableConstructor(vm, structure);
    63     constructor->finishCreation(vm, thisPrototype, thisStructure);
     63    constructor->finishCreation(vm, thisPrototype);
    6464    return constructor;
    6565}
     
    7070}
    7171
    72 void WebAssemblyTableConstructor::finishCreation(VM& vm, WebAssemblyTablePrototype* prototype, Structure* structure)
     72void WebAssemblyTableConstructor::finishCreation(VM& vm, WebAssemblyTablePrototype* prototype)
    7373{
    7474    Base::finishCreation(vm, ASCIILiteral("Table"));
    7575    putDirectWithoutTransition(vm, vm.propertyNames->prototype, prototype, DontEnum | DontDelete | ReadOnly);
    7676    putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(1), ReadOnly | DontEnum | DontDelete);
    77     m_TableStructure.set(vm, this, structure);
    7877}
    7978
     
    10099    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
    101100    Base::visitChildren(thisObject, visitor);
    102     visitor.append(&thisObject->m_TableStructure);
    103101}
    104102
  • trunk/Source/JavaScriptCore/wasm/js/WebAssemblyTableConstructor.h

    r207650 r207825  
    4040    static const unsigned StructureFlags = Base::StructureFlags | HasStaticPropertyTable;
    4141
    42     static WebAssemblyTableConstructor* create(VM&, Structure*, WebAssemblyTablePrototype*, Structure*);
     42    static WebAssemblyTableConstructor* create(VM&, Structure*, WebAssemblyTablePrototype*);
    4343    static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
    4444
    4545    DECLARE_INFO;
    4646
    47     Structure* TableStructure() const { return m_TableStructure.get(); }
    48 
    4947protected:
    50     void finishCreation(VM&, WebAssemblyTablePrototype*, Structure*);
     48    void finishCreation(VM&, WebAssemblyTablePrototype*);
    5149
    5250private:
     
    5553    static CallType getCallData(JSCell*, CallData&);
    5654    static void visitChildren(JSCell*, SlotVisitor&);
    57 
    58     WriteBarrier<Structure> m_TableStructure;
    5955};
    6056
Note: See TracChangeset for help on using the changeset viewer.