Commit 71cc94da authored by bradnelson's avatar bradnelson Committed by Commit bot

[wasm][asm.js] Allow a function to be exported more than once.

Allow a function to be exported multiple times in a asm.js
module.
Remarkably, this had not been working before.

BUG=670057
R=titzer@chromium.org

Review-Url: https://codereview.chromium.org/2535723009
Cr-Commit-Position: refs/heads/master@{#41416}
parent a328143e
......@@ -715,8 +715,7 @@ class AsmWasmBuilderImpl final : public AstVisitor<AsmWasmBuilderImpl> {
const AstRawString* raw_name = name->AsRawPropertyName();
if (var->is_function()) {
WasmFunctionBuilder* function = LookupOrInsertFunction(var);
function->Export();
function->SetName({reinterpret_cast<const char*>(raw_name->raw_data()),
function->ExportAs({reinterpret_cast<const char*>(raw_name->raw_data()),
raw_name->length()});
}
}
......
......@@ -50,11 +50,10 @@ WasmFunctionBuilder::WasmFunctionBuilder(WasmModuleBuilder* builder)
: builder_(builder),
locals_(builder->zone()),
signature_index_(0),
exported_(0),
func_index_(static_cast<uint32_t>(builder->functions_.size())),
body_(builder->zone()),
name_(builder->zone()),
exported_name_(builder->zone()),
exported_names_(builder->zone()),
i32_temps_(builder->zone()),
i64_temps_(builder->zone()),
f32_temps_(builder->zone()),
......@@ -141,12 +140,9 @@ void WasmFunctionBuilder::EmitDirectCallIndex(uint32_t index) {
EmitCode(code, sizeof(code));
}
void WasmFunctionBuilder::Export() { exported_ = true; }
void WasmFunctionBuilder::ExportAs(Vector<const char> name) {
exported_ = true;
exported_name_.resize(name.length());
memcpy(exported_name_.data(), name.start(), name.length());
exported_names_.push_back(ZoneVector<char>(
name.start(), name.start() + name.length(), builder_->zone()));
}
void WasmFunctionBuilder::SetName(Vector<const char> name) {
......@@ -172,13 +168,10 @@ void WasmFunctionBuilder::WriteSignature(ZoneBuffer& buffer) const {
buffer.write_u32v(signature_index_);
}
void WasmFunctionBuilder::WriteExport(ZoneBuffer& buffer) const {
if (exported_) {
const ZoneVector<char>* exported_name =
exported_name_.size() == 0 ? &name_ : &exported_name_;
buffer.write_size(exported_name->size());
buffer.write(reinterpret_cast<const byte*>(exported_name->data()),
exported_name->size());
void WasmFunctionBuilder::WriteExports(ZoneBuffer& buffer) const {
for (auto name : exported_names_) {
buffer.write_size(name.size());
buffer.write(reinterpret_cast<const byte*>(name.data()), name.size());
buffer.write_u8(kExternalFunction);
buffer.write_u32v(func_index_ +
static_cast<uint32_t>(builder_->imports_.size()));
......@@ -348,7 +341,7 @@ void WasmModuleBuilder::WriteTo(ZoneBuffer& buffer) const {
buffer.write_size(functions_.size());
for (auto function : functions_) {
function->WriteSignature(buffer);
if (function->exported()) exports++;
exports += function->exported_names_.size();
if (function->name_.size() > 0) has_names = true;
}
FixupSection(buffer, start);
......@@ -451,7 +444,7 @@ void WasmModuleBuilder::WriteTo(ZoneBuffer& buffer) const {
if (exports > 0) {
size_t start = EmitSection(kExportSectionCode, buffer);
buffer.write_u32v(exports);
for (auto function : functions_) function->WriteExport(buffer);
for (auto function : functions_) function->WriteExports(buffer);
FixupSection(buffer, start);
}
......@@ -524,10 +517,8 @@ void WasmModuleBuilder::WriteTo(ZoneBuffer& buffer) const {
}
for (auto function : functions_) {
buffer.write_size(function->name_.size());
if (function->name_.size() > 0) {
buffer.write(reinterpret_cast<const byte*>(&function->name_[0]),
buffer.write(reinterpret_cast<const byte*>(function->name_.data()),
function->name_.size());
}
buffer.write_u8(0);
}
FixupSection(buffer, start);
......
......@@ -132,17 +132,15 @@ class V8_EXPORT_PRIVATE WasmFunctionBuilder : public ZoneObject {
void EmitWithU8U8(WasmOpcode opcode, const byte imm1, const byte imm2);
void EmitWithVarInt(WasmOpcode opcode, uint32_t immediate);
void EmitDirectCallIndex(uint32_t index);
void Export();
void ExportAs(Vector<const char> name);
void SetName(Vector<const char> name);
void AddAsmWasmOffset(int asm_position);
void WriteSignature(ZoneBuffer& buffer) const;
void WriteExport(ZoneBuffer& buffer) const;
void WriteExports(ZoneBuffer& buffer) const;
void WriteBody(ZoneBuffer& buffer) const;
void WriteAsmWasmOffsetTable(ZoneBuffer& buffer) const;
bool exported() { return exported_; }
uint32_t func_index() { return func_index_; }
FunctionSig* signature();
......@@ -159,11 +157,10 @@ class V8_EXPORT_PRIVATE WasmFunctionBuilder : public ZoneObject {
WasmModuleBuilder* builder_;
LocalDeclEncoder locals_;
uint32_t signature_index_;
bool exported_;
uint32_t func_index_;
ZoneVector<uint8_t> body_;
ZoneVector<char> name_;
ZoneVector<char> exported_name_;
ZoneVector<ZoneVector<char>> exported_names_;
ZoneVector<uint32_t> i32_temps_;
ZoneVector<uint32_t> i64_temps_;
ZoneVector<uint32_t> f32_temps_;
......
......@@ -1675,3 +1675,17 @@ function TestFloatGlobals(stdlib) {
}
assertWasm(3.25, TestFloatGlobals);
(function TestExportTwice() {
function asmModule() {
"use asm";
function foo() {
return 42;
}
return {bar: foo, baz: foo};
}
var m = asmModule();
assertEquals(42, m.bar());
assertEquals(42, m.baz());
})();
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