summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2016-04-05 16:13:04 -0700
committerAlon Zakai <alonzakai@gmail.com>2016-04-05 16:13:04 -0700
commit176cac16a7a7910620f88d62b6a5675cdca87741 (patch)
tree771090aa8786660a9bb688fbf08d62bf1c59a334 /src
parent155223a2a0dd222817881dab85fa11166cc5bbb3 (diff)
parent656fc9ec3161111b27be861b1e920e4f77b4bf60 (diff)
downloadbinaryen-176cac16a7a7910620f88d62b6a5675cdca87741.tar.gz
binaryen-176cac16a7a7910620f88d62b6a5675cdca87741.tar.bz2
binaryen-176cac16a7a7910620f88d62b6a5675cdca87741.zip
Merge pull request #314 from WebAssembly/binary-updates
Some binary format updates
Diffstat (limited to 'src')
-rw-r--r--src/wasm-binary.h90
1 files changed, 51 insertions, 39 deletions
diff --git a/src/wasm-binary.h b/src/wasm-binary.h
index 5695cffcc..f73ec7c44 100644
--- a/src/wasm-binary.h
+++ b/src/wasm-binary.h
@@ -387,30 +387,28 @@ enum ASTNodes {
F32StoreMem = 0x35,
F64StoreMem = 0x36,
- I32Const = 0x0a,
- I64Const = 0x0b,
- F64Const = 0x0c,
- F32Const = 0x0d,
- GetLocal = 0x0e,
- SetLocal = 0x0f,
- LoadGlobal = 0x10,
- StoreGlobal = 0x11,
- CallFunction = 0x12,
- CallIndirect = 0x13,
- CallImport = 0x1f,
+ I32Const = 0x10,
+ I64Const = 0x11,
+ F64Const = 0x12,
+ F32Const = 0x13,
+ GetLocal = 0x14,
+ SetLocal = 0x15,
+ CallFunction = 0x16,
+ CallIndirect = 0x17,
+ CallImport = 0x18,
Nop = 0x00,
Block = 0x01,
Loop = 0x02,
If = 0x03,
- IfElse = 0x04,
+ Else = 0x04,
Select = 0x05,
Br = 0x06,
BrIf = 0x07,
TableSwitch = 0x08,
- Return = 0x14,
- Unreachable = 0x15,
- EndMarker = 0xff
+ Return = 0x09,
+ Unreachable = 0x0a,
+ End = 0x0f
};
enum MemoryAccess {
@@ -486,9 +484,8 @@ public:
int32_t startSection(const char* name) {
// emit 5 bytes of 0, which we'll fill with LEB later
- auto ret = writeU32LEBPlaceholder();
writeInlineString(name);
- return ret;
+ return writeU32LEBPlaceholder();
}
void finishSection(int32_t start) {
@@ -631,7 +628,7 @@ public:
if (numLocalsByType[f64]) o << U32LEB(numLocalsByType[f64]) << binaryWasmType(f64);
depth = 0;
recurse(function->body);
- o << int8_t(BinaryConsts::EndMarker);
+ o << int8_t(BinaryConsts::End);
assert(depth == 0);
size_t size = o.size() - start;
assert(size <= std::numeric_limits<uint32_t>::max());
@@ -795,14 +792,18 @@ public:
recurse(child);
}
breakStack.pop_back();
- o << int8_t(BinaryConsts::EndMarker);
+ o << int8_t(BinaryConsts::End);
}
void visitIf(If *curr) {
if (debug) std::cerr << "zz node: If" << std::endl;
+ o << int8_t(BinaryConsts::If);
recurse(curr->condition);
- recurse(curr->ifTrue);
- if (curr->ifFalse) recurse(curr->ifFalse);
- o << int8_t(curr->ifFalse ? BinaryConsts::IfElse : BinaryConsts::If);
+ recurse(curr->ifTrue); // TODO: emit block contents directly, if block with no name
+ if (curr->ifFalse) {
+ o << int8_t(BinaryConsts::Else);
+ recurse(curr->ifFalse);
+ }
+ o << int8_t(BinaryConsts::End);
}
void visitLoop(Loop *curr) {
if (debug) std::cerr << "zz node: Loop" << std::endl;
@@ -813,7 +814,7 @@ public:
recurse(curr->body);
breakStack.pop_back();
breakStack.pop_back();
- o << int8_t(BinaryConsts::EndMarker);
+ o << int8_t(BinaryConsts::End);
}
int32_t getBreakIndex(Name name) { // -1 if not found
@@ -845,13 +846,13 @@ public:
}
o << U32LEB(getBreakIndex(curr->default_));
recurse(curr->condition);
- o << int8_t(BinaryConsts::EndMarker);
+ o << int8_t(BinaryConsts::End);
if (curr->value) {
recurse(curr->value);
} else {
visitNop(nullptr);
}
- o << int8_t(BinaryConsts::EndMarker);
+ o << int8_t(BinaryConsts::End);
}
void visitCall(Call *curr) {
if (debug) std::cerr << "zz node: Call" << std::endl;
@@ -1135,9 +1136,8 @@ public:
// read sections until the end
while (more()) {
- auto sectionSize = getU32LEB();
- assert(sectionSize < pos + input.size());
auto nameSize = getU32LEB();
+ uint32_t sectionSize, before;
auto match = [&](const char* name) {
for (size_t i = 0; i < nameSize; i++) {
if (pos + i >= input.size()) return false;
@@ -1145,7 +1145,11 @@ public:
if (input[pos + i] != name[i]) return false;
}
if (strlen(name) != nameSize) return false;
+ // name matched, read section size and then section itself
pos += nameSize;
+ sectionSize = getU32LEB();
+ before = pos;
+ assert(pos + sectionSize <= input.size());
return true;
};
if (match(BinaryConsts::Section::Start)) readStart();
@@ -1164,6 +1168,7 @@ public:
} else {
abort();
}
+ assert(pos == before + sectionSize);
}
processFunctions();
@@ -1467,11 +1472,11 @@ public:
std::vector<Expression*> expressionStack;
- void processExpressions() { // until an end marker
+ BinaryConsts::ASTNodes processExpressions() { // until an end or else marker
while (1) {
Expression* curr;
- readExpression(curr);
- if (!curr) break; // end marker, done with this function/block/etc
+ auto ret = readExpression(curr);
+ if (!curr) return ret;
expressionStack.push_back(curr);
}
}
@@ -1555,14 +1560,13 @@ public:
int depth; // only for debugging
- void readExpression(Expression*& curr) {
+ BinaryConsts::ASTNodes readExpression(Expression*& curr) {
if (debug) std::cerr << "zz recurse into " << ++depth << " at " << pos << std::endl;
uint8_t code = getInt8();
if (debug) std::cerr << "readExpression seeing " << (int)code << std::endl;
switch (code) {
case BinaryConsts::Block: visitBlock((curr = allocator.alloc<Block>())->cast<Block>()); break;
- case BinaryConsts::If:
- case BinaryConsts::IfElse: visitIf((curr = allocator.alloc<If>())->cast<If>(), code); break;// code distinguishes if from if_else
+ case BinaryConsts::If: visitIf((curr = allocator.alloc<If>())->cast<If>()); break;
case BinaryConsts::Loop: visitLoop((curr = allocator.alloc<Loop>())->cast<Loop>()); break;
case BinaryConsts::Br:
case BinaryConsts::BrIf: visitBreak((curr = allocator.alloc<Break>())->cast<Break>(), code); break; // code distinguishes br from br_if
@@ -1576,7 +1580,8 @@ public:
case BinaryConsts::Return: visitReturn((curr = allocator.alloc<Return>())->cast<Return>()); break;
case BinaryConsts::Nop: visitNop((curr = allocator.alloc<Nop>())->cast<Nop>()); break;
case BinaryConsts::Unreachable: visitUnreachable((curr = allocator.alloc<Unreachable>())->cast<Unreachable>()); break;
- case BinaryConsts::EndMarker: curr = nullptr; break;
+ case BinaryConsts::End:
+ case BinaryConsts::Else: curr = nullptr; break;
default: {
// otherwise, the code is a subcode TODO: optimize
if (maybeVisit<Binary>(curr, code)) break;
@@ -1590,6 +1595,7 @@ public:
}
}
if (debug) std::cerr << "zz recurse from " << depth-- << " at " << pos << std::endl;
+ return BinaryConsts::ASTNodes(code);
}
template<typename T>
@@ -1645,14 +1651,20 @@ public:
breakStack.pop_back();
}
}
- void visitIf(If *curr, uint8_t code) {
+ void visitIf(If *curr) {
if (debug) std::cerr << "zz node: If" << std::endl;
- if (code == BinaryConsts::IfElse) {
- curr->ifFalse = popExpression();
- }
+ size_t start = expressionStack.size();
+ auto next = processExpressions();
+ size_t end = expressionStack.size();
+ assert(end - start == 2);
curr->ifTrue = popExpression();
curr->condition = popExpression();
- if (code == BinaryConsts::IfElse) {
+ if (next == BinaryConsts::Else) {
+ size_t start = expressionStack.size();
+ processExpressions();
+ size_t end = expressionStack.size();
+ assert(end - start == 1);
+ curr->ifFalse = popExpression();
curr->finalize();
}
}