// File: lukewagner[P]asmjs2wasm/src/parser.cpp
// Function: parser::parse_asmjs(memory::Pool&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&)
Func&
parser::parse_asmjs(memory::Pool& pool, const string& chars)
{
  // cashew needs to be able to mutate the chars
  vector<char> mutable_chars(chars.begin(), chars.end());

  cashew::Parser<Node*, Builder> parser(pool);
  Node* top_level = parser.parseToplevel(mutable_chars.data());

  List<Node>& top = top_level->as<Block>().stmts;
  if (top.compute_length() != 1 || !top.first().is<Func>())
    throw runtime_error("expecting single top-level asm.js module function");

  Func& func = top.first().as<Func>();
  List<Node>& body = func.body.stmts;
  if (body.empty() || !body.first().is<String>() || !body.first().as<String>().str.equals("use asm"))
    throw runtime_error("expecting single top-level asm.js module function");

  return func;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x130, %rsp            # imm = 0x130
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x10(%rbp), %rdi
callq 0x2190
movq %rax, -0x30(%rbp)
movq -0x10(%rbp), %rdi
callq 0x22f0
movq %rax, -0x38(%rbp)
leaq -0x39(%rbp), %rdi
movq %rdi, -0xa8(%rbp)
callq 0x22c0
movq -0xa8(%rbp), %rcx
movq -0x30(%rbp), %rsi
movq -0x38(%rbp), %rdx
leaq -0x28(%rbp), %rdi
callq 0x3d50
jmp 0x3a47
leaq -0x39(%rbp), %rdi
callq 0x21e0
movq -0x8(%rbp), %rsi
leaq -0x80(%rbp), %rdi
callq 0x3dd0
jmp 0x3a5f
leaq -0x28(%rbp), %rdi
callq 0x3ed0
movq %rax, %rsi
leaq -0x80(%rbp), %rdi
callq 0x3e50
movq %rax, -0xb0(%rbp)
jmp 0x3a7d
movq -0xb0(%rbp), %rax
movq %rax, -0x88(%rbp)
movq -0x88(%rbp), %rdi
callq 0x3ef0
movq %rax, -0xb8(%rbp)
jmp 0x3aa0
movq -0xb8(%rbp), %rax
addq $0x10, %rax
movq %rax, -0x90(%rbp)
movq -0x90(%rbp), %rdi
callq 0x3f40
movl %eax, -0xbc(%rbp)
jmp 0x3ac6
movl -0xbc(%rbp), %eax
cmpl $0x1, %eax
jne 0x3b0a
movq -0x90(%rbp), %rdi
callq 0x3f80
movq %rax, -0xc8(%rbp)
jmp 0x3ae6
movq -0xc8(%rbp), %rdi
callq 0x3fa0
movb %al, -0xc9(%rbp)
jmp 0x3afa
movb -0xc9(%rbp), %al
testb $0x1, %al
jne 0x3ba7
jmp 0x3b0a
movl $0x10, %edi
callq 0x20c0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0xd8(%rbp)
leaq 0x116b8(%rip), %rsi     # 0x151e0
callq 0x2090
jmp 0x3b2f
movq -0xd8(%rbp), %rdi
movq 0x1e4b3(%rip), %rsi     # 0x21ff0
movq 0x1e46c(%rip), %rdx     # 0x21fb0
callq 0x22a0
jmp 0x3d49
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x39(%rbp), %rdi
callq 0x21e0
jmp 0x3d40
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x3d37
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x3d2e
movq -0xd8(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
callq 0x2140
jmp 0x3d2e
movq -0x90(%rbp), %rdi
callq 0x3f80
movq %rax, -0xe0(%rbp)
jmp 0x3bbc
movq -0xe0(%rbp), %rdi
callq 0x3fc0
movq %rax, -0xe8(%rbp)
jmp 0x3bd1
movq -0xe8(%rbp), %rax
movq %rax, -0x98(%rbp)
movq -0x98(%rbp), %rax
movq 0x28(%rax), %rax
addq $0x10, %rax
movq %rax, -0xa0(%rbp)
movq -0xa0(%rbp), %rdi
callq 0x4010
movb %al, -0xe9(%rbp)
jmp 0x3c09
movb -0xe9(%rbp), %al
testb $0x1, %al
jne 0x3ca3
jmp 0x3c19
movq -0xa0(%rbp), %rdi
callq 0x3f80
movq %rax, -0xf8(%rbp)
jmp 0x3c2e
movq -0xf8(%rbp), %rdi
callq 0x4030
movb %al, -0xf9(%rbp)
jmp 0x3c42
movb -0xf9(%rbp), %al
testb $0x1, %al
jne 0x3c4e
jmp 0x3ca3
movq -0xa0(%rbp), %rdi
callq 0x3f80
movq %rax, -0x108(%rbp)
jmp 0x3c63
movq -0x108(%rbp), %rdi
callq 0x4050
movq %rax, -0x110(%rbp)
jmp 0x3c78
movq -0x110(%rbp), %rdi
addq $0x10, %rdi
leaq 0x11588(%rip), %rsi     # 0x15212
callq 0x40a0
movb %al, -0x111(%rbp)
jmp 0x3c97
movb -0x111(%rbp), %al
testb $0x1, %al
jne 0x3cfe
jmp 0x3ca3
movl $0x10, %edi
callq 0x20c0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x120(%rbp)
leaq 0x1151f(%rip), %rsi     # 0x151e0
callq 0x2090
jmp 0x3cc8
movq -0x120(%rbp), %rdi
movq 0x1e31a(%rip), %rsi     # 0x21ff0
movq 0x1e2d3(%rip), %rdx     # 0x21fb0
callq 0x22a0
jmp 0x3d49
movq -0x120(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
callq 0x2140
jmp 0x3d2e
movq -0x98(%rbp), %rax
movq %rax, -0x128(%rbp)
leaq -0x80(%rbp), %rdi
callq 0x40d0
leaq -0x28(%rbp), %rdi
callq 0x40f0
movq -0x128(%rbp), %rax
addq $0x130, %rsp            # imm = 0x130
popq %rbp
retq
leaq -0x80(%rbp), %rdi
callq 0x40d0
leaq -0x28(%rbp), %rdi
callq 0x40f0
movq -0x48(%rbp), %rdi
callq 0x22b0
nopl (%rax)