diff options
-rw-r--r-- | src/passes/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/passes/PrintCallGraph.cpp | 115 | ||||
-rw-r--r-- | src/passes/pass.cpp | 1 | ||||
-rw-r--r-- | src/passes/passes.h | 1 | ||||
-rw-r--r-- | test/passes/print-call-graph.txt | 1528 | ||||
-rw-r--r-- | test/passes/print-call-graph.wast | 1382 |
6 files changed, 3028 insertions, 0 deletions
diff --git a/src/passes/CMakeLists.txt b/src/passes/CMakeLists.txt index 3f6574ec4..eadc69e0a 100644 --- a/src/passes/CMakeLists.txt +++ b/src/passes/CMakeLists.txt @@ -13,6 +13,7 @@ SET(passes_SOURCES PostEmscripten.cpp Precompute.cpp Print.cpp + PrintCallGraph.cpp RelooperJumpThreading.cpp RemoveImports.cpp RemoveMemory.cpp diff --git a/src/passes/PrintCallGraph.cpp b/src/passes/PrintCallGraph.cpp new file mode 100644 index 000000000..33fcb3457 --- /dev/null +++ b/src/passes/PrintCallGraph.cpp @@ -0,0 +1,115 @@ +/* + * Copyright 2016 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +// Prints the call graph in .dot format. You can use http://www.graphviz.org/ to view .dot files. +// + + +#include <memory> +#include <iomanip> +#include "wasm.h" +#include "pass.h" +#include "ast_utils.h" + +namespace wasm { + +struct PrintCallGraph : public Pass { + void run(PassRunner* runner, Module* module) override { + std::ostream &o = std::cout; + o << "digraph call {\n"; + o << " rankdir = LR;\n"; + o << " subgraph cluster_key {\n"; + o << " node [shape=box, style=rounded, fontname=courier, fontsize=10];\n"; + o << " edge [fontname=courier, fontsize=10];\n"; + o << " label = \"Key\";\n"; + o << " \"Import\" [style=\"filled, rounded\", fillcolor=\"turquoise\"];\n"; + o << " \"Export\" [style=\"filled, rounded\", fillcolor=\"gray\"];\n"; + o << " \"A\" -> \"B\" [style=\"filled, rounded\", label = \"Direct Call\"];\n"; + o << " \"C\" -> \"D\" [style=\"filled, rounded, dashed\", label = \"Possible Indirect Call\"];\n"; + o << " }\n\n"; + o << " node [shape=box,style=rounded, fontname=courier, fontsize=10];\n"; + + // Imports Nodes + for (auto& curr : module->imports) { + if (curr->kind == ExternalKind::Function) { + o << " \"" << curr->name << "\" [style=\"filled, rounded\", fillcolor=\"turquoise\"];\n"; + } + } + + // Exports Nodes + for (auto& curr : module->exports) { + if (curr->kind == ExternalKind::Function) { + Function* func = module->getFunction(curr->value); + o << " \"" << func->name << "\" [style=\"filled, rounded\", fillcolor=\"gray\"];\n"; + } + } + + struct CallPrinter : public PostWalker<CallPrinter, Visitor<CallPrinter>> { + Module *module; + Function *currFunction; + std::set<Name> visitedTargets; // Used to avoid printing duplicate edges. + std::vector<Function*> allIndirectTargets; + CallPrinter(Module *module) : module(module) { + // Gather targets of indirect calls. + for (auto& segment : module->table.segments) { + for (auto& curr : segment.data) { + allIndirectTargets.push_back(module->getFunction(curr)); + } + } + // Walk function bodies. + for (auto& func : module->functions) { + currFunction = func.get(); + std::cout << " \"" << func->name << "\";\n"; + visitedTargets.clear(); + walk(func.get()->body); + } + } + void visitCall(Call *curr) { + auto* target = module->getFunction(curr->target); + if (visitedTargets.count(target->name) > 0) return; + visitedTargets.insert(target->name); + std::cout << " \"" << currFunction->name << "\" -> \"" << target->name << "\"; // call\n"; + } + void visitCallImport(CallImport *curr) { + auto name = curr->target; + if (visitedTargets.count(name) > 0) return; + visitedTargets.insert(name); + std::cout << " \"" << currFunction->name << "\" -> \"" << name << "\"; // callImport\n"; + } + void visitCallIndirect(CallIndirect *curr) { + // Find eligible indirect targets. + auto* currType = module->getFunctionType(curr->fullType); + for (auto& target : allIndirectTargets) { + auto* targetType = module->getFunctionType(target->type); + if (targetType->structuralComparison(*currType)) continue; + auto name = target->name; + if (visitedTargets.count(name) > 0) continue; + visitedTargets.insert(name); + std::cout << " \"" << currFunction->name << "\" -> \"" << name << "\" [style=\"dashed\"]; // callIndirect\n"; + } + } + }; + CallPrinter printer(module); + o << "}\n"; + } +}; + +Pass *createPrintCallGraphPass() { + return new PrintCallGraph(); +} + +} // namespace wasm diff --git a/src/passes/pass.cpp b/src/passes/pass.cpp index 3ae0819ea..42e74fbb7 100644 --- a/src/passes/pass.cpp +++ b/src/passes/pass.cpp @@ -78,6 +78,7 @@ void PassRegistry::registerPasses() { registerPass("print", "print in s-expression format", createPrinterPass); registerPass("print-minified", "print in minified s-expression format", createMinifiedPrinterPass); registerPass("print-full", "print in full s-expression format", createFullPrinterPass); + registerPass("print-call-graph", "print call graph", createPrintCallGraphPass); registerPass("relooper-jump-threading", "thread relooper jumps (fastcomp output only)", createRelooperJumpThreadingPass); registerPass("remove-imports", "removes imports and replaces them with nops", createRemoveImportsPass); registerPass("remove-memory", "removes memory segments", createRemoveMemoryPass); diff --git a/src/passes/passes.h b/src/passes/passes.h index 13193bc4c..5bc221ee5 100644 --- a/src/passes/passes.h +++ b/src/passes/passes.h @@ -38,6 +38,7 @@ Pass *createNameManagerPass(); Pass *createOptimizeInstructionsPass(); Pass *createPostEmscriptenPass(); Pass *createPrinterPass(); +Pass *createPrintCallGraphPass(); Pass *createRelooperJumpThreadingPass(); Pass *createRemoveImportsPass(); Pass *createRemoveMemoryPass(); diff --git a/test/passes/print-call-graph.txt b/test/passes/print-call-graph.txt new file mode 100644 index 000000000..4558194ef --- /dev/null +++ b/test/passes/print-call-graph.txt @@ -0,0 +1,1528 @@ +digraph call { + rankdir = LR; + subgraph cluster_key { + node [shape=box, style=rounded, fontname=courier, fontsize=10]; + edge [fontname=courier, fontsize=10]; + label = "Key"; + "Import" [style="filled, rounded", fillcolor="turquoise"]; + "Export" [style="filled, rounded", fillcolor="gray"]; + "A" -> "B" [style="filled, rounded", label = "Direct Call"]; + "C" -> "D" [style="filled, rounded, dashed", label = "Possible Indirect Call"]; + } + + node [shape=box,style=rounded, fontname=courier, fontsize=10]; + "$abort" [style="filled, rounded", fillcolor="turquoise"]; + "$_pthread_cleanup_pop" [style="filled, rounded", fillcolor="turquoise"]; + "$___lock" [style="filled, rounded", fillcolor="turquoise"]; + "$___syscall6" [style="filled, rounded", fillcolor="turquoise"]; + "$_pthread_cleanup_push" [style="filled, rounded", fillcolor="turquoise"]; + "$___syscall140" [style="filled, rounded", fillcolor="turquoise"]; + "$_emscripten_memcpy_big" [style="filled, rounded", fillcolor="turquoise"]; + "$___syscall54" [style="filled, rounded", fillcolor="turquoise"]; + "$___unlock" [style="filled, rounded", fillcolor="turquoise"]; + "$___syscall146" [style="filled, rounded", fillcolor="turquoise"]; + "$_fflush" [style="filled, rounded", fillcolor="gray"]; + "$_main" [style="filled, rounded", fillcolor="gray"]; + "$_pthread_self" [style="filled, rounded", fillcolor="gray"]; + "$_memset" [style="filled, rounded", fillcolor="gray"]; + "$_malloc" [style="filled, rounded", fillcolor="gray"]; + "$_memcpy" [style="filled, rounded", fillcolor="gray"]; + "$_free" [style="filled, rounded", fillcolor="gray"]; + "$___errno_location" [style="filled, rounded", fillcolor="gray"]; + "$runPostSets" [style="filled, rounded", fillcolor="gray"]; + "$stackAlloc" [style="filled, rounded", fillcolor="gray"]; + "$stackSave" [style="filled, rounded", fillcolor="gray"]; + "$stackRestore" [style="filled, rounded", fillcolor="gray"]; + "$establishStackSpace" [style="filled, rounded", fillcolor="gray"]; + "$setThrew" [style="filled, rounded", fillcolor="gray"]; + "$setTempRet0" [style="filled, rounded", fillcolor="gray"]; + "$getTempRet0" [style="filled, rounded", fillcolor="gray"]; + "$dynCall_ii" [style="filled, rounded", fillcolor="gray"]; + "$dynCall_iiii" [style="filled, rounded", fillcolor="gray"]; + "$dynCall_vi" [style="filled, rounded", fillcolor="gray"]; + "$dynCall_v" [style="filled, rounded", fillcolor="gray"]; + "$stackAlloc"; + "$stackSave"; + "$stackRestore"; + "$establishStackSpace"; + "$setThrew"; + "$setTempRet0"; + "$getTempRet0"; + "$_malloc"; + "$_free"; + "$_main"; + "$_main" -> "$__Znwj"; // call + "$___stdio_close"; + "$___stdio_close" -> "$___syscall6"; // callImport + "$___stdio_close" -> "$___syscall_ret"; // call + "$___stdio_write"; + "$___stdio_write" -> "$_pthread_cleanup_push"; // callImport + "$___stdio_write" -> "$___syscall146"; // callImport + "$___stdio_write" -> "$___syscall_ret"; // call + "$___stdio_write" -> "$_pthread_cleanup_pop"; // callImport + "$___stdio_seek"; + "$___stdio_seek" -> "$___syscall140"; // callImport + "$___stdio_seek" -> "$___syscall_ret"; // call + "$___syscall_ret"; + "$___syscall_ret" -> "$___errno_location"; // call + "$___errno_location"; + "$___errno_location" -> "$_pthread_self"; // call + "$_cleanup_387"; + "$_cleanup_387" -> "$_free"; // call + "$___stdout_write"; + "$___stdout_write" -> "$___syscall54"; // callImport + "$___stdout_write" -> "$___stdio_write"; // call + "$_fflush"; + "$_fflush" -> "$___fflush_unlocked"; // call + "$_fflush" -> "$_malloc"; // call + "$_fflush" -> "$_free"; // call + "$_fflush" -> "$_fflush"; // call + "$_fflush" -> "$___lock"; // callImport + "$_fflush" -> "$___unlock"; // callImport + "$___fflush_unlocked"; + "$___fflush_unlocked" -> "$b0" [style="dashed"]; // callIndirect + "$___fflush_unlocked" -> "$___stdio_close" [style="dashed"]; // callIndirect + "$___fflush_unlocked" -> "$b2" [style="dashed"]; // callIndirect + "$___fflush_unlocked" -> "$_cleanup_387" [style="dashed"]; // callIndirect + "$___fflush_unlocked" -> "$b3" [style="dashed"]; // callIndirect + "$__Znwj"; + "$__Znwj" -> "$_malloc"; // call + "$__Znwj" -> "$__ZSt15get_new_handlerv"; // call + "$__Znwj" -> "$b0" [style="dashed"]; // callIndirect + "$__Znwj" -> "$___stdio_close" [style="dashed"]; // callIndirect + "$__Znwj" -> "$b1" [style="dashed"]; // callIndirect + "$__Znwj" -> "$___stdout_write" [style="dashed"]; // callIndirect + "$__Znwj" -> "$___stdio_seek" [style="dashed"]; // callIndirect + "$__Znwj" -> "$___stdio_write" [style="dashed"]; // callIndirect + "$__Znwj" -> "$b2" [style="dashed"]; // callIndirect + "$__Znwj" -> "$_cleanup_387" [style="dashed"]; // callIndirect + "$__ZSt15get_new_handlerv"; + "$runPostSets"; + "$_memset"; + "$_memcpy"; + "$_memcpy" -> "$_emscripten_memcpy_big"; // callImport + "$_pthread_self"; + "$dynCall_ii"; + "$dynCall_ii" -> "$b1" [style="dashed"]; // callIndirect + "$dynCall_ii" -> "$___stdout_write" [style="dashed"]; // callIndirect + "$dynCall_ii" -> "$___stdio_seek" [style="dashed"]; // callIndirect + "$dynCall_ii" -> "$___stdio_write" [style="dashed"]; // callIndirect + "$dynCall_ii" -> "$b2" [style="dashed"]; // callIndirect + "$dynCall_ii" -> "$_cleanup_387" [style="dashed"]; // callIndirect + "$dynCall_ii" -> "$b3" [style="dashed"]; // callIndirect + "$dynCall_iiii"; + "$dynCall_iiii" -> "$b0" [style="dashed"]; // callIndirect + "$dynCall_iiii" -> "$___stdio_close" [style="dashed"]; // callIndirect + "$dynCall_iiii" -> "$b2" [style="dashed"]; // callIndirect + "$dynCall_iiii" -> "$_cleanup_387" [style="dashed"]; // callIndirect + "$dynCall_iiii" -> "$b3" [style="dashed"]; // callIndirect + "$dynCall_vi"; + "$dynCall_vi" -> "$b0" [style="dashed"]; // callIndirect + "$dynCall_vi" -> "$___stdio_close" [style="dashed"]; // callIndirect + "$dynCall_vi" -> "$b1" [style="dashed"]; // callIndirect + "$dynCall_vi" -> "$___stdout_write" [style="dashed"]; // callIndirect + "$dynCall_vi" -> "$___stdio_seek" [style="dashed"]; // callIndirect + "$dynCall_vi" -> "$___stdio_write" [style="dashed"]; // callIndirect + "$dynCall_vi" -> "$b3" [style="dashed"]; // callIndirect + "$dynCall_v"; + "$dynCall_v" -> "$b0" [style="dashed"]; // callIndirect + "$dynCall_v" -> "$___stdio_close" [style="dashed"]; // callIndirect + "$dynCall_v" -> "$b1" [style="dashed"]; // callIndirect + "$dynCall_v" -> "$___stdout_write" [style="dashed"]; // callIndirect + "$dynCall_v" -> "$___stdio_seek" [style="dashed"]; // callIndirect + "$dynCall_v" -> "$___stdio_write" [style="dashed"]; // callIndirect + "$dynCall_v" -> "$b2" [style="dashed"]; // callIndirect + "$dynCall_v" -> "$_cleanup_387" [style="dashed"]; // callIndirect + "$b0"; + "$b0" -> "$abort"; // callImport + "$b1"; + "$b1" -> "$abort"; // callImport + "$b2"; + "$b2" -> "$abort"; // callImport + "$b3"; + "$b3" -> "$abort"; // callImport +} +(module + (type $FUNCSIG$iiii (func (param i32 i32 i32) (result i32))) + (type $FUNCSIG$v (func)) + (type $FUNCSIG$ii (func (param i32) (result i32))) + (type $FUNCSIG$vi (func (param i32))) + (type $FUNCSIG$iii (func (param i32 i32) (result i32))) + (type $FUNCSIG$vii (func (param i32 i32))) + (type $6 (func (result i32))) + (type $7 (func (param i32 i32 i32 i32) (result i32))) + (import "env" "STACKTOP" (global $STACKTOP$asm2wasm$import i32)) + (import "env" "STACK_MAX" (global $STACK_MAX$asm2wasm$import i32)) + (import "env" "DYNAMICTOP_PTR" (global $DYNAMICTOP_PTR$asm2wasm$import i32)) + (import "env" "tempDoublePtr" (global $tempDoublePtr$asm2wasm$import i32)) + (import "env" "ABORT" (global $ABORT$asm2wasm$import i32)) + (import "global" "NaN" (global $nan$asm2wasm$import f64)) + (import "global" "Infinity" (global $inf$asm2wasm$import f64)) + (import "env" "abort" (func $abort (param i32))) + (import "env" "_pthread_cleanup_pop" (func $_pthread_cleanup_pop (param i32))) + (import "env" "___lock" (func $___lock (param i32))) + (import "env" "___syscall6" (func $___syscall6 (param i32 i32) (result i32))) + (import "env" "_pthread_cleanup_push" (func $_pthread_cleanup_push (param i32 i32))) + (import "env" "___syscall140" (func $___syscall140 (param i32 i32) (result i32))) + (import "env" "_emscripten_memcpy_big" (func $_emscripten_memcpy_big (param i32 i32 i32) (result i32))) + (import "env" "___syscall54" (func $___syscall54 (param i32 i32) (result i32))) + (import "env" "___unlock" (func $___unlock (param i32))) + (import "env" "___syscall146" (func $___syscall146 (param i32 i32) (result i32))) + (import "env" "memory" (memory $0 256 256)) + (import "env" "table" (table 9 9 anyfunc)) + (import "env" "memoryBase" (global $memoryBase i32)) + (import "env" "tableBase" (global $tableBase i32)) + (elem (i32.const 0) $b0 $___stdio_close $b1 $___stdout_write $___stdio_seek $___stdio_write $b2 $_cleanup_387 $b3) + (data (get_global $memoryBase) "\05\00\00\00\00\00\00\00\00\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\01\00\00\00\02\00\00\00\b0\04\00\00\00\04\00\00\00\00\00\00\00\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\n\ff\ff\ff\ff\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\04") + (global $STACKTOP (mut i32) (get_global $STACKTOP$asm2wasm$import)) + (global $STACK_MAX (mut i32) (get_global $STACK_MAX$asm2wasm$import)) + (global $DYNAMICTOP_PTR (mut i32) (get_global $DYNAMICTOP_PTR$asm2wasm$import)) + (global $tempDoublePtr (mut i32) (get_global $tempDoublePtr$asm2wasm$import)) + (global $ABORT (mut i32) (get_global $ABORT$asm2wasm$import)) + (global $__THREW__ (mut i32) (i32.const 0)) + (global $threwValue (mut i32) (i32.const 0)) + (global $setjmpId (mut i32) (i32.const 0)) + (global $undef (mut i32) (i32.const 0)) + (global $nan (mut f64) (get_global $nan$asm2wasm$import)) + (global $inf (mut f64) (get_global $inf$asm2wasm$import)) + (global $tempInt (mut i32) (i32.const 0)) + (global $tempBigInt (mut i32) (i32.const 0)) + (global $tempBigIntP (mut i32) (i32.const 0)) + (global $tempBigIntS (mut i32) (i32.const 0)) + (global $tempBigIntR (mut f64) (f64.const 0)) + (global $tempBigIntI (mut i32) (i32.const 0)) + (global $tempBigIntD (mut i32) (i32.const 0)) + (global $tempValue (mut i32) (i32.const 0)) + (global $tempDouble (mut f64) (f64.const 0)) + (global $tempRet0 (mut i32) (i32.const 0)) + (global $tempFloat (mut f32) (f32.const 0)) + (global $f0 (mut f32) (f32.const 0)) + (export "_fflush" (func $_fflush)) + (export "_main" (func $_main)) + (export "_pthread_self" (func $_pthread_self)) + (export "_memset" (func $_memset)) + (export "_malloc" (func $_malloc)) + (export "_memcpy" (func $_memcpy)) + (export "_free" (func $_free)) + (export "___errno_location" (func $___errno_location)) + (export "runPostSets" (func $runPostSets)) + (export "stackAlloc" (func $stackAlloc)) + (export "stackSave" (func $stackSave)) + (export "stackRestore" (func $stackRestore)) + (export "establishStackSpace" (func $establishStackSpace)) + (export "setThrew" (func $setThrew)) + (export "setTempRet0" (func $setTempRet0)) + (export "getTempRet0" (func $getTempRet0)) + (export "dynCall_ii" (func $dynCall_ii)) + (export "dynCall_iiii" (func $dynCall_iiii)) + (export "dynCall_vi" (func $dynCall_vi)) + (export "dynCall_v" (func $dynCall_v)) + (func $stackAlloc (type $FUNCSIG$ii) (param $0 i32) (result i32) + (local $1 i32) + (set_local $1 + (get_global $STACKTOP) + ) + (set_global $STACKTOP + (i32.add + (get_global $STACKTOP) + (get_local $0) + ) + ) + (set_global $STACKTOP + (i32.and + (i32.add + (get_global $STACKTOP) + (i32.const 15) + ) + (i32.const -16) + ) + ) + (get_local $1) + ) + (func $stackSave (type $6) (result i32) + (get_global $STACKTOP) + ) + (func $stackRestore (type $FUNCSIG$vi) (param $0 i32) + (set_global $STACKTOP + (get_local $0) + ) + ) + (func $establishStackSpace (type $FUNCSIG$vii) (param $0 i32) (param $1 i32) + (set_global $STACKTOP + (get_local $0) + ) + (set_global $STACK_MAX + (get_local $1) + ) + ) + (func $setThrew (type $FUNCSIG$vii) (param $0 i32) (param $1 i32) + (if + (i32.eqz + (get_global $__THREW__) + ) + (block $block + (set_global $__THREW__ + (get_local $0) + ) + (set_global $threwValue + (get_local $1) + ) + ) + ) + ) + (func $setTempRet0 (type $FUNCSIG$vi) (param $0 i32) + (set_global $tempRet0 + (get_local $0) + ) + ) + (func $getTempRet0 (type $6) (result i32) + (get_global $tempRet0) + ) + (func $_malloc (type $FUNCSIG$ii) (param $0 i32) (result i32) + (i32.const 0) + ) + (func $_free (type $FUNCSIG$vi) (param $0 i32) + (nop) + ) + (func $_main (type $6) (result i32) + (local $0 i32) + (i64.store align=4 + (tee_local $0 + (call $__Znwj + (i32.const 8) + ) + ) + (i64.const 0) + ) + (get_local $0) + ) + (func $___stdio_close (type $FUNCSIG$ii) (param $0 i32) (result i32) + (local $1 i32) + (local $2 i32) + (set_local $1 + (get_global $STACKTOP) + ) + (set_global $STACKTOP + (i32.add + (get_global $STACKTOP) + (i32.const 16) + ) + ) + (i32.store + (tee_local $2 + (get_local $1) + ) + (i32.load offset=60 + (get_local $0) + ) + ) + (set_local $0 + (call $___syscall_ret + (call $___syscall6 + (i32.const 6) + (get_local $2) + ) + ) + ) + (set_global $STACKTOP + (get_local $1) + ) + (get_local $0) + ) + (func $___stdio_write (type $FUNCSIG$iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (local $9 i32) + (local $10 i32) + (local $11 i32) + (local $12 i32) + (local $13 i32) + (local $14 i32) + (set_local $7 + (get_global $STACKTOP) + ) + (set_global $STACKTOP + (i32.add + (get_global $STACKTOP) + (i32.const 48) + ) + ) + (set_local $8 + (i32.add + (get_local $7) + (i32.const 16) + ) + ) + (set_local $9 + (get_local $7) + ) + (i32.store + (tee_local $3 + (i32.add + (get_local $7) + (i32.const 32) + ) + ) + (tee_local $5 + (i32.load + (tee_local $6 + (i32.add + (get_local $0) + (i32.const 28) + ) + ) + ) + ) + ) + (i32.store offset=4 + (get_local $3) + (tee_local $4 + (i32.sub + (i32.load + (tee_local $10 + (i32.add + (get_local $0) + (i32.const 20) + ) + ) + ) + (get_local $5) + ) + ) + ) + (i32.store offset=8 + (get_local $3) + (get_local $1) + ) + (i32.store offset=12 + (get_local $3) + (get_local $2) + ) + (set_local $13 + (i32.add + (get_local $0) + (i32.const 60) + ) + ) + (set_local $14 + (i32.add + (get_local $0) + (i32.const 44) + ) + ) + (set_local $1 + (get_local $3) + ) + (set_local $5 + (i32.const 2) + ) + (set_local $11 + (i32.add + (get_local $4) + (get_local $2) + ) + ) + (set_local $0 + (block $jumpthreading$outer$1 i32 + (block $jumpthreading$inner$1 + (block $jumpthreading$inner$0 + (loop $while-in + (br_if $jumpthreading$inner$0 + (i32.eq + (get_local $11) + (tee_local $4 + (if i32 + (i32.load + (i32.const 1140) + ) + (block $block i32 + (call $_pthread_cleanup_push + (i32.const 1) + (get_local $0) + ) + (i32.store + (get_local $9) + (i32.load + (get_local $13) + ) + ) + (i32.store offset=4 + (get_local $9) + (get_local $1) + ) + (i32.store offset=8 + (get_local $9) + (get_local $5) + ) + (set_local $3 + (call $___syscall_ret + (call $___syscall146 + (i32.const 146) + (get_local $9) + ) + ) + ) + (call $_pthread_cleanup_pop + (i32.const 0) + ) + (get_local $3) + ) + (block $block0 i32 + (i32.store + (get_local $8) + (i32.load + (get_local $13) + ) + ) + (i32.store offset=4 + (get_local $8) + (get_local $1) + ) + (i32.store offset=8 + (get_local $8) + (get_local $5) + ) + (call $___syscall_ret + (call $___syscall146 + (i32.const 146) + (get_local $8) + ) + ) + ) + ) + ) + ) + ) + (br_if $jumpthreading$inner$1 + (i32.lt_s + (get_local $4) + (i32.const 0) + ) + ) + (set_local $11 + (i32.sub + (get_local $11) + (get_local $4) + ) + ) + (set_local $1 + (if i32 + (i32.gt_u + (get_local $4) + (tee_local $12 + (i32.load offset=4 + (get_local $1) + ) + ) + ) + (block $block2 i32 + (i32.store + (get_local $6) + (tee_local $3 + (i32.load + (get_local $14) + ) + ) + ) + (i32.store + (get_local $10) + (get_local $3) + ) + (set_local $4 + (i32.sub + (get_local $4) + (get_local $12) + ) + ) + (set_local $3 + (i32.add + (get_local $1) + (i32.const 8) + ) + ) + (set_local $5 + (i32.add + (get_local $5) + (i32.const -1) + ) + ) + (i32.load offset=12 + (get_local $1) + ) + ) + (if i32 + (i32.eq + (get_local $5) + (i32.const 2) + ) + (block $block4 i32 + (i32.store + (get_local $6) + (i32.add + (i32.load + (get_local $6) + ) + (get_local $4) + ) + ) + (set_local $3 + (get_local $1) + ) + (set_local $5 + (i32.const 2) + ) + (get_local $12) + ) + (block $block5 i32 + (set_local $3 + (get_local $1) + ) + (get_local $12) + ) + ) + ) + ) + (i32.store + (get_local $3) + (i32.add + (i32.load + (get_local $3) + ) + (get_local $4) + ) + ) + (i32.store offset=4 + (get_local $3) + (i32.sub + (get_local $1) + (get_local $4) + ) + ) + (set_local $1 + (get_local $3) + ) + (br $while-in) + ) + ) + (i32.store offset=16 + (get_local $0) + (i32.add + (tee_local $1 + (i32.load + (get_local $14) + ) + ) + (i32.load offset=48 + (get_local $0) + ) + ) + ) + (i32.store + (get_local $6) + (tee_local $0 + (get_local $1) + ) + ) + (i32.store + (get_local $10) + (get_local $0) + ) + (br $jumpthreading$outer$1 + (get_local $2) + ) + ) + (i32.store offset=16 + (get_local $0) + (i32.const 0) + ) + (i32.store + (get_local $6) + (i32.const 0) + ) + (i32.store + (get_local $10) + (i32.const 0) + ) + (i32.store + (get_local $0) + (i32.or + (i32.load + (get_local $0) + ) + (i32.const 32) + ) + ) + (select + (i32.const 0) + (i32.sub + (get_local $2) + (i32.load offset=4 + (get_local $1) + ) + ) + (i32.eq + (get_local $5) + (i32.const 2) + ) + ) + ) + ) + (set_global $STACKTOP + (get_local $7) + ) + (get_local $0) + ) + (func $___stdio_seek (type $FUNCSIG$iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (local $3 i32) + (local $4 i32) + (set_local $4 + (get_global $STACKTOP) + ) + (set_global $STACKTOP + (i32.add + (get_global $STACKTOP) + (i32.const 32) + ) + ) + (i32.store + (tee_local $3 + (get_local $4) + ) + (i32.load offset=60 + (get_local $0) + ) + ) + (i32.store offset=4 + (get_local $3) + (i32.const 0) + ) + (i32.store offset=8 + (get_local $3) + (get_local $1) + ) + (i32.store offset=12 + (get_local $3) + (tee_local $0 + (i32.add + (get_local $4) + (i32.const 20) + ) + ) + ) + (i32.store offset=16 + (get_local $3) + (get_local $2) + ) + (set_local $0 + (if i32 + (i32.lt_s + (call $___syscall_ret + (call $___syscall140 + (i32.const 140) + (get_local $3) + ) + ) + (i32.const 0) + ) + (block $block i32 + (i32.store + (get_local $0) + (i32.const -1) + ) + (i32.const -1) + ) + (i32.load + (get_local $0) + ) + ) + ) + (set_global $STACKTOP + (get_local $4) + ) + (get_local $0) + ) + (func $___syscall_ret (type $FUNCSIG$ii) (param $0 i32) (result i32) + (if i32 + (i32.gt_u + (get_local $0) + (i32.const -4096) + ) + (block $block i32 + (i32.store + (call $___errno_location) + (i32.sub + (i32.const 0) + (get_local $0) + ) + ) + (i32.const -1) + ) + (get_local $0) + ) + ) + (func $___errno_location (type $6) (result i32) + (if i32 + (i32.load + (i32.const 1140) + ) + (i32.load offset=64 + (call $_pthread_self) + ) + (i32.const 1184) + ) + ) + (func $_cleanup_387 (type $FUNCSIG$vi) (param $0 i32) + (if + (i32.eqz + (i32.load offset=68 + (get_local $0) + ) + ) + (call $_free + (get_local $0) + ) + ) + ) + (func $___stdout_write (type $FUNCSIG$iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (set_local $4 + (get_global $STACKTOP) + ) + (set_global $STACKTOP + (i32.add + (get_global $STACKTOP) + (i32.const 80) + ) + ) + (set_local $3 + (get_local $4) + ) + (set_local $5 + (i32.add + (get_local $4) + (i32.const 12) + ) + ) + (i32.store offset=36 + (get_local $0) + (i32.const 3) + ) + (if + (i32.eqz + (i32.and + (i32.load + (get_local $0) + ) + (i32.const 64) + ) + ) + (block $block + (i32.store + (get_local $3) + (i32.load offset=60 + (get_local $0) + ) + ) + (i32.store offset=4 + (get_local $3) + (i32.const 21505) + ) + (i32.store offset=8 + (get_local $3) + (get_local $5) + ) + (if + (call $___syscall54 + (i32.const 54) + (get_local $3) + ) + (i32.store8 offset=75 + (get_local $0) + (i32.const -1) + ) + ) + ) + ) + (set_local $0 + (call $___stdio_write + (get_local $0) + (get_local $1) + (get_local $2) + ) + ) + (set_global $STACKTOP + (get_local $4) + ) + (get_local $0) + ) + (func $_fflush (type $FUNCSIG$ii) (param $0 i32) (result i32) + (local $1 i32) + (local $2 i32) + (block $do-once i32 + (if i32 + (get_local $0) + (block $block i32 + (if + (i32.le_s + (i32.load offset=76 + (get_local $0) + ) + (i32.const -1) + ) + (br $do-once + (call $___fflush_unlocked + (get_local $0) + ) + ) + ) + (set_local $2 + (i32.eqz + (call $_malloc + (get_local $0) + ) + ) + ) + (set_local $1 + (call $___fflush_unlocked + (get_local $0) + ) + ) + (if i32 + (get_local $2) + (get_local $1) + (block $block9 i32 + (call $_free + (get_local $0) + ) + (get_local $1) + ) + ) + ) + (block $block10 i32 + (set_local $0 + (if i32 + (i32.load + (i32.const 1136) + ) + (call $_fflush + (i32.load + (i32.const 1136) + ) + ) + (i32.const 0) + ) + ) + (call $___lock + (i32.const 1168) + ) + (if + (tee_local $1 + (i32.load + (i32.const 1164) + ) + ) + (loop $while-in + (set_local $2 + (if i32 + (i32.gt_s + (i32.load offset=76 + (get_local $1) + ) + (i32.const -1) + ) + (call $_malloc + (get_local $1) + ) + (i32.const 0) + ) + ) + (set_local $0 + (if i32 + (i32.gt_u + (i32.load offset=20 + (get_local $1) + ) + (i32.load offset=28 + (get_local $1) + ) + ) + (i32.or + (call $___fflush_unlocked + (get_local $1) + ) + (get_local $0) + ) + (get_local $0) + ) + ) + (if + (get_local $2) + (call $_free + (get_local $1) + ) + ) + (br_if $while-in + (tee_local $1 + (i32.load offset=56 + (get_local $1) + ) + ) + ) + ) + ) + (call $___unlock + (i32.const 1168) + ) + (get_local $0) + ) + ) + ) + ) + (func $___fflush_unlocked (type $FUNCSIG$ii) (param $0 i32) (result i32) + (local $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (block $jumpthreading$outer$0 i32 + (block $jumpthreading$inner$0 + (br_if $jumpthreading$inner$0 + (i32.le_u + (i32.load + (tee_local $1 + (i32.add + (get_local $0) + (i32.const 20) + ) + ) + ) + (i32.load + (tee_local $2 + (i32.add + (get_local $0) + (i32.const 28) + ) + ) + ) + ) + ) + (drop + (call_indirect $FUNCSIG$iiii + (get_local $0) + (i32.const 0) + (i32.const 0) + (i32.add + (i32.and + (i32.load offset=36 + (get_local $0) + ) + (i32.const 3) + ) + (i32.const 2) + ) + ) + ) + (br_if $jumpthreading$inner$0 + (i32.load + (get_local $1) + ) + ) + (br $jumpthreading$outer$0 + (i32.const -1) + ) + ) + (if + (i32.lt_u + (tee_local $4 + (i32.load + (tee_local $3 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + ) + (tee_local $6 + (i32.load + (tee_local $5 + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + ) + ) + ) + (drop + (call_indirect $FUNCSIG$iiii + (get_local $0) + (i32.sub + (get_local $4) + (get_local $6) + ) + (i32.const 1) + (i32.add + (i32.and + (i32.load offset=40 + (get_local $0) + ) + (i32.const 3) + ) + (i32.const 2) + ) + ) + ) + ) + (i32.store offset=16 + (get_local $0) + (i32.const 0) + ) + (i32.store + (get_local $2) + (i32.const 0) + ) + (i32.store + (get_local $1) + (i32.const 0) + ) + (i32.store + (get_local $5) + (i32.const 0) + ) + (i32.store + (get_local $3) + (i32.const 0) + ) + (i32.const 0) + ) + ) + (func $__Znwj (type $FUNCSIG$ii) (param $0 i32) (result i32) + (local $1 i32) + (set_local $1 + (select + (get_local $0) + (i32.const 1) + (get_local $0) + ) + ) + (loop $while-in + (block $while-out + (br_if $while-out + (tee_local $0 + (call $_malloc + (get_local $1) + ) + ) + ) + (if + (tee_local $0 + (call $__ZSt15get_new_handlerv) + ) + (block $block + (call_indirect $FUNCSIG$v + (i32.add + (i32.and + (get_local $0) + (i32.const 0) + ) + (i32.const 8) + ) + ) + (br $while-in) + ) + (set_local $0 + (i32.const 0) + ) + ) + ) + ) + (get_local $0) + ) + (func $__ZSt15get_new_handlerv (type $6) (result i32) + (local $0 i32) + (i32.store + (i32.const 1188) + (i32.add + (tee_local $0 + (i32.load + (i32.const 1188) + ) + ) + (i32.const 0) + ) + ) + (get_local $0) + ) + (func $runPostSets (type $FUNCSIG$v) + (nop) + ) + (func $_memset (type $FUNCSIG$iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (set_local $4 + (i32.add + (get_local $0) + (get_local $2) + ) + ) + (if + (i32.ge_s + (get_local $2) + (i32.const 20) + ) + (block $block + (set_local $5 + (i32.or + (i32.or + (i32.or + (tee_local $1 + (i32.and + (get_local $1) + (i32.const 255) + ) + ) + (i32.shl + (get_local $1) + (i32.const 8) + ) + ) + (i32.shl + (get_local $1) + (i32.const 16) + ) + ) + (i32.shl + (get_local $1) + (i32.const 24) + ) + ) + ) + (set_local $6 + (i32.and + (get_local $4) + (i32.const -4) + ) + ) + (if + (tee_local $3 + (i32.and + (get_local $0) + (i32.const 3) + ) + ) + (block $block17 + (set_local $3 + (i32.sub + (i32.add + (get_local $0) + (i32.const 4) + ) + (get_local $3) + ) + ) + (loop $while-in + (if + (i32.lt_s + (get_local $0) + (get_local $3) + ) + (block $block19 + (i32.store8 + (get_local $0) + (get_local $1) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 1) + ) + ) + (br $while-in) + ) + ) + ) + ) + ) + (loop $while-in1 + (if + (i32.lt_s + (get_local $0) + (get_local $6) + ) + (block $block21 + (i32.store + (get_local $0) + (get_local $5) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + (br $while-in1) + ) + ) + ) + ) + ) + (loop $while-in3 + (if + (i32.lt_s + (get_local $0) + (get_local $4) + ) + (block $block23 + (i32.store8 + (get_local $0) + (get_local $1) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 1) + ) + ) + (br $while-in3) + ) + ) + ) + (i32.sub + (get_local $0) + (get_local $2) + ) + ) + (func $_memcpy (type $FUNCSIG$iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (local $3 i32) + (if + (i32.ge_s + (get_local $2) + (i32.const 4096) + ) + (return + (call $_emscripten_memcpy_big + (get_local $0) + (get_local $1) + (get_local $2) + ) + ) + ) + (set_local $3 + (get_local $0) + ) + (if + (i32.eq + (i32.and + (get_local $0) + (i32.const 3) + ) + (i32.and + (get_local $1) + (i32.const 3) + ) + ) + (block $block + (loop $while-in + (block $while-out + (br_if $while-out + (i32.eqz + (i32.and + (get_local $0) + (i32.const 3) + ) + ) + ) + (if + (i32.eqz + (get_local $2) + ) + (return + (get_local $3) + ) + ) + (i32.store8 + (get_local $0) + (i32.load8_s + (get_local $1) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 1) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (set_local $2 + (i32.sub + (get_local $2) + (i32.const 1) + ) + ) + (br $while-in) + ) + ) + (loop $while-in1 + (if + (i32.ge_s + (get_local $2) + (i32.const 4) + ) + (block $block27 + (i32.store + (get_local $0) + (i32.load + (get_local $1) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 4) + ) + ) + (set_local $2 + (i32.sub + (get_local $2) + (i32.const 4) + ) + ) + (br $while-in1) + ) + ) + ) + ) + ) + (loop $while-in3 + (if + (i32.gt_s + (get_local $2) + (i32.const 0) + ) + (block $block29 + (i32.store8 + (get_local $0) + (i32.load8_s + (get_local $1) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 1) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (set_local $2 + (i32.sub + (get_local $2) + (i32.const 1) + ) + ) + (br $while-in3) + ) + ) + ) + (get_local $3) + ) + (func $_pthread_self (type $6) (result i32) + (i32.const 0) + ) + (func $dynCall_ii (type $FUNCSIG$iii) (param $0 i32) (param $1 i32) (result i32) + (call_indirect $FUNCSIG$ii + (get_local $1) + (i32.add + (i32.and + (get_local $0) + (i32.const 1) + ) + (i32.const 0) + ) + ) + ) + (func $dynCall_iiii (type $7) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) + (call_indirect $FUNCSIG$iiii + (get_local $1) + (get_local $2) + (get_local $3) + (i32.add + (i32.and + (get_local $0) + (i32.const 3) + ) + (i32.const 2) + ) + ) + ) + (func $dynCall_vi (type $FUNCSIG$vii) (param $0 i32) (param $1 i32) + (call_indirect $FUNCSIG$vi + (get_local $1) + (i32.add + (i32.and + (get_local $0) + (i32.const 1) + ) + (i32.const 6) + ) + ) + ) + (func $dynCall_v (type $FUNCSIG$vi) (param $0 i32) + (call_indirect $FUNCSIG$v + (i32.add + (i32.and + (get_local $0) + (i32.const 0) + ) + (i32.const 8) + ) + ) + ) + (func $b0 (type $FUNCSIG$ii) (param $0 i32) (result i32) + (call $abort + (i32.const 0) + ) + (i32.const 0) + ) + (func $b1 (type $FUNCSIG$iiii) (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (call $abort + (i32.const 1) + ) + (i32.const 0) + ) + (func $b2 (type $FUNCSIG$vi) (param $0 i32) + (call $abort + (i32.const 2) + ) + ) + (func $b3 (type $FUNCSIG$v) + (call $abort + (i32.const 3) + ) + ) +) diff --git a/test/passes/print-call-graph.wast b/test/passes/print-call-graph.wast new file mode 100644 index 000000000..33fdc946a --- /dev/null +++ b/test/passes/print-call-graph.wast @@ -0,0 +1,1382 @@ +(module + (type $FUNCSIG$iiii (func (param i32 i32 i32) (result i32))) + (type $FUNCSIG$v (func)) + (type $FUNCSIG$ii (func (param i32) (result i32))) + (type $FUNCSIG$vi (func (param i32))) + (type $FUNCSIG$iii (func (param i32 i32) (result i32))) + (type $FUNCSIG$vii (func (param i32 i32))) + (import "env" "STACKTOP" (global $STACKTOP$asm2wasm$import i32)) + (import "env" "STACK_MAX" (global $STACK_MAX$asm2wasm$import i32)) + (import "env" "DYNAMICTOP_PTR" (global $DYNAMICTOP_PTR$asm2wasm$import i32)) + (import "env" "tempDoublePtr" (global $tempDoublePtr$asm2wasm$import i32)) + (import "env" "ABORT" (global $ABORT$asm2wasm$import i32)) + (import "global" "NaN" (global $nan$asm2wasm$import f64)) + (import "global" "Infinity" (global $inf$asm2wasm$import f64)) + (import "env" "abort" (func $abort (param i32))) + (import "env" "_pthread_cleanup_pop" (func $_pthread_cleanup_pop (param i32))) + (import "env" "___lock" (func $___lock (param i32))) + (import "env" "___syscall6" (func $___syscall6 (param i32 i32) (result i32))) + (import "env" "_pthread_cleanup_push" (func $_pthread_cleanup_push (param i32 i32))) + (import "env" "___syscall140" (func $___syscall140 (param i32 i32) (result i32))) + (import "env" "_emscripten_memcpy_big" (func $_emscripten_memcpy_big (param i32 i32 i32) (result i32))) + (import "env" "___syscall54" (func $___syscall54 (param i32 i32) (result i32))) + (import "env" "___unlock" (func $___unlock (param i32))) + (import "env" "___syscall146" (func $___syscall146 (param i32 i32) (result i32))) + (import "env" "memory" (memory $0 256 256)) + (import "env" "table" (table 9 9 anyfunc)) + (import "env" "memoryBase" (global $memoryBase i32)) + (import "env" "tableBase" (global $tableBase i32)) + (elem (i32.const 0) $b0 $___stdio_close $b1 $___stdout_write $___stdio_seek $___stdio_write $b2 $_cleanup_387 $b3) + (data (get_global $memoryBase) "\05\00\00\00\00\00\00\00\00\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\01\00\00\00\02\00\00\00\b0\04\00\00\00\04\00\00\00\00\00\00\00\00\00\00\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\n\ff\ff\ff\ff\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\04") + (global $STACKTOP (mut i32) (get_global $STACKTOP$asm2wasm$import)) + (global $STACK_MAX (mut i32) (get_global $STACK_MAX$asm2wasm$import)) + (global $DYNAMICTOP_PTR (mut i32) (get_global $DYNAMICTOP_PTR$asm2wasm$import)) + (global $tempDoublePtr (mut i32) (get_global $tempDoublePtr$asm2wasm$import)) + (global $ABORT (mut i32) (get_global $ABORT$asm2wasm$import)) + (global $__THREW__ (mut i32) (i32.const 0)) + (global $threwValue (mut i32) (i32.const 0)) + (global $setjmpId (mut i32) (i32.const 0)) + (global $undef (mut i32) (i32.const 0)) + (global $nan (mut f64) (get_global $nan$asm2wasm$import)) + (global $inf (mut f64) (get_global $inf$asm2wasm$import)) + (global $tempInt (mut i32) (i32.const 0)) + (global $tempBigInt (mut i32) (i32.const 0)) + (global $tempBigIntP (mut i32) (i32.const 0)) + (global $tempBigIntS (mut i32) (i32.const 0)) + (global $tempBigIntR (mut f64) (f64.const 0)) + (global $tempBigIntI (mut i32) (i32.const 0)) + (global $tempBigIntD (mut i32) (i32.const 0)) + (global $tempValue (mut i32) (i32.const 0)) + (global $tempDouble (mut f64) (f64.const 0)) + (global $tempRet0 (mut i32) (i32.const 0)) + (global $tempFloat (mut f32) (f32.const 0)) + (global $f0 (mut f32) (f32.const 0)) + (export "_fflush" (func $_fflush)) + (export "_main" (func $_main)) + (export "_pthread_self" (func $_pthread_self)) + (export "_memset" (func $_memset)) + (export "_malloc" (func $_malloc)) + (export "_memcpy" (func $_memcpy)) + (export "_free" (func $_free)) + (export "___errno_location" (func $___errno_location)) + (export "runPostSets" (func $runPostSets)) + (export "stackAlloc" (func $stackAlloc)) + (export "stackSave" (func $stackSave)) + (export "stackRestore" (func $stackRestore)) + (export "establishStackSpace" (func $establishStackSpace)) + (export "setThrew" (func $setThrew)) + (export "setTempRet0" (func $setTempRet0)) + (export "getTempRet0" (func $getTempRet0)) + (export "dynCall_ii" (func $dynCall_ii)) + (export "dynCall_iiii" (func $dynCall_iiii)) + (export "dynCall_vi" (func $dynCall_vi)) + (export "dynCall_v" (func $dynCall_v)) + (func $stackAlloc (param $0 i32) (result i32) + (local $1 i32) + (set_local $1 + (get_global $STACKTOP) + ) + (set_global $STACKTOP + (i32.add + (get_global $STACKTOP) + (get_local $0) + ) + ) + (set_global $STACKTOP + (i32.and + (i32.add + (get_global $STACKTOP) + (i32.const 15) + ) + (i32.const -16) + ) + ) + (get_local $1) + ) + (func $stackSave (result i32) + (get_global $STACKTOP) + ) + (func $stackRestore (param $0 i32) + (set_global $STACKTOP + (get_local $0) + ) + ) + (func $establishStackSpace (param $0 i32) (param $1 i32) + (set_global $STACKTOP + (get_local $0) + ) + (set_global $STACK_MAX + (get_local $1) + ) + ) + (func $setThrew (param $0 i32) (param $1 i32) + (if + (i32.eqz + (get_global $__THREW__) + ) + (block + (set_global $__THREW__ + (get_local $0) + ) + (set_global $threwValue + (get_local $1) + ) + ) + ) + ) + (func $setTempRet0 (param $0 i32) + (set_global $tempRet0 + (get_local $0) + ) + ) + (func $getTempRet0 (result i32) + (get_global $tempRet0) + ) + (func $_malloc (param $0 i32) (result i32) + (i32.const 0) + ) + (func $_free (param $0 i32) + (nop) + ) + (func $_main (result i32) + (local $0 i32) + (i64.store align=4 + (tee_local $0 + (call $__Znwj + (i32.const 8) + ) + ) + (i64.const 0) + ) + (get_local $0) + ) + (func $___stdio_close (param $0 i32) (result i32) + (local $1 i32) + (local $2 i32) + (set_local $1 + (get_global $STACKTOP) + ) + (set_global $STACKTOP + (i32.add + (get_global $STACKTOP) + (i32.const 16) + ) + ) + (i32.store + (tee_local $2 + (get_local $1) + ) + (i32.load offset=60 + (get_local $0) + ) + ) + (set_local $0 + (call $___syscall_ret + (call $___syscall6 + (i32.const 6) + (get_local $2) + ) + ) + ) + (set_global $STACKTOP + (get_local $1) + ) + (get_local $0) + ) + (func $___stdio_write (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (local $9 i32) + (local $10 i32) + (local $11 i32) + (local $12 i32) + (local $13 i32) + (local $14 i32) + (set_local $7 + (get_global $STACKTOP) + ) + (set_global $STACKTOP + (i32.add + (get_global $STACKTOP) + (i32.const 48) + ) + ) + (set_local $8 + (i32.add + (get_local $7) + (i32.const 16) + ) + ) + (set_local $9 + (get_local $7) + ) + (i32.store + (tee_local $3 + (i32.add + (get_local $7) + (i32.const 32) + ) + ) + (tee_local $5 + (i32.load + (tee_local $6 + (i32.add + (get_local $0) + (i32.const 28) + ) + ) + ) + ) + ) + (i32.store offset=4 + (get_local $3) + (tee_local $4 + (i32.sub + (i32.load + (tee_local $10 + (i32.add + (get_local $0) + (i32.const 20) + ) + ) + ) + (get_local $5) + ) + ) + ) + (i32.store offset=8 + (get_local $3) + (get_local $1) + ) + (i32.store offset=12 + (get_local $3) + (get_local $2) + ) + (set_local $13 + (i32.add + (get_local $0) + (i32.const 60) + ) + ) + (set_local $14 + (i32.add + (get_local $0) + (i32.const 44) + ) + ) + (set_local $1 + (get_local $3) + ) + (set_local $5 + (i32.const 2) + ) + (set_local $11 + (i32.add + (get_local $4) + (get_local $2) + ) + ) + (set_local $0 + (block $jumpthreading$outer$1 i32 + (block $jumpthreading$inner$1 + (block $jumpthreading$inner$0 + (loop $while-in + (br_if $jumpthreading$inner$0 + (i32.eq + (get_local $11) + (tee_local $4 + (if i32 + (i32.load + (i32.const 1140) + ) + (block i32 + (call $_pthread_cleanup_push + (i32.const 1) + (get_local $0) + ) + (i32.store + (get_local $9) + (i32.load + (get_local $13) + ) + ) + (i32.store offset=4 + (get_local $9) + (get_local $1) + ) + (i32.store offset=8 + (get_local $9) + (get_local $5) + ) + (set_local $3 + (call $___syscall_ret + (call $___syscall146 + (i32.const 146) + (get_local $9) + ) + ) + ) + (call $_pthread_cleanup_pop + (i32.const 0) + ) + (get_local $3) + ) + (block i32 + (i32.store + (get_local $8) + (i32.load + (get_local $13) + ) + ) + (i32.store offset=4 + (get_local $8) + (get_local $1) + ) + (i32.store offset=8 + (get_local $8) + (get_local $5) + ) + (call $___syscall_ret + (call $___syscall146 + (i32.const 146) + (get_local $8) + ) + ) + ) + ) + ) + ) + ) + (br_if $jumpthreading$inner$1 + (i32.lt_s + (get_local $4) + (i32.const 0) + ) + ) + (set_local $11 + (i32.sub + (get_local $11) + (get_local $4) + ) + ) + (set_local $1 + (if i32 + (i32.gt_u + (get_local $4) + (tee_local $12 + (i32.load offset=4 + (get_local $1) + ) + ) + ) + (block i32 + (i32.store + (get_local $6) + (tee_local $3 + (i32.load + (get_local $14) + ) + ) + ) + (i32.store + (get_local $10) + (get_local $3) + ) + (set_local $4 + (i32.sub + (get_local $4) + (get_local $12) + ) + ) + (set_local $3 + (i32.add + (get_local $1) + (i32.const 8) + ) + ) + (set_local $5 + (i32.add + (get_local $5) + (i32.const -1) + ) + ) + (i32.load offset=12 + (get_local $1) + ) + ) + (if i32 + (i32.eq + (get_local $5) + (i32.const 2) + ) + (block i32 + (i32.store + (get_local $6) + (i32.add + (i32.load + (get_local $6) + ) + (get_local $4) + ) + ) + (set_local $3 + (get_local $1) + ) + (set_local $5 + (i32.const 2) + ) + (get_local $12) + ) + (block i32 + (set_local $3 + (get_local $1) + ) + (get_local $12) + ) + ) + ) + ) + (i32.store + (get_local $3) + (i32.add + (i32.load + (get_local $3) + ) + (get_local $4) + ) + ) + (i32.store offset=4 + (get_local $3) + (i32.sub + (get_local $1) + (get_local $4) + ) + ) + (set_local $1 + (get_local $3) + ) + (br $while-in) + ) + ) + (i32.store offset=16 + (get_local $0) + (i32.add + (tee_local $1 + (i32.load + (get_local $14) + ) + ) + (i32.load offset=48 + (get_local $0) + ) + ) + ) + (i32.store + (get_local $6) + (tee_local $0 + (get_local $1) + ) + ) + (i32.store + (get_local $10) + (get_local $0) + ) + (br $jumpthreading$outer$1 + (get_local $2) + ) + ) + (i32.store offset=16 + (get_local $0) + (i32.const 0) + ) + (i32.store + (get_local $6) + (i32.const 0) + ) + (i32.store + (get_local $10) + (i32.const 0) + ) + (i32.store + (get_local $0) + (i32.or + (i32.load + (get_local $0) + ) + (i32.const 32) + ) + ) + (select + (i32.const 0) + (i32.sub + (get_local $2) + (i32.load offset=4 + (get_local $1) + ) + ) + (i32.eq + (get_local $5) + (i32.const 2) + ) + ) + ) + ) + (set_global $STACKTOP + (get_local $7) + ) + (get_local $0) + ) + (func $___stdio_seek (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (local $3 i32) + (local $4 i32) + (set_local $4 + (get_global $STACKTOP) + ) + (set_global $STACKTOP + (i32.add + (get_global $STACKTOP) + (i32.const 32) + ) + ) + (i32.store + (tee_local $3 + (get_local $4) + ) + (i32.load offset=60 + (get_local $0) + ) + ) + (i32.store offset=4 + (get_local $3) + (i32.const 0) + ) + (i32.store offset=8 + (get_local $3) + (get_local $1) + ) + (i32.store offset=12 + (get_local $3) + (tee_local $0 + (i32.add + (get_local $4) + (i32.const 20) + ) + ) + ) + (i32.store offset=16 + (get_local $3) + (get_local $2) + ) + (set_local $0 + (if i32 + (i32.lt_s + (call $___syscall_ret + (call $___syscall140 + (i32.const 140) + (get_local $3) + ) + ) + (i32.const 0) + ) + (block i32 + (i32.store + (get_local $0) + (i32.const -1) + ) + (i32.const -1) + ) + (i32.load + (get_local $0) + ) + ) + ) + (set_global $STACKTOP + (get_local $4) + ) + (get_local $0) + ) + (func $___syscall_ret (param $0 i32) (result i32) + (if i32 + (i32.gt_u + (get_local $0) + (i32.const -4096) + ) + (block i32 + (i32.store + (call $___errno_location) + (i32.sub + (i32.const 0) + (get_local $0) + ) + ) + (i32.const -1) + ) + (get_local $0) + ) + ) + (func $___errno_location (result i32) + (if i32 + (i32.load + (i32.const 1140) + ) + (i32.load offset=64 + (call $_pthread_self) + ) + (i32.const 1184) + ) + ) + (func $_cleanup_387 (param $0 i32) + (if + (i32.eqz + (i32.load offset=68 + (get_local $0) + ) + ) + (call $_free + (get_local $0) + ) + ) + ) + (func $___stdout_write (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (set_local $4 + (get_global $STACKTOP) + ) + (set_global $STACKTOP + (i32.add + (get_global $STACKTOP) + (i32.const 80) + ) + ) + (set_local $3 + (get_local $4) + ) + (set_local $5 + (i32.add + (get_local $4) + (i32.const 12) + ) + ) + (i32.store offset=36 + (get_local $0) + (i32.const 3) + ) + (if + (i32.eqz + (i32.and + (i32.load + (get_local $0) + ) + (i32.const 64) + ) + ) + (block + (i32.store + (get_local $3) + (i32.load offset=60 + (get_local $0) + ) + ) + (i32.store offset=4 + (get_local $3) + (i32.const 21505) + ) + (i32.store offset=8 + (get_local $3) + (get_local $5) + ) + (if + (call $___syscall54 + (i32.const 54) + (get_local $3) + ) + (i32.store8 offset=75 + (get_local $0) + (i32.const -1) + ) + ) + ) + ) + (set_local $0 + (call $___stdio_write + (get_local $0) + (get_local $1) + (get_local $2) + ) + ) + (set_global $STACKTOP + (get_local $4) + ) + (get_local $0) + ) + (func $_fflush (param $0 i32) (result i32) + (local $1 i32) + (local $2 i32) + (block $do-once i32 + (if i32 + (get_local $0) + (block i32 + (if + (i32.le_s + (i32.load offset=76 + (get_local $0) + ) + (i32.const -1) + ) + (br $do-once + (call $___fflush_unlocked + (get_local $0) + ) + ) + ) + (set_local $2 + (i32.eqz + (call $_malloc + (get_local $0) + ) + ) + ) + (set_local $1 + (call $___fflush_unlocked + (get_local $0) + ) + ) + (if i32 + (get_local $2) + (get_local $1) + (block i32 + (call $_free + (get_local $0) + ) + (get_local $1) + ) + ) + ) + (block i32 + (set_local $0 + (if i32 + (i32.load + (i32.const 1136) + ) + (call $_fflush + (i32.load + (i32.const 1136) + ) + ) + (i32.const 0) + ) + ) + (call $___lock + (i32.const 1168) + ) + (if + (tee_local $1 + (i32.load + (i32.const 1164) + ) + ) + (loop $while-in + (set_local $2 + (if i32 + (i32.gt_s + (i32.load offset=76 + (get_local $1) + ) + (i32.const -1) + ) + (call $_malloc + (get_local $1) + ) + (i32.const 0) + ) + ) + (set_local $0 + (if i32 + (i32.gt_u + (i32.load offset=20 + (get_local $1) + ) + (i32.load offset=28 + (get_local $1) + ) + ) + (i32.or + (call $___fflush_unlocked + (get_local $1) + ) + (get_local $0) + ) + (get_local $0) + ) + ) + (if + (get_local $2) + (call $_free + (get_local $1) + ) + ) + (br_if $while-in + (tee_local $1 + (i32.load offset=56 + (get_local $1) + ) + ) + ) + ) + ) + (call $___unlock + (i32.const 1168) + ) + (get_local $0) + ) + ) + ) + ) + (func $___fflush_unlocked (param $0 i32) (result i32) + (local $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (block $jumpthreading$outer$0 i32 + (block $jumpthreading$inner$0 + (br_if $jumpthreading$inner$0 + (i32.le_u + (i32.load + (tee_local $1 + (i32.add + (get_local $0) + (i32.const 20) + ) + ) + ) + (i32.load + (tee_local $2 + (i32.add + (get_local $0) + (i32.const 28) + ) + ) + ) + ) + ) + (drop + (call_indirect $FUNCSIG$iiii + (get_local $0) + (i32.const 0) + (i32.const 0) + (i32.add + (i32.and + (i32.load offset=36 + (get_local $0) + ) + (i32.const 3) + ) + (i32.const 2) + ) + ) + ) + (br_if $jumpthreading$inner$0 + (i32.load + (get_local $1) + ) + ) + (br $jumpthreading$outer$0 + (i32.const -1) + ) + ) + (if + (i32.lt_u + (tee_local $4 + (i32.load + (tee_local $3 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + ) + (tee_local $6 + (i32.load + (tee_local $5 + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + ) + ) + ) + (drop + (call_indirect $FUNCSIG$iiii + (get_local $0) + (i32.sub + (get_local $4) + (get_local $6) + ) + (i32.const 1) + (i32.add + (i32.and + (i32.load offset=40 + (get_local $0) + ) + (i32.const 3) + ) + (i32.const 2) + ) + ) + ) + ) + (i32.store offset=16 + (get_local $0) + (i32.const 0) + ) + (i32.store + (get_local $2) + (i32.const 0) + ) + (i32.store + (get_local $1) + (i32.const 0) + ) + (i32.store + (get_local $5) + (i32.const 0) + ) + (i32.store + (get_local $3) + (i32.const 0) + ) + (i32.const 0) + ) + ) + (func $__Znwj (param $0 i32) (result i32) + (local $1 i32) + (set_local $1 + (select + (get_local $0) + (i32.const 1) + (get_local $0) + ) + ) + (loop $while-in + (block $while-out + (br_if $while-out + (tee_local $0 + (call $_malloc + (get_local $1) + ) + ) + ) + (if + (tee_local $0 + (call $__ZSt15get_new_handlerv) + ) + (block + (call_indirect $FUNCSIG$v + (i32.add + (i32.and + (get_local $0) + (i32.const 0) + ) + (i32.const 8) + ) + ) + (br $while-in) + ) + (set_local $0 + (i32.const 0) + ) + ) + ) + ) + (get_local $0) + ) + (func $__ZSt15get_new_handlerv (result i32) + (local $0 i32) + (i32.store + (i32.const 1188) + (i32.add + (tee_local $0 + (i32.load + (i32.const 1188) + ) + ) + (i32.const 0) + ) + ) + (get_local $0) + ) + (func $runPostSets + (nop) + ) + (func $_memset (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (set_local $4 + (i32.add + (get_local $0) + (get_local $2) + ) + ) + (if + (i32.ge_s + (get_local $2) + (i32.const 20) + ) + (block + (set_local $5 + (i32.or + (i32.or + (i32.or + (tee_local $1 + (i32.and + (get_local $1) + (i32.const 255) + ) + ) + (i32.shl + (get_local $1) + (i32.const 8) + ) + ) + (i32.shl + (get_local $1) + (i32.const 16) + ) + ) + (i32.shl + (get_local $1) + (i32.const 24) + ) + ) + ) + (set_local $6 + (i32.and + (get_local $4) + (i32.const -4) + ) + ) + (if + (tee_local $3 + (i32.and + (get_local $0) + (i32.const 3) + ) + ) + (block + (set_local $3 + (i32.sub + (i32.add + (get_local $0) + (i32.const 4) + ) + (get_local $3) + ) + ) + (loop $while-in + (if + (i32.lt_s + (get_local $0) + (get_local $3) + ) + (block + (i32.store8 + (get_local $0) + (get_local $1) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 1) + ) + ) + (br $while-in) + ) + ) + ) + ) + ) + (loop $while-in1 + (if + (i32.lt_s + (get_local $0) + (get_local $6) + ) + (block + (i32.store + (get_local $0) + (get_local $5) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + (br $while-in1) + ) + ) + ) + ) + ) + (loop $while-in3 + (if + (i32.lt_s + (get_local $0) + (get_local $4) + ) + (block + (i32.store8 + (get_local $0) + (get_local $1) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 1) + ) + ) + (br $while-in3) + ) + ) + ) + (i32.sub + (get_local $0) + (get_local $2) + ) + ) + (func $_memcpy (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (local $3 i32) + (if + (i32.ge_s + (get_local $2) + (i32.const 4096) + ) + (return + (call $_emscripten_memcpy_big + (get_local $0) + (get_local $1) + (get_local $2) + ) + ) + ) + (set_local $3 + (get_local $0) + ) + (if + (i32.eq + (i32.and + (get_local $0) + (i32.const 3) + ) + (i32.and + (get_local $1) + (i32.const 3) + ) + ) + (block + (loop $while-in + (block $while-out + (br_if $while-out + (i32.eqz + (i32.and + (get_local $0) + (i32.const 3) + ) + ) + ) + (if + (i32.eqz + (get_local $2) + ) + (return + (get_local $3) + ) + ) + (i32.store8 + (get_local $0) + (i32.load8_s + (get_local $1) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 1) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (set_local $2 + (i32.sub + (get_local $2) + (i32.const 1) + ) + ) + (br $while-in) + ) + ) + (loop $while-in1 + (if + (i32.ge_s + (get_local $2) + (i32.const 4) + ) + (block + (i32.store + (get_local $0) + (i32.load + (get_local $1) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 4) + ) + ) + (set_local $2 + (i32.sub + (get_local $2) + (i32.const 4) + ) + ) + (br $while-in1) + ) + ) + ) + ) + ) + (loop $while-in3 + (if + (i32.gt_s + (get_local $2) + (i32.const 0) + ) + (block + (i32.store8 + (get_local $0) + (i32.load8_s + (get_local $1) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 1) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (set_local $2 + (i32.sub + (get_local $2) + (i32.const 1) + ) + ) + (br $while-in3) + ) + ) + ) + (get_local $3) + ) + (func $_pthread_self (result i32) + (i32.const 0) + ) + (func $dynCall_ii (param $0 i32) (param $1 i32) (result i32) + (call_indirect $FUNCSIG$ii + (get_local $1) + (i32.add + (i32.and + (get_local $0) + (i32.const 1) + ) + (i32.const 0) + ) + ) + ) + (func $dynCall_iiii (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) + (call_indirect $FUNCSIG$iiii + (get_local $1) + (get_local $2) + (get_local $3) + (i32.add + (i32.and + (get_local $0) + (i32.const 3) + ) + (i32.const 2) + ) + ) + ) + (func $dynCall_vi (param $0 i32) (param $1 i32) + (call_indirect $FUNCSIG$vi + (get_local $1) + (i32.add + (i32.and + (get_local $0) + (i32.const 1) + ) + (i32.const 6) + ) + ) + ) + (func $dynCall_v (param $0 i32) + (call_indirect $FUNCSIG$v + (i32.add + (i32.and + (get_local $0) + (i32.const 0) + ) + (i32.const 8) + ) + ) + ) + (func $b0 (param $0 i32) (result i32) + (call $abort + (i32.const 0) + ) + (i32.const 0) + ) + (func $b1 (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (call $abort + (i32.const 1) + ) + (i32.const 0) + ) + (func $b2 (param $0 i32) + (call $abort + (i32.const 2) + ) + ) + (func $b3 + (call $abort + (i32.const 3) + ) + ) +) |