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