Commit 437735ed authored by bradnelson's avatar bradnelson Committed by Commit bot

[wasm][asm.js] Make asm.js->wasm return a regular object.

Return a regular JSObject in the asm.js -> wasm case.

BUG=v8:5877
R=mtrofin@chromium.org,aseemgarg@chromium.org,titzer@chromium.org

Review-Url: https://codereview.chromium.org/2664493002
Cr-Commit-Position: refs/heads/master@{#42757}
parent 6cd2d4ba
......@@ -273,22 +273,19 @@ MaybeHandle<Object> AsmJs::InstantiateAsmWasm(i::Isolate* isolate,
foreign, NONE);
}
i::MaybeHandle<i::JSObject> maybe_module_object =
i::MaybeHandle<i::Object> maybe_module_object =
i::wasm::WasmModule::Instantiate(isolate, &thrower, module, ffi_object,
memory);
if (maybe_module_object.is_null()) {
return MaybeHandle<Object>();
}
i::Handle<i::Object> module_object = maybe_module_object.ToHandleChecked();
i::Handle<i::Name> init_name(isolate->factory()->InternalizeUtf8String(
wasm::AsmWasmBuilder::foreign_init_name));
i::Handle<i::Object> init =
i::Object::GetProperty(module_object, init_name).ToHandleChecked();
i::Handle<i::Object> module_object = maybe_module_object.ToHandleChecked();
i::MaybeHandle<i::Object> maybe_init =
i::Object::GetProperty(module_object, init_name);
DCHECK(!maybe_init.is_null());
i::Handle<i::Object> init = maybe_init.ToHandleChecked();
i::Handle<i::Object> undefined(isolate->heap()->undefined_value(), isolate);
i::Handle<i::Object>* foreign_args_array =
new i::Handle<i::Object>[foreign_globals->length()];
......@@ -347,7 +344,9 @@ MaybeHandle<Object> AsmJs::InstantiateAsmWasm(i::Isolate* isolate,
MessageHandler::ReportMessage(isolate, &location, message);
}
return module_object;
Handle<String> exports_name =
isolate->factory()->InternalizeUtf8String("exports");
return i::Object::GetProperty(module_object, exports_name);
}
} // namespace internal
......
......@@ -16,6 +16,7 @@
#include "src/snapshot/snapshot.h"
#include "src/v8.h"
#include "src/asmjs/asm-wasm-builder.h"
#include "src/wasm/function-body-decoder.h"
#include "src/wasm/module-decoder.h"
#include "src/wasm/wasm-js.h"
......@@ -1918,17 +1919,30 @@ class WasmInstanceBuilder {
Handle<JSFunction>::null());
}
Handle<JSObject> exports_object = instance;
Handle<JSObject> exports_object;
if (module_->origin == kWasmOrigin) {
// Create the "exports" object.
exports_object = isolate_->factory()->NewJSObjectWithNullProto();
Handle<String> exports_name =
isolate_->factory()->InternalizeUtf8String("exports");
JSObject::AddProperty(instance, exports_name, exports_object, NONE);
} else if (module_->origin == kAsmJsOrigin) {
Handle<JSFunction> object_function = Handle<JSFunction>(
isolate_->native_context()->object_function(), isolate_);
exports_object = isolate_->factory()->NewJSObject(object_function);
} else {
UNREACHABLE();
}
Handle<String> exports_name =
isolate_->factory()->InternalizeUtf8String("exports");
JSObject::AddProperty(instance, exports_name, exports_object, NONE);
Handle<String> foreign_init_name =
isolate_->factory()->InternalizeUtf8String(
wasm::AsmWasmBuilder::foreign_init_name);
Handle<String> single_function_name =
isolate_->factory()->InternalizeUtf8String(
wasm::AsmWasmBuilder::single_function_name);
PropertyDescriptor desc;
desc.set_writable(false);
desc.set_writable(module_->origin == kAsmJsOrigin);
desc.set_enumerable(true);
// Count up export indexes.
......@@ -1957,6 +1971,15 @@ class WasmInstanceBuilder {
WasmCompiledModule::ExtractUtf8StringFromModuleBytes(
isolate_, compiled_module_, exp.name_offset, exp.name_length)
.ToHandleChecked();
Handle<JSObject> export_to;
if (module_->origin == kAsmJsOrigin && exp.kind == kExternalFunction &&
(String::Equals(name, foreign_init_name) ||
String::Equals(name, single_function_name))) {
export_to = instance;
} else {
export_to = exports_object;
}
switch (exp.kind) {
case kExternalFunction: {
// Wrap and export the code as a JSFunction.
......@@ -2053,14 +2076,13 @@ class WasmInstanceBuilder {
// Skip duplicates for asm.js.
if (module_->origin == kAsmJsOrigin) {
v8::Maybe<bool> status =
JSReceiver::HasOwnProperty(exports_object, name);
v8::Maybe<bool> status = JSReceiver::HasOwnProperty(export_to, name);
if (status.FromMaybe(false)) {
continue;
}
}
v8::Maybe<bool> status = JSReceiver::DefineOwnProperty(
isolate_, exports_object, name, &desc, Object::THROW_ON_ERROR);
isolate_, export_to, name, &desc, Object::THROW_ON_ERROR);
if (!status.IsJust()) {
thrower_->LinkError("export of %.*s failed.", name->length(),
name->ToCString().get());
......
......@@ -476,3 +476,23 @@ function assertValidAsm(func) {
Module();
assertFalse(% IsAsmWasmCode(Module));
})();
(function TestAsmIsRegular() {
function Module() {
'use asm';
var g = 123;
function foo() {
return g | 0;
}
return {x: foo};
}
var o = Module();
assertValidAsm(Module);
assertFalse(o instanceof WebAssembly.Instance);
assertTrue(o instanceof Object);
assertTrue(o.__proto__ === Object.prototype);
o.x = 5;
assertTrue(typeof o.x === 'number');
assertTrue(o.__single_function__ === undefined);
assertTrue(o.__foreign_init__ === undefined);
})();
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