Skip to content

Commit

Permalink
Merge r230119 - WebAssembly compilation from DataView
Browse files Browse the repository at this point in the history
  • Loading branch information
jfbastien authored and carlosgcampos committed Jun 11, 2018
1 parent 2bc84b6 commit e03cf66
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 15 deletions.
12 changes: 12 additions & 0 deletions JSTests/ChangeLog
@@ -1,3 +1,15 @@
2018-03-30 JF Bastien <jfbastien@apple.com>

WebAssembly: support DataView compilation
https://bugs.webkit.org/show_bug.cgi?id=183342

Reviewed by Mark Lam.

Test WebAssembly compilation using a DataView with offset.

* wasm/regress/183342.js: Added.
(attempt.catch):

2018-05-01 Dominik Infuehr <dinfuehr@igalia.com>

Add SetCallee as DFG-Operation
Expand Down
57 changes: 57 additions & 0 deletions JSTests/wasm/regress/183342.js
@@ -0,0 +1,57 @@
const verbose = false;

{
// The simplest module with a DataView offset.
let buffer = new Uint8Array(16);
buffer[ 8] = 0x00; // \0
buffer[ 9] = 0x61; // a
buffer[10] = 0x73; // s
buffer[11] = 0x6d; // m
buffer[12] = 0x01; // version
buffer[13] = 0x00; // version
buffer[14] = 0x00; // version
buffer[15] = 0x00; // version
const view = new DataView(buffer.buffer, 8);
const module = new WebAssembly.Module(view);
const instance = new WebAssembly.Instance(module);
}

{
// A bunch of random offsets into large buffers with mostly valid content.
const headerSize = 16;
const roundToHeaderSize = s => Math.round(s / headerSize) * headerSize;
for (let attempt = 0; attempt < 100; ++attempt) {
const bufferSize = Math.max(roundToHeaderSize(Math.random() * 0xffff), headerSize * 2);
let buffer = new Uint8Array(bufferSize);
for (let i = 0; i < bufferSize; i += headerSize) {
buffer[ 0 + i] = 0x00; // \0
buffer[ 1 + i] = 0x61; // a
buffer[ 2 + i] = 0x73; // s
buffer[ 3 + i] = 0x6d; // m
buffer[ 4 + i] = 0x01; // version
buffer[ 5 + i] = 0x00; // version
buffer[ 6 + i] = 0x00; // version
buffer[ 7 + i] = 0x00; // version
buffer[ 8 + i] = 0x00; // ID = custom
buffer[ 9 + i] = 0x80 | Math.round(Math.random() * 0x7f); // section byte size, LEB128
buffer[10 + i] = 0x80 | Math.round(Math.random() * 0x7f); // section byte size, LEB128
buffer[11 + i] = 0x00 | Math.round(Math.random() * 0x7f); // section byte size, LEB128
buffer[12 + i] = 0x04; // custom section name length, LEB128
buffer[13 + i] = 0x42; // B
buffer[14 + i] = 0x4f; // O
buffer[15 + i] = 0X4f; // O
buffer[16 + i] = 0x4d; // M
}
const viewOffset = roundToHeaderSize(Math.random() * bufferSize);
if (verbose)
print("Buffer size: ", bufferSize, " view offset: ", viewOffset, " view size: ", bufferSize - viewOffset);
const view = new DataView(buffer.buffer, viewOffset);
try {
const module = new WebAssembly.Module(view);
const instance = new WebAssembly.Instance(module);
} catch (e) {
if (verbose)
print(e);
}
}
}
18 changes: 18 additions & 0 deletions Source/JavaScriptCore/ChangeLog
@@ -1,3 +1,21 @@
2018-03-30 JF Bastien <jfbastien@apple.com>

WebAssembly: support DataView compilation
https://bugs.webkit.org/show_bug.cgi?id=183342

Reviewed by Mark Lam.

Compiling a module from a DataView was incorrectly dealing with
DataView's offset.

* wasm/WasmModuleParser.cpp:
(JSC::Wasm::ModuleParser::parse):
* wasm/js/JSWebAssemblyHelpers.h:
(JSC::getWasmBufferFromValue):
(JSC::createSourceBufferFromValue):
* wasm/js/WebAssemblyPrototype.cpp:
(JSC::webAssemblyValidateFunc):

2018-05-22 Alberto Garcia <berto@igalia.com>

[CMake] Properly detect compiler flags, needed libs, and fallbacks for usage of 64-bit atomic operations
Expand Down
4 changes: 2 additions & 2 deletions Source/JavaScriptCore/wasm/WasmModuleParser.cpp
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2016-2017 Apple Inc. All rights reserved.
* Copyright (C) 2016-2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
Expand Down Expand Up @@ -69,7 +69,7 @@ auto ModuleParser::parse() -> Result
uint32_t sectionLength;
WASM_PARSER_FAIL_IF(!validateOrder(previousKnownSection, section), "invalid section order, ", previousKnownSection, " followed by ", section);
WASM_PARSER_FAIL_IF(!parseVarUInt32(sectionLength), "can't get ", section, " section's length");
WASM_PARSER_FAIL_IF(sectionLength > length() - m_offset, section, "section of size ", sectionLength, " would overflow Module's size");
WASM_PARSER_FAIL_IF(sectionLength > length() - m_offset, section, " section of size ", sectionLength, " would overflow Module's size");

auto end = m_offset + sectionLength;

Expand Down
20 changes: 10 additions & 10 deletions Source/JavaScriptCore/wasm/js/JSWebAssemblyHelpers.h
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2016 Apple Inc. All rights reserved.
* Copyright (C) 2016-2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
Expand Down Expand Up @@ -49,7 +49,7 @@ ALWAYS_INLINE uint32_t toNonWrappingUint32(ExecState* exec, JSValue value)
return static_cast<uint32_t>(doubleValue);
}

ALWAYS_INLINE uint8_t* getWasmBufferFromValue(ExecState* exec, JSValue value, size_t& byteOffset, size_t& byteSize)
ALWAYS_INLINE std::pair<uint8_t*, size_t> getWasmBufferFromValue(ExecState* exec, JSValue value)
{
VM& vm = exec->vm();
auto throwScope = DECLARE_THROW_SCOPE(vm);
Expand All @@ -59,26 +59,26 @@ ALWAYS_INLINE uint8_t* getWasmBufferFromValue(ExecState* exec, JSValue value, si
if (!(arrayBuffer || arrayBufferView)) {
throwException(exec, throwScope, createTypeError(exec,
ASCIILiteral("first argument must be an ArrayBufferView or an ArrayBuffer"), defaultSourceAppender, runtimeTypeForValue(value)));
return nullptr;
return { nullptr, 0 };
}

if (arrayBufferView ? arrayBufferView->isNeutered() : arrayBuffer->impl()->isNeutered()) {
throwException(exec, throwScope, createTypeError(exec,
ASCIILiteral("underlying TypedArray has been detatched from the ArrayBuffer"), defaultSourceAppender, runtimeTypeForValue(value)));
return nullptr;
return { nullptr, 0 };
}

byteOffset = arrayBufferView ? arrayBufferView->byteOffset() : 0;
byteSize = arrayBufferView ? arrayBufferView->length() : arrayBuffer->impl()->byteLength();
return arrayBufferView ? static_cast<uint8_t*>(arrayBufferView->vector()) : static_cast<uint8_t*>(arrayBuffer->impl()->data());
uint8_t* base = arrayBufferView ? static_cast<uint8_t*>(arrayBufferView->vector()) : static_cast<uint8_t*>(arrayBuffer->impl()->data());
size_t byteSize = arrayBufferView ? arrayBufferView->length() : arrayBuffer->impl()->byteLength();
return { base, byteSize };
}

ALWAYS_INLINE Vector<uint8_t> createSourceBufferFromValue(VM& vm, ExecState* exec, JSValue value)
{
auto throwScope = DECLARE_THROW_SCOPE(vm);
size_t byteOffset;
uint8_t* data;
size_t byteSize;
uint8_t* data = getWasmBufferFromValue(exec, value, byteOffset, byteSize);
std::tie(data, byteSize) = getWasmBufferFromValue(exec, value);
RETURN_IF_EXCEPTION(throwScope, Vector<uint8_t>());

Vector<uint8_t> result;
Expand All @@ -88,7 +88,7 @@ ALWAYS_INLINE Vector<uint8_t> createSourceBufferFromValue(VM& vm, ExecState* exe
}

result.grow(byteSize);
memcpy(result.data(), data + byteOffset, byteSize);
memcpy(result.data(), data, byteSize);
return result;
}

Expand Down
6 changes: 3 additions & 3 deletions Source/JavaScriptCore/wasm/js/WebAssemblyPrototype.cpp
Expand Up @@ -220,11 +220,11 @@ static EncodedJSValue JSC_HOST_CALL webAssemblyValidateFunc(ExecState* exec)
VM& vm = exec->vm();
auto scope = DECLARE_THROW_SCOPE(vm);

size_t byteOffset;
uint8_t* base;
size_t byteSize;
uint8_t* base = getWasmBufferFromValue(exec, exec->argument(0), byteOffset, byteSize);
std::tie(base, byteSize) = getWasmBufferFromValue(exec, exec->argument(0));
RETURN_IF_EXCEPTION(scope, encodedJSValue());
BBQPlan plan(&vm.wasmContext, base + byteOffset, byteSize, BBQPlan::Validation, Plan::dontFinalize());
BBQPlan plan(&vm.wasmContext, base, byteSize, BBQPlan::Validation, Plan::dontFinalize());
// FIXME: We might want to throw an OOM exception here if we detect that something will OOM.
// https://bugs.webkit.org/show_bug.cgi?id=166015
return JSValue::encode(jsBoolean(plan.parseAndValidateModule()));
Expand Down

0 comments on commit e03cf66

Please sign in to comment.