summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJF Bastien <jfb@chromium.org>2016-01-27 17:56:12 -0800
committerJF Bastien <jfb@chromium.org>2016-01-27 19:55:26 -0800
commitdbe29fc629356ca5abdfeeaf0da573b1208eb3de (patch)
tree5794a191c5e6eff073d26c1d07827b16c030b614
parentbe3ee4d97e81af88dcc9ac97b86da53d0d49c302 (diff)
downloadbinaryen-dbe29fc629356ca5abdfeeaf0da573b1208eb3de.tar.gz
binaryen-dbe29fc629356ca5abdfeeaf0da573b1208eb3de.tar.bz2
binaryen-dbe29fc629356ca5abdfeeaf0da573b1208eb3de.zip
s2wasm: support aliased functions
-rw-r--r--src/s2wasm.h37
-rw-r--r--test/dot_s/alias.s29
-rw-r--r--test/dot_s/alias.wast22
3 files changed, 81 insertions, 7 deletions
diff --git a/src/s2wasm.h b/src/s2wasm.h
index 5eeb808bb..8ef1135dd 100644
--- a/src/s2wasm.h
+++ b/src/s2wasm.h
@@ -66,6 +66,7 @@ private:
std::vector<Relocation> relocations;
std::set<Name> implementedFunctions;
+ std::map<Name, Name> aliasedFunctions;
std::map<size_t, size_t> addressSegments; // address => segment index
@@ -143,7 +144,7 @@ private:
Name getStrToSep() {
std::string str;
- while (*s && !isspace(*s) && *s != ',' && *s != '(' && *s != ')' && *s != ':' && *s != '+' && *s != '-') {
+ while (*s && !isspace(*s) && *s != ',' && *s != '(' && *s != ')' && *s != ':' && *s != '+' && *s != '-' && *s != '=') {
str += *s;
s++;
}
@@ -257,16 +258,18 @@ private:
return value;
}
- Name getCommaSeparated() {
+ Name getSeparated(char separator) {
skipWhitespace();
std::string str;
- while (*s && *s != ',' && *s != '\n') {
+ while (*s && *s != separator && *s != '\n') {
str += *s;
s++;
}
skipWhitespace();
return cashew::IString(str.c_str(), false);
}
+ Name getCommaSeparated() { return getSeparated(','); }
+ Name getAtSeparated() { return getSeparated('@'); }
Name getAssign() {
skipWhitespace();
@@ -346,9 +349,17 @@ private:
Name name = getCommaSeparated();
skipComma();
if (!match("@function")) continue;
+ if (match(".hidden")) mustMatch(name.str);
mustMatch(name.str);
- mustMatch(":");
- implementedFunctions.insert(name);
+ if (match(":")) {
+ implementedFunctions.insert(name);
+ } else if (match("=")) {
+ Name alias = getAtSeparated();
+ mustMatch("@FUNCTION");
+ aliasedFunctions.insert({name, alias});
+ } else {
+ abort_on("unknown directive");
+ }
}
}
@@ -427,6 +438,12 @@ private:
void parseFunction() {
if (debug) dump("func");
Name name = getStrToSep();
+ if (match(" =")) {
+ /* alias = */ getAtSeparated();
+ mustMatch("@FUNCTION");
+ return;
+ }
+
mustMatch(":");
unsigned nextId = 0;
@@ -653,6 +670,8 @@ private:
} else {
assign = getAssign();
Name target = cleanFunction(getCommaSeparated());
+ auto aliased = aliasedFunctions.find(target);
+ if (aliased != aliasedFunctions.end()) target = aliased->second;
if (implementedFunctions.count(target) > 0) {
auto specific = allocator.alloc<Call>();
specific->target = target;
@@ -973,8 +992,12 @@ private:
if (debug) dump("type");
Name name = getStrToSep();
skipComma();
- if (match("@function")) return parseFunction();
- else if (match("@object")) return parseObject(name);
+ if (match("@function")) {
+ if (match(".hidden")) mustMatch(name.str);
+ return parseFunction();
+ } else if (match("@object")) {
+ return parseObject(name);
+ }
abort_on("parseType");
}
diff --git a/test/dot_s/alias.s b/test/dot_s/alias.s
new file mode 100644
index 000000000..a29470b2f
--- /dev/null
+++ b/test/dot_s/alias.s
@@ -0,0 +1,29 @@
+ .text
+ .file "alias.c"
+
+ .hidden __exit
+ .globl __exit
+ .type __exit,@function
+__exit: # @__exit
+ .local i32
+# BB#0: # %entry
+ return
+ .endfunc
+.Lfunc_end0:
+ .size __exit, .Lfunc_end0-__exit
+
+ .hidden __needs_exit
+ .globl __needs_exit
+ .type __needs_exit,@function
+__needs_exit: # @__needs_exit
+# BB#0: # %entry
+ call __exit_needed@FUNCTION
+ return
+ .endfunc
+.Lfunc_end1:
+ .size __needs_exit, .Lfunc_end1-__needs_exit
+
+ .weak __exit_needed
+ .type __exit_needed,@function
+ .hidden __exit_needed
+__exit_needed = __exit@FUNCTION
diff --git a/test/dot_s/alias.wast b/test/dot_s/alias.wast
new file mode 100644
index 000000000..41fb16f75
--- /dev/null
+++ b/test/dot_s/alias.wast
@@ -0,0 +1,22 @@
+(module
+ (memory 0 4294967295)
+ (export "__exit" $__exit)
+ (export "__needs_exit" $__needs_exit)
+ (func $__exit
+ (local $$0 i32)
+ (block $fake_return_waka123
+ (block
+ (br $fake_return_waka123)
+ )
+ )
+ )
+ (func $__needs_exit
+ (block $fake_return_waka123
+ (block
+ (call $__exit)
+ (br $fake_return_waka123)
+ )
+ )
+ )
+)
+;; METADATA: { "asmConsts": {},"staticBump": 4 }