Commit fb5b2f52 authored by rossberg's avatar rossberg Committed by Commit bot

[wasm] Implement {Compile,Runtime}Error; fix traps from start function

R=ahaas@chromium.org, titzer@chromium.org
BUG=v8:5507

Review-Url: https://codereview.chromium.org/2421453002
Cr-Commit-Position: refs/heads/master@{#40280}
parent f0c3a252
......@@ -1056,7 +1056,6 @@ static void InstallError(Isolate* isolate, Handle<JSObject> global,
Builtins::kErrorPrototypeToString, 0, true);
isolate->native_context()->set_error_to_string(*to_string_fun);
} else {
DCHECK(context_index != Context::ERROR_FUNCTION_INDEX);
DCHECK(isolate->native_context()->error_to_string()->IsJSFunction());
InstallFunction(prototype, isolate->error_to_string(),
......@@ -1923,6 +1922,16 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
Context::MAKE_URI_ERROR_INDEX);
}
{ // -- C o m p i l e E r r o r
Handle<JSObject> dummy = factory->NewJSObject(isolate->object_function());
InstallError(isolate, dummy, factory->CompileError_string(),
Context::WASM_COMPILE_ERROR_FUNCTION_INDEX);
// -- R u n t i m e E r r o r
InstallError(isolate, dummy, factory->RuntimeError_string(),
Context::WASM_RUNTIME_ERROR_FUNCTION_INDEX);
}
// Initialize the embedder data slot.
Handle<FixedArray> embedder_data = factory->NewFixedArray(3);
native_context()->set_embedder_data(*embedder_data);
......
......@@ -3385,7 +3385,7 @@ Handle<Code> WasmCompilationUnit::FinishCompilation() {
function_->name_offset, function_->name_length);
SNPrintF(buffer, "Compiling WASM function #%d:%.*s failed:",
function_->func_index, name.length(), name.start());
thrower_->Failed(buffer.start(), graph_construction_result_);
thrower_->CompileFailed(buffer.start(), graph_construction_result_);
}
return Handle<Code>::null();
......
......@@ -108,7 +108,10 @@ enum ContextLookupFlags {
V(SET_HAS_METHOD_INDEX, JSFunction, set_has) \
V(SYNTAX_ERROR_FUNCTION_INDEX, JSFunction, syntax_error_function) \
V(TYPE_ERROR_FUNCTION_INDEX, JSFunction, type_error_function) \
V(URI_ERROR_FUNCTION_INDEX, JSFunction, uri_error_function)
V(URI_ERROR_FUNCTION_INDEX, JSFunction, uri_error_function) \
V(WASM_COMPILE_ERROR_FUNCTION_INDEX, JSFunction, \
wasm_compile_error_function) \
V(WASM_RUNTIME_ERROR_FUNCTION_INDEX, JSFunction, wasm_runtime_error_function)
#define NATIVE_CONTEXT_FIELDS(V) \
V(GLOBAL_PROXY_INDEX, JSObject, global_proxy_object) \
......
......@@ -1289,6 +1289,8 @@ DEFINE_ERROR(RangeError, range_error)
DEFINE_ERROR(ReferenceError, reference_error)
DEFINE_ERROR(SyntaxError, syntax_error)
DEFINE_ERROR(TypeError, type_error)
DEFINE_ERROR(WasmCompileError, wasm_compile_error)
DEFINE_ERROR(WasmRuntimeError, wasm_runtime_error)
#undef DEFINE_ERROR
Handle<JSFunction> Factory::NewFunction(Handle<Map> map,
......
......@@ -634,6 +634,8 @@ class Factory final {
DECLARE_ERROR(ReferenceError)
DECLARE_ERROR(SyntaxError)
DECLARE_ERROR(TypeError)
DECLARE_ERROR(WasmCompileError)
DECLARE_ERROR(WasmRuntimeError)
#undef DEFINE_ERROR
Handle<String> NumberToString(Handle<Object> number,
......
......@@ -156,6 +156,8 @@
V(true_string, "true") \
V(TypeError_string, "TypeError") \
V(type_string, "type") \
V(CompileError_string, "CompileError") \
V(RuntimeError_string, "RuntimeError") \
V(uint16x8_string, "uint16x8") \
V(Uint16x8_string, "Uint16x8") \
V(uint32x4_string, "uint32x4") \
......
......@@ -122,7 +122,7 @@ RUNTIME_FUNCTION(Runtime_ThrowWasmError) {
DCHECK_EQ(2, args.length());
CONVERT_SMI_ARG_CHECKED(message_id, 0);
CONVERT_SMI_ARG_CHECKED(byte_offset, 1);
Handle<Object> error_obj = isolate->factory()->NewError(
Handle<Object> error_obj = isolate->factory()->NewWasmRuntimeError(
static_cast<MessageTemplate::Template>(message_id));
// For wasm traps, the byte offset (a.k.a source position) can not be
......
......@@ -60,7 +60,7 @@ RawBuffer GetRawBufferSource(
end = start + contents.ByteLength();
if (start == nullptr || end == start) {
thrower->Error("ArrayBuffer argument is empty");
thrower->CompileError("ArrayBuffer argument is empty");
}
} else if (source->IsTypedArray()) {
// A TypedArray was passed.
......@@ -74,10 +74,10 @@ RawBuffer GetRawBufferSource(
end = start + array->ByteLength();
if (start == nullptr || end == start) {
thrower->Error("ArrayBuffer argument is empty");
thrower->TypeError("ArrayBuffer argument is empty");
}
} else {
thrower->Error("Argument 0 must be an ArrayBuffer or Uint8Array");
thrower->TypeError("Argument 0 must be an ArrayBuffer or Uint8Array");
}
return {start, end};
......@@ -101,7 +101,7 @@ void VerifyModule(const v8::FunctionCallbackInfo<v8::Value>& args) {
true, internal::wasm::kWasmOrigin);
if (result.failed()) {
thrower.Failed("", result);
thrower.CompileFailed("", result);
}
if (result.val) delete result.val;
......@@ -129,7 +129,7 @@ void VerifyFunction(const v8::FunctionCallbackInfo<v8::Value>& args) {
}
if (result.failed()) {
thrower.Failed("", result);
thrower.CompileFailed("", result);
}
if (result.val) delete result.val;
......@@ -331,9 +331,10 @@ void WebAssemblyInstance(const v8::FunctionCallbackInfo<v8::Value>& args) {
i::MaybeHandle<i::JSObject> instance =
i::wasm::WasmModule::Instantiate(i_isolate, &thrower, i_obj, ffi, memory);
if (instance.is_null()) {
if (!thrower.error()) thrower.Error("Could not instantiate module");
if (!thrower.error()) thrower.RuntimeError("Could not instantiate module");
return;
}
DCHECK(!i_isolate->has_pending_exception());
v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
return_value.Set(Utils::ToLocal(instance.ToHandleChecked()));
}
......@@ -748,6 +749,17 @@ void WasmJs::InstallWasmConstructors(Isolate* isolate,
memory_constructor, DONT_ENUM);
InstallFunc(isolate, memory_proto, "grow", WebAssemblyMemoryGrow);
InstallGetter(isolate, memory_proto, "buffer", WebAssemblyMemoryGetBuffer);
// Setup errors
attributes = static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY);
Handle<JSFunction> compile_error(
isolate->native_context()->wasm_compile_error_function());
JSObject::AddProperty(wasm_object, isolate->factory()->CompileError_string(),
compile_error, attributes);
Handle<JSFunction> runtime_error(
isolate->native_context()->wasm_runtime_error_function());
JSObject::AddProperty(wasm_object, isolate->factory()->RuntimeError_string(),
runtime_error, attributes);
}
void WasmJs::Install(Isolate* isolate, Handle<JSGlobalObject> global) {
......
......@@ -565,8 +565,8 @@ void CompileSequentially(Isolate* isolate, const WasmModule* module,
code = compiler::WasmCompilationUnit::CompileWasmFunction(
thrower, isolate, module_env, &func);
if (code.is_null()) {
thrower->Error("Compilation of #%d:%.*s failed.", i, str.length(),
str.start());
thrower->CompileError("Compilation of #%d:%.*s failed.", i, str.length(),
str.start());
break;
}
// Install the code into the linker table.
......@@ -1268,7 +1268,7 @@ class WasmInstanceBuilder {
NewArrayBuffer(isolate_, globals_size);
globals = global_buffer;
if (globals.is_null()) {
thrower_->Error("Out of memory: wasm globals");
thrower_->RangeError("Out of memory: wasm globals");
return nothing;
}
Address old_address = owner.is_null()
......@@ -1425,6 +1425,8 @@ class WasmInstanceBuilder {
}
}
DCHECK(wasm::IsWasmObject(*instance));
//--------------------------------------------------------------------------
// Run the start function if one was specified.
//--------------------------------------------------------------------------
......@@ -1448,7 +1450,8 @@ class WasmInstanceBuilder {
Execution::Call(isolate_, startup_fct, undefined, 0, nullptr);
if (retval.is_null()) {
thrower_->Error("WASM.instantiateModule(): start function failed");
DCHECK(isolate_->has_pending_exception());
isolate_->OptionalRescheduleException(false);
// It's unfortunate that the new instance is already linked in the
// chain. However, we need to set up everything before executing the
// start function, such that stack trace information can be generated
......@@ -1457,8 +1460,7 @@ class WasmInstanceBuilder {
}
}
DCHECK(wasm::IsWasmObject(*instance));
DCHECK(!isolate_->has_pending_exception());
TRACE("Finishing instance %d\n", compiled_module_->instance_id());
TRACE_CHAIN(WasmCompiledModule::cast(module_object_->GetInternalField(0)));
return instance;
......@@ -1478,17 +1480,17 @@ class WasmInstanceBuilder {
MaybeHandle<String> function_name) {
Handle<String> function_name_handle;
if (function_name.ToHandle(&function_name_handle)) {
thrower_->Error("Import #%d module=\"%.*s\" function=\"%.*s\" error: %s",
index, module_name->length(),
module_name->ToCString().get(),
function_name_handle->length(),
function_name_handle->ToCString().get(), error);
thrower_->TypeError(
"Import #%d module=\"%.*s\" function=\"%.*s\" error: %s", index,
module_name->length(), module_name->ToCString().get(),
function_name_handle->length(),
function_name_handle->ToCString().get(), error);
} else {
thrower_->Error("Import #%d module=\"%.*s\" error: %s", index,
module_name->length(), module_name->ToCString().get(),
error);
thrower_->TypeError("Import #%d module=\"%.*s\" error: %s", index,
module_name->length(), module_name->ToCString().get(),
error);
}
thrower_->Error("Import ");
thrower_->TypeError("Import ");
return MaybeHandle<JSFunction>();
}
......@@ -1773,14 +1775,14 @@ class WasmInstanceBuilder {
// Allocate memory for a module instance as a new JSArrayBuffer.
Handle<JSArrayBuffer> AllocateMemory(uint32_t min_mem_pages) {
if (min_mem_pages > WasmModule::kMaxMemPages) {
thrower_->Error("Out of memory: wasm memory too large");
thrower_->RangeError("Out of memory: wasm memory too large");
return Handle<JSArrayBuffer>::null();
}
Handle<JSArrayBuffer> mem_buffer =
NewArrayBuffer(isolate_, min_mem_pages * WasmModule::kPageSize);
if (mem_buffer.is_null()) {
thrower_->Error("Out of memory: wasm memory");
thrower_->RangeError("Out of memory: wasm memory");
}
return mem_buffer;
}
......@@ -1881,8 +1883,8 @@ class WasmInstanceBuilder {
v8::Maybe<bool> status = JSReceiver::DefineOwnProperty(
isolate_, exports_object, name, &desc, Object::THROW_ON_ERROR);
if (!status.IsJust()) {
thrower_->Error("export of %.*s failed.", name->length(),
name->ToCString().get());
thrower_->TypeError("export of %.*s failed.", name->length(),
name->ToCString().get());
return;
}
}
......@@ -2166,7 +2168,7 @@ MaybeHandle<JSObject> wasm::CreateModuleObjectFromBytes(
DecodeWasmModule(isolate, &zone, start, end, false, origin);
std::unique_ptr<const WasmModule> decoded_module(result.val);
if (result.failed()) {
thrower->Failed("Wasm decoding failed", result);
thrower->CompileFailed("Wasm decoding failed", result);
return nothing;
}
MaybeHandle<WasmCompiledModule> maybe_compiled_module =
......
......@@ -46,28 +46,35 @@ void ErrorThrower::Format(i::Handle<i::JSFunction> constructor,
exception_ = isolate_->factory()->NewError(constructor, message);
}
void ErrorThrower::Error(const char* format, ...) {
void ErrorThrower::TypeError(const char* format, ...) {
if (error()) return;
va_list arguments;
va_start(arguments, format);
Format(isolate_->error_function(), format, arguments);
Format(isolate_->type_error_function(), format, arguments);
va_end(arguments);
}
void ErrorThrower::TypeError(const char* format, ...) {
void ErrorThrower::RangeError(const char* format, ...) {
if (error()) return;
va_list arguments;
va_start(arguments, format);
Format(isolate_->type_error_function(), format, arguments);
Format(isolate_->range_error_function(), format, arguments);
va_end(arguments);
}
void ErrorThrower::RangeError(const char* format, ...) {
void ErrorThrower::CompileError(const char* format, ...) {
if (error()) return;
va_list arguments;
va_start(arguments, format);
CHECK(*isolate_->range_error_function() != *isolate_->type_error_function());
Format(isolate_->range_error_function(), format, arguments);
Format(isolate_->wasm_compile_error_function(), format, arguments);
va_end(arguments);
}
void ErrorThrower::RuntimeError(const char* format, ...) {
if (error()) return;
va_list arguments;
va_start(arguments, format);
Format(isolate_->wasm_runtime_error_function(), format, arguments);
va_end(arguments);
}
......
......@@ -91,15 +91,16 @@ class V8_EXPORT_PRIVATE ErrorThrower {
: isolate_(isolate), context_(context) {}
~ErrorThrower();
PRINTF_FORMAT(2, 3) void Error(const char* fmt, ...);
PRINTF_FORMAT(2, 3) void TypeError(const char* fmt, ...);
PRINTF_FORMAT(2, 3) void RangeError(const char* fmt, ...);
PRINTF_FORMAT(2, 3) void CompileError(const char* fmt, ...);
PRINTF_FORMAT(2, 3) void RuntimeError(const char* fmt, ...);
template <typename T>
void Failed(const char* error, Result<T>& result) {
void CompileFailed(const char* error, Result<T>& result) {
std::ostringstream str;
str << error << result;
Error("%s", str.str().c_str());
CompileError("%s", str.str().c_str());
}
i::Handle<i::Object> Reify() {
......
......@@ -36,8 +36,8 @@ const WasmModule* DecodeWasmModuleForTesting(Isolate* isolate, Zone* zone,
std::unique_ptr<const WasmModule> module(decoding_result.val);
if (decoding_result.failed()) {
// Module verification failed. throw.
thrower->Error("WASM.compileRun() failed: %s",
decoding_result.error_msg.get());
thrower->CompileError("WASM.compileRun() failed: %s",
decoding_result.error_msg.get());
return nullptr;
}
......@@ -51,10 +51,10 @@ const Handle<JSObject> InstantiateModuleForTesting(Isolate* isolate,
CHECK(module != nullptr);
if (module->import_table.size() > 0) {
thrower->Error("Not supported: module has imports.");
thrower->CompileError("Not supported: module has imports.");
}
if (module->export_table.size() == 0) {
thrower->Error("Not supported: module has no exports.");
thrower->CompileError("Not supported: module has no exports.");
}
if (thrower->error()) return Handle<JSObject>::null();
......@@ -64,7 +64,7 @@ const Handle<JSObject> InstantiateModuleForTesting(Isolate* isolate,
isolate, module->module_start, module->module_end, thrower,
ModuleOrigin::kWasmOrigin, Handle<Script>::null(), nullptr, nullptr);
if (module_object.is_null()) {
thrower->Error("Module pre-validation failed.");
thrower->CompileError("Module pre-validation failed.");
return Handle<JSObject>::null();
}
MaybeHandle<JSObject> maybe_instance = WasmModule::Instantiate(
......@@ -84,7 +84,7 @@ const Handle<JSObject> CompileInstantiateWasmModuleForTesting(
isolate, zone, thrower, module_start, module_end, origin));
if (module == nullptr) {
thrower->Error("Wasm module decode failed");
thrower->CompileError("Wasm module decoding failed");
return Handle<JSObject>::null();
}
return InstantiateModuleForTesting(isolate, thrower, module.get());
......@@ -121,10 +121,10 @@ int32_t InterpretWasmModule(Isolate* isolate, ErrorThrower* thrower,
v8::internal::HandleScope scope(isolate);
if (module->import_table.size() > 0) {
thrower->Error("Not supported: module has imports.");
thrower->CompileError("Not supported: module has imports.");
}
if (module->export_table.size() == 0) {
thrower->Error("Not supported: module has no exports.");
thrower->CompileError("Not supported: module has no exports.");
}
if (thrower->error()) return -1;
......@@ -140,7 +140,7 @@ int32_t InterpretWasmModule(Isolate* isolate, ErrorThrower* thrower,
module->module_start + module->functions[i].code_end_offset};
DecodeResult result = VerifyWasmCode(isolate->allocator(), body);
if (result.failed()) {
thrower->Error("Function did not verify");
thrower->CompileError("Function did not verify");
return -1;
}
}
......@@ -171,7 +171,7 @@ int32_t InterpretWasmModule(Isolate* isolate, ErrorThrower* thrower,
} else if (thread->state() == WasmInterpreter::TRAPPED) {
return 0xdeadbeef;
} else {
thrower->Error(
thrower->RangeError(
"Interpreter did not finish execution within its step bound");
return -1;
}
......@@ -204,7 +204,7 @@ int32_t CallWasmFunctionForTesting(Isolate* isolate, Handle<JSObject> instance,
// The result should be a number.
if (retval.is_null()) {
thrower->Error("WASM.compileRun() failed: Invocation was null");
thrower->RuntimeError("WASM.compileRun() failed: Invocation was null");
return -1;
}
Handle<Object> result = retval.ToHandleChecked();
......@@ -214,7 +214,8 @@ int32_t CallWasmFunctionForTesting(Isolate* isolate, Handle<JSObject> instance,
if (result->IsHeapNumber()) {
return static_cast<int32_t>(HeapNumber::cast(*result)->value());
}
thrower->Error("WASM.compileRun() failed: Return value should be number");
thrower->RuntimeError(
"WASM.compileRun() failed: Return value should be number");
return -1;
}
......
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --expose-wasm
'use strict';
load("test/mjsunit/wasm/wasm-constants.js");
load("test/mjsunit/wasm/wasm-module-builder.js");
function module(bytes) {
let buffer = bytes;
if (typeof buffer === 'string') {
buffer = new ArrayBuffer(bytes.length);
let view = new Uint8Array(buffer);
for (let i = 0; i < bytes.length; ++i) {
view[i] = bytes.charCodeAt(i);
}
}
return new WebAssembly.Module(buffer);
}
function instance(bytes, imports = {}) {
return new WebAssembly.Instance(module(bytes), imports);
}
function builder() {
return new WasmModuleBuilder;
}
function assertCompileError(bytes) {
assertThrows(() => module(bytes), WebAssembly.CompileError);
}
function assertLinkError(bytes, imports = {}) {
assertThrows(() => instance(bytes, imports), TypeError);
}
function assertRuntimeError(bytes, imports = {}) {
assertThrows(() => instance(bytes, imports).exports.run(),
WebAssembly.RuntimeError);
}
function assertConversionError(bytes, imports = {}) {
assertThrows(() => instance(bytes, imports).exports.run(), TypeError);
}
(function TestDecodingError() {
assertCompileError("");
assertCompileError("X");
assertCompileError("\0x00asm");
})();
(function TestValidationError() {
assertCompileError(builder().addFunction("f", kSig_i_v).end().toBuffer());
assertCompileError(builder().addFunction("f", kSig_i_v).addBody([
kExprReturn
]).end().toBuffer());
assertCompileError(builder().addFunction("f", kSig_v_v).addBody([
kExprGetLocal, 0
]).end().toBuffer());
assertCompileError(builder().addStart(0).toBuffer());
})();
(function TestLinkingError() {
let b;
b = builder();
b.addImportWithModule("foo", "bar", kSig_v_v);
assertLinkError(b.toBuffer(), {});
b = builder();
b.addImportWithModule("foo", "bar", kSig_v_v);
assertLinkError(b.toBuffer(), {foo: {}});
b = builder();
b.addImportWithModule("foo", "bar", kSig_v_v);
assertLinkError(b.toBuffer(), {foo: {bar: 9}});
b = builder();
b.addImportedGlobal("foo", "bar", kAstI32);
assertLinkError(b.toBuffer(), {});
// TODO(titzer): implement stricter import checks for globals.
// b = builder();
// b.addImportedGlobal("foo", "bar", kAstI32);
// assertLinkError(b.toBuffer(), {foo: {}});
// b = builder();
// b.addImportedGlobal("foo", "bar", kAstI32);
// assertLinkError(b.toBuffer(), {foo: {bar: ""}});
// b = builder();
// b.addImportedGlobal("foo", "bar", kAstI32);
// assertLinkError(b.toBuffer(), {foo: {bar: () => 9}});
b = builder();
b.addImportedMemory("foo", "bar");
assertLinkError(b.toBuffer(), {});
b = builder();
b.addImportedMemory("foo", "bar");
assertLinkError(b.toBuffer(), {foo: {}});
// TODO(titzer): implement stricter import checks for globals.
// b = builder();
// b.addImportedMemory("foo", "bar", 1);
// assertLinkError(b.toBuffer(),
// {foo: {bar: new WebAssembly.Memory({initial: 0})}});
})();
(function TestTrapError() {
assertRuntimeError(builder().addFunction("run", kSig_v_v).addBody([
kExprUnreachable
]).exportFunc().end().toBuffer());
assertRuntimeError(builder().addFunction("run", kSig_v_v).addBody([
kExprI32Const, 1,
kExprI32Const, 0,
kExprI32DivS,
kExprDrop
]).exportFunc().end().toBuffer());
assertRuntimeError(builder().addFunction("run", kSig_v_v).addBody([
]).exportFunc().end().
addFunction("start", kSig_v_v).addBody([
kExprUnreachable
]).end().addStart(1).toBuffer());
})();
(function TestConversionError() {
let b = builder();
b.addImportWithModule("foo", "bar", kSig_v_l);
assertConversionError(b.addFunction("run", kSig_v_v).addBody([
kExprI64Const, 0, kExprCallFunction, 0
]).exportFunc().end().toBuffer());
assertConversionError(builder().addFunction("run", kSig_l_v).addBody([
kExprI64Const, 0
]).exportFunc().end().toBuffer());
})();
......@@ -4,6 +4,8 @@
// Flags: --expose-wasm
'use strict';
// Basic tests.
var outOfUint32RangeValue = 1e12;
......
......@@ -99,11 +99,13 @@ var kSig_l_ll = makeSig([kAstI64, kAstI64], [kAstI64]);
var kSig_i_dd = makeSig([kAstF64, kAstF64], [kAstI32]);
var kSig_v_v = makeSig([], []);
var kSig_i_v = makeSig([], [kAstI32]);
var kSig_l_v = makeSig([], [kAstI64]);
var kSig_f_v = makeSig([], [kAstF64]);
var kSig_d_v = makeSig([], [kAstF64]);
var kSig_v_i = makeSig([kAstI32], []);
var kSig_v_ii = makeSig([kAstI32, kAstI32], []);
var kSig_v_iii = makeSig([kAstI32, kAstI32, kAstI32], []);
var kSig_v_l = makeSig([kAstI64], []);
var kSig_v_d = makeSig([kAstF64], []);
var kSig_v_dd = makeSig([kAstF64, kAstF64], []);
var kSig_v_ddi = makeSig([kAstF64, kAstF64, kAstI32], []);
......
......@@ -83,6 +83,7 @@ class WasmFunctionBuilder {
this.module = module;
this.name = name;
this.type_index = type_index;
this.body = [];
}
exportAs(name) {
......@@ -104,6 +105,10 @@ class WasmFunctionBuilder {
this.locals = locals;
return this;
}
end() {
return this.module;
}
}
class WasmGlobalBuilder {
......@@ -138,6 +143,7 @@ class WasmModuleBuilder {
addStart(start_index) {
this.start_index = start_index;
return this;
}
addMemory(min, max, exp) {
......@@ -197,6 +203,7 @@ class WasmModuleBuilder {
addImportedMemory(module, name, initial = 0, maximum) {
let o = {module: module, name: name, kind: kExternalMemory, initial: initial, maximum: maximum};
this.imports.push(o);
return this;
}
addDataSegment(addr, data, is_global = false) {
......@@ -213,7 +220,7 @@ class WasmModuleBuilder {
return this;
}
toArray(debug) {
toArray(debug = false) {
let binary = new Binary;
let wasm = this;
......@@ -483,7 +490,7 @@ class WasmModuleBuilder {
return binary;
}
toBuffer(debug) {
toBuffer(debug = false) {
let bytes = this.toArray(debug);
let buffer = new ArrayBuffer(bytes.length);
let view = new Uint8Array(buffer);
......
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