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

[wasm][asm.js] Ignore duplicate exports in asm.js.

BUG=672789
R=titzer@chromium.org

Review-Url: https://codereview.chromium.org/2559113006
Cr-Commit-Position: refs/heads/master@{#41647}
parent fc2503d1
...@@ -491,8 +491,8 @@ class ModuleDecoder : public Decoder { ...@@ -491,8 +491,8 @@ class ModuleDecoder : public Decoder {
break; break;
} }
} }
// Check for duplicate exports. // Check for duplicate exports (except for asm.js).
if (ok() && module->export_table.size() > 1) { if (ok() && origin_ != kAsmJsOrigin && module->export_table.size() > 1) {
std::vector<WasmExport> sorted_exports(module->export_table); std::vector<WasmExport> sorted_exports(module->export_table);
const byte* base = start_; const byte* base = start_;
auto cmp_less = [base](const WasmExport& a, const WasmExport& b) { auto cmp_less = [base](const WasmExport& a, const WasmExport& b) {
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include <memory> #include <memory>
#include "src/base/adapters.h"
#include "src/base/atomic-utils.h" #include "src/base/atomic-utils.h"
#include "src/code-stubs.h" #include "src/code-stubs.h"
#include "src/compiler/wasm-compiler.h" #include "src/compiler/wasm-compiler.h"
...@@ -1750,9 +1751,16 @@ class WasmInstanceBuilder { ...@@ -1750,9 +1751,16 @@ class WasmInstanceBuilder {
PropertyDescriptor desc; PropertyDescriptor desc;
desc.set_writable(false); desc.set_writable(false);
// Process each export in the export table. // Count up export indexes.
int export_index = 0; int export_index = 0;
for (auto exp : module_->export_table) { for (auto exp : module_->export_table) {
if (exp.kind == kExternalFunction) {
++export_index;
}
}
// Process each export in the export table (go in reverse so asm.js
// can skip duplicates).
for (auto exp : base::Reversed(module_->export_table)) {
Handle<String> name = Handle<String> name =
ExtractStringFromModuleBytes(isolate_, compiled_module_, ExtractStringFromModuleBytes(isolate_, compiled_module_,
exp.name_offset, exp.name_length) exp.name_offset, exp.name_length)
...@@ -1762,7 +1770,7 @@ class WasmInstanceBuilder { ...@@ -1762,7 +1770,7 @@ class WasmInstanceBuilder {
// Wrap and export the code as a JSFunction. // Wrap and export the code as a JSFunction.
WasmFunction& function = module_->functions[exp.index]; WasmFunction& function = module_->functions[exp.index];
int func_index = int func_index =
static_cast<int>(module_->functions.size() + export_index); static_cast<int>(module_->functions.size() + --export_index);
Handle<JSFunction> js_function = js_wrappers_[exp.index]; Handle<JSFunction> js_function = js_wrappers_[exp.index];
if (js_function.is_null()) { if (js_function.is_null()) {
// Wrap the exported code as a JSFunction. // Wrap the exported code as a JSFunction.
...@@ -1782,7 +1790,6 @@ class WasmInstanceBuilder { ...@@ -1782,7 +1790,6 @@ class WasmInstanceBuilder {
js_wrappers_[exp.index] = js_function; js_wrappers_[exp.index] = js_function;
} }
desc.set_value(js_function); desc.set_value(js_function);
export_index++;
break; break;
} }
case kExternalTable: { case kExternalTable: {
...@@ -1845,6 +1852,14 @@ class WasmInstanceBuilder { ...@@ -1845,6 +1852,14 @@ class WasmInstanceBuilder {
break; break;
} }
// Skip duplicates for asm.js.
if (module_->origin == kAsmJsOrigin) {
v8::Maybe<bool> status =
JSReceiver::HasOwnProperty(exports_object, name);
if (status.FromMaybe(false)) {
continue;
}
}
v8::Maybe<bool> status = JSReceiver::DefineOwnProperty( v8::Maybe<bool> status = JSReceiver::DefineOwnProperty(
isolate_, exports_object, name, &desc, Object::THROW_ON_ERROR); isolate_, exports_object, name, &desc, Object::THROW_ON_ERROR);
if (!status.IsJust()) { if (!status.IsJust()) {
......
...@@ -316,6 +316,18 @@ function assertValidAsm(func) { ...@@ -316,6 +316,18 @@ function assertValidAsm(func) {
assertEquals(3, m.foo(3)); assertEquals(3, m.foo(3));
})(); })();
(function TestBadExportTwice() {
function Module() {
"use asm";
function bar() { return 1; }
function baz() { return 2; }
return {foo: bar, foo: baz};
}
var m = Module();
assertTrue(%IsAsmWasmCode(Module));
assertEquals(2, m.foo());
})();
(function TestBadImport() { (function TestBadImport() {
function Module(stdlib) { function Module(stdlib) {
"use asm"; "use asm";
......
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