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, ...@@ -273,22 +273,19 @@ MaybeHandle<Object> AsmJs::InstantiateAsmWasm(i::Isolate* isolate,
foreign, NONE); 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, i::wasm::WasmModule::Instantiate(isolate, &thrower, module, ffi_object,
memory); memory);
if (maybe_module_object.is_null()) { if (maybe_module_object.is_null()) {
return MaybeHandle<Object>(); return MaybeHandle<Object>();
} }
i::Handle<i::Object> module_object = maybe_module_object.ToHandleChecked();
i::Handle<i::Name> init_name(isolate->factory()->InternalizeUtf8String( i::Handle<i::Name> init_name(isolate->factory()->InternalizeUtf8String(
wasm::AsmWasmBuilder::foreign_init_name)); 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> undefined(isolate->heap()->undefined_value(), isolate);
i::Handle<i::Object>* foreign_args_array = i::Handle<i::Object>* foreign_args_array =
new i::Handle<i::Object>[foreign_globals->length()]; new i::Handle<i::Object>[foreign_globals->length()];
...@@ -347,7 +344,9 @@ MaybeHandle<Object> AsmJs::InstantiateAsmWasm(i::Isolate* isolate, ...@@ -347,7 +344,9 @@ MaybeHandle<Object> AsmJs::InstantiateAsmWasm(i::Isolate* isolate,
MessageHandler::ReportMessage(isolate, &location, message); 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 } // namespace internal
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "src/snapshot/snapshot.h" #include "src/snapshot/snapshot.h"
#include "src/v8.h" #include "src/v8.h"
#include "src/asmjs/asm-wasm-builder.h"
#include "src/wasm/function-body-decoder.h" #include "src/wasm/function-body-decoder.h"
#include "src/wasm/module-decoder.h" #include "src/wasm/module-decoder.h"
#include "src/wasm/wasm-js.h" #include "src/wasm/wasm-js.h"
...@@ -1918,17 +1919,30 @@ class WasmInstanceBuilder { ...@@ -1918,17 +1919,30 @@ class WasmInstanceBuilder {
Handle<JSFunction>::null()); Handle<JSFunction>::null());
} }
Handle<JSObject> exports_object = instance; Handle<JSObject> exports_object;
if (module_->origin == kWasmOrigin) { if (module_->origin == kWasmOrigin) {
// Create the "exports" object. // Create the "exports" object.
exports_object = isolate_->factory()->NewJSObjectWithNullProto(); exports_object = isolate_->factory()->NewJSObjectWithNullProto();
Handle<String> exports_name = } else if (module_->origin == kAsmJsOrigin) {
isolate_->factory()->InternalizeUtf8String("exports"); Handle<JSFunction> object_function = Handle<JSFunction>(
JSObject::AddProperty(instance, exports_name, exports_object, NONE); 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; PropertyDescriptor desc;
desc.set_writable(false); desc.set_writable(module_->origin == kAsmJsOrigin);
desc.set_enumerable(true); desc.set_enumerable(true);
// Count up export indexes. // Count up export indexes.
...@@ -1957,6 +1971,15 @@ class WasmInstanceBuilder { ...@@ -1957,6 +1971,15 @@ class WasmInstanceBuilder {
WasmCompiledModule::ExtractUtf8StringFromModuleBytes( WasmCompiledModule::ExtractUtf8StringFromModuleBytes(
isolate_, compiled_module_, exp.name_offset, exp.name_length) isolate_, compiled_module_, exp.name_offset, exp.name_length)
.ToHandleChecked(); .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) { switch (exp.kind) {
case kExternalFunction: { case kExternalFunction: {
// Wrap and export the code as a JSFunction. // Wrap and export the code as a JSFunction.
...@@ -2053,14 +2076,13 @@ class WasmInstanceBuilder { ...@@ -2053,14 +2076,13 @@ class WasmInstanceBuilder {
// Skip duplicates for asm.js. // Skip duplicates for asm.js.
if (module_->origin == kAsmJsOrigin) { if (module_->origin == kAsmJsOrigin) {
v8::Maybe<bool> status = v8::Maybe<bool> status = JSReceiver::HasOwnProperty(export_to, name);
JSReceiver::HasOwnProperty(exports_object, name);
if (status.FromMaybe(false)) { if (status.FromMaybe(false)) {
continue; continue;
} }
} }
v8::Maybe<bool> status = JSReceiver::DefineOwnProperty( 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()) { if (!status.IsJust()) {
thrower_->LinkError("export of %.*s failed.", name->length(), thrower_->LinkError("export of %.*s failed.", name->length(),
name->ToCString().get()); name->ToCString().get());
......
...@@ -476,3 +476,23 @@ function assertValidAsm(func) { ...@@ -476,3 +476,23 @@ function assertValidAsm(func) {
Module(); Module();
assertFalse(% IsAsmWasmCode(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