Changeset 210282 in webkit


Ignore:
Timestamp:
Jan 4, 2017 11:27:01 AM (7 years ago)
Author:
jfbastien@apple.com
Message:

WebAssembly JS API: add Module.sections
https://bugs.webkit.org/show_bug.cgi?id=165159
<rdar://problem/29760326>

Reviewed by Mark Lam.

JSTests:

As described here: https://github.com/WebAssembly/design/blob/master/JS.md#webassemblymodulecustomsections

  • wasm/Builder.js: allow custom sections to be duplicated
  • wasm/js-api/Module.customSection.js: Added.

(assert.throws.WebAssembly.Module.prototype.customSections):
(assert.eq):

Source/JavaScriptCore:

As described in: https://github.com/WebAssembly/design/blob/master/JS.md#webassemblymodulecustomsections

This was added for Emscripten, and is likely to be used soon.

  • wasm/WasmFormat.h: custom sections are just name + bytes
  • wasm/WasmModuleParser.cpp: parse them, instead of skipping over
  • wasm/WasmModuleParser.h:
  • wasm/js/WebAssemblyModulePrototype.cpp: construct the Array of

ArrayBuffer as described in the spec
(JSC::webAssemblyModuleProtoCustomSections):

Location:
trunk
Files:
1 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r210276 r210282  
     12017-01-04  JF Bastien  <jfbastien@apple.com>
     2
     3        WebAssembly JS API: add Module.sections
     4        https://bugs.webkit.org/show_bug.cgi?id=165159
     5        <rdar://problem/29760326>
     6
     7        Reviewed by Mark Lam.
     8
     9        As described here: https://github.com/WebAssembly/design/blob/master/JS.md#webassemblymodulecustomsections
     10
     11        * wasm/Builder.js: allow custom sections to be duplicated
     12        * wasm/js-api/Module.customSection.js: Added.
     13        (assert.throws.WebAssembly.Module.prototype.customSections):
     14        (assert.eq):
     15
    1162017-01-04  Saam Barati  <sbarati@apple.com>
    217
  • trunk/JSTests/wasm/Builder.js

    r210244 r210282  
    714714            // Check uniqueness.
    715715            for (const s of this._sections)
    716                 assert.falsy(s.name === name && s.id === number, `Cannot have two sections with the same name "${name}" and ID ${number}`);
     716                if (number !== _unknownSectionId)
     717                    assert.falsy(s.name === name && s.id === number, `Cannot have two sections with the same name "${name}" and ID ${number}`);
    717718            // Check ordering.
    718719            if ((number !== _unknownSectionId) && (this._sections.length !== 0)) {
  • trunk/Source/JavaScriptCore/ChangeLog

    r210276 r210282  
     12017-01-04  JF Bastien  <jfbastien@apple.com>
     2
     3        WebAssembly JS API: add Module.sections
     4        https://bugs.webkit.org/show_bug.cgi?id=165159
     5        <rdar://problem/29760326>
     6
     7        Reviewed by Mark Lam.
     8
     9        As described in: https://github.com/WebAssembly/design/blob/master/JS.md#webassemblymodulecustomsections
     10
     11        This was added for Emscripten, and is likely to be used soon.
     12
     13        * wasm/WasmFormat.h: custom sections are just name + bytes
     14        * wasm/WasmModuleParser.cpp: parse them, instead of skipping over
     15        * wasm/WasmModuleParser.h:
     16        * wasm/js/WebAssemblyModulePrototype.cpp: construct the Array of
     17        ArrayBuffer as described in the spec
     18        (JSC::webAssemblyModuleProtoCustomSections):
     19
    1202017-01-04  Saam Barati  <sbarati@apple.com>
    221
  • trunk/Source/JavaScriptCore/wasm/WasmFormat.h

    r210229 r210282  
    221221    bool m_isValid { false };
    222222};
     223   
     224struct CustomSection {
     225    String name;
     226    Vector<uint8_t> payload;
     227};
    223228
    224229struct ModuleInformation {
     
    236241    Vector<Global> globals;
    237242    unsigned firstInternalGlobal { 0 };
     243    Vector<CustomSection> customSections;
     244
    238245    size_t functionIndexSpaceSize() const { return importFunctionSignatureIndices.size() + internalFunctionSignatureIndices.size(); }
    239246    bool isImportedFunctionFromFunctionIndexSpace(size_t functionIndex) const
  • trunk/Source/JavaScriptCore/wasm/WasmModuleParser.cpp

    r210229 r210282  
    8888
    8989        case Section::Unknown: {
    90             // Ignore section's name LEB and bytes: they're already included in sectionLength.
    91             m_offset += sectionLength;
     90            WASM_FAIL_IF_HELPER_FAILS(parseCustom(sectionLength));
    9291            break;
    9392        }
     
    601600    return { };
    602601}
     602   
     603auto ModuleParser::parseCustom(uint32_t sectionLength) -> PartialResult
     604{
     605    const uint32_t customSectionStartOffset = m_offset;
     606
     607    CustomSection section;
     608    uint32_t customSectionNumber = m_result.module->customSections.size() + 1;
     609    uint32_t nameLen;
     610    WASM_PARSER_FAIL_IF(!m_result.module->customSections.tryReserveCapacity(customSectionNumber), "can't allocate enough memory for ", customSectionNumber, "th custom section");
     611    WASM_PARSER_FAIL_IF(!parseVarUInt32(nameLen), "can't get ", customSectionNumber, "th custom section's name length");
     612    WASM_PARSER_FAIL_IF(!consumeUTF8String(section.name, nameLen), "nameLen get ", customSectionNumber, "th custom section's name of length ", nameLen);
     613
     614    uint32_t payloadBytes = sectionLength - (m_offset - customSectionStartOffset);
     615    WASM_PARSER_FAIL_IF(!section.payload.tryReserveCapacity(payloadBytes), "can't allocate enough memory for ", customSectionNumber, "th custom section's ", payloadBytes, " bytes");
     616    for (uint32_t byteNumber = 0; byteNumber < payloadBytes; ++byteNumber) {
     617        uint8_t byte;
     618        WASM_PARSER_FAIL_IF(!parseUInt8(byte), "can't get ", byteNumber, "th data byte from ", customSectionNumber, "th custom section");
     619        section.payload.uncheckedAppend(byte);
     620    }
     621   
     622    m_result.module->customSections.uncheckedAppend(WTFMove(section));
     623
     624    return { };
     625}
    603626
    604627} } // namespace JSC::Wasm
  • trunk/Source/JavaScriptCore/wasm/WasmModuleParser.h

    r210229 r210282  
    6161#undef WASM_SECTION_DECLARE_PARSER
    6262
     63    PartialResult WARN_UNUSED_RETURN parseCustom(uint32_t);
    6364    PartialResult WARN_UNUSED_RETURN parseGlobalType(Global&);
    6465    PartialResult WARN_UNUSED_RETURN parseMemoryHelper(bool isImport);
  • trunk/Source/JavaScriptCore/wasm/js/WebAssemblyModulePrototype.cpp

    r207650 r210282  
    2929#if ENABLE(WEBASSEMBLY)
    3030
     31#include "ArrayBuffer.h"
    3132#include "FunctionPrototype.h"
     33#include "JSArrayBuffer.h"
    3234#include "JSCInlines.h"
     35#include "JSWebAssemblyModule.h"
     36
     37namespace JSC {
     38static EncodedJSValue JSC_HOST_CALL webAssemblyModuleProtoCustomSections(ExecState*);
     39}
    3340
    3441#include "WebAssemblyModulePrototype.lut.h"
     
    4047/* Source for WebAssemblyModulePrototype.lut.h
    4148 @begin prototypeTableWebAssemblyModule
     49 customSections webAssemblyModuleProtoCustomSections DontEnum|Function 1
    4250 @end
    4351 */
     52
     53EncodedJSValue JSC_HOST_CALL webAssemblyModuleProtoCustomSections(ExecState* exec)
     54{
     55    VM& vm = exec->vm();
     56    auto* globalObject = exec->lexicalGlobalObject();
     57    auto throwScope = DECLARE_THROW_SCOPE(vm);
     58
     59    JSWebAssemblyModule* module = jsDynamicCast<JSWebAssemblyModule*>(exec->thisValue());
     60    if (!module)
     61        throwException(exec, throwScope, createTypeError(exec, ASCIILiteral("WebAssembly.Module.prototype.customSections called with non WebAssembly.Module |this| value")));
     62    RETURN_IF_EXCEPTION(throwScope, { });
     63
     64    const String sectionNameString = exec->argument(0).getString(exec);
     65    RETURN_IF_EXCEPTION(throwScope, { });
     66
     67    JSArray* result = constructEmptyArray(exec, nullptr, globalObject);
     68    RETURN_IF_EXCEPTION(throwScope, { });
     69
     70    const auto& customSections = module->moduleInformation().customSections;
     71    for (const Wasm::CustomSection& section : customSections) {
     72        if (section.name == sectionNameString) {
     73            auto buffer = ArrayBuffer::tryCreate(section.payload.data(), section.payload.size());
     74            if (!buffer)
     75                throwException(exec, throwScope, createOutOfMemoryError(exec));
     76
     77            Structure* arrayBufferStructure = InternalFunction::createSubclassStructure(exec, JSValue(), globalObject->arrayBufferStructure(ArrayBufferSharingMode::Default));
     78            RETURN_IF_EXCEPTION(throwScope, { });
     79
     80            result->push(exec, JSArrayBuffer::create(vm, arrayBufferStructure, WTFMove(buffer)));
     81            RETURN_IF_EXCEPTION(throwScope, { });
     82        }
     83    }
     84
     85    return JSValue::encode(result);
     86}
    4487
    4588WebAssemblyModulePrototype* WebAssemblyModulePrototype::create(VM& vm, JSGlobalObject*, Structure* structure)
Note: See TracChangeset for help on using the changeset viewer.