summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/emscripten-optimizer/parser.cpp2
-rw-r--r--src/emscripten-optimizer/parser.h6
-rw-r--r--src/emscripten-optimizer/simple_ast.h54
-rw-r--r--src/wasm2js.h37
-rw-r--r--test/wasm2js/export_global.2asm.js37
-rw-r--r--test/wasm2js/export_global.2asm.js.opt37
-rw-r--r--test/wasm2js/export_global.wast6
7 files changed, 169 insertions, 10 deletions
diff --git a/src/emscripten-optimizer/parser.cpp b/src/emscripten-optimizer/parser.cpp
index de749817f..016966299 100644
--- a/src/emscripten-optimizer/parser.cpp
+++ b/src/emscripten-optimizer/parser.cpp
@@ -107,6 +107,8 @@ IString ATOMICS("Atomics");
IString COMPARE_EXCHANGE("compareExchange");
IString LOAD("load");
IString STORE("store");
+IString GETTER("get");
+IString SETTER("set");
IStringSet
keywords("var const function if else do while for break continue return "
diff --git a/src/emscripten-optimizer/parser.h b/src/emscripten-optimizer/parser.h
index 3e1623c19..c4d596058 100644
--- a/src/emscripten-optimizer/parser.h
+++ b/src/emscripten-optimizer/parser.h
@@ -124,6 +124,8 @@ extern IString ATOMICS;
extern IString COMPARE_EXCHANGE;
extern IString LOAD;
extern IString STORE;
+extern IString GETTER;
+extern IString SETTER;
extern IStringSet keywords;
@@ -207,8 +209,8 @@ template<class NodeRef, class Builder> class Parser {
};
struct Frag {
- // MSVC does not allow unrestricted unions:
- // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2544.pdf
+ // MSVC does not allow unrestricted unions:
+ // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2544.pdf
#ifndef _MSC_VER
union {
#endif
diff --git a/src/emscripten-optimizer/simple_ast.h b/src/emscripten-optimizer/simple_ast.h
index 7644daac3..64db04d79 100644
--- a/src/emscripten-optimizer/simple_ast.h
+++ b/src/emscripten-optimizer/simple_ast.h
@@ -1463,12 +1463,24 @@ struct JSPrinter {
newline();
}
bool needQuote = false;
+ const char* getterSetter = nullptr;
+ const char* setterParam = nullptr;
const char* str;
if (args[i][0]->isArray()) {
- assert(args[i][0][0] == STRING);
- // A quoted string.
- needQuote = true;
- str = args[i][0][1]->getCString();
+ if (args[i][0][0] == STRING) {
+ // A quoted string.
+ needQuote = true;
+ str = args[i][0][1]->getCString();
+ } else if (args[i][0][0] == GETTER) {
+ getterSetter = GETTER.c_str();
+ str = args[i][0][1]->getCString();
+ } else if (args[i][0][0] == SETTER) {
+ getterSetter = SETTER.c_str();
+ str = args[i][0][1]->getCString();
+ setterParam = args[i][0][2]->getCString();
+ } else {
+ abort();
+ }
} else {
// Just a raw string, no quotes.
str = args[i][0]->getCString();
@@ -1481,6 +1493,10 @@ struct JSPrinter {
}
check++;
}
+ if (getterSetter != nullptr) {
+ emit(getterSetter);
+ space();
+ }
if (needQuote) {
emit('"');
}
@@ -1488,7 +1504,15 @@ struct JSPrinter {
if (needQuote) {
emit('"');
}
- emit(":");
+ if (getterSetter != nullptr) {
+ emit('(');
+ if (setterParam != nullptr) {
+ emit(setterParam);
+ }
+ emit(')');
+ } else {
+ emit(":");
+ }
space();
print(args[i][1]);
}
@@ -1828,6 +1852,26 @@ public:
&makeRawArray(2)->push_back(makeString(key)).push_back(value));
}
+ static void appendToObjectAsGetter(Ref array, IString key, Ref value) {
+ assert(array[0] == OBJECT);
+ array[1]->push_back(&makeRawArray(2)
+ ->push_back(&makeRawArray(2)
+ ->push_back(makeRawString(GETTER))
+ .push_back(makeRawString(key)))
+ .push_back(value));
+ }
+
+ static void
+ appendToObjectAsSetter(Ref array, IString key, IString param, Ref value) {
+ assert(array[0] == OBJECT);
+ array[1]->push_back(&makeRawArray(2)
+ ->push_back(&makeRawArray(3)
+ ->push_back(makeRawString(SETTER))
+ .push_back(makeRawString(key))
+ .push_back(makeRawString(param)))
+ .push_back(value));
+ }
+
static Ref makeSub(Ref obj, Ref index) {
return &makeRawArray(2)
->push_back(makeRawString(SUB))
diff --git a/src/wasm2js.h b/src/wasm2js.h
index 43f4d520f..b74572cfe 100644
--- a/src/wasm2js.h
+++ b/src/wasm2js.h
@@ -764,10 +764,40 @@ void Wasm2JSBuilder::addExports(Ref ast, Module* wasm) {
break;
}
case ExternalKind::Global: {
+ Ref object = ValueBuilder::makeObject();
+
+ IString identName = fromName(export_->value, NameScope::Top);
+
+ // getter
+ {
+ Ref block = ValueBuilder::makeBlock();
+
+ block[1]->push_back(
+ ValueBuilder::makeReturn(ValueBuilder::makeName(identName)));
+
+ ValueBuilder::appendToObjectAsGetter(object, IString("value"), block);
+ }
+
+ // setter
+ {
+ std::ostringstream buffer;
+ buffer << '_' << identName.c_str();
+ auto setterParam = stringToIString(buffer.str());
+
+ auto block = ValueBuilder::makeBlock();
+
+ block[1]->push_back(
+ ValueBuilder::makeBinary(ValueBuilder::makeName(identName),
+ SET,
+ ValueBuilder::makeName(setterParam)));
+
+ ValueBuilder::appendToObjectAsSetter(
+ object, IString("value"), setterParam, block);
+ }
+
ValueBuilder::appendToObjectWithQuotes(
- exports,
- fromName(export_->name, NameScope::Export),
- ValueBuilder::makeName(fromName(export_->value, NameScope::Top)));
+ exports, fromName(export_->name, NameScope::Export), object);
+
break;
}
case ExternalKind::Tag:
@@ -2600,6 +2630,7 @@ void Wasm2JSGlue::emitPostES6() {
for (auto& exp : wasm.exports) {
switch (exp->kind) {
case ExternalKind::Function:
+ case ExternalKind::Global:
case ExternalKind::Memory:
break;
diff --git a/test/wasm2js/export_global.2asm.js b/test/wasm2js/export_global.2asm.js
new file mode 100644
index 000000000..7db0d3a20
--- /dev/null
+++ b/test/wasm2js/export_global.2asm.js
@@ -0,0 +1,37 @@
+
+function asmFunc(env) {
+ var Math_imul = Math.imul;
+ var Math_fround = Math.fround;
+ var Math_abs = Math.abs;
+ var Math_clz32 = Math.clz32;
+ var Math_min = Math.min;
+ var Math_max = Math.max;
+ var Math_floor = Math.floor;
+ var Math_ceil = Math.ceil;
+ var Math_trunc = Math.trunc;
+ var Math_sqrt = Math.sqrt;
+ var abort = env.abort;
+ var nan = NaN;
+ var infinity = Infinity;
+ var global0 = 655360;
+ function $0() {
+ return 42 | 0;
+ }
+
+ return {
+ "HELLO": {
+ get value() {
+ return global0;
+ },
+ set value(_global0) {
+ global0 = _global0;
+ }
+ },
+ "helloWorld": $0
+ };
+}
+
+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }
+ });
+export var HELLO = retasmFunc.HELLO;
+export var helloWorld = retasmFunc.helloWorld;
diff --git a/test/wasm2js/export_global.2asm.js.opt b/test/wasm2js/export_global.2asm.js.opt
new file mode 100644
index 000000000..eb4e88090
--- /dev/null
+++ b/test/wasm2js/export_global.2asm.js.opt
@@ -0,0 +1,37 @@
+
+function asmFunc(env) {
+ var Math_imul = Math.imul;
+ var Math_fround = Math.fround;
+ var Math_abs = Math.abs;
+ var Math_clz32 = Math.clz32;
+ var Math_min = Math.min;
+ var Math_max = Math.max;
+ var Math_floor = Math.floor;
+ var Math_ceil = Math.ceil;
+ var Math_trunc = Math.trunc;
+ var Math_sqrt = Math.sqrt;
+ var abort = env.abort;
+ var nan = NaN;
+ var infinity = Infinity;
+ var global0 = 655360;
+ function $0() {
+ return 42;
+ }
+
+ return {
+ "HELLO": {
+ get value() {
+ return global0;
+ },
+ set value(_global0) {
+ global0 = _global0;
+ }
+ },
+ "helloWorld": $0
+ };
+}
+
+var retasmFunc = asmFunc( { abort: function() { throw new Error('abort'); }
+ });
+export var HELLO = retasmFunc.HELLO;
+export var helloWorld = retasmFunc.helloWorld;
diff --git a/test/wasm2js/export_global.wast b/test/wasm2js/export_global.wast
new file mode 100644
index 000000000..9b990be8d
--- /dev/null
+++ b/test/wasm2js/export_global.wast
@@ -0,0 +1,6 @@
+(module
+ (global $global0 i32 (i32.const 655360))
+ (export "HELLO" (global $global0))
+ (func (result i32) (i32.const 42))
+ (export "helloWorld" (func 0))
+) \ No newline at end of file