Commit a4737793 authored by bradnelson's avatar bradnelson Committed by Commit bot

[wasm] Support asm.js modules with a single function.

Handle the case of asm.js modules that return a single function
instead of a collection of them.

R=mtrofin@chromium.org
TEST=mjsunit/asm/asm-wasm
BUG=v8:4203
BUG=v8:5356

Review-Url: https://codereview.chromium.org/2348383003
Cr-Commit-Position: refs/heads/master@{#39515}
parent 58507b71
......@@ -212,12 +212,12 @@ MaybeHandle<Object> AsmJs::InstantiateAsmWasm(i::Isolate* isolate,
return MaybeHandle<Object>();
}
i::Handle<i::Name> name(isolate->factory()->InternalizeOneByteString(
STATIC_CHAR_VECTOR("__foreign_init__")));
i::Handle<i::Name> init_name(isolate->factory()->InternalizeUtf8String(
wasm::AsmWasmBuilder::foreign_init_name));
i::Handle<i::Object> module_object = maybe_module_object.ToHandleChecked();
i::MaybeHandle<i::Object> maybe_init =
i::Object::GetProperty(module_object, name);
i::Object::GetProperty(module_object, init_name);
DCHECK(!maybe_init.is_null());
i::Handle<i::Object> init = maybe_init.ToHandleChecked();
......@@ -242,10 +242,18 @@ MaybeHandle<Object> AsmJs::InstantiateAsmWasm(i::Isolate* isolate,
i::MaybeHandle<i::Object> retval = i::Execution::Call(
isolate, init, undefined, foreign_globals->length(), foreign_args_array);
delete[] foreign_args_array;
DCHECK(!retval.is_null());
return maybe_module_object;
i::Handle<i::Name> single_function_name(
isolate->factory()->InternalizeUtf8String(
wasm::AsmWasmBuilder::single_function_name));
i::MaybeHandle<i::Object> single_function =
i::Object::GetProperty(module_object, single_function_name);
if (!single_function.is_null() &&
!single_function.ToHandleChecked()->IsUndefined(isolate)) {
return single_function;
}
return module_object;
}
} // namespace internal
......
......@@ -90,9 +90,9 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
current_function_builder_ =
builder_->FunctionAt(foreign_init_function_index_);
current_function_builder_->SetExported();
std::string raw_name = "__foreign_init__";
current_function_builder_->SetName(raw_name.data(),
static_cast<int>(raw_name.size()));
current_function_builder_->SetName(
AsmWasmBuilder::foreign_init_name,
static_cast<int>(strlen(AsmWasmBuilder::foreign_init_name)));
current_function_builder_->SetSignature(b.Build());
for (size_t pos = 0; pos < foreign_variables_.size(); ++pos) {
current_function_builder_->EmitGetLocal(static_cast<uint32_t>(pos));
......@@ -551,6 +551,14 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
current_function_builder_->EmitGetLocal(
LookupOrInsertLocal(var, var_type));
}
} else if (scope_ == kExportScope) {
Variable* var = expr->var();
DCHECK(var->is_function());
uint32_t index = LookupOrInsertFunction(var);
builder_->FunctionAt(index)->SetExported();
builder_->FunctionAt(index)->SetName(
AsmWasmBuilder::single_function_name,
static_cast<int>(strlen(AsmWasmBuilder::single_function_name)));
}
}
......@@ -1792,6 +1800,10 @@ ZoneBuffer* AsmWasmBuilder::Run(i::Handle<i::FixedArray>* foreign_args) {
impl.builder_->WriteTo(*buffer);
return buffer;
}
const char* AsmWasmBuilder::foreign_init_name = "__foreign_init__";
const char* AsmWasmBuilder::single_function_name = "__single_function__";
} // namespace wasm
} // namespace internal
} // namespace v8
......@@ -24,6 +24,9 @@ class AsmWasmBuilder {
AsmTyper* typer);
ZoneBuffer* Run(Handle<FixedArray>* foreign_args);
static const char* foreign_init_name;
static const char* single_function_name;
private:
Isolate* isolate_;
Zone* zone_;
......
......@@ -1581,3 +1581,16 @@ function TestLoopsWithUnsigned() {
}
assertWasm(323, TestLoopsWithUnsigned);
function TestSingleFunctionModule() {
"use asm";
function add(a, b) {
a = a | 0;
b = b | 0;
return (a + b) | 0;
}
return add;
}
assertEquals(7, TestSingleFunctionModule()(3, 4));
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