Commit 386c747b authored by rossberg's avatar rossberg Committed by Commit bot

Upgrade Wasm JS API, step 1

Implements:
- WebAssembly object,
- WebAssembly.Module constructor,
- WebAssembly.Instance constructor,
- WebAssembly.compile async method,
- and Module and Instance instance objects.

Also, changes ErrorThrower to support capturing errors in a promise reject.

Since we cannot yet compile without fixing the Wasm memory, and cannot validate a module without compiling, the Module constructor and compile method don't do anything yet but checking that their argument is a suitable BufferSource. Instead of a compiled module, the hidden state of a Module object currently is just that buffer.

BUG=

Review-Url: https://codereview.chromium.org/2084573002
Cr-Commit-Position: refs/heads/master@{#37143}
parent 61386fb8
......@@ -239,6 +239,10 @@ enum BindingFlags {
V(SLOPPY_FUNCTION_WITH_READONLY_PROTOTYPE_MAP_INDEX, Map, \
sloppy_function_with_readonly_prototype_map) \
V(WASM_FUNCTION_MAP_INDEX, Map, wasm_function_map) \
V(WASM_MODULE_CONSTRUCTOR_INDEX, JSFunction, wasm_module_constructor) \
V(WASM_INSTANCE_CONSTRUCTOR_INDEX, JSFunction, wasm_instance_constructor) \
V(WASM_MODULE_SYM_INDEX, Symbol, wasm_module_sym) \
V(WASM_INSTANCE_SYM_INDEX, Symbol, wasm_instance_sym) \
V(SLOPPY_ASYNC_FUNCTION_MAP_INDEX, Map, sloppy_async_function_map) \
V(SLOPPY_GENERATOR_FUNCTION_MAP_INDEX, Map, sloppy_generator_function_map) \
V(SLOW_ALIASED_ARGUMENTS_MAP_INDEX, Map, slow_aliased_arguments_map) \
......
This diff is collapsed.
......@@ -28,11 +28,10 @@ std::ostream& operator<<(std::ostream& os, const ErrorCode& error_code) {
}
void ErrorThrower::Error(const char* format, ...) {
// only report the first error.
if (error_ || isolate_->has_pending_exception()) return;
error_ = true;
char buffer[256];
// Only report the first error.
if (error()) return;
char buffer[256];
va_list arguments;
va_start(arguments, format);
base::OS::VSNPrintF(buffer, 255, format, arguments);
......@@ -44,8 +43,13 @@ void ErrorThrower::Error(const char* format, ...) {
}
str << buffer;
isolate_->ScheduleThrow(
*isolate_->factory()->NewStringFromAsciiChecked(str.str().c_str()));
message_ = isolate_->factory()->NewStringFromAsciiChecked(str.str().c_str());
}
ErrorThrower::~ErrorThrower() {
if (error() && !isolate_->has_pending_exception()) {
isolate_->ScheduleThrow(*message_);
}
}
} // namespace wasm
} // namespace internal
......
......@@ -8,6 +8,7 @@
#include "src/base/compiler-specific.h"
#include "src/base/smart-pointers.h"
#include "src/handles.h"
#include "src/globals.h"
namespace v8 {
......@@ -91,7 +92,8 @@ std::ostream& operator<<(std::ostream& os, const ErrorCode& error_code);
class ErrorThrower {
public:
ErrorThrower(Isolate* isolate, const char* context)
: isolate_(isolate), context_(context), error_(false) {}
: isolate_(isolate), context_(context) {}
~ErrorThrower();
PRINTF_FORMAT(2, 3) void Error(const char* fmt, ...);
......@@ -102,12 +104,18 @@ class ErrorThrower {
return Error("%s", str.str().c_str());
}
bool error() const { return error_; }
i::Handle<i::String> Reify() {
auto result = message_;
message_ = i::Handle<i::String>();
return result;
}
bool error() const { return !message_.is_null(); }
private:
Isolate* isolate_;
const char* context_;
bool error_;
i::Handle<i::String> message_;
};
} // namespace wasm
} // namespace internal
......
......@@ -80,7 +80,7 @@ bytecodes: [
/* 15 S> */ B(LdrUndefined), R(0),
B(CreateArrayLiteral), U8(0), U8(0), U8(3),
B(Star), R(1),
B(CallJSRuntime), U8(124), R(0), U8(2),
B(CallJSRuntime), U8(128), R(0), U8(2),
/* 44 S> */ B(Return),
]
constant pool: [
......
......@@ -7,44 +7,54 @@
load("test/mjsunit/wasm/wasm-constants.js");
load("test/mjsunit/wasm/wasm-module-builder.js");
var kReturnValue = 117;
var module = (function Build() {
var builder = new WasmModuleBuilder();
let kReturnValue = 117;
let buffer = (() => {
let builder = new WasmModuleBuilder();
builder.addMemory(1, 1, true);
builder.addFunction("main", kSig_i)
.addBody([kExprI8Const, kReturnValue])
.exportFunc();
return builder.instantiate();
})();
// Check the module exists.
assertFalse(module === undefined);
assertFalse(module === null);
assertFalse(module === 0);
assertEquals("object", typeof module);
// Check the memory is an ArrayBuffer.
var mem = module.exports.memory;
assertFalse(mem === undefined);
assertFalse(mem === null);
assertFalse(mem === 0);
assertEquals("object", typeof mem);
assertTrue(mem instanceof ArrayBuffer);
for (var i = 0; i < 4; i++) {
module.exports.memory = 0; // should be ignored
assertEquals(mem, module.exports.memory);
return builder.toBuffer();
})()
function CheckInstance(instance) {
assertFalse(instance === undefined);
assertFalse(instance === null);
assertFalse(instance === 0);
assertEquals("object", typeof instance);
// Check the memory is an ArrayBuffer.
var mem = instance.exports.memory;
assertFalse(mem === undefined);
assertFalse(mem === null);
assertFalse(mem === 0);
assertEquals("object", typeof mem);
assertTrue(mem instanceof ArrayBuffer);
for (let i = 0; i < 4; i++) {
instance.exports.memory = 0; // should be ignored
assertSame(mem, instance.exports.memory);
}
assertEquals(65536, instance.exports.memory.byteLength);
// Check the properties of the main function.
let main = instance.exports.main;
assertFalse(main === undefined);
assertFalse(main === null);
assertFalse(main === 0);
assertEquals("function", typeof main);
assertEquals(kReturnValue, main());
}
assertEquals(65536, module.exports.memory.byteLength);
// Deprecated experimental API.
CheckInstance(Wasm.instantiateModule(buffer));
// Check the properties of the main function.
var main = module.exports.main;
assertFalse(main === undefined);
assertFalse(main === null);
assertFalse(main === 0);
assertEquals("function", typeof main);
// Official API
let module = new WebAssembly.Module(buffer);
CheckInstance(new WebAssembly.Instance(module));
assertEquals(kReturnValue, main());
let promise = WebAssembly.compile(buffer);
promise.then(module => CheckInstance(new WebAssembly.Instance(module)));
......@@ -342,11 +342,8 @@ WasmModuleBuilder.prototype.toBuffer = function(debug) {
return buffer;
}
WasmModuleBuilder.prototype.instantiate = function(ffi, memory) {
var buffer = this.toBuffer();
if (memory != undefined) {
return Wasm.instantiateModule(buffer, ffi, memory);
} else {
return Wasm.instantiateModule(buffer, ffi);
}
WasmModuleBuilder.prototype.instantiate = function(...args) {
var module = new WebAssembly.Module(this.toBuffer());
var instance = new WebAssembly.Instance(module, ...args);
return instance;
}
......@@ -11,3 +11,8 @@ assertEquals("function", typeof Wasm.verifyFunction);
assertEquals("function", typeof Wasm.instantiateModule);
assertEquals("function", typeof Wasm.instantiateModuleFromAsm);
assertFalse(undefined == Wasm.experimentalVersion);
assertEquals('object', typeof WebAssembly);
assertEquals('function', typeof WebAssembly.Module);
assertEquals('function', typeof WebAssembly.Instance);
assertEquals('function', typeof WebAssembly.compile);
......@@ -4,6 +4,7 @@
#include "test/unittests/test-utils.h"
#include "src/objects-inl.h"
#include "src/wasm/decoder.h"
#include "src/wasm/wasm-macro-gen.h"
......
......@@ -4,6 +4,7 @@
#include "test/unittests/test-utils.h"
#include "src/objects-inl.h"
#include "src/wasm/decoder.h"
#include "src/wasm/leb-helper.h"
......
......@@ -4,6 +4,8 @@
#include "test/unittests/test-utils.h"
#include "src/handles.h"
#include "src/objects-inl.h"
#include "src/wasm/module-decoder.h"
#include "src/wasm/wasm-macro-gen.h"
#include "src/wasm/wasm-opcodes.h"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment