diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/asm2wasm-main.cpp | 5 | ||||
-rw-r--r-- | src/asm2wasm.h | 43 | ||||
-rw-r--r-- | src/emscripten-optimizer/parser.h | 21 | ||||
-rw-r--r-- | src/emscripten-optimizer/simple_ast.h | 14 |
4 files changed, 82 insertions, 1 deletions
diff --git a/src/asm2wasm-main.cpp b/src/asm2wasm-main.cpp index 0edd82c2f..6a784bd76 100644 --- a/src/asm2wasm-main.cpp +++ b/src/asm2wasm-main.cpp @@ -54,6 +54,11 @@ int main(int argc, char **argv) { if (debug) std::cerr << "parsing...\n"; cashew::Parser<Ref, DotZeroValueBuilder> builder; Ref asmjs = builder.parseToplevel(input); + if (debug) { + std::cerr << "parsed:\n"; + asmjs->stringify(std::cerr, true); + std::cerr << '\n'; + } if (debug) std::cerr << "wasming...\n"; AllocatingModule wasm; diff --git a/src/asm2wasm.h b/src/asm2wasm.h index d3d76ff83..e37751a66 100644 --- a/src/asm2wasm.h +++ b/src/asm2wasm.h @@ -1338,6 +1338,49 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) { block->list.push_back(continuer); ret->body = block; return ret; + } else if (what == FOR) { + Ref finit = ast[1], + fcond = ast[2], + finc = ast[3], + fbody = ast[4]; + auto ret = allocator.alloc<Loop>(); + IString out, in; + if (!parentLabel.isNull()) { + out = getBreakLabelName(parentLabel); + in = getContinueLabelName(parentLabel); + parentLabel = IString(); + } else { + out = getNextId("for-out"); + in = getNextId("for-in"); + } + ret->out = out; + ret->in = in; + breakStack.push_back(out); + continueStack.push_back(in); + Break *breakOut = allocator.alloc<Break>(); + breakOut->name = out; + If *condition = allocator.alloc<If>(); + condition->condition = process(fcond); + condition->ifTrue = allocator.alloc<Nop>(); + condition->ifFalse = breakOut; + auto body = allocator.alloc<Block>(); + body->list.push_back(condition); + body->list.push_back(process(fbody)); + body->list.push_back(process(finc)); + ret->body = body; + // loops do not automatically loop, add a branch back + Block* block = blockify(ret->body); + auto continuer = allocator.alloc<Break>(); + continuer->name = ret->in; + block->list.push_back(continuer); + ret->body = block; + continueStack.pop_back(); + breakStack.pop_back(); + Block *outer = allocator.alloc<Block>(); + // add an outer block for the init as well + outer->list.push_back(process(finit)); + outer->list.push_back(ret); + return outer; } else if (what == LABEL) { assert(parentLabel.isNull()); parentLabel = ast[1]->getIString(); diff --git a/src/emscripten-optimizer/parser.h b/src/emscripten-optimizer/parser.h index 6b2fa2faa..c805ca9f6 100644 --- a/src/emscripten-optimizer/parser.h +++ b/src/emscripten-optimizer/parser.h @@ -386,6 +386,7 @@ class Parser { else if (frag.str == CONTINUE) return parseContinue(src, seps); else if (frag.str == SWITCH) return parseSwitch(src, seps); else if (frag.str == NEW) return parseNew(src, seps); + else if (frag.str == FOR) return parseFor(src, seps); dump(frag.str.str, src); abort(); return nullptr; @@ -492,6 +493,26 @@ class Parser { return Builder::makeWhile(condition, body); } + NodeRef parseFor(char*& src, const char* seps) { + skipSpace(src); + assert(*src == '('); + src++; + NodeRef init = parseElement(src, ";"); + skipSpace(src); + assert(*src == ';'); + src++; + NodeRef condition = parseElement(src, ";"); + skipSpace(src); + assert(*src == ';'); + src++; + NodeRef inc = parseElement(src, ")"); + skipSpace(src); + assert(*src == ')'); + src++; + NodeRef body = parseMaybeBracketed(src, seps); + return Builder::makeFor(init, condition, inc, body); + } + NodeRef parseBreak(char*& src, const char* seps) { skipSpace(src); Frag next(src); diff --git a/src/emscripten-optimizer/simple_ast.h b/src/emscripten-optimizer/simple_ast.h index 862e1f0bc..712845dea 100644 --- a/src/emscripten-optimizer/simple_ast.h +++ b/src/emscripten-optimizer/simple_ast.h @@ -380,7 +380,11 @@ struct Value { #define indentify() { for (int i = 0; i < indent; i++) os << " "; } switch (type) { case String: - os << '"' << str.str << '"'; + if (str.str) { + os << '"' << str.str << '"'; + } else { + os << "\"(null)\""; + } break; case Number: os << std::setprecision(17) << num; // doubles can have 17 digits of precision @@ -1561,6 +1565,14 @@ public: .push_back(body); } + static Ref makeFor(Ref init, Ref condition, Ref inc, Ref body) { + return &makeRawArray(5)->push_back(makeRawString(FOR)) + .push_back(init) + .push_back(condition) + .push_back(inc) + .push_back(body); + } + static Ref makeBreak(IString label) { return &makeRawArray(2)->push_back(makeRawString(BREAK)) .push_back(!!label ? makeRawString(label) : makeNull()); |