Changeset 209630 in webkit


Ignore:
Timestamp:
Dec 9, 2016, 2:38:39 PM (9 years ago)
Author:
[email protected]
Message:

WebAssembly JS API: implement importing and defining Memory
https://bugs.webkit.org/show_bug.cgi?id=164134

Reviewed by Keith Miller.

JSTests:

  • wasm/Builder.js:

(const._importMemoryContinuation.section):
(const._importMemoryContinuation.assert):
(const._importMemoryContinuation):
(const._exportFunctionContinuation.const): Deleted.
(const._exportFunctionContinuation): Deleted.

  • wasm/Builder_WebAssemblyBinary.js:

(const.emitters.Import):

  • wasm/js-api/test_basic_api.js:

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

  • wasm/js-api/test_memory.js: Added.

(assert):
(binaryShouldNotParse):
(test):
(test.testMemImportError):

  • wasm/js-api/test_memory_constructor.js: Added.

(assert):
(throw.new.Error):
(testInvalidSize):
(assert.testInvalidInitial):
(testInvalidInitial.testInvalidMaximum):
(testInvalidInitial):
(testInvalidMaximum):

  • wasm/self-test/test_BuilderJSON.js:

Source/JavaScriptCore:

This patch implements the WebAssembly.Memory object. It refactors
the code to now associate a Memory with the instance instead of
the Module.

(functionTestWasmModuleFunctions):

  • runtime/VM.h:
  • shell/CMakeLists.txt:
  • testWasm.cpp: Removed.

This has bitrotted. I'm removing it.

  • wasm/WasmB3IRGenerator.cpp:

(JSC::Wasm::B3IRGenerator::B3IRGenerator):
(JSC::Wasm::sizeOfLoadOp):
(JSC::Wasm::createJSToWasmWrapper):
(JSC::Wasm::parseAndCompile):

  • wasm/WasmB3IRGenerator.h:
  • wasm/WasmFormat.cpp:

(JSC::Wasm::ModuleInformation::~ModuleInformation): Deleted.

  • wasm/WasmFormat.h:
  • wasm/WasmMemory.cpp:

(JSC::Wasm::Memory::Memory):

  • wasm/WasmMemory.h:

(JSC::Wasm::Memory::size):
(JSC::Wasm::Memory::initial):
(JSC::Wasm::Memory::maximum):
(JSC::Wasm::Memory::pinnedRegisters): Deleted.

  • wasm/WasmMemoryInformation.cpp: Added.

(JSC::Wasm::MemoryInformation::MemoryInformation):

  • wasm/WasmMemoryInformation.h: Added.

(JSC::Wasm::MemoryInformation::MemoryInformation):
(JSC::Wasm::MemoryInformation::pinnedRegisters):
(JSC::Wasm::MemoryInformation::initial):
(JSC::Wasm::MemoryInformation::maximum):
(JSC::Wasm::MemoryInformation::isImport):
(JSC::Wasm::MemoryInformation::operator bool):

  • wasm/WasmModuleParser.cpp:

(JSC::Wasm::ModuleParser::parseImport):
(JSC::Wasm::ModuleParser::parseMemoryHelper):
(JSC::Wasm::ModuleParser::parseMemory):
(JSC::Wasm::ModuleParser::parseExport):

  • wasm/WasmModuleParser.h:
  • wasm/WasmPageCount.h: Added. Implement a new way of describing Wasm

pages and then asking for how many bytes a quantity of pages is. This
class also makes it clear when we're talking about bytes or pages.

(JSC::Wasm::PageCount::PageCount):
(JSC::Wasm::PageCount::bytes):
(JSC::Wasm::PageCount::isValid):
(JSC::Wasm::PageCount::max):
(JSC::Wasm::PageCount::operator bool):
(JSC::Wasm::PageCount::operator<):
(JSC::Wasm::PageCount::operator>):
(JSC::Wasm::PageCount::operator>=):

  • wasm/WasmPlan.cpp:

(JSC::Wasm::Plan::run):

  • wasm/WasmPlan.h:

(JSC::Wasm::Plan::memory): Deleted.

  • wasm/WasmValidate.cpp:

(JSC::Wasm::Validate::hasMemory):
(JSC::Wasm::Validate::Validate):
(JSC::Wasm::validateFunction):

  • wasm/WasmValidate.h:
  • wasm/generateWasmValidateInlinesHeader.py:
  • wasm/js/JSWebAssemblyInstance.cpp:

(JSC::JSWebAssemblyInstance::visitChildren):

  • wasm/js/JSWebAssemblyInstance.h:

(JSC::JSWebAssemblyInstance::memory):
(JSC::JSWebAssemblyInstance::setMemory):
(JSC::JSWebAssemblyInstance::offsetOfImportFunctions):
(JSC::JSWebAssemblyInstance::allocationSize):

  • wasm/js/JSWebAssemblyMemory.cpp:

(JSC::JSWebAssemblyMemory::create):
(JSC::JSWebAssemblyMemory::JSWebAssemblyMemory):
(JSC::JSWebAssemblyMemory::buffer):
(JSC::JSWebAssemblyMemory::visitChildren):

  • wasm/js/JSWebAssemblyMemory.h:

(JSC::JSWebAssemblyMemory::memory):

  • wasm/js/WebAssemblyFunction.cpp:

(JSC::callWebAssemblyFunction):

  • wasm/js/WebAssemblyInstanceConstructor.cpp:

Handle importing and creating of memory according
to the spec. This also does the needed validation
of making sure the memory defined in the module
is compatible with the imported memory.

(JSC::constructJSWebAssemblyInstance):

  • wasm/js/WebAssemblyMemoryConstructor.cpp:

(JSC::constructJSWebAssemblyMemory):
(JSC::callJSWebAssemblyMemory):

  • wasm/js/WebAssemblyMemoryPrototype.cpp:

(JSC::webAssemblyMemoryProtoFuncBuffer):
(JSC::WebAssemblyMemoryPrototype::create):
(JSC::WebAssemblyMemoryPrototype::finishCreation):

  • wasm/js/WebAssemblyMemoryPrototype.h:
  • wasm/js/WebAssemblyModuleRecord.cpp:

(JSC::WebAssemblyModuleRecord::finishCreation):
(JSC::WebAssemblyModuleRecord::link):

Location:
trunk
Files:
5 added
1 deleted
34 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r209597 r209630  
     12016-12-09  Saam Barati  <[email protected]>
     2
     3        WebAssembly JS API: implement importing and defining Memory
     4        https://bugs.webkit.org/show_bug.cgi?id=164134
     5
     6        Reviewed by Keith Miller.
     7
     8        * wasm/Builder.js:
     9        (const._importMemoryContinuation.section):
     10        (const._importMemoryContinuation.assert):
     11        (const._importMemoryContinuation):
     12        (const._exportFunctionContinuation.const): Deleted.
     13        (const._exportFunctionContinuation): Deleted.
     14        * wasm/Builder_WebAssemblyBinary.js:
     15        (const.emitters.Import):
     16        * wasm/js-api/test_basic_api.js:
     17        (const.c.in.constructorProperties.switch):
     18        * wasm/js-api/test_memory.js: Added.
     19        (assert):
     20        (binaryShouldNotParse):
     21        (test):
     22        (test.testMemImportError):
     23        * wasm/js-api/test_memory_constructor.js: Added.
     24        (assert):
     25        (throw.new.Error):
     26        (testInvalidSize):
     27        (assert.testInvalidInitial):
     28        (testInvalidInitial.testInvalidMaximum):
     29        (testInvalidInitial):
     30        (testInvalidMaximum):
     31        * wasm/self-test/test_BuilderJSON.js:
     32
    1332016-12-08  JF Bastien  <[email protected]>
    234
  • trunk/JSTests/wasm/Builder.js

    r209306 r209630  
    103103};
    104104
     105const _importMemoryContinuation = (builder, section, nextBuilder) => {
     106    return (module, field, memoryDescription) => {
     107        assert.isString(module, `Import function module should be a string, got "${module}"`);
     108        assert.isString(field, `Import function field should be a string, got "${field}"`);
     109        section.data.push({module, field, kind: "Memory", memoryDescription});
     110        return nextBuilder;
     111    };
     112};
     113
    105114const _exportFunctionContinuation = (builder, section, nextBuilder) => {
    106115    return (field, index, type) => {
     
    111120            type = _maybeRegisterType(builder, type);
    112121        }
     122
    113123        // We can't check much about "index" here because the Code section succeeds the Export section. More work is done at Code().End() time.
    114124        switch (typeof(index)) {
     
    126136        default: throw new Error(`Export section's index must be a string or a number, got ${index}`);
    127137        }
     138
    128139        const correspondingImport = builder._getFunctionFromIndexSpace(index);
    129140        const importSection = builder._getSection("Import");
     
    369380                        End: () => this,
    370381                        Table: () => { throw new Error(`Unimplemented: import table`); },
    371                         Memory: () => { throw new Error(`Unimplemented: import memory`); },
    372382                        Global: () => { throw new Error(`Unimplemented: import global`); },
    373383                    };
    374384                    importBuilder.Function = _importFunctionContinuation(this, s, importBuilder);
     385                    importBuilder.Memory = _importMemoryContinuation(this, s, importBuilder);
    375386                    return importBuilder;
    376387                };
     
    466477                                    if (typeof(e.type) === "undefined") {
    467478                                        // This must be a function export from the Code section (re-exports were handled earlier).
    468                                         const functionIndexSpaceOffset = importSection ? importSection.data.length : 0;
     479                                        let functionIndexSpaceOffset = 0;
     480                                        if (importSection) {
     481                                            for (const {kind} of importSection.data) {
     482                                                if (kind === "Function")
     483                                                    ++functionIndexSpaceOffset;
     484                                            }
     485                                        }
    469486                                        const functionIndex = e.index - functionIndexSpaceOffset;
    470487                                        e.type = codeSection.data[functionIndex].type;
  • trunk/JSTests/wasm/Builder_WebAssemblyBinary.js

    r209306 r209630  
    5454            switch (entry.kind) {
    5555            default: throw new Error(`Implementation problem: unexpected kind ${entry.kind}`);
    56             case "Function": put(bin, "varuint32", entry.type); break;
     56            case "Function": {
     57                put(bin, "varuint32", entry.type);
     58                break;
     59            }
    5760            case "Table": throw new Error(`Not yet implemented`);
    58             case "Memory": throw new Error(`Not yet implemented`);
     61            case "Memory": {
     62                let {initial, maximum} = entry.memoryDescription;
     63                assert.truthy(typeof initial === "number", "We expect 'initial' to be a number");
     64                initial |= 0;
     65                let hasMaximum = 0;
     66                if (typeof maximum === "number") {
     67                    maximum |= 0;
     68                    hasMaximum = 1;
     69                } else {
     70                    assert.truthy(typeof maximum === "undefined", "We expect 'maximum' to be a number if it's defined");
     71                }
     72
     73                put(bin, "varuint1", hasMaximum);
     74                put(bin, "varuint32", initial);
     75                if (hasMaximum)
     76                    put(bin, "varuint32", maximum);
     77                break;
     78            };
    5979            case "Global": throw new Error(`Not yet implemented`);
    6080            }
  • trunk/JSTests/wasm/js-api/test_basic_api.js

    r209306 r209630  
    7676        break;
    7777    case "Memory":
    78         // FIXME Implement and test these APIs further. For now they just throw. https://bugs.webkit.org/show_bug.cgi?id=159775
    79         assert.throws(() => new WebAssembly[c](), Error, `WebAssembly doesn't yet implement the ${c} constructor property`);
     78        new WebAssembly.Memory({initial: 20});
    8079        break;
    8180    case "Table":
  • trunk/JSTests/wasm/self-test/test_BuilderJSON.js

    r209165 r209630  
    570570})();
    571571
     572(function MemoryImport() {
     573    const builder = (new Builder())
     574        .Type().End()
     575        .Import()
     576            .Memory("__module__", "__field__", {initial: 30, maximum: 31})
     577        .End()
     578        .Code().End();
     579
     580    const json = JSON.parse(builder.json());
     581    assert.eq(json.section.length, 3);
     582    assert.eq(json.section[1].name, "Import");
     583    assert.eq(json.section[1].data.length, 1);
     584    assert.eq(json.section[1].data[0].module, "__module__");
     585    assert.eq(json.section[1].data[0].field, "__field__");
     586    assert.eq(json.section[1].data[0].kind, "Memory");
     587    assert.eq(json.section[1].data[0].memoryDescription.initial, 30);
     588    assert.eq(json.section[1].data[0].memoryDescription.maximum, 31);
     589})();
     590
    572591// FIXME test type mismatch with select. https://bugs.webkit.org/show_bug.cgi?id=163267
  • trunk/Source/JavaScriptCore/CMakeLists.txt

    r209570 r209630  
    903903    wasm/WasmFormat.cpp
    904904    wasm/WasmMemory.cpp
     905    wasm/WasmMemoryInformation.cpp
    905906    wasm/WasmModuleParser.cpp
    906907    wasm/WasmPlan.cpp
  • trunk/Source/JavaScriptCore/ChangeLog

    r209629 r209630  
     12016-12-09  Saam Barati  <[email protected]>
     2
     3        WebAssembly JS API: implement importing and defining Memory
     4        https://bugs.webkit.org/show_bug.cgi?id=164134
     5
     6        Reviewed by Keith Miller.
     7
     8        This patch implements the WebAssembly.Memory object. It refactors
     9        the code to now associate a Memory with the instance instead of
     10        the Module.
     11
     12        * CMakeLists.txt:
     13        * JavaScriptCore.xcodeproj/project.pbxproj:
     14        * jsc.cpp:
     15        (functionTestWasmModuleFunctions):
     16        * runtime/VM.h:
     17        * shell/CMakeLists.txt:
     18        * testWasm.cpp: Removed.
     19        This has bitrotted. I'm removing it.
     20
     21        * wasm/WasmB3IRGenerator.cpp:
     22        (JSC::Wasm::B3IRGenerator::B3IRGenerator):
     23        (JSC::Wasm::sizeOfLoadOp):
     24        (JSC::Wasm::createJSToWasmWrapper):
     25        (JSC::Wasm::parseAndCompile):
     26        * wasm/WasmB3IRGenerator.h:
     27        * wasm/WasmFormat.cpp:
     28        (JSC::Wasm::ModuleInformation::~ModuleInformation): Deleted.
     29        * wasm/WasmFormat.h:
     30        * wasm/WasmMemory.cpp:
     31        (JSC::Wasm::Memory::Memory):
     32        * wasm/WasmMemory.h:
     33        (JSC::Wasm::Memory::size):
     34        (JSC::Wasm::Memory::initial):
     35        (JSC::Wasm::Memory::maximum):
     36        (JSC::Wasm::Memory::pinnedRegisters): Deleted.
     37        * wasm/WasmMemoryInformation.cpp: Added.
     38        (JSC::Wasm::MemoryInformation::MemoryInformation):
     39        * wasm/WasmMemoryInformation.h: Added.
     40        (JSC::Wasm::MemoryInformation::MemoryInformation):
     41        (JSC::Wasm::MemoryInformation::pinnedRegisters):
     42        (JSC::Wasm::MemoryInformation::initial):
     43        (JSC::Wasm::MemoryInformation::maximum):
     44        (JSC::Wasm::MemoryInformation::isImport):
     45        (JSC::Wasm::MemoryInformation::operator bool):
     46        * wasm/WasmModuleParser.cpp:
     47        (JSC::Wasm::ModuleParser::parseImport):
     48        (JSC::Wasm::ModuleParser::parseMemoryHelper):
     49        (JSC::Wasm::ModuleParser::parseMemory):
     50        (JSC::Wasm::ModuleParser::parseExport):
     51        * wasm/WasmModuleParser.h:
     52        * wasm/WasmPageCount.h: Added. Implement a new way of describing Wasm
     53        pages and then asking for how many bytes a quantity of pages is. This
     54        class also makes it clear when we're talking about bytes or pages.
     55
     56        (JSC::Wasm::PageCount::PageCount):
     57        (JSC::Wasm::PageCount::bytes):
     58        (JSC::Wasm::PageCount::isValid):
     59        (JSC::Wasm::PageCount::max):
     60        (JSC::Wasm::PageCount::operator bool):
     61        (JSC::Wasm::PageCount::operator<):
     62        (JSC::Wasm::PageCount::operator>):
     63        (JSC::Wasm::PageCount::operator>=):
     64        * wasm/WasmPlan.cpp:
     65        (JSC::Wasm::Plan::run):
     66        * wasm/WasmPlan.h:
     67        (JSC::Wasm::Plan::memory): Deleted.
     68        * wasm/WasmValidate.cpp:
     69        (JSC::Wasm::Validate::hasMemory):
     70        (JSC::Wasm::Validate::Validate):
     71        (JSC::Wasm::validateFunction):
     72        * wasm/WasmValidate.h:
     73        * wasm/generateWasmValidateInlinesHeader.py:
     74        * wasm/js/JSWebAssemblyInstance.cpp:
     75        (JSC::JSWebAssemblyInstance::visitChildren):
     76        * wasm/js/JSWebAssemblyInstance.h:
     77        (JSC::JSWebAssemblyInstance::memory):
     78        (JSC::JSWebAssemblyInstance::setMemory):
     79        (JSC::JSWebAssemblyInstance::offsetOfImportFunctions):
     80        (JSC::JSWebAssemblyInstance::allocationSize):
     81        * wasm/js/JSWebAssemblyMemory.cpp:
     82        (JSC::JSWebAssemblyMemory::create):
     83        (JSC::JSWebAssemblyMemory::JSWebAssemblyMemory):
     84        (JSC::JSWebAssemblyMemory::buffer):
     85        (JSC::JSWebAssemblyMemory::visitChildren):
     86        * wasm/js/JSWebAssemblyMemory.h:
     87        (JSC::JSWebAssemblyMemory::memory):
     88        * wasm/js/WebAssemblyFunction.cpp:
     89        (JSC::callWebAssemblyFunction):
     90        * wasm/js/WebAssemblyInstanceConstructor.cpp:
     91        Handle importing and creating of memory according
     92        to the spec. This also does the needed validation
     93        of making sure the memory defined in the module
     94        is compatible with the imported memory.
     95
     96        (JSC::constructJSWebAssemblyInstance):
     97        * wasm/js/WebAssemblyMemoryConstructor.cpp:
     98        (JSC::constructJSWebAssemblyMemory):
     99        (JSC::callJSWebAssemblyMemory):
     100        * wasm/js/WebAssemblyMemoryPrototype.cpp:
     101        (JSC::webAssemblyMemoryProtoFuncBuffer):
     102        (JSC::WebAssemblyMemoryPrototype::create):
     103        (JSC::WebAssemblyMemoryPrototype::finishCreation):
     104        * wasm/js/WebAssemblyMemoryPrototype.h:
     105        * wasm/js/WebAssemblyModuleRecord.cpp:
     106        (JSC::WebAssemblyModuleRecord::finishCreation):
     107        (JSC::WebAssemblyModuleRecord::link):
     108
    11092016-12-09  Joseph Pecoraro  <[email protected]>
    2110
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r209570 r209630  
    2626                        );
    2727                        dependencies = (
    28                                 539EB0831D5560F400C82EF7 /* PBXTargetDependency */,
    2928                                0F6183471C45F67A0072450B /* PBXTargetDependency */,
    3029                                0F93275D1C20BF3A00CF6564 /* PBXTargetDependency */,
     
    12881287                5370B4F61BF26205005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 5370B4F41BF25EA2005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.h */; };
    12891288                53917E7B1B7906FA000EBD33 /* JSGenericTypedArrayViewPrototypeFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = 53917E7A1B7906E4000EBD33 /* JSGenericTypedArrayViewPrototypeFunctions.h */; };
    1290                 539EB0791D55607000C82EF7 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 51F0EB6105C86C6B00E6DF1B /* Foundation.framework */; };
    1291                 539EB07A1D55607000C82EF7 /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 932F5BD90822A1C700736975 /* JavaScriptCore.framework */; };
    1292                 539EB0811D55608A00C82EF7 /* testWasm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 539EB0711D553DF800C82EF7 /* testWasm.cpp */; };
    12931289                539FB8BA1C99DA7C00940FA1 /* JSArrayInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 539FB8B91C99DA7C00940FA1 /* JSArrayInlines.h */; };
    12941290                53D444DC1DAF08AB00B92784 /* B3WasmAddressValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 53D444DB1DAF08AB00B92784 /* B3WasmAddressValue.h */; };
     
    14301426                79B00CBF1C6AB07E0088C65D /* ProxyObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 79B00CBB1C6AB07E0088C65D /* ProxyObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
    14311427                79B1788E1D399B8000B1A567 /* JITMathICForwards.h in Headers */ = {isa = PBXBuildFile; fileRef = 79A899FE1D38612E00D18C73 /* JITMathICForwards.h */; settings = {ATTRIBUTES = (Private, ); }; };
     1428                79B759741DFA4C600052174C /* WasmMemoryInformation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 79B759711DFA4C600052174C /* WasmMemoryInformation.cpp */; };
     1429                79B759751DFA4C600052174C /* WasmMemoryInformation.h in Headers */ = {isa = PBXBuildFile; fileRef = 79B759721DFA4C600052174C /* WasmMemoryInformation.h */; settings = {ATTRIBUTES = (Private, ); }; };
     1430                79B759761DFA4C600052174C /* WasmPageCount.h in Headers */ = {isa = PBXBuildFile; fileRef = 79B759731DFA4C600052174C /* WasmPageCount.h */; settings = {ATTRIBUTES = (Private, ); }; };
    14321431                79B819931DD25CF500DDC714 /* JSGlobalObjectInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 79B819921DD25CF500DDC714 /* JSGlobalObjectInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
    14331432                79C4B15D1BA2158F00FD592E /* DFGLiveCatchVariablePreservationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 79C4B15B1BA2158F00FD592E /* DFGLiveCatchVariablePreservationPhase.cpp */; };
     
    23792378                        remoteGlobalIDString = 0F4680A914BA7FD900BFE272;
    23802379                        remoteInfo = "LLInt Offsets";
    2381                 };
    2382                 539EB0821D5560F400C82EF7 /* PBXContainerItemProxy */ = {
    2383                         isa = PBXContainerItemProxy;
    2384                         containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
    2385                         proxyType = 1;
    2386                         remoteGlobalIDString = 539EB0751D55607000C82EF7;
    2387                         remoteInfo = testWASM;
    23882380                };
    23892381                5D69E911152BE5470028D720 /* PBXContainerItemProxy */ = {
     
    36843676                53917E831B791CB8000EBD33 /* TypedArrayPrototype.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = TypedArrayPrototype.js; path = builtins/TypedArrayPrototype.js; sourceTree = SOURCE_ROOT; };
    36853677                539EB0711D553DF800C82EF7 /* testWasm.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = testWasm.cpp; sourceTree = "<group>"; };
    3686                 539EB0801D55607000C82EF7 /* testWASM */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testWASM; sourceTree = BUILT_PRODUCTS_DIR; };
    36873678                539FB8B91C99DA7C00940FA1 /* JSArrayInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSArrayInlines.h; sourceTree = "<group>"; };
    36883679                53D444DB1DAF08AB00B92784 /* B3WasmAddressValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3WasmAddressValue.h; path = b3/B3WasmAddressValue.h; sourceTree = "<group>"; };
     
    38613852                79B00CBA1C6AB07E0088C65D /* ProxyObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProxyObject.cpp; sourceTree = "<group>"; };
    38623853                79B00CBB1C6AB07E0088C65D /* ProxyObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProxyObject.h; sourceTree = "<group>"; };
     3854                79B759711DFA4C600052174C /* WasmMemoryInformation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmMemoryInformation.cpp; sourceTree = "<group>"; };
     3855                79B759721DFA4C600052174C /* WasmMemoryInformation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmMemoryInformation.h; sourceTree = "<group>"; };
     3856                79B759731DFA4C600052174C /* WasmPageCount.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmPageCount.h; sourceTree = "<group>"; };
    38633857                79B819921DD25CF500DDC714 /* JSGlobalObjectInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGlobalObjectInlines.h; sourceTree = "<group>"; };
    38643858                79C4B15B1BA2158F00FD592E /* DFGLiveCatchVariablePreservationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGLiveCatchVariablePreservationPhase.cpp; path = dfg/DFGLiveCatchVariablePreservationPhase.cpp; sourceTree = "<group>"; };
     
    49124906                        runOnlyForDeploymentPostprocessing = 0;
    49134907                };
    4914                 539EB0781D55607000C82EF7 /* Frameworks */ = {
    4915                         isa = PBXFrameworksBuildPhase;
    4916                         buildActionMask = 2147483647;
    4917                         files = (
    4918                                 539EB0791D55607000C82EF7 /* Foundation.framework in Frameworks */,
    4919                                 539EB07A1D55607000C82EF7 /* JavaScriptCore.framework in Frameworks */,
    4920                         );
    4921                         runOnlyForDeploymentPostprocessing = 0;
    4922                 };
    49234908                651122FC14046A4C002B101D /* Frameworks */ = {
    49244909                        isa = PBXFrameworksBuildPhase;
     
    49684953                                0F9327591C20BCBA00CF6564 /* dynbench */,
    49694954                                0F6183431C45F62A0072450B /* testair */,
    4970                                 539EB0801D55607000C82EF7 /* testWASM */,
    49714955                        );
    49724956                        name = Products;
     
    60256009                                535557151D9DFA32006D583B /* WasmMemory.cpp */,
    60266010                                535557131D9D9EA5006D583B /* WasmMemory.h */,
     6011                                79B759711DFA4C600052174C /* WasmMemoryInformation.cpp */,
     6012                                79B759721DFA4C600052174C /* WasmMemoryInformation.h */,
    60276013                                53F40E961D5A7BEC0099A1B6 /* WasmModuleParser.cpp */,
    60286014                                53F40E941D5A7AEF0099A1B6 /* WasmModuleParser.h */,
     6015                                79B759731DFA4C600052174C /* WasmPageCount.h */,
    60296016                                53F40E8C1D5901F20099A1B6 /* WasmParser.h */,
    60306017                                531374BE1D5CE95000AF7A0B /* WasmPlan.cpp */,
     
    79847971                                998ED6751BED768C00DD8017 /* RemoteControllableTarget.h in Headers */,
    79857972                                0F33FCF81C136E2500323F67 /* B3StackmapGenerationParams.h in Headers */,
     7973                                79B759761DFA4C600052174C /* WasmPageCount.h in Headers */,
    79867974                                0F66E16B14DF3F1600B7B2E4 /* DFGAdjacencyList.h in Headers */,
    79877975                                0FFB921816D02EB20055A5DB /* DFGAllocator.h in Headers */,
     
    82238211                                BC02E90F0E1839DB000F9297 /* ErrorPrototype.h in Headers */,
    82248212                                996B731B1BDA08D100331B84 /* ErrorPrototype.lut.h in Headers */,
     8213                                79B759751DFA4C600052174C /* WasmMemoryInformation.h in Headers */,
    82258214                                969A07980ED1D3AE00F1F681 /* DirectEvalCodeCache.h in Headers */,
    82268215                                A54982041891D0B00081E5B8 /* EventLoop.h in Headers */,
     
    91479136                        productType = "com.apple.product-type.tool";
    91489137                };
    9149                 539EB0751D55607000C82EF7 /* testWASM */ = {
    9150                         isa = PBXNativeTarget;
    9151                         buildConfigurationList = 539EB07B1D55607000C82EF7 /* Build configuration list for PBXNativeTarget "testWASM" */;
    9152                         buildPhases = (
    9153                                 539EB0761D55607000C82EF7 /* Sources */,
    9154                                 539EB0781D55607000C82EF7 /* Frameworks */,
    9155                         );
    9156                         buildRules = (
    9157                         );
    9158                         dependencies = (
    9159                         );
    9160                         name = testWASM;
    9161                         productName = testapi;
    9162                         productReference = 539EB0801D55607000C82EF7 /* testWASM */;
    9163                         productType = "com.apple.product-type.tool";
    9164                 };
    91659138                651122F714046A4C002B101D /* testRegExp */ = {
    91669139                        isa = PBXNativeTarget;
     
    92649237                                0F93274E1C20BCBA00CF6564 /* dynbench */,
    92659238                                0F6183381C45F62A0072450B /* testair */,
    9266                                 539EB0751D55607000C82EF7 /* testWASM */,
    92679239                        );
    92689240                };
     
    95329504                                1440F6100A4F85670005F061 /* testapi.c in Sources */,
    95339505                                86D2221A167EF9440024C804 /* testapi.mm in Sources */,
    9534                         );
    9535                         runOnlyForDeploymentPostprocessing = 0;
    9536                 };
    9537                 539EB0761D55607000C82EF7 /* Sources */ = {
    9538                         isa = PBXSourcesBuildPhase;
    9539                         buildActionMask = 2147483647;
    9540                         files = (
    9541                                 539EB0811D55608A00C82EF7 /* testWasm.cpp in Sources */,
    95429506                        );
    95439507                        runOnlyForDeploymentPostprocessing = 0;
     
    96489612                                148F21AA107EC53A0042EC2C /* BytecodeGenerator.cpp in Sources */,
    96499613                                7094C4DE1AE439530041A2EE /* BytecodeIntrinsicRegistry.cpp in Sources */,
     9614                                79B759741DFA4C600052174C /* WasmMemoryInformation.cpp in Sources */,
    96509615                                C2FCAE1217A9C24E0034C735 /* BytecodeLivenessAnalysis.cpp in Sources */,
    96519616                                0F338E0D1BF0276C0013C88F /* B3DataSection.cpp in Sources */,
     
    1047210437                        targetProxy = 0FF922D214F46B2F0041A24E /* PBXContainerItemProxy */;
    1047310438                };
    10474                 539EB0831D5560F400C82EF7 /* PBXTargetDependency */ = {
    10475                         isa = PBXTargetDependency;
    10476                         target = 539EB0751D55607000C82EF7 /* testWASM */;
    10477                         targetProxy = 539EB0821D5560F400C82EF7 /* PBXContainerItemProxy */;
    10478                 };
    1047910439                5D69E912152BE5470028D720 /* PBXTargetDependency */ = {
    1048010440                        isa = PBXTargetDependency;
     
    1081210772                        name = Production;
    1081310773                };
    10814                 539EB07C1D55607000C82EF7 /* Debug */ = {
    10815                         isa = XCBuildConfiguration;
    10816                         baseConfigurationReference = BC021BF2136900C300FC5467 /* ToolExecutable.xcconfig */;
    10817                         buildSettings = {
    10818                                 PRODUCT_NAME = "$(TARGET_NAME)";
    10819                         };
    10820                         name = Debug;
    10821                 };
    10822                 539EB07D1D55607000C82EF7 /* Release */ = {
    10823                         isa = XCBuildConfiguration;
    10824                         baseConfigurationReference = BC021BF2136900C300FC5467 /* ToolExecutable.xcconfig */;
    10825                         buildSettings = {
    10826                                 PRODUCT_NAME = "$(TARGET_NAME)";
    10827                         };
    10828                         name = Release;
    10829                 };
    10830                 539EB07E1D55607000C82EF7 /* Profiling */ = {
    10831                         isa = XCBuildConfiguration;
    10832                         baseConfigurationReference = BC021BF2136900C300FC5467 /* ToolExecutable.xcconfig */;
    10833                         buildSettings = {
    10834                                 PRODUCT_NAME = "$(TARGET_NAME)";
    10835                         };
    10836                         name = Profiling;
    10837                 };
    10838                 539EB07F1D55607000C82EF7 /* Production */ = {
    10839                         isa = XCBuildConfiguration;
    10840                         baseConfigurationReference = BC021BF2136900C300FC5467 /* ToolExecutable.xcconfig */;
    10841                         buildSettings = {
    10842                                 PRODUCT_NAME = "$(TARGET_NAME)";
    10843                         };
    10844                         name = Production;
    10845                 };
    1084610774                5D6B2A48152B9E17005231DE /* Debug */ = {
    1084710775                        isa = XCBuildConfiguration;
     
    1113511063                        defaultConfigurationName = Production;
    1113611064                };
    11137                 539EB07B1D55607000C82EF7 /* Build configuration list for PBXNativeTarget "testWASM" */ = {
    11138                         isa = XCConfigurationList;
    11139                         buildConfigurations = (
    11140                                 539EB07C1D55607000C82EF7 /* Debug */,
    11141                                 539EB07D1D55607000C82EF7 /* Release */,
    11142                                 539EB07E1D55607000C82EF7 /* Profiling */,
    11143                                 539EB07F1D55607000C82EF7 /* Production */,
    11144                         );
    11145                         defaultConfigurationIsVisible = 0;
    11146                         defaultConfigurationName = Production;
    11147                 };
    1114811065                5D6B2A4C152B9E17005231DE /* Build configuration list for PBXAggregateTarget "Test Tools" */ = {
    1114911066                        isa = XCConfigurationList;
  • trunk/Source/JavaScriptCore/jsc.cpp

    r209627 r209630  
    7070#include "TypeProfilerLog.h"
    7171#include "WasmPlan.h"
     72#include "WasmMemory.h"
    7273#include <locale.h>
    7374#include <math.h>
     
    26332634    }
    26342635
     2636    void* memoryBytes = nullptr;
     2637    uint32_t memorySize = 0;
     2638    std::unique_ptr<Wasm::Memory> memory;
     2639    std::unique_ptr<Wasm::ModuleInformation> moduleInformation = plan.takeModuleInformation();
     2640
     2641    if (!!moduleInformation->memory) {
     2642        memory = std::make_unique<Wasm::Memory>(moduleInformation->memory.initial(), moduleInformation->memory.maximum());
     2643        memoryBytes = memory->memory();
     2644        memorySize = memory->size();
     2645    }
     2646    vm.topWasmMemoryPointer = memoryBytes;
     2647    vm.topWasmMemorySize = memorySize;
     2648
    26352649    for (uint32_t i = 0; i < functionCount; ++i) {
    26362650        JSArray* testCases = jsCast<JSArray*>(exec->argument(i + 2));
  • trunk/Source/JavaScriptCore/runtime/VM.h

    r209570 r209630  
    297297    ExecState* topCallFrame;
    298298    JSWebAssemblyInstance* topJSWebAssemblyInstance;
     299    void* topWasmMemoryPointer;
     300    uint32_t topWasmMemorySize;
    299301    Strong<Structure> structureStructure;
    300302    Strong<Structure> structureRareDataStructure;
  • trunk/Source/JavaScriptCore/shell/CMakeLists.txt

    r207831 r209630  
    5050    )
    5151
    52     set(TESTWASM_SOURCES
    53         ../testWasm.cpp
    54     )
    55 
    5652    add_executable(testb3 ${TESTB3_SOURCES})
    5753    target_link_libraries(testb3 ${JSC_LIBRARIES})
     
    6056    target_link_libraries(testair ${JSC_LIBRARIES})
    6157
    62     add_executable(testWASM ${TESTWASM_SOURCES})
    63     target_link_libraries(testWASM ${JSC_LIBRARIES})
    64 
    6558endif ()
  • trunk/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp

    r209560 r209630  
    131131    static constexpr ExpressionType emptyExpression = nullptr;
    132132
    133     B3IRGenerator(Memory*, Procedure&, WasmInternalFunction*, Vector<UnlinkedWasmToWasmCall>&);
     133    B3IRGenerator(MemoryInformation&, Procedure&, WasmInternalFunction*, Vector<UnlinkedWasmToWasmCall>&);
    134134
    135135    bool WARN_UNUSED_RETURN addArguments(const Vector<Type>&);
     
    180180    Value* zeroForType(Type);
    181181
    182     Memory* m_memory;
    183182    Procedure& m_proc;
    184183    BasicBlock* m_currentBlock;
     
    190189};
    191190
    192 B3IRGenerator::B3IRGenerator(Memory* memory, Procedure& procedure, WasmInternalFunction* compilation, Vector<UnlinkedWasmToWasmCall>& unlinkedWasmToWasmCalls)
    193     : m_memory(memory)
    194     , m_proc(procedure)
     191B3IRGenerator::B3IRGenerator(MemoryInformation& memory, Procedure& procedure, WasmInternalFunction* compilation, Vector<UnlinkedWasmToWasmCall>& unlinkedWasmToWasmCalls)
     192    : m_proc(procedure)
    195193    , m_unlinkedWasmToWasmCalls(unlinkedWasmToWasmCalls)
    196194{
     
    211209    }
    212210
    213     if (m_memory) {
    214         m_memoryBaseGPR = m_memory->pinnedRegisters().baseMemoryPointer;
     211    if (!!memory) {
     212        m_memoryBaseGPR = memory.pinnedRegisters().baseMemoryPointer;
    215213        m_proc.pinRegister(m_memoryBaseGPR);
    216         ASSERT(!m_memory->pinnedRegisters().sizeRegisters[0].sizeOffset);
    217         m_memorySizeGPR = m_memory->pinnedRegisters().sizeRegisters[0].sizeRegister;
    218         for (const PinnedSizeRegisterInfo& info : m_memory->pinnedRegisters().sizeRegisters)
     214        ASSERT(!memory.pinnedRegisters().sizeRegisters[0].sizeOffset);
     215        m_memorySizeGPR = memory.pinnedRegisters().sizeRegisters[0].sizeRegister;
     216        for (const PinnedSizeRegisterInfo& info : memory.pinnedRegisters().sizeRegisters)
    219217            m_proc.pinRegister(info.sizeRegister);
    220218
     
    303301    case LoadOpType::I64Load32S:
    304302    case LoadOpType::I64Load32U:
     303    case LoadOpType::F32Load:
    305304        return 4;
    306305    case LoadOpType::I64Load:
     306    case LoadOpType::F64Load:
    307307        return 8;
    308308    case LoadOpType::I32Load16U:
    309309    case LoadOpType::I64Load16U:
    310     case LoadOpType::F32Load:
    311     case LoadOpType::F64Load:
    312310        break;
    313311    }
     
    660658}
    661659
    662 static std::unique_ptr<Compilation> createJSToWasmWrapper(VM& vm, const Signature* signature, MacroAssemblerCodePtr mainFunction, Memory* memory)
     660static std::unique_ptr<Compilation> createJSToWasmWrapper(VM& vm, const Signature* signature, MacroAssemblerCodePtr mainFunction, MemoryInformation& memory)
    663661{
    664662    Procedure proc;
     
    682680    Value* baseMemory = nullptr;
    683681    Vector<Value*> sizes;
    684     if (memory) {
    685         baseMemory = block->appendNew<ConstPtrValue>(proc, Origin(), memory->memory());
     682    if (!!memory) {
     683        baseMemory = block->appendNew<MemoryValue>(proc, Load, Int64, Origin(),
     684            block->appendNew<ConstPtrValue>(proc, Origin(), &vm.topWasmMemoryPointer));
    686685        Value* size = block->appendNew<MemoryValue>(proc, Load, Int32, Origin(),
    687             block->appendNew<ConstPtrValue>(proc, Origin(), bitwise_cast<char*>(memory) + Memory::offsetOfSize()));
    688         sizes.reserveCapacity(memory->pinnedRegisters().sizeRegisters.size());
    689         for (auto info : memory->pinnedRegisters().sizeRegisters) {
     686            block->appendNew<ConstPtrValue>(proc, Origin(), &vm.topWasmMemorySize));
     687        sizes.reserveCapacity(memory.pinnedRegisters().sizeRegisters.size());
     688        for (auto info : memory.pinnedRegisters().sizeRegisters) {
    690689            sizes.append(block->appendNew<Value>(proc, Sub, Origin(), size,
    691690                block->appendNew<Const32Value>(proc, Origin(), info.sizeOffset)));
     
    701700    // Move the arguments into place.
    702701    Value* result = wasmCallingConvention().setupCall(proc, block, Origin(), arguments, toB3Type(signature->returnType), [&] (PatchpointValue* patchpoint) {
    703         if (memory) {
    704             ASSERT(sizes.size() == memory->pinnedRegisters().sizeRegisters.size());
    705             patchpoint->append(ConstrainedValue(baseMemory, ValueRep::reg(memory->pinnedRegisters().baseMemoryPointer)));
     702        if (!!memory) {
     703            ASSERT(sizes.size() == memory.pinnedRegisters().sizeRegisters.size());
     704            patchpoint->append(ConstrainedValue(baseMemory, ValueRep::reg(memory.pinnedRegisters().baseMemoryPointer)));
    706705            for (unsigned i = 0; i < sizes.size(); ++i)
    707                 patchpoint->append(ConstrainedValue(sizes[i], ValueRep::reg(memory->pinnedRegisters().sizeRegisters[i].sizeRegister)));
     706                patchpoint->append(ConstrainedValue(sizes[i], ValueRep::reg(memory.pinnedRegisters().sizeRegisters[i].sizeRegister)));
    708707        }
    709708
     
    739738}
    740739
    741 std::unique_ptr<WasmInternalFunction> parseAndCompile(VM& vm, const uint8_t* functionStart, size_t functionLength, Memory* memory, const Signature* signature, Vector<UnlinkedWasmToWasmCall>& unlinkedWasmToWasmCalls, const FunctionIndexSpace& functionIndexSpace, unsigned optLevel)
     740std::unique_ptr<WasmInternalFunction> parseAndCompile(VM& vm, const uint8_t* functionStart, size_t functionLength, MemoryInformation& memory, const Signature* signature, Vector<UnlinkedWasmToWasmCall>& unlinkedWasmToWasmCalls, const FunctionIndexSpace& functionIndexSpace, unsigned optLevel)
    742741{
    743742    auto result = std::make_unique<WasmInternalFunction>();
  • trunk/Source/JavaScriptCore/wasm/WasmB3IRGenerator.h

    r209560 r209630  
    3636namespace JSC { namespace Wasm {
    3737
    38 class Memory;
     38class MemoryInformation;
    3939
    40 std::unique_ptr<WasmInternalFunction> parseAndCompile(VM&, const uint8_t*, size_t, Memory*, const Signature*, Vector<UnlinkedWasmToWasmCall>&, const FunctionIndexSpace&, unsigned optLevel = 1);
     40std::unique_ptr<WasmInternalFunction> parseAndCompile(VM&, const uint8_t*, size_t, MemoryInformation&, const Signature*, Vector<UnlinkedWasmToWasmCall>&, const FunctionIndexSpace&, unsigned optLevel = 1);
    4141
    4242} } // namespace JSC::Wasm
  • trunk/Source/JavaScriptCore/wasm/WasmFormat.cpp

    r209306 r209630  
    3434namespace JSC { namespace Wasm {
    3535
    36 ModuleInformation::~ModuleInformation() { }
    37 
    3836} } // namespace JSC::Wasm
    3937
  • trunk/Source/JavaScriptCore/wasm/WasmFormat.h

    r209560 r209630  
    3333#include "Identifier.h"
    3434#include "MacroAssemblerCodeRef.h"
     35#include "WasmMemoryInformation.h"
    3536#include "WasmOps.h"
     37#include "WasmPageCount.h"
    3638#include <wtf/Vector.h>
    3739
     
    9698};
    9799
    98 class Memory;
    99 
    100100struct Export {
    101101    Identifier field;
     
    104104        uint32_t functionIndex;
    105105        // FIXME implement Table https://bugs.webkit.org/show_bug.cgi?id=164135
    106         // FIXME implement Memory https://bugs.webkit.org/show_bug.cgi?id=164134
     106        // FIXME implement Memory https://bugs.webkit.org/show_bug.cgi?id=165671
    107107        // FIXME implement Global https://bugs.webkit.org/show_bug.cgi?id=164133
    108108    };
     
    120120    Vector<Signature*> importFunctions;
    121121    // FIXME implement import Table https://bugs.webkit.org/show_bug.cgi?id=164135
    122     // FIXME implement import Memory https://bugs.webkit.org/show_bug.cgi?id=164134
    123122    // FIXME implement import Global https://bugs.webkit.org/show_bug.cgi?id=164133
    124123    Vector<Signature*> internalFunctionSignatures;
    125     std::unique_ptr<Memory> memory;
     124    MemoryInformation memory;
    126125    Vector<Export> exports;
    127 
    128     ~ModuleInformation();
    129126};
    130127
  • trunk/Source/JavaScriptCore/wasm/WasmMemory.cpp

    r207693 r209630  
    3131namespace JSC { namespace Wasm {
    3232
    33 Memory::Memory(uint32_t startingSize, uint32_t capacity, const Vector<unsigned>& pinnedSizeRegisters)
     33Memory::Memory(PageCount initial, PageCount maximum)
    3434    : m_mode(Mode::BoundsChecking)
    35     , m_size(startingSize)
    36     , m_capacity(capacity)
     35    , m_size(initial.bytes())
     36    , m_capacity(maximum ? maximum.bytes() : PageCount::max().bytes())
     37    , m_initial(initial)
     38    , m_maximum(maximum)
    3739    // FIXME: If we add signal based bounds checking then we need extra space for overflow on load.
    3840    // see: https://bugs.webkit.org/show_bug.cgi?id=162693
    39     , m_mappedCapacity(static_cast<uint64_t>(maxPageCount) * static_cast<uint64_t>(pageSize))
     41    , m_mappedCapacity(PageCount::max().bytes())
    4042{
    41     ASSERT(pinnedSizeRegisters.size() > 0);
     43    RELEASE_ASSERT(!maximum || maximum >= initial); // This should be guaranteed by our caller.
    4244
    4345    // FIXME: It would be nice if we had a VM tag for wasm memory. https://bugs.webkit.org/show_bug.cgi?id=163600
     
    5153    }
    5254
    53     ASSERT(startingSize <= m_mappedCapacity);
    54     if (mprotect(result, startingSize, PROT_READ | PROT_WRITE)) {
     55    ASSERT(m_size <= m_mappedCapacity);
     56    if (mprotect(result, m_size, PROT_READ | PROT_WRITE)) {
    5557        munmap(result, m_mappedCapacity);
    5658        return;
    5759    }
    5860
    59     unsigned remainingPinnedRegisters = pinnedSizeRegisters.size() + 1;
    60     jscCallingConvention().m_calleeSaveRegisters.forEach([&] (Reg reg) {
    61         GPRReg gpr = reg.gpr();
    62         if (!remainingPinnedRegisters || RegisterSet::stackRegisters().get(reg))
    63             return;
    64         if (remainingPinnedRegisters == 1) {
    65             m_pinnedRegisters.baseMemoryPointer = gpr;
    66             remainingPinnedRegisters--;
    67         } else
    68             m_pinnedRegisters.sizeRegisters.append({ gpr, pinnedSizeRegisters[--remainingPinnedRegisters - 1] });
    69     });
    70 
    71     ASSERT(!remainingPinnedRegisters);
    7261    m_memory = result;
    7362}
  • trunk/Source/JavaScriptCore/wasm/WasmMemory.h

    r207693 r209630  
    2929
    3030#include "WasmCallingConvention.h"
     31#include "WasmPageCount.h"
    3132
    3233#include <wtf/Vector.h>
    3334
    3435namespace JSC { namespace Wasm {
    35 
    36 struct PinnedSizeRegisterInfo {
    37     GPRReg sizeRegister;
    38     unsigned sizeOffset;
    39 };
    40 
    41 // FIXME: We should support more than one memory size register. Right now we take a vector with only one
    42 // entry. Specifically an entry where the sizeOffset == 0. If we have more than one size register,
    43 // we can have one for each load size class. see: https://bugs.webkit.org/show_bug.cgi?id=162952
    44 struct PinnedRegisterInfo {
    45     Vector<PinnedSizeRegisterInfo> sizeRegisters;
    46     GPRReg baseMemoryPointer;
    47 };
    48 
    49 constexpr uint32_t pageSize = 64 * KB;
    50 constexpr uint32_t maxPageCount = static_cast<uint32_t>((1ull << 32) / pageSize);
    5136
    5237class Memory {
     
    6045    };
    6146
    62     Memory() = default;
    63     Memory(uint32_t startingSize, uint32_t capacity, const Vector<unsigned>& pinnedSizeRegisters);
     47    JS_EXPORT_PRIVATE Memory(PageCount initial, PageCount maximum);
    6448
    6549    ~Memory()
     
    7155    void* memory() const { return m_memory; }
    7256    uint32_t size() const { return m_size; }
    73     const PinnedRegisterInfo& pinnedRegisters() const { return m_pinnedRegisters; }
    7457
    7558    Mode mode() const { return m_mode; }
     59
     60    PageCount initial() const { return m_initial; }
     61    PageCount maximum() const { return m_maximum; }
    7662
    7763    bool grow(uint32_t newSize)
     
    8571
    8672    static ptrdiff_t offsetOfSize() { return OBJECT_OFFSETOF(Memory, m_size); }
     73
    8774   
    8875private:
    8976    void* m_memory { nullptr };
    90     PinnedRegisterInfo m_pinnedRegisters;
    9177    Mode m_mode;
    9278    uint32_t m_size { 0 };
    9379    uint32_t m_capacity { 0 };
     80    PageCount m_initial;
     81    PageCount m_maximum;
    9482    uint64_t m_mappedCapacity { 0 };
    9583};
  • trunk/Source/JavaScriptCore/wasm/WasmModuleParser.cpp

    r209560 r209630  
    3131#include "IdentifierInlines.h"
    3232#include "WasmFormat.h"
    33 #include "WasmMemory.h"
     33#include "WasmMemoryInformation.h"
    3434#include "WasmOps.h"
    3535#include "WasmSections.h"
     
    257257        }
    258258        case External::Memory: {
    259             // FIXME https://bugs.webkit.org/show_bug.cgi?id=164134
     259            bool isImport = true;
     260            if (!parseMemoryHelper(isImport))
     261                return false;
    260262            break;
    261263        }
     
    306308}
    307309
     310bool ModuleParser::parseMemoryHelper(bool isImport)
     311{
     312    // We don't allow redeclaring memory. Either via import or definition.
     313    if (m_module->memory)
     314        return false;
     315
     316    uint8_t flags;
     317    if (!parseVarUInt1(flags))
     318        return false;
     319
     320    uint32_t initial;
     321    if (!parseVarUInt32(initial))
     322        return false;
     323
     324    if (!PageCount::isValid(initial))
     325        return false;
     326
     327    PageCount initialPageCount(initial);
     328
     329    PageCount maximumPageCount;
     330    if (flags) {
     331        uint32_t maximum;
     332        if (!parseVarUInt32(maximum))
     333            return false;
     334
     335        if (!PageCount::isValid(maximum))
     336            return false;
     337
     338        maximumPageCount = PageCount(maximum);
     339        if (initialPageCount > maximumPageCount)
     340            return false;
     341    }
     342
     343    Vector<unsigned> pinnedSizes = { 0 };
     344    m_module->memory = MemoryInformation(initialPageCount, maximumPageCount, pinnedSizes, isImport);
     345    return true;
     346}
     347
    308348bool ModuleParser::parseMemory()
    309349{
     
    315355        return true;
    316356
    317     uint8_t flags;
    318     uint32_t size;
    319     if (!parseVarUInt1(flags)
    320         || !parseVarUInt32(size)
    321         || size > maxPageCount)
    322         return false;
    323 
    324     uint32_t capacity = maxPageCount;
    325     if (flags) {
    326         if (!parseVarUInt32(capacity)
    327             || size > capacity
    328             || capacity > maxPageCount)
    329             return false;
    330     }
    331 
    332     capacity *= pageSize;
    333     size *= pageSize;
    334 
    335     Vector<unsigned> pinnedSizes = { 0 };
    336     m_module->memory = std::make_unique<Memory>(size, capacity, pinnedSizes);
    337     return m_module->memory->memory();
     357    // We only allow one memory for now.
     358    if (count != 1)
     359        return false;
     360
     361    bool isImport = false;
     362    return parseMemoryHelper(isImport);
    338363}
    339364
     
    373398        }
    374399        case External::Memory: {
    375             // FIXME https://bugs.webkit.org/show_bug.cgi?id=164134
     400            // FIXME: https://bugs.webkit.org/show_bug.cgi?id=165671
    376401            break;
    377402        }
  • trunk/Source/JavaScriptCore/wasm/WasmModuleParser.h

    r209560 r209630  
    7979#undef WASM_SECTION_DECLARE_PARSER
    8080
     81    bool WARN_UNUSED_RETURN parseMemoryHelper(bool isImport);
     82
    8183    VM* m_vm;
    8284    std::unique_ptr<ModuleInformation> m_module;
  • trunk/Source/JavaScriptCore/wasm/WasmPlan.cpp

    r209560 r209630  
    117117        ASSERT(m_functionIndexSpace[functionIndexSpace].signature == signature);
    118118
    119         String error = validateFunction(functionStart, functionLength, signature, m_functionIndexSpace);
     119        String error = validateFunction(functionStart, functionLength, signature, m_functionIndexSpace, m_moduleInformation->memory);
    120120        if (!error.isNull()) {
    121121            if (verbose) {
     
    129129
    130130        unlinkedWasmToWasmCalls.uncheckedAppend(Vector<UnlinkedWasmToWasmCall>());
    131         m_wasmInternalFunctions.uncheckedAppend(parseAndCompile(*m_vm, functionStart, functionLength, m_moduleInformation->memory.get(), signature, unlinkedWasmToWasmCalls.at(functionIndex), m_functionIndexSpace));
     131        m_wasmInternalFunctions.uncheckedAppend(parseAndCompile(*m_vm, functionStart, functionLength, m_moduleInformation->memory, signature, unlinkedWasmToWasmCalls.at(functionIndex), m_functionIndexSpace));
    132132        m_functionIndexSpace[functionIndexSpace].code = m_wasmInternalFunctions[functionIndex]->code->code().executableAddress();
    133133    }
  • trunk/Source/JavaScriptCore/wasm/WasmPlan.h

    r209560 r209630  
    4343namespace Wasm {
    4444
    45 class Memory;
    46 
    4745class Plan {
    4846public:
     
    6866    }
    6967
    70     const Memory* memory() const
    71     {
    72         RELEASE_ASSERT(!failed());
    73         return m_moduleInformation->memory.get();
    74     }
    75 
    7668    size_t internalFunctionCount() const
    7769    {
     
    7971        return m_wasmInternalFunctions.size();
    8072    }
     73
    8174    B3::Compilation* jsToWasmEntryPointForFunction(size_t i) const
    8275    {
  • trunk/Source/JavaScriptCore/wasm/WasmValidate.cpp

    r209560 r209630  
    116116    void dump(const Vector<ControlEntry>& controlStack, const ExpressionList& expressionStack);
    117117
     118    bool hasMemory() const { return !!m_memory; }
     119
    118120    void setErrorMessage(String&& message) { ASSERT(m_errorMessage.isNull()); m_errorMessage = WTFMove(message); }
    119121    String errorMessage() const { return m_errorMessage; }
    120     Validate(ExpressionType returnType)
     122    Validate(ExpressionType returnType, const MemoryInformation& memory)
    121123        : m_returnType(returnType)
     124        , m_memory(memory)
    122125    {
    123126    }
     
    132135    Vector<Type> m_locals;
    133136    String m_errorMessage;
     137    const MemoryInformation& m_memory;
    134138};
    135139
     
    368372}
    369373
    370 String validateFunction(const uint8_t* source, size_t length, const Signature* signature, const FunctionIndexSpace& functionIndexSpace)
    371 {
    372     Validate context(signature->returnType);
     374String validateFunction(const uint8_t* source, size_t length, const Signature* signature, const FunctionIndexSpace& functionIndexSpace, const MemoryInformation& memory)
     375{
     376    Validate context(signature->returnType, memory);
    373377    FunctionParser<Validate> validator(context, source, length, signature, functionIndexSpace);
    374378    if (!validator.parse()) {
  • trunk/Source/JavaScriptCore/wasm/WasmValidate.h

    r209560 r209630  
    3232namespace JSC { namespace Wasm {
    3333
    34 String validateFunction(const uint8_t*, size_t, const Signature*, const FunctionIndexSpace&);
     34String validateFunction(const uint8_t*, size_t, const Signature*, const FunctionIndexSpace&, const MemoryInformation&);
    3535
    3636} } // namespace JSC::Wasm
  • trunk/Source/JavaScriptCore/wasm/generateWasmValidateInlinesHeader.py

    r208821 r209630  
    144144bool Validate::load(LoadOpType op, ExpressionType pointer, ExpressionType& result, uint32_t)
    145145{
     146    if (!hasMemory())
     147        return false;
     148
    146149    switch (op) {
    147150""" + loadCases + """
     
    151154bool Validate::store(StoreOpType op, ExpressionType pointer, ExpressionType value, uint32_t)
    152155{
     156    if (!hasMemory())
     157        return false;
     158
    153159    switch (op) {
    154160""" + storeCases + """
  • trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.cpp

    r209560 r209630  
    3333#include "JSModuleEnvironment.h"
    3434#include "JSModuleNamespaceObject.h"
     35#include "JSWebAssemblyMemory.h"
    3536#include "JSWebAssemblyModule.h"
    3637#include <wtf/StdLibExtras.h>
     
    7980    visitor.append(&thisObject->m_module);
    8081    visitor.append(&thisObject->m_moduleNamespaceObject);
     82    visitor.append(&thisObject->m_memory);
    8183    for (unsigned i = 0; i < thisObject->m_numImportFunctions; ++i)
    8284        visitor.append(thisObject->importFunction(i));
  • trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.h

    r209560 r209630  
    3030#include "JSDestructibleObject.h"
    3131#include "JSObject.h"
     32#include "JSWebAssemblyMemory.h"
    3233
    3334namespace JSC {
     
    6869    }
    6970
    70     static size_t offsetOfImportFunctions()
    71     {
    72         return WTF::roundUpToMultipleOf<sizeof(WriteBarrier<JSCell>)>(sizeof(JSWebAssemblyInstance));
    73     }
     71    JSWebAssemblyMemory* memory() { return m_memory.get(); }
     72    void setMemory(VM& vm, JSWebAssemblyMemory* memory) { m_memory.set(vm, this, memory); }
    7473
    7574    static size_t offsetOfImportFunction(unsigned idx)
    7675    {
    7776        return offsetOfImportFunctions() + sizeof(WriteBarrier<JSCell>) * idx;
    78     }
    79 
    80     static size_t allocationSize(unsigned numImportFunctions)
    81     {
    82         return offsetOfImportFunctions() + sizeof(WriteBarrier<JSCell>) * numImportFunctions;
    8377    }
    8478
     
    8983    static void visitChildren(JSCell*, SlotVisitor&);
    9084
     85    static size_t offsetOfImportFunctions()
     86    {
     87        return WTF::roundUpToMultipleOf<sizeof(WriteBarrier<JSCell>)>(sizeof(JSWebAssemblyInstance));
     88    }
     89
     90    static size_t allocationSize(unsigned numImportFunctions)
     91    {
     92        return offsetOfImportFunctions() + sizeof(WriteBarrier<JSCell>) * numImportFunctions;
     93    }
     94
    9195private:
    9296    WriteBarrier<JSWebAssemblyModule> m_module;
    9397    WriteBarrier<JSModuleNamespaceObject> m_moduleNamespaceObject;
     98    WriteBarrier<JSWebAssemblyMemory> m_memory;
    9499    unsigned m_numImportFunctions;
    95100};
  • trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyMemory.cpp

    r207650 r209630  
    3131#include "JSCInlines.h"
    3232
     33#include "JSArrayBuffer.h"
     34#include "ArrayBuffer.h"
     35
    3336namespace JSC {
    3437
    35 JSWebAssemblyMemory* JSWebAssemblyMemory::create(VM& vm, Structure* structure)
     38const ClassInfo JSWebAssemblyMemory::s_info = { "WebAssembly.Memory", &Base::s_info, 0, CREATE_METHOD_TABLE(JSWebAssemblyMemory) };
     39
     40JSWebAssemblyMemory* JSWebAssemblyMemory::create(VM& vm, Structure* structure, std::unique_ptr<Wasm::Memory>&& memory)
    3641{
    37     auto* instance = new (NotNull, allocateCell<JSWebAssemblyMemory>(vm.heap)) JSWebAssemblyMemory(vm, structure);
     42    auto* instance = new (NotNull, allocateCell<JSWebAssemblyMemory>(vm.heap)) JSWebAssemblyMemory(vm, structure, WTFMove(memory));
    3843    instance->finishCreation(vm);
    3944    return instance;
     
    4550}
    4651
    47 JSWebAssemblyMemory::JSWebAssemblyMemory(VM& vm, Structure* structure)
     52JSWebAssemblyMemory::JSWebAssemblyMemory(VM& vm, Structure* structure, std::unique_ptr<Wasm::Memory>&& memory)
    4853    : Base(vm, structure)
     54    , m_memory(WTFMove(memory))
    4955{
     56}
     57
     58JSArrayBuffer* JSWebAssemblyMemory::buffer(VM& vm, JSGlobalObject* globalObject)
     59{
     60    if (m_bufferWrapper)
     61        return m_bufferWrapper.get();
     62
     63    auto destructor = [] (void*) {
     64        // We don't need to do anything here to destroy the memory.
     65        // The ArrayBuffer backing the JSArrayBuffer is only owned by us,
     66        // so we guarantee its lifecylce.
     67    };
     68    m_buffer = ArrayBuffer::createFromBytes(memory()->memory(), memory()->size(), WTFMove(destructor));
     69    m_bufferWrapper.set(vm, this, JSArrayBuffer::create(vm, globalObject->m_arrayBufferStructure.get(), m_buffer.get()));
     70    RELEASE_ASSERT(m_bufferWrapper);
     71    return m_bufferWrapper.get();
    5072}
    5173
     
    6789
    6890    Base::visitChildren(thisObject, visitor);
     91    visitor.append(&thisObject->m_bufferWrapper);
    6992}
    70 
    71 const ClassInfo JSWebAssemblyMemory::s_info = { "WebAssembly.Memory", &Base::s_info, 0, CREATE_METHOD_TABLE(JSWebAssemblyMemory) };
    7293
    7394} // namespace JSC
  • trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyMemory.h

    r207650 r209630  
    3030#include "JSDestructibleObject.h"
    3131#include "JSObject.h"
     32#include "WasmMemory.h"
     33#include <wtf/RefPtr.h>
    3234
    3335namespace JSC {
     36
     37class ArrayBuffer;
     38class JSArrayBuffer;
    3439
    3540class JSWebAssemblyMemory : public JSDestructibleObject {
     
    3742    typedef JSDestructibleObject Base;
    3843
    39     static JSWebAssemblyMemory* create(VM&, Structure*);
     44    static JSWebAssemblyMemory* create(VM&, Structure*, std::unique_ptr<Wasm::Memory>&&);
    4045    static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
    4146
    4247    DECLARE_INFO;
    4348
     49    Wasm::Memory* memory() { return m_memory.get(); }
     50    JSArrayBuffer* buffer(VM& vm, JSGlobalObject*);
     51
    4452protected:
    45     JSWebAssemblyMemory(VM&, Structure*);
     53    JSWebAssemblyMemory(VM&, Structure*, std::unique_ptr<Wasm::Memory>&&);
    4654    void finishCreation(VM&);
    4755    static void destroy(JSCell*);
    4856    static void visitChildren(JSCell*, SlotVisitor&);
     57
     58    std::unique_ptr<Wasm::Memory> m_memory;
     59    WriteBarrier<JSArrayBuffer> m_bufferWrapper;
     60    RefPtr<ArrayBuffer> m_buffer;
    4961};
    5062
  • trunk/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp

    r209560 r209630  
    3535#include "JSWebAssemblyCallee.h"
    3636#include "JSWebAssemblyInstance.h"
     37#include "JSWebAssemblyMemory.h"
    3738#include "LLIntThunks.h"
    3839#include "ProtoCallFrame.h"
    3940#include "VM.h"
    4041#include "WasmFormat.h"
     42#include "WasmMemory.h"
    4143
    4244namespace JSC {
     
    8991        remainingArgs++;
    9092        argCount = boxedArgs.size();
     93    }
     94
     95    // Setup the memory that the entrance loads.
     96    if (JSWebAssemblyMemory* memory = wasmFunction->instance()->memory()) {
     97        Wasm::Memory* wasmMemory = memory->memory();
     98        vm.topWasmMemoryPointer = wasmMemory->memory();
     99        vm.topWasmMemorySize = wasmMemory->size();
     100    } else {
     101        vm.topWasmMemoryPointer = nullptr;
     102        vm.topWasmMemorySize = 0;
    91103    }
    92104
  • trunk/Source/JavaScriptCore/wasm/js/WebAssemblyInstanceConstructor.cpp

    r209560 r209630  
    3434#include "JSModuleNamespaceObject.h"
    3535#include "JSWebAssemblyInstance.h"
     36#include "JSWebAssemblyMemory.h"
    3637#include "JSWebAssemblyModule.h"
    3738#include "WebAssemblyFunction.h"
     
    5253 */
    5354
    54 static EncodedJSValue JSC_HOST_CALL constructJSWebAssemblyInstance(ExecState* state)
    55 {
    56     auto& vm = state->vm();
    57     auto scope = DECLARE_THROW_SCOPE(vm);
    58     auto* globalObject = state->lexicalGlobalObject();
     55static EncodedJSValue JSC_HOST_CALL constructJSWebAssemblyInstance(ExecState* exec)
     56{
     57    auto& vm = exec->vm();
     58    auto throwScope = DECLARE_THROW_SCOPE(vm);
     59    auto* globalObject = exec->lexicalGlobalObject();
    5960
    6061    // If moduleObject is not a WebAssembly.Module instance, a TypeError is thrown.
    61     JSWebAssemblyModule* jsModule = jsDynamicCast<JSWebAssemblyModule*>(state->argument(0));
     62    JSWebAssemblyModule* jsModule = jsDynamicCast<JSWebAssemblyModule*>(exec->argument(0));
    6263    if (!jsModule)
    63         return JSValue::encode(throwException(state, scope, createTypeError(state, ASCIILiteral("first argument to WebAssembly.Instance must be a WebAssembly.Module"), defaultSourceAppender, runtimeTypeForValue(state->argument(0)))));
     64        return JSValue::encode(throwException(exec, throwScope, createTypeError(exec, ASCIILiteral("first argument to WebAssembly.Instance must be a WebAssembly.Module"), defaultSourceAppender, runtimeTypeForValue(exec->argument(0)))));
    6465    const Wasm::ModuleInformation& moduleInformation = jsModule->moduleInformation();
    6566
    6667    // If the importObject parameter is not undefined and Type(importObject) is not Object, a TypeError is thrown.
    67     JSValue importArgument = state->argument(1);
     68    JSValue importArgument = exec->argument(1);
    6869    JSObject* importObject = importArgument.getObject();
    6970    if (!importArgument.isUndefined() && !importObject)
    70         return JSValue::encode(throwException(state, scope, createTypeError(state, ASCIILiteral("second argument to WebAssembly.Instance must be undefined or an Object"), defaultSourceAppender, runtimeTypeForValue(importArgument))));
     71        return JSValue::encode(throwException(exec, throwScope, createTypeError(exec, ASCIILiteral("second argument to WebAssembly.Instance must be undefined or an Object"), defaultSourceAppender, runtimeTypeForValue(importArgument))));
    7172
    7273    // If the list of module.imports is not empty and Type(importObject) is not Object, a TypeError is thrown.
    7374    if (moduleInformation.imports.size() && !importObject)
    74         return JSValue::encode(throwException(state, scope, createTypeError(state, ASCIILiteral("second argument to WebAssembly.Instance must be Object because the WebAssembly.Module has imports"), defaultSourceAppender, runtimeTypeForValue(importArgument))));
     75        return JSValue::encode(throwException(exec, throwScope, createTypeError(exec, ASCIILiteral("second argument to WebAssembly.Instance must be Object because the WebAssembly.Module has imports"), defaultSourceAppender, runtimeTypeForValue(importArgument))));
    7576
    7677    Identifier moduleKey = Identifier::fromUid(PrivateName(PrivateName::Description, "WebAssemblyInstance"));
    77     WebAssemblyModuleRecord* moduleRecord = WebAssemblyModuleRecord::create(state, vm, globalObject->webAssemblyModuleRecordStructure(), moduleKey, moduleInformation);
    78     RETURN_IF_EXCEPTION(scope, { });
    79 
    80     Structure* instanceStructure = InternalFunction::createSubclassStructure(state, state->newTarget(), globalObject->WebAssemblyInstanceStructure());
    81     RETURN_IF_EXCEPTION(scope, { });
    82 
    83     JSWebAssemblyInstance* instance = JSWebAssemblyInstance::create(vm, instanceStructure, jsModule, moduleRecord->getModuleNamespace(state), moduleInformation.imports.size());
    84     RETURN_IF_EXCEPTION(scope, { });
     78    WebAssemblyModuleRecord* moduleRecord = WebAssemblyModuleRecord::create(exec, vm, globalObject->webAssemblyModuleRecordStructure(), moduleKey, moduleInformation);
     79    RETURN_IF_EXCEPTION(throwScope, { });
     80
     81    Structure* instanceStructure = InternalFunction::createSubclassStructure(exec, exec->newTarget(), globalObject->WebAssemblyInstanceStructure());
     82    RETURN_IF_EXCEPTION(throwScope, { });
     83
     84    JSWebAssemblyInstance* instance = JSWebAssemblyInstance::create(vm, instanceStructure, jsModule, moduleRecord->getModuleNamespace(exec), moduleInformation.imports.size());
     85    RETURN_IF_EXCEPTION(throwScope, { });
    8586
    8687    // Let funcs, memories and tables be initially-empty lists of callable JavaScript objects, WebAssembly.Memory objects and WebAssembly.Table objects, respectively.
     
    8990
    9091    // FIXME implement Table https://bugs.webkit.org/show_bug.cgi?id=164135
    91     // FIXME implement Memory https://bugs.webkit.org/show_bug.cgi?id=164134
    9292    // FIXME implement Global https://bugs.webkit.org/show_bug.cgi?id=164133
    9393
     94    bool hasMemoryImport = false;
    9495    // For each import i in module.imports:
    9596    for (auto& import : moduleInformation.imports) {
    9697        // 1. Let o be the resultant value of performing Get(importObject, i.module_name).
    97         JSValue importModuleValue = importObject->get(state, import.module);
    98         RETURN_IF_EXCEPTION(scope, { });
     98        JSValue importModuleValue = importObject->get(exec, import.module);
     99        RETURN_IF_EXCEPTION(throwScope, { });
    99100        // 2. If Type(o) is not Object, throw a TypeError.
    100101        if (!importModuleValue.isObject())
    101             return JSValue::encode(throwException(state, scope, createTypeError(state, ASCIILiteral("import must be an object"), defaultSourceAppender, runtimeTypeForValue(importModuleValue))));
     102            return JSValue::encode(throwException(exec, throwScope, createTypeError(exec, ASCIILiteral("import must be an object"), defaultSourceAppender, runtimeTypeForValue(importModuleValue))));
     103
    102104        // 3. Let v be the value of performing Get(o, i.item_name)
    103105        JSObject* object = jsCast<JSObject*>(importModuleValue);
    104         JSValue value = object->get(state, import.field);
    105         RETURN_IF_EXCEPTION(scope, { });
     106        JSValue value = object->get(exec, import.field);
     107        RETURN_IF_EXCEPTION(throwScope, { });
     108
    106109        switch (import.kind) {
    107110        case Wasm::External::Function: {
     
    109112            // i. If IsCallable(v) is false, throw a TypeError.
    110113            if (!value.isFunction())
    111                 return JSValue::encode(throwException(state, scope, createTypeError(state, ASCIILiteral("import function must be callable"), defaultSourceAppender, runtimeTypeForValue(value))));
     114                return JSValue::encode(throwException(exec, throwScope, createTypeError(exec, ASCIILiteral("import function must be callable"), defaultSourceAppender, runtimeTypeForValue(value))));
    112115            JSCell* cell = value.asCell();
    113116            // ii. If v is an Exported Function Exotic Object:
     
    139142        case Wasm::External::Memory: {
    140143            // 6. If i is a memory import:
    141             // FIXME implement Memory https://bugs.webkit.org/show_bug.cgi?id=164134
     144            RELEASE_ASSERT(!hasMemoryImport); // This should be guaranteed by a validation failure.
     145            RELEASE_ASSERT(moduleInformation.memory);
     146            hasMemoryImport = true;
     147            JSWebAssemblyMemory* memory = jsDynamicCast<JSWebAssemblyMemory*>(value);
    142148            // i. If v is not a WebAssembly.Memory object, throw a TypeError.
     149            if (!memory)
     150                return JSValue::encode(throwException(exec, throwScope, createTypeError(exec, ASCIILiteral("Memory import is not an instance of WebAssembly.Memory"))));
     151
     152            Wasm::PageCount expectedInitial = moduleInformation.memory.initial();
     153            Wasm::PageCount actualInitial = memory->memory()->initial();
     154            if (actualInitial < expectedInitial)
     155                return JSValue::encode(throwException(exec, throwScope, createTypeError(exec, ASCIILiteral("Memory import provided an 'initial' that is too small"))));
     156
     157            if (Wasm::PageCount expectedMaximum = moduleInformation.memory.maximum()) {
     158                Wasm::PageCount actualMaximum = memory->memory()->maximum();
     159                if (!actualMaximum) {
     160                    return JSValue::encode(
     161                        throwException(exec, throwScope, createTypeError(exec, ASCIILiteral("Memory import did not have a 'maximum' but the module requires that it does"))));
     162                }
     163
     164                if (actualMaximum > expectedMaximum) {
     165                    return JSValue::encode(
     166                        throwException(exec, throwScope, createTypeError(exec, ASCIILiteral("Memory imports 'maximum' is larger than the module's expected 'maximum"))));
     167                }
     168            }
    143169            // ii. Append v to memories.
    144170            // iii. Append v.[[Memory]] to imports.
    145             RELEASE_ASSERT_NOT_REACHED();
     171            instance->setMemory(vm, memory);
    146172            break;
    147173        }
     
    158184    }
    159185
    160     moduleRecord->link(state, instance);
    161     RETURN_IF_EXCEPTION(scope, { });
     186    {
     187        if (!!moduleInformation.memory && moduleInformation.memory.isImport()) {
     188            // We should either have an import or we should have thrown an exception.
     189            RELEASE_ASSERT(hasMemoryImport);
     190        }
     191
     192        if (moduleInformation.memory && !hasMemoryImport) {
     193            RELEASE_ASSERT(!moduleInformation.memory.isImport());
     194            // We create a memory when it's a memory definition.
     195            std::unique_ptr<Wasm::Memory> memory = std::make_unique<Wasm::Memory>(moduleInformation.memory.initial(), moduleInformation.memory.maximum());
     196            instance->setMemory(vm,
     197               JSWebAssemblyMemory::create(vm, exec->lexicalGlobalObject()->WebAssemblyMemoryStructure(), WTFMove(memory)));
     198        }
     199    }
     200
     201    moduleRecord->link(exec, instance);
     202    RETURN_IF_EXCEPTION(throwScope, { });
    162203    if (verbose)
    163204        moduleRecord->dump();
    164     JSValue startResult = moduleRecord->evaluate(state);
     205    JSValue startResult = moduleRecord->evaluate(exec);
    165206    UNUSED_PARAM(startResult);
    166     RETURN_IF_EXCEPTION(scope, { });
     207    RETURN_IF_EXCEPTION(throwScope, { });
    167208
    168209    return JSValue::encode(instance);
  • trunk/Source/JavaScriptCore/wasm/js/WebAssemblyMemoryConstructor.cpp

    r208401 r209630  
    3131#include "FunctionPrototype.h"
    3232#include "JSCInlines.h"
     33#include "JSWebAssemblyMemory.h"
     34#include "WasmMemory.h"
     35#include "WasmPageCount.h"
    3336#include "WebAssemblyMemoryPrototype.h"
     37#include <wtf/Optional.h>
    3438
    3539#include "WebAssemblyMemoryConstructor.lut.h"
     
    4448 */
    4549
    46 static EncodedJSValue JSC_HOST_CALL constructJSWebAssemblyMemory(ExecState* state)
     50static EncodedJSValue JSC_HOST_CALL constructJSWebAssemblyMemory(ExecState* exec)
    4751{
    48     VM& vm = state->vm();
    49     auto scope = DECLARE_THROW_SCOPE(vm);
    50     // FIXME https://bugs.webkit.org/show_bug.cgi?id=164134
    51     return JSValue::encode(throwException(state, scope, createError(state, ASCIILiteral("WebAssembly doesn't yet implement the Memory constructor property"))));
     52    VM& vm = exec->vm();
     53    auto throwScope = DECLARE_THROW_SCOPE(vm);
     54    if (exec->argumentCount() != 1)
     55        return JSValue::encode(throwException(exec, throwScope, createTypeError(exec, ASCIILiteral("WebAssembly.Memory expects exactly one argument"))));
     56
     57    auto getUint32 = [&] (JSValue value) -> uint32_t {
     58        double doubleValue = value.toInteger(exec);
     59        RETURN_IF_EXCEPTION(throwScope, { });
     60        if (doubleValue < 0 || doubleValue > UINT_MAX) {
     61            throwException(exec, throwScope,
     62                createRangeError(exec, ASCIILiteral("WebAssembly.Memory expects the 'initial' and 'maximum' properties to be integers in the range: [0, 2^32 - 1]")));
     63            return 0;
     64        }
     65        return static_cast<uint32_t>(doubleValue);
     66    };
     67
     68    JSObject* memoryDescriptor;
     69    {
     70        JSValue argument = exec->argument(0);
     71        if (!argument.isObject())
     72            return JSValue::encode(throwException(exec, throwScope, createTypeError(exec, ASCIILiteral("WebAssembly.Memory expects its first argument to be an object"))));
     73        memoryDescriptor = jsCast<JSObject*>(argument);
     74    }
     75
     76    Wasm::PageCount initialPageCount;
     77    {
     78        Identifier initial = Identifier::fromString(&vm, "initial");
     79        JSValue minSizeValue = memoryDescriptor->get(exec, initial);
     80        RETURN_IF_EXCEPTION(throwScope, { });
     81        uint32_t size = getUint32(minSizeValue);
     82        RETURN_IF_EXCEPTION(throwScope, { });
     83        if (!Wasm::PageCount::isValid(size))
     84            return JSValue::encode(throwException(exec, throwScope, createRangeError(exec, ASCIILiteral("WebAssembly.Memory 'initial' page count is too large"))));
     85        initialPageCount = Wasm::PageCount(size);
     86    }
     87
     88    Wasm::PageCount maximumPageCount;
     89    {
     90        Identifier maximum = Identifier::fromString(&vm, "maximum");
     91        bool hasProperty = memoryDescriptor->hasProperty(exec, maximum);
     92        RETURN_IF_EXCEPTION(throwScope, { });
     93        if (hasProperty) {
     94            JSValue maxSizeValue = memoryDescriptor->get(exec, maximum);
     95            RETURN_IF_EXCEPTION(throwScope, { });
     96            uint32_t size = getUint32(maxSizeValue);
     97            if (!Wasm::PageCount::isValid(size))
     98                return JSValue::encode(throwException(exec, throwScope, createRangeError(exec, ASCIILiteral("WebAssembly.Memory 'maximum' page count is too large"))));
     99            RETURN_IF_EXCEPTION(throwScope, { });
     100            maximumPageCount = Wasm::PageCount(size);
     101
     102            if (initialPageCount > maximumPageCount) {
     103                return JSValue::encode(throwException(exec, throwScope,
     104                    createRangeError(exec, ASCIILiteral("'maximum' page count must be than greater than or equal to the 'initial' page count"))));
     105            }
     106        }
     107    }
     108
     109    std::unique_ptr<Wasm::Memory> memory = std::make_unique<Wasm::Memory>(initialPageCount, maximumPageCount);
     110
     111    return JSValue::encode(JSWebAssemblyMemory::create(vm, exec->lexicalGlobalObject()->WebAssemblyMemoryStructure(), WTFMove(memory)));
    52112}
    53113
     
    55115{
    56116    VM& vm = state->vm();
    57     auto scope = DECLARE_THROW_SCOPE(vm);
    58     return JSValue::encode(throwConstructorCannotBeCalledAsFunctionTypeError(state, scope, "WebAssembly.Memory"));
     117    auto throwScope = DECLARE_THROW_SCOPE(vm);
     118    return JSValue::encode(throwConstructorCannotBeCalledAsFunctionTypeError(state, throwScope, "WebAssembly.Memory"));
    59119}
    60120
  • trunk/Source/JavaScriptCore/wasm/js/WebAssemblyMemoryPrototype.cpp

    r207650 r209630  
    3030
    3131#include "FunctionPrototype.h"
     32#include "JSArrayBuffer.h"
    3233#include "JSCInlines.h"
     34#include "JSWebAssemblyMemory.h"
    3335
    3436#include "WebAssemblyMemoryPrototype.lut.h"
     
    4345 */
    4446
    45 WebAssemblyMemoryPrototype* WebAssemblyMemoryPrototype::create(VM& vm, JSGlobalObject*, Structure* structure)
     47static EncodedJSValue JSC_HOST_CALL webAssemblyMemoryProtoFuncBuffer(ExecState*);
     48
     49EncodedJSValue JSC_HOST_CALL webAssemblyMemoryProtoFuncBuffer(ExecState* exec)
     50{
     51    VM& vm = exec->vm();
     52    auto throwScope = DECLARE_THROW_SCOPE(vm);
     53
     54    JSWebAssemblyMemory* memory = jsDynamicCast<JSWebAssemblyMemory*>(exec->thisValue());
     55    if (!memory) {
     56        return JSValue::encode(throwException(exec, throwScope,
     57                    createTypeError(exec, ASCIILiteral("WebAssembly.Memory.prototype.buffer getter called with non WebAssembly.Memory |this| value"))));
     58    }
     59    return JSValue::encode(memory->buffer(exec->vm(), exec->lexicalGlobalObject()));
     60}
     61
     62WebAssemblyMemoryPrototype* WebAssemblyMemoryPrototype::create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
    4663{
    4764    auto* object = new (NotNull, allocateCell<WebAssemblyMemoryPrototype>(vm.heap)) WebAssemblyMemoryPrototype(vm, structure);
    48     object->finishCreation(vm);
     65    object->finishCreation(vm, globalObject);
    4966    return object;
    5067}
     
    5572}
    5673
    57 void WebAssemblyMemoryPrototype::finishCreation(VM& vm)
     74void WebAssemblyMemoryPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject)
    5875{
    5976    Base::finishCreation(vm);
     77    JSC_NATIVE_GETTER("buffer", webAssemblyMemoryProtoFuncBuffer, DontEnum | Accessor);
    6078}
    6179
  • trunk/Source/JavaScriptCore/wasm/js/WebAssemblyMemoryPrototype.h

    r207650 r209630  
    4444
    4545protected:
    46     void finishCreation(VM&);
     46    void finishCreation(VM&, JSGlobalObject*);
    4747
    4848private:
  • trunk/Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.cpp

    r209560 r209630  
    8080        }
    8181        case Wasm::External::Memory: {
    82             // FIXME https://bugs.webkit.org/show_bug.cgi?id=164134
     82            // FIXME: https://bugs.webkit.org/show_bug.cgi?id=165671
    8383            break;
    8484        }
     
    141141        }
    142142        case Wasm::External::Memory: {
    143             // FIXME https://bugs.webkit.org/show_bug.cgi?id=164134
     143            // FIXME: https://bugs.webkit.org/show_bug.cgi?id=165671
    144144            break;
    145145        }
Note: See TracChangeset for help on using the changeset viewer.