Commit 224ca74a authored by Michael Starzinger's avatar Michael Starzinger Committed by Commit Bot

[asm.js] Propagate language mode to exported functions.

This makes sure the language mode of the module is correctly propagated
through the WebAssembly module, so that exported functions are allocated
with the correct language mode. It extends the existing {ModuleOrigin}
enum to consist of three values now.

R=clemensh@chromium.org
TEST=mjsunit/regress/wasm/regress-985154
BUG=chromium:985154

Change-Id: Id7b566738b1e710cc5001b894022bcd0f2c01bc3
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1708484
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Reviewed-by: 's avatarClemens Hammacher <clemensh@chromium.org>
Reviewed-by: 's avatarMichael Achenbach <machenbach@chromium.org>
Cr-Commit-Position: refs/heads/master@{#62826}
parent d251ec41
...@@ -287,7 +287,7 @@ UnoptimizedCompilationJob::Status AsmJsCompilationJob::FinalizeJobImpl( ...@@ -287,7 +287,7 @@ UnoptimizedCompilationJob::Status AsmJsCompilationJob::FinalizeJobImpl(
isolate, &thrower, isolate, &thrower,
wasm::ModuleWireBytes(module_->begin(), module_->end()), wasm::ModuleWireBytes(module_->begin(), module_->end()),
Vector<const byte>(asm_offsets_->begin(), asm_offsets_->size()), Vector<const byte>(asm_offsets_->begin(), asm_offsets_->size()),
uses_bitset) uses_bitset, shared_info->language_mode())
.ToHandleChecked(); .ToHandleChecked();
DCHECK(!thrower.error()); DCHECK(!thrower.error());
compile_time_ = compile_timer.Elapsed().InMillisecondsF(); compile_time_ = compile_timer.Elapsed().InMillisecondsF();
......
...@@ -2625,7 +2625,7 @@ void Pipeline::GenerateCodeForWasmFunction( ...@@ -2625,7 +2625,7 @@ void Pipeline::GenerateCodeForWasmFunction(
pipeline.RunPrintAndVerify("V8.WasmMachineCode", true); pipeline.RunPrintAndVerify("V8.WasmMachineCode", true);
data.BeginPhaseKind("V8.WasmOptimization"); data.BeginPhaseKind("V8.WasmOptimization");
const bool is_asm_js = module->origin == wasm::kAsmJsOrigin; const bool is_asm_js = is_asmjs_module(module);
if (FLAG_turbo_splitting && !is_asm_js) { if (FLAG_turbo_splitting && !is_asm_js) {
data.info()->MarkAsSplittingEnabled(); data.info()->MarkAsSplittingEnabled();
} }
......
...@@ -2386,8 +2386,7 @@ class WasmFullDecoder : public WasmDecoder<validate> { ...@@ -2386,8 +2386,7 @@ class WasmFullDecoder : public WasmDecoder<validate> {
break; break;
default: { default: {
// Deal with special asmjs opcodes. // Deal with special asmjs opcodes.
if (this->module_ != nullptr && if (this->module_ != nullptr && is_asmjs_module(this->module_)) {
this->module_->origin == kAsmJsOrigin) {
FunctionSig* sig = WasmOpcodes::AsmjsSignature(opcode); FunctionSig* sig = WasmOpcodes::AsmjsSignature(opcode);
if (sig) { if (sig) {
BuildSimpleOperator(opcode, sig); BuildSimpleOperator(opcode, sig);
......
...@@ -112,7 +112,7 @@ ExecutionTier WasmCompilationUnit::GetDefaultExecutionTier( ...@@ -112,7 +112,7 @@ ExecutionTier WasmCompilationUnit::GetDefaultExecutionTier(
const WasmModule* module) { const WasmModule* module) {
// Liftoff does not support the special asm.js opcodes, thus always compile // Liftoff does not support the special asm.js opcodes, thus always compile
// asm.js modules with TurboFan. // asm.js modules with TurboFan.
if (module->origin == kAsmJsOrigin) return ExecutionTier::kTurbofan; if (is_asmjs_module(module)) return ExecutionTier::kTurbofan;
if (FLAG_wasm_interpret_all) return ExecutionTier::kInterpreter; if (FLAG_wasm_interpret_all) return ExecutionTier::kInterpreter;
return FLAG_liftoff ? ExecutionTier::kLiftoff : ExecutionTier::kTurbofan; return FLAG_liftoff ? ExecutionTier::kLiftoff : ExecutionTier::kTurbofan;
} }
...@@ -147,7 +147,7 @@ WasmCompilationResult WasmCompilationUnit::ExecuteImportWrapperCompilation( ...@@ -147,7 +147,7 @@ WasmCompilationResult WasmCompilationUnit::ExecuteImportWrapperCompilation(
// Assume the wrapper is going to be a JS function with matching arity at // Assume the wrapper is going to be a JS function with matching arity at
// instantiation time. // instantiation time.
auto kind = compiler::kDefaultImportCallKind; auto kind = compiler::kDefaultImportCallKind;
bool source_positions = env->module->origin == kAsmJsOrigin; bool source_positions = is_asmjs_module(env->module);
WasmCompilationResult result = compiler::CompileWasmImportCallWrapper( WasmCompilationResult result = compiler::CompileWasmImportCallWrapper(
engine, env, kind, sig, source_positions); engine, env, kind, sig, source_positions);
return result; return result;
......
...@@ -824,7 +824,7 @@ void ValidateSequentially( ...@@ -824,7 +824,7 @@ void ValidateSequentially(
bool IsLazyModule(const WasmModule* module) { bool IsLazyModule(const WasmModule* module) {
return FLAG_wasm_lazy_compilation || return FLAG_wasm_lazy_compilation ||
(FLAG_asm_wasm_lazy_compilation && module->origin == kAsmJsOrigin); (FLAG_asm_wasm_lazy_compilation && is_asmjs_module(module));
} }
} // namespace } // namespace
...@@ -2502,7 +2502,7 @@ WasmCode* CompileImportWrapper( ...@@ -2502,7 +2502,7 @@ WasmCode* CompileImportWrapper(
// yet. // yet.
WasmImportWrapperCache::CacheKey key(kind, sig); WasmImportWrapperCache::CacheKey key(kind, sig);
DCHECK_NULL((*cache_scope)[key]); DCHECK_NULL((*cache_scope)[key]);
bool source_positions = native_module->module()->origin == kAsmJsOrigin; bool source_positions = is_asmjs_module(native_module->module());
// Keep the {WasmCode} alive until we explicitly call {IncRef}. // Keep the {WasmCode} alive until we explicitly call {IncRef}.
WasmCodeRefScope code_ref_scope; WasmCodeRefScope code_ref_scope;
CompilationEnv env = native_module->CreateCompilationEnv(); CompilationEnv env = native_module->CreateCompilationEnv();
......
...@@ -259,13 +259,13 @@ class ModuleDecoderImpl : public Decoder { ...@@ -259,13 +259,13 @@ class ModuleDecoderImpl : public Decoder {
explicit ModuleDecoderImpl(const WasmFeatures& enabled, ModuleOrigin origin) explicit ModuleDecoderImpl(const WasmFeatures& enabled, ModuleOrigin origin)
: Decoder(nullptr, nullptr), : Decoder(nullptr, nullptr),
enabled_features_(enabled), enabled_features_(enabled),
origin_(FLAG_assume_asmjs_origin ? kAsmJsOrigin : origin) {} origin_(FLAG_assume_asmjs_origin ? kAsmJsSloppyOrigin : origin) {}
ModuleDecoderImpl(const WasmFeatures& enabled, const byte* module_start, ModuleDecoderImpl(const WasmFeatures& enabled, const byte* module_start,
const byte* module_end, ModuleOrigin origin) const byte* module_end, ModuleOrigin origin)
: Decoder(module_start, module_end), : Decoder(module_start, module_end),
enabled_features_(enabled), enabled_features_(enabled),
origin_(FLAG_assume_asmjs_origin ? kAsmJsOrigin : origin) { origin_(FLAG_assume_asmjs_origin ? kAsmJsSloppyOrigin : origin) {
if (end_ < start_) { if (end_ < start_) {
error(start_, "end is less than start"); error(start_, "end is less than start");
end_ = start_; end_ = start_;
...@@ -746,7 +746,7 @@ class ModuleDecoderImpl : public Decoder { ...@@ -746,7 +746,7 @@ class ModuleDecoderImpl : public Decoder {
} }
} }
// Check for duplicate exports (except for asm.js). // Check for duplicate exports (except for asm.js).
if (ok() && origin_ != kAsmJsOrigin && module_->export_table.size() > 1) { if (ok() && origin_ == kWasmOrigin && module_->export_table.size() > 1) {
std::vector<WasmExport> sorted_exports(module_->export_table); std::vector<WasmExport> sorted_exports(module_->export_table);
auto cmp_less = [this](const WasmExport& a, const WasmExport& b) { auto cmp_less = [this](const WasmExport& a, const WasmExport& b) {
......
...@@ -312,8 +312,7 @@ MaybeHandle<WasmInstanceObject> InstanceBuilder::Build() { ...@@ -312,8 +312,7 @@ MaybeHandle<WasmInstanceObject> InstanceBuilder::Build() {
memory->set_is_detachable(false); memory->set_is_detachable(false);
DCHECK_IMPLIES(native_module->use_trap_handler(), DCHECK_IMPLIES(native_module->use_trap_handler(),
module_->origin == kAsmJsOrigin || is_asmjs_module(module_) || memory->is_wasm_memory() ||
memory->is_wasm_memory() ||
memory->backing_store() == nullptr); memory->backing_store() == nullptr);
} else if (initial_pages > 0 || native_module->use_trap_handler()) { } else if (initial_pages > 0 || native_module->use_trap_handler()) {
// We need to unconditionally create a guard region if using trap handlers, // We need to unconditionally create a guard region if using trap handlers,
...@@ -795,7 +794,7 @@ void InstanceBuilder::SanitizeImports() { ...@@ -795,7 +794,7 @@ void InstanceBuilder::SanitizeImports() {
int int_index = static_cast<int>(index); int int_index = static_cast<int>(index);
MaybeHandle<Object> result = MaybeHandle<Object> result =
module_->origin == kAsmJsOrigin is_asmjs_module(module_)
? LookupImportAsm(int_index, import_name) ? LookupImportAsm(int_index, import_name)
: LookupImport(int_index, module_name, import_name); : LookupImport(int_index, module_name, import_name);
if (thrower_->error()) { if (thrower_->error()) {
...@@ -1131,7 +1130,7 @@ bool InstanceBuilder::ProcessImportedGlobal(Handle<WasmInstanceObject> instance, ...@@ -1131,7 +1130,7 @@ bool InstanceBuilder::ProcessImportedGlobal(Handle<WasmInstanceObject> instance,
module_name, import_name); module_name, import_name);
return false; return false;
} }
if (module_->origin == kAsmJsOrigin) { if (is_asmjs_module(module_)) {
// Accepting {JSFunction} on top of just primitive values here is a // Accepting {JSFunction} on top of just primitive values here is a
// workaround to support legacy asm.js code with broken binding. Note // workaround to support legacy asm.js code with broken binding. Note
// that using {NaN} (or Smi::kZero) here is what using the observable // that using {NaN} (or Smi::kZero) here is what using the observable
...@@ -1469,7 +1468,8 @@ void InstanceBuilder::ProcessExports(Handle<WasmInstanceObject> instance) { ...@@ -1469,7 +1468,8 @@ void InstanceBuilder::ProcessExports(Handle<WasmInstanceObject> instance) {
exports_object = isolate_->factory()->NewJSObjectWithNullProto(); exports_object = isolate_->factory()->NewJSObjectWithNullProto();
break; break;
} }
case kAsmJsOrigin: { case kAsmJsSloppyOrigin:
case kAsmJsStrictOrigin: {
Handle<JSFunction> object_function = Handle<JSFunction>( Handle<JSFunction> object_function = Handle<JSFunction>(
isolate_->native_context()->object_function(), isolate_); isolate_->native_context()->object_function(), isolate_);
exports_object = isolate_->factory()->NewJSObject(object_function); exports_object = isolate_->factory()->NewJSObject(object_function);
......
...@@ -238,10 +238,13 @@ bool WasmEngine::SyncValidate(Isolate* isolate, const WasmFeatures& enabled, ...@@ -238,10 +238,13 @@ bool WasmEngine::SyncValidate(Isolate* isolate, const WasmFeatures& enabled,
MaybeHandle<AsmWasmData> WasmEngine::SyncCompileTranslatedAsmJs( MaybeHandle<AsmWasmData> WasmEngine::SyncCompileTranslatedAsmJs(
Isolate* isolate, ErrorThrower* thrower, const ModuleWireBytes& bytes, Isolate* isolate, ErrorThrower* thrower, const ModuleWireBytes& bytes,
Vector<const byte> asm_js_offset_table_bytes, Vector<const byte> asm_js_offset_table_bytes,
Handle<HeapNumber> uses_bitset) { Handle<HeapNumber> uses_bitset, LanguageMode language_mode) {
ModuleOrigin origin = language_mode == LanguageMode::kSloppy
? kAsmJsSloppyOrigin
: kAsmJsStrictOrigin;
ModuleResult result = ModuleResult result =
DecodeWasmModule(kAsmjsWasmFeatures, bytes.start(), bytes.end(), false, DecodeWasmModule(kAsmjsWasmFeatures, bytes.start(), bytes.end(), false,
kAsmJsOrigin, isolate->counters(), allocator()); origin, isolate->counters(), allocator());
if (result.failed()) { if (result.failed()) {
// This happens once in a while when we have missed some limit check // This happens once in a while when we have missed some limit check
// in the asm parser. Output an error message to help diagnose, but crash. // in the asm parser. Output an error message to help diagnose, but crash.
......
...@@ -62,7 +62,7 @@ class V8_EXPORT_PRIVATE WasmEngine { ...@@ -62,7 +62,7 @@ class V8_EXPORT_PRIVATE WasmEngine {
MaybeHandle<AsmWasmData> SyncCompileTranslatedAsmJs( MaybeHandle<AsmWasmData> SyncCompileTranslatedAsmJs(
Isolate* isolate, ErrorThrower* thrower, const ModuleWireBytes& bytes, Isolate* isolate, ErrorThrower* thrower, const ModuleWireBytes& bytes,
Vector<const byte> asm_js_offset_table_bytes, Vector<const byte> asm_js_offset_table_bytes,
Handle<HeapNumber> uses_bitset); Handle<HeapNumber> uses_bitset, LanguageMode language_mode);
Handle<WasmModuleObject> FinalizeTranslatedAsmJs( Handle<WasmModuleObject> FinalizeTranslatedAsmJs(
Isolate* isolate, Handle<AsmWasmData> asm_wasm_data, Isolate* isolate, Handle<AsmWasmData> asm_wasm_data,
Handle<Script> script); Handle<Script> script);
......
...@@ -164,7 +164,11 @@ struct WasmCompilationHint { ...@@ -164,7 +164,11 @@ struct WasmCompilationHint {
WasmCompilationHintTier top_tier; WasmCompilationHintTier top_tier;
}; };
enum ModuleOrigin : uint8_t { kWasmOrigin, kAsmJsOrigin }; enum ModuleOrigin : uint8_t {
kWasmOrigin,
kAsmJsSloppyOrigin,
kAsmJsStrictOrigin
};
#define SELECT_WASM_COUNTER(counters, origin, prefix, suffix) \ #define SELECT_WASM_COUNTER(counters, origin, prefix, suffix) \
((origin) == kWasmOrigin ? (counters)->prefix##_wasm_##suffix() \ ((origin) == kWasmOrigin ? (counters)->prefix##_wasm_##suffix() \
...@@ -221,6 +225,10 @@ struct V8_EXPORT_PRIVATE WasmModule { ...@@ -221,6 +225,10 @@ struct V8_EXPORT_PRIVATE WasmModule {
void AddFunctionNameForTesting(int function_index, WireBytesRef name); void AddFunctionNameForTesting(int function_index, WireBytesRef name);
}; };
inline bool is_asmjs_module(const WasmModule* module) {
return module->origin != kWasmOrigin;
}
size_t EstimateStoredSize(const WasmModule* module); size_t EstimateStoredSize(const WasmModule* module);
// Returns the number of possible export wrappers for a given module. // Returns the number of possible export wrappers for a given module.
......
...@@ -111,7 +111,7 @@ void WasmModuleObject::reset_breakpoint_infos() { ...@@ -111,7 +111,7 @@ void WasmModuleObject::reset_breakpoint_infos() {
GetReadOnlyRoots().undefined_value()); GetReadOnlyRoots().undefined_value());
} }
bool WasmModuleObject::is_asm_js() { bool WasmModuleObject::is_asm_js() {
bool asm_js = module()->origin == wasm::kAsmJsOrigin; bool asm_js = is_asmjs_module(module());
DCHECK_EQ(asm_js, script().IsUserJavaScript()); DCHECK_EQ(asm_js, script().IsUserJavaScript());
DCHECK_EQ(asm_js, has_asm_js_offset_table()); DCHECK_EQ(asm_js, has_asm_js_offset_table());
return asm_js; return asm_js;
......
...@@ -511,7 +511,7 @@ int WasmModuleObject::GetSourcePosition(Handle<WasmModuleObject> module_object, ...@@ -511,7 +511,7 @@ int WasmModuleObject::GetSourcePosition(Handle<WasmModuleObject> module_object,
Isolate* isolate = module_object->GetIsolate(); Isolate* isolate = module_object->GetIsolate();
const WasmModule* module = module_object->module(); const WasmModule* module = module_object->module();
if (module->origin != wasm::kAsmJsOrigin) { if (module->origin == wasm::kWasmOrigin) {
// for non-asm.js modules, we just add the function's start offset // for non-asm.js modules, we just add the function's start offset
// to make a module-relative position. // to make a module-relative position.
return byte_offset + module_object->GetFunctionOffset(func_index); return byte_offset + module_object->GetFunctionOffset(func_index);
...@@ -2237,7 +2237,8 @@ Handle<WasmExportedFunction> WasmExportedFunction::New( ...@@ -2237,7 +2237,8 @@ Handle<WasmExportedFunction> WasmExportedFunction::New(
function_data->set_packed_args_size(0); function_data->set_packed_args_size(0);
MaybeHandle<String> maybe_name; MaybeHandle<String> maybe_name;
if (instance->module()->origin == wasm::kAsmJsOrigin) { bool is_asm_js_module = instance->module_object().is_asm_js();
if (is_asm_js_module) {
// We can use the function name only for asm.js. For WebAssembly, the // We can use the function name only for asm.js. For WebAssembly, the
// function name is specified as the function_index.toString(). // function name is specified as the function_index.toString().
maybe_name = WasmModuleObject::GetFunctionNameOrNull( maybe_name = WasmModuleObject::GetFunctionNameOrNull(
...@@ -2252,10 +2253,18 @@ Handle<WasmExportedFunction> WasmExportedFunction::New( ...@@ -2252,10 +2253,18 @@ Handle<WasmExportedFunction> WasmExportedFunction::New(
Vector<uint8_t>::cast(buffer.SubVector(0, length))) Vector<uint8_t>::cast(buffer.SubVector(0, length)))
.ToHandleChecked(); .ToHandleChecked();
} }
bool is_asm_js_module = instance->module_object().is_asm_js(); Handle<Map> function_map;
Handle<Map> function_map = is_asm_js_module switch (instance->module()->origin) {
? isolate->sloppy_function_map() case wasm::kWasmOrigin:
: isolate->wasm_exported_function_map(); function_map = isolate->wasm_exported_function_map();
break;
case wasm::kAsmJsSloppyOrigin:
function_map = isolate->sloppy_function_map();
break;
case wasm::kAsmJsStrictOrigin:
function_map = isolate->strict_function_map();
break;
}
NewFunctionArgs args = NewFunctionArgs args =
NewFunctionArgs::ForWasm(name, function_data, function_map); NewFunctionArgs::ForWasm(name, function_data, function_map);
Handle<JSFunction> js_function = isolate->factory()->NewFunction(args); Handle<JSFunction> js_function = isolate->factory()->NewFunction(args);
......
...@@ -90,7 +90,7 @@ class TestingModuleBuilder { ...@@ -90,7 +90,7 @@ class TestingModuleBuilder {
TestingModuleBuilder(Zone*, ManuallyImportedJSFunction*, ExecutionTier, TestingModuleBuilder(Zone*, ManuallyImportedJSFunction*, ExecutionTier,
RuntimeExceptionSupport, LowerSimd); RuntimeExceptionSupport, LowerSimd);
void ChangeOriginToAsmjs() { test_module_->origin = kAsmJsOrigin; } void ChangeOriginToAsmjs() { test_module_->origin = kAsmJsSloppyOrigin; }
byte* AddMemory(uint32_t size, SharedFlag shared = SharedFlag::kNotShared); byte* AddMemory(uint32_t size, SharedFlag shared = SharedFlag::kNotShared);
......
...@@ -162,7 +162,7 @@ int32_t CompileAndRunAsmWasmModule(Isolate* isolate, const byte* module_start, ...@@ -162,7 +162,7 @@ int32_t CompileAndRunAsmWasmModule(Isolate* isolate, const byte* module_start,
MaybeHandle<AsmWasmData> data = MaybeHandle<AsmWasmData> data =
isolate->wasm_engine()->SyncCompileTranslatedAsmJs( isolate->wasm_engine()->SyncCompileTranslatedAsmJs(
isolate, &thrower, ModuleWireBytes(module_start, module_end), isolate, &thrower, ModuleWireBytes(module_start, module_end),
Vector<const byte>(), Handle<HeapNumber>()); Vector<const byte>(), Handle<HeapNumber>(), LanguageMode::kSloppy);
DCHECK_EQ(thrower.error(), data.is_null()); DCHECK_EQ(thrower.error(), data.is_null());
if (data.is_null()) return -1; if (data.is_null()) return -1;
......
// Copyright 2019 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.
(function TestSloppynessPropagates() {
let f = (function() {
function Module() {
"use asm";
function f() {}
return {f: f}
}
return Module;
})()().f;
let p = Object.getOwnPropertyNames(f);
assertArrayEquals(["length", "name", "arguments", "caller", "prototype"], p);
assertEquals(null, f.arguments);
assertEquals(null, f.caller);
})();
(function TestStrictnessPropagates() {
let f = (function() {
"use strict";
function Module() {
"use asm";
function f() {}
return {f: f}
}
return Module;
})()().f;
let p = Object.getOwnPropertyNames(f);
assertArrayEquals(["length", "name", "prototype"], p);
assertThrows(() => f.arguments, TypeError);
assertThrows(() => f.caller, TypeError);
})();
...@@ -2159,7 +2159,7 @@ TEST_F(FunctionBodyDecoderTest, WasmMemoryGrow) { ...@@ -2159,7 +2159,7 @@ TEST_F(FunctionBodyDecoderTest, WasmMemoryGrow) {
} }
TEST_F(FunctionBodyDecoderTest, AsmJsMemoryGrow) { TEST_F(FunctionBodyDecoderTest, AsmJsMemoryGrow) {
TestModuleBuilder builder(kAsmJsOrigin); TestModuleBuilder builder(kAsmJsSloppyOrigin);
module = builder.module(); module = builder.module();
builder.InitializeMemory(); builder.InitializeMemory();
...@@ -2191,7 +2191,7 @@ TEST_F(FunctionBodyDecoderTest, AsmJsBinOpsCheckOrigin) { ...@@ -2191,7 +2191,7 @@ TEST_F(FunctionBodyDecoderTest, AsmJsBinOpsCheckOrigin) {
}; };
{ {
TestModuleBuilder builder(kAsmJsOrigin); TestModuleBuilder builder(kAsmJsSloppyOrigin);
module = builder.module(); module = builder.module();
builder.InitializeMemory(); builder.InitializeMemory();
for (size_t i = 0; i < arraysize(AsmJsBinOps); i++) { for (size_t i = 0; i < arraysize(AsmJsBinOps); i++) {
...@@ -2239,7 +2239,7 @@ TEST_F(FunctionBodyDecoderTest, AsmJsUnOpsCheckOrigin) { ...@@ -2239,7 +2239,7 @@ TEST_F(FunctionBodyDecoderTest, AsmJsUnOpsCheckOrigin) {
{kExprI32AsmjsSConvertF64, sigs.i_d()}, {kExprI32AsmjsSConvertF64, sigs.i_d()},
{kExprI32AsmjsUConvertF64, sigs.i_d()}}; {kExprI32AsmjsUConvertF64, sigs.i_d()}};
{ {
TestModuleBuilder builder(kAsmJsOrigin); TestModuleBuilder builder(kAsmJsSloppyOrigin);
module = builder.module(); module = builder.module();
builder.InitializeMemory(); builder.InitializeMemory();
for (size_t i = 0; i < arraysize(AsmJsUnOps); i++) { for (size_t i = 0; i < arraysize(AsmJsUnOps); i++) {
......
...@@ -19,3 +19,14 @@ print("https://crbug.com/935800"); ...@@ -19,3 +19,14 @@ print("https://crbug.com/935800");
} }
print(Object.getOwnPropertyNames(foo().bar)); print(Object.getOwnPropertyNames(foo().bar));
})(); })();
print("https://crbug.com/985154");
(function () {
"use strict";
function foo() {
"use asm";
function baz() {}
return {bar: baz};
}
print(Object.getOwnPropertyNames(foo().bar));
})();
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