summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2015-11-05 19:08:02 -0800
committerAlon Zakai <alonzakai@gmail.com>2015-11-05 19:08:02 -0800
commit0500af8981f03982aa68bee6d28e3ad339c01e28 (patch)
treeadf31f698ebd9fdff7323deee21171ef3e39c8cd
parent2b314faa4c50738473f977dcf9adae3708363e16 (diff)
downloadbinaryen-0500af8981f03982aa68bee6d28e3ad339c01e28.tar.gz
binaryen-0500af8981f03982aa68bee6d28e3ad339c01e28.tar.bz2
binaryen-0500af8981f03982aa68bee6d28e3ad339c01e28.zip
has_feature
-rwxr-xr-xcheck.py2
-rw-r--r--src/wasm-interpreter.h15
-rw-r--r--src/wasm-s-parser.h17
-rw-r--r--src/wasm.h1
4 files changed, 32 insertions, 3 deletions
diff --git a/check.py b/check.py
index 732d7b196..df6a7f923 100755
--- a/check.py
+++ b/check.py
@@ -83,7 +83,7 @@ if len(requested) == 0:
#spec_tests = [] # XXX [os.path.join('spec', t) for t in sorted(os.listdir(os.path.join('test', 'spec')))]
# 'address' : filed issue, test looks invalid
# 'exports' : has a "return" https://github.com/WebAssembly/spec/issues/164
- spec_tests = [os.path.join('spec', t + '.wast') for t in ['conversions', 'endianness', 'f32_cmp', 'f32', 'f64_cmp', 'f64', 'float_exprs', 'forward', 'func_ptrs', 'functions']]
+ spec_tests = [os.path.join('spec', t + '.wast') for t in ['conversions', 'endianness', 'f32_cmp', 'f32', 'f64_cmp', 'f64', 'float_exprs', 'forward', 'func_ptrs', 'functions', 'has_feature']]
else:
spec_tests = requested[:]
diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h
index c4bf21d54..7b8812d69 100644
--- a/src/wasm-interpreter.h
+++ b/src/wasm-interpreter.h
@@ -15,6 +15,8 @@ using namespace cashew;
// An instance of a WebAssembly module, which can execute it via AST interpretation
//
+IString WASM("wasm");
+
class ModuleInstance {
public:
typedef std::vector<Literal> LiteralList;
@@ -562,7 +564,18 @@ public:
}
Flow visitHost(Host *curr) override {
NOTE_ENTER("Host");
- abort();
+
+ switch (curr->op) {
+ case PageSize: return Literal(64*1024);
+ case MemorySize: return Literal(instance.memorySize);
+ case GrowMemory: abort();
+ case HasFeature: {
+ IString id = curr->nameOperand;
+ if (id == WASM) return Literal(1);
+ return Literal(0);
+ }
+ default: abort();
+ }
}
Flow visitNop(Nop *curr) override {
NOTE_ENTER("Nop");
diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h
index 2f86fcef2..0e9967128 100644
--- a/src/wasm-s-parser.h
+++ b/src/wasm-s-parser.h
@@ -336,7 +336,7 @@ public:
#define abort_on(str) { std::cerr << "aborting on " << str << '\n'; onError(); }
Expression* parseExpression(Element& s) {
- //if (debug) std::cerr << "parse expression " << s << '\n';
+ //std::cerr << "parse expression " << s << '\n';
IString id = s[0]->str();
const char *str = id.str;
const char *dot = strchr(str, '.');
@@ -483,6 +483,10 @@ public:
if (str[1] == 'e') return makeGetLocal(s);
abort_on(str);
}
+ case 'h': {
+ if (str[1] == 'a') return makeHost(s, HostOp::HasFeature);
+ abort_on(str);
+ }
case 'i': {
if (str[1] == 'f') return makeIf(s);
abort_on(str);
@@ -548,6 +552,17 @@ private:
return ret;
}
+ Expression* makeHost(Element& s, HostOp op) {
+ auto ret = allocator.alloc<Host>();
+ ret->op = op;
+ if (op == HostOp::HasFeature) {
+ ret->nameOperand = s[1]->str();
+ } else {
+ parseCallOperands(s, 1, ret);
+ }
+ return ret;
+ }
+
Expression* makeSetLocal(Element& s) {
auto ret = allocator.alloc<SetLocal>();
ret->name = s[1]->str();
diff --git a/src/wasm.h b/src/wasm.h
index 6d1ac7b83..f2c9b742b 100644
--- a/src/wasm.h
+++ b/src/wasm.h
@@ -748,6 +748,7 @@ public:
Host() : Expression(HostId) {}
HostOp op;
+ Name nameOperand;
ExpressionList operands;
std::ostream& doPrint(std::ostream &o, unsigned indent) {