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 { ...@@ -239,6 +239,10 @@ enum BindingFlags {
V(SLOPPY_FUNCTION_WITH_READONLY_PROTOTYPE_MAP_INDEX, Map, \ V(SLOPPY_FUNCTION_WITH_READONLY_PROTOTYPE_MAP_INDEX, Map, \
sloppy_function_with_readonly_prototype_map) \ sloppy_function_with_readonly_prototype_map) \
V(WASM_FUNCTION_MAP_INDEX, Map, wasm_function_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_ASYNC_FUNCTION_MAP_INDEX, Map, sloppy_async_function_map) \
V(SLOPPY_GENERATOR_FUNCTION_MAP_INDEX, Map, sloppy_generator_function_map) \ V(SLOPPY_GENERATOR_FUNCTION_MAP_INDEX, Map, sloppy_generator_function_map) \
V(SLOW_ALIASED_ARGUMENTS_MAP_INDEX, Map, slow_aliased_arguments_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) { ...@@ -28,11 +28,10 @@ std::ostream& operator<<(std::ostream& os, const ErrorCode& error_code) {
} }
void ErrorThrower::Error(const char* format, ...) { void ErrorThrower::Error(const char* format, ...) {
// only report the first error. // Only report the first error.
if (error_ || isolate_->has_pending_exception()) return; if (error()) return;
error_ = true;
char buffer[256];
char buffer[256];
va_list arguments; va_list arguments;
va_start(arguments, format); va_start(arguments, format);
base::OS::VSNPrintF(buffer, 255, format, arguments); base::OS::VSNPrintF(buffer, 255, format, arguments);
...@@ -44,8 +43,13 @@ void ErrorThrower::Error(const char* format, ...) { ...@@ -44,8 +43,13 @@ void ErrorThrower::Error(const char* format, ...) {
} }
str << buffer; str << buffer;
isolate_->ScheduleThrow( message_ = isolate_->factory()->NewStringFromAsciiChecked(str.str().c_str());
*isolate_->factory()->NewStringFromAsciiChecked(str.str().c_str())); }
ErrorThrower::~ErrorThrower() {
if (error() && !isolate_->has_pending_exception()) {
isolate_->ScheduleThrow(*message_);
}
} }
} // namespace wasm } // namespace wasm
} // namespace internal } // namespace internal
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "src/base/compiler-specific.h" #include "src/base/compiler-specific.h"
#include "src/base/smart-pointers.h" #include "src/base/smart-pointers.h"
#include "src/handles.h"
#include "src/globals.h" #include "src/globals.h"
namespace v8 { namespace v8 {
...@@ -91,7 +92,8 @@ std::ostream& operator<<(std::ostream& os, const ErrorCode& error_code); ...@@ -91,7 +92,8 @@ std::ostream& operator<<(std::ostream& os, const ErrorCode& error_code);
class ErrorThrower { class ErrorThrower {
public: public:
ErrorThrower(Isolate* isolate, const char* context) 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, ...); PRINTF_FORMAT(2, 3) void Error(const char* fmt, ...);
...@@ -102,12 +104,18 @@ class ErrorThrower { ...@@ -102,12 +104,18 @@ class ErrorThrower {
return Error("%s", str.str().c_str()); 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: private:
Isolate* isolate_; Isolate* isolate_;
const char* context_; const char* context_;
bool error_; i::Handle<i::String> message_;
}; };
} // namespace wasm } // namespace wasm
} // namespace internal } // namespace internal
......
...@@ -80,7 +80,7 @@ bytecodes: [ ...@@ -80,7 +80,7 @@ bytecodes: [
/* 15 S> */ B(LdrUndefined), R(0), /* 15 S> */ B(LdrUndefined), R(0),
B(CreateArrayLiteral), U8(0), U8(0), U8(3), B(CreateArrayLiteral), U8(0), U8(0), U8(3),
B(Star), R(1), B(Star), R(1),
B(CallJSRuntime), U8(124), R(0), U8(2), B(CallJSRuntime), U8(128), R(0), U8(2),
/* 44 S> */ B(Return), /* 44 S> */ B(Return),
] ]
constant pool: [ constant pool: [
......
...@@ -7,44 +7,54 @@ ...@@ -7,44 +7,54 @@
load("test/mjsunit/wasm/wasm-constants.js"); load("test/mjsunit/wasm/wasm-constants.js");
load("test/mjsunit/wasm/wasm-module-builder.js"); load("test/mjsunit/wasm/wasm-module-builder.js");
var kReturnValue = 117; let kReturnValue = 117;
var module = (function Build() {
var builder = new WasmModuleBuilder();
let buffer = (() => {
let builder = new WasmModuleBuilder();
builder.addMemory(1, 1, true); builder.addMemory(1, 1, true);
builder.addFunction("main", kSig_i) builder.addFunction("main", kSig_i)
.addBody([kExprI8Const, kReturnValue]) .addBody([kExprI8Const, kReturnValue])
.exportFunc(); .exportFunc();
return builder.instantiate(); return builder.toBuffer();
})(); })()
// Check the module exists. function CheckInstance(instance) {
assertFalse(module === undefined); assertFalse(instance === undefined);
assertFalse(module === null); assertFalse(instance === null);
assertFalse(module === 0); assertFalse(instance === 0);
assertEquals("object", typeof module); assertEquals("object", typeof instance);
// Check the memory is an ArrayBuffer. // Check the memory is an ArrayBuffer.
var mem = module.exports.memory; var mem = instance.exports.memory;
assertFalse(mem === undefined); assertFalse(mem === undefined);
assertFalse(mem === null); assertFalse(mem === null);
assertFalse(mem === 0); assertFalse(mem === 0);
assertEquals("object", typeof mem); assertEquals("object", typeof mem);
assertTrue(mem instanceof ArrayBuffer); assertTrue(mem instanceof ArrayBuffer);
for (var i = 0; i < 4; i++) { for (let i = 0; i < 4; i++) {
module.exports.memory = 0; // should be ignored instance.exports.memory = 0; // should be ignored
assertEquals(mem, module.exports.memory); 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. // Official API
var main = module.exports.main; let module = new WebAssembly.Module(buffer);
assertFalse(main === undefined); CheckInstance(new WebAssembly.Instance(module));
assertFalse(main === null);
assertFalse(main === 0);
assertEquals("function", typeof main);
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) { ...@@ -342,11 +342,8 @@ WasmModuleBuilder.prototype.toBuffer = function(debug) {
return buffer; return buffer;
} }
WasmModuleBuilder.prototype.instantiate = function(ffi, memory) { WasmModuleBuilder.prototype.instantiate = function(...args) {
var buffer = this.toBuffer(); var module = new WebAssembly.Module(this.toBuffer());
if (memory != undefined) { var instance = new WebAssembly.Instance(module, ...args);
return Wasm.instantiateModule(buffer, ffi, memory); return instance;
} else {
return Wasm.instantiateModule(buffer, ffi);
}
} }
...@@ -11,3 +11,8 @@ assertEquals("function", typeof Wasm.verifyFunction); ...@@ -11,3 +11,8 @@ assertEquals("function", typeof Wasm.verifyFunction);
assertEquals("function", typeof Wasm.instantiateModule); assertEquals("function", typeof Wasm.instantiateModule);
assertEquals("function", typeof Wasm.instantiateModuleFromAsm); assertEquals("function", typeof Wasm.instantiateModuleFromAsm);
assertFalse(undefined == Wasm.experimentalVersion); 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 @@ ...@@ -4,6 +4,7 @@
#include "test/unittests/test-utils.h" #include "test/unittests/test-utils.h"
#include "src/objects-inl.h"
#include "src/wasm/decoder.h" #include "src/wasm/decoder.h"
#include "src/wasm/wasm-macro-gen.h" #include "src/wasm/wasm-macro-gen.h"
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "test/unittests/test-utils.h" #include "test/unittests/test-utils.h"
#include "src/objects-inl.h"
#include "src/wasm/decoder.h" #include "src/wasm/decoder.h"
#include "src/wasm/leb-helper.h" #include "src/wasm/leb-helper.h"
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include "test/unittests/test-utils.h" #include "test/unittests/test-utils.h"
#include "src/handles.h"
#include "src/objects-inl.h"
#include "src/wasm/module-decoder.h" #include "src/wasm/module-decoder.h"
#include "src/wasm/wasm-macro-gen.h" #include "src/wasm/wasm-macro-gen.h"
#include "src/wasm/wasm-opcodes.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