// File: cphinton42[P]hinton-language/src/scope.cpp
// Function: create_scope_metadata(Scoping_Context*, Function_AST*, unsigned long, Hashed_Scope*, unsigned long, AST*)
internal
void create_scope_metadata(Scoping_Context *ctx, Function_AST *func, u64 type, Hashed_Scope *scope, u64 scope_index, AST *ast)
{
    if(!ast)
    {
        return;
    }
    
    switch(ast->type)
    {
        case AST_Type::decl_ast: {
            Decl_AST *decl_ast = static_cast<Decl_AST*>(ast);
            create_scope_metadata(ctx, func, IDENT_DECL, scope, scope_index, &decl_ast->ident);
            create_scope_metadata(ctx, func, IDENT_REFERENCE, scope, scope_index, decl_ast->decl_type);
            create_scope_metadata(ctx, func, IDENT_REFERENCE, scope, scope_index, decl_ast->expr);
        } break;
        case AST_Type::block_ast: {
            Block_AST *block_ast = static_cast<Block_AST*>(ast);
            
            Hashed_Scope *block_scope = pool_alloc(Hashed_Scope, ctx->ast_pool);
            init_hashed_scope(block_scope, scope, scope_index, 8);
            
            for(u64 i = 0; i < block_ast->statements.count; ++i)
            {
                create_scope_metadata(ctx, func, IDENT_REFERENCE, block_scope, i, block_ast->statements[i]);
            }
        } break;
        case AST_Type::while_ast: {
            While_AST *while_ast = static_cast<While_AST*>(ast);
            create_scope_metadata(ctx, func, IDENT_REFERENCE, scope, scope_index, while_ast->guard);
            create_scope_metadata(ctx, func, IDENT_DECL, scope, scope_index, while_ast->body);
        } break;
        case AST_Type::for_ast: {
            For_AST *for_ast = static_cast<For_AST*>(ast);
            
            Hashed_Scope *for_scope = pool_alloc(Hashed_Scope, ctx->ast_pool);
            init_hashed_scope(for_scope, scope, scope_index, 4);
            
            create_scope_metadata(ctx, func, IDENT_LOOP_VAR, for_scope, 0, for_ast->induction_var);
            
            if(for_ast->flags & FOR_FLAG_OVER_ARRAY)
            {
                create_scope_metadata(ctx, func, IDENT_LOOP_VAR, for_scope, 0, for_ast->index_var);
                create_scope_metadata(ctx, func, IDENT_REFERENCE, scope, scope_index, for_ast->array_expr);
            }
            else
            {
                create_scope_metadata(ctx, func, IDENT_REFERENCE, scope, scope_index, for_ast->low_expr);
                create_scope_metadata(ctx, func, IDENT_REFERENCE, scope, scope_index, for_ast->high_expr);
            }
            create_scope_metadata(ctx, func, IDENT_REFERENCE, for_scope, 1, for_ast->body);
        } break;
        case AST_Type::if_ast: {
            If_AST *if_ast = static_cast<If_AST*>(ast);
            create_scope_metadata(ctx, func, IDENT_REFERENCE, scope, scope_index, if_ast->guard);
            create_scope_metadata(ctx, func, IDENT_REFERENCE, scope, scope_index, if_ast->then_block);
            create_scope_metadata(ctx, func, IDENT_REFERENCE, scope, scope_index, if_ast->else_block);
        } break;
        case AST_Type::assign_ast: {
            Assign_AST *assign_ast = static_cast<Assign_AST*>(ast);
            create_scope_metadata(ctx, func, IDENT_REFERENCE, scope, scope_index, assign_ast->lhs);
            create_scope_metadata(ctx, func, IDENT_REFERENCE, scope, scope_index, assign_ast->rhs);
        } break;
        case AST_Type::return_ast: {
            Return_AST *return_ast = static_cast<Return_AST*>(ast);
            return_ast->function = func;
            create_scope_metadata(ctx, func, IDENT_REFERENCE, scope, scope_index, return_ast->expr);
        } break;
        case AST_Type::ident_ast: {
            Ident_AST *ident_ast = static_cast<Ident_AST*>(ast);
            
            String str = ident_ast->ident;
            Atom atom = atomize_string(ctx->atom_table, str);
            
            ident_ast->atom = atom;
            ident_ast->tagged_expr_ptr = type; // need to know this
            ident_ast->scope_index = scope_index;
            ident_ast->scope = scope;
            
            if(type != IDENT_REFERENCE)
            {
                Scope_Entry entry;
                entry.key = atom;
                entry.index = scope_index;
                entry.definition = ident_ast;
                bool success = scope_insert(scope, entry);
                if(!success)
                {
                    // TODO: better error reporting
                    Expr_AST *prev = scope_find(scope, atom, scope_index);
                    assert(prev);
                    print_err("Error: %d:%d: Redeclared identifier '%.*s'\nPrevious declaration at %d:%d\n", ident_ast->line_number, ident_ast->line_offset, str.count, str.data, prev->line_number, prev->line_offset);
                    ctx->success = false;
                }
            }
        } break;
        case AST_Type::function_type_ast: {
            Function_Type_AST *function_type_ast = static_cast<Function_Type_AST*>(ast);
            for(u64 i = 0; i < function_type_ast->parameter_types.count; ++i)
            {
                create_scope_metadata(ctx, func, IDENT_REFERENCE, scope, scope_index, function_type_ast->parameter_types[i]);
            }
            for(u64 i = 0; i < function_type_ast->return_types.count; ++i)
            {
                create_scope_metadata(ctx, func, IDENT_REFERENCE, scope, scope_index, function_type_ast->return_types[i]);
            }
        } break;
        case AST_Type::function_ast: {
            Function_AST *function_ast = static_cast<Function_AST*>(ast);
            
            Hashed_Scope *func_scope = pool_alloc(Hashed_Scope, ctx->ast_pool);
            init_hashed_scope(func_scope, scope, scope_index, 8);
            
            create_scope_metadata(ctx, function_ast, IDENT_REFERENCE, func_scope, 0, function_ast->prototype);
            
            for(u64 i = 0; i < function_ast->param_names.count; ++i)
            {
                create_scope_metadata(ctx, function_ast, IDENT_PARAM, func_scope, 0, function_ast->param_names[i]);
            }
            for(u64 i = 0; i < function_ast->default_values.count; ++i)
            {
                create_scope_metadata(ctx, function_ast, IDENT_REFERENCE, func_scope, 1, function_ast->default_values[i]);
            }
            create_scope_metadata(ctx, function_ast, IDENT_REFERENCE, func_scope, 2, function_ast->block);
        } break;
        case AST_Type::function_call_ast: {
            Function_Call_AST *function_call_ast = static_cast<Function_Call_AST*>(ast);
            
            create_scope_metadata(ctx, func, IDENT_REFERENCE, scope, scope_index, function_call_ast->function);
            
            for(u64 i = 0; i < function_call_ast->args.count; ++i)
            {
                create_scope_metadata(ctx, func, IDENT_REFERENCE, scope, scope_index, function_call_ast->args[i]);
            }
        } break;
        case AST_Type::access_ast: {
            Access_AST *access_ast = static_cast<Access_AST*>(ast);
            
            String str = access_ast->ident;
            Atom atom = atomize_string(ctx->atom_table, str);
            access_ast->atom = atom;
            access_ast->expr = nullptr;
            create_scope_metadata(ctx, func, IDENT_REFERENCE, scope, scope_index, access_ast->lhs);
        } break;
        case AST_Type::binary_operator_ast: {
            Binary_Operator_AST *binop_ast = static_cast<Binary_Operator_AST*>(ast);
            create_scope_metadata(ctx, func, IDENT_REFERENCE, scope, scope_index, binop_ast->lhs);
            create_scope_metadata(ctx, func, IDENT_REFERENCE, scope, scope_index, binop_ast->rhs);
        } break;
        case AST_Type::enum_ast: {
            Enum_AST *enum_ast = static_cast<Enum_AST*>(ast);
            
            Hashed_Scope *values_scope = pool_alloc(Hashed_Scope, ctx->ast_pool);
            init_hashed_scope(values_scope, scope, scope_index, 8);
            
            for(u64 i = 0; i < enum_ast->values.count; ++i)
            {
                // TODO: is IDENT_DECL best for this?
                create_scope_metadata(ctx, func, IDENT_REFERENCE, values_scope, 0, enum_ast->values[i]);
            }
            enum_ast->scope = values_scope;
        } break;
        case AST_Type::struct_ast: {
            Struct_AST *struct_ast = static_cast<Struct_AST*>(ast);
            
            Hashed_Scope *constants_scope = pool_alloc(Hashed_Scope, ctx->ast_pool);
            init_hashed_scope(constants_scope, scope, scope_index, 8);
            Hashed_Scope *fields_scope = pool_alloc(Hashed_Scope, ctx->ast_pool);
            init_hashed_scope(fields_scope, constants_scope, 0, 8);
            
            for(u64 i = 0; i < struct_ast->constants.count; ++i)
            {
                create_scope_metadata(ctx, func, IDENT_DECL, constants_scope, 0, struct_ast->constants[i]);
            }
            for(u64 i = 0; i < struct_ast->fields.count; ++i)
            {
                create_scope_metadata(ctx, func, IDENT_FIELD, fields_scope, 0, struct_ast->fields[i]);
            }
            struct_ast->constant_scope = constants_scope;
            struct_ast->field_scope = fields_scope;
        } break;
        case AST_Type::unary_ast: {
            Unary_Operator_AST *unop_ast = static_cast<Unary_Operator_AST*>(ast);
            create_scope_metadata(ctx, func, IDENT_REFERENCE, scope, scope_index, unop_ast->operand);
        } break;
        case AST_Type::number_ast:
        case AST_Type::primitive_ast:
        case AST_Type::string_ast:
        case AST_Type::bool_ast: {
            // Do nothing
        } break;
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x2e0, %rsp            # imm = 0x2E0
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movq %r9, -0x30(%rbp)
cmpq $0x0, -0x30(%rbp)
jne 0xd75f
jmp 0xe517
movq -0x30(%rbp), %rax
movzwl (%rax), %eax
movq %rax, -0x1c8(%rbp)
subq $0x13, %rax
ja 0xe517
movq -0x1c8(%rbp), %rax
leaq 0xbcb3(%rip), %rcx      # 0x19438
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x30(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x20(%rbp), %rcx
movq -0x28(%rbp), %r8
movq -0x38(%rbp), %r9
addq $0x10, %r9
movl $0x2, %edx
callq 0xd730
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x20(%rbp), %rcx
movq -0x28(%rbp), %r8
movq -0x38(%rbp), %rax
movq 0x50(%rax), %r9
movl $0x1, %edx
callq 0xd730
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x20(%rbp), %rcx
movq -0x28(%rbp), %r8
movq -0x38(%rbp), %rax
movq 0x58(%rax), %r9
movl $0x1, %edx
callq 0xd730
jmp 0xe517
movq -0x30(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rdi
movl $0x30, %esi
callq 0xcd80
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq -0x28(%rbp), %rdx
movl $0x8, %ecx
callq 0xd380
movq $0x0, -0x50(%rbp)
movq -0x50(%rbp), %rax
movq -0x40(%rbp), %rcx
cmpq 0x10(%rcx), %rax
jae 0xd8c2
movq -0x8(%rbp), %rax
movq %rax, -0x1e8(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x1e0(%rbp)
movq -0x48(%rbp), %rax
movq %rax, -0x1d8(%rbp)
movq -0x50(%rbp), %rax
movq %rax, -0x1d0(%rbp)
movq -0x40(%rbp), %rdi
addq $0x10, %rdi
movq -0x50(%rbp), %rsi
callq 0x16fe0
movq -0x1e8(%rbp), %rdi
movq -0x1e0(%rbp), %rsi
movq -0x1d8(%rbp), %rcx
movq -0x1d0(%rbp), %r8
movq (%rax), %r9
movl $0x1, %edx
callq 0xd730
movq -0x50(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x50(%rbp)
jmp 0xd83d
jmp 0xe517
movq -0x30(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x20(%rbp), %rcx
movq -0x28(%rbp), %r8
movq -0x58(%rbp), %rax
movq 0x10(%rax), %r9
movl $0x1, %edx
callq 0xd730
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x20(%rbp), %rcx
movq -0x28(%rbp), %r8
movq -0x58(%rbp), %rax
movq 0x18(%rax), %r9
movl $0x2, %edx
callq 0xd730
jmp 0xe517
movq -0x30(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rdi
movl $0x30, %esi
callq 0xcd80
movq %rax, -0x68(%rbp)
movq -0x68(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq -0x28(%rbp), %rdx
movl $0x4, %ecx
callq 0xd380
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x68(%rbp), %rcx
movq -0x60(%rbp), %rax
movq 0x10(%rax), %r9
movl $0x4, %edx
xorl %eax, %eax
movl %eax, %r8d
callq 0xd730
movq -0x60(%rbp), %rax
movzwl 0x2(%rax), %eax
andl $0x8, %eax
cmpl $0x0, %eax
je 0xd9c6
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x68(%rbp), %rcx
movq -0x60(%rbp), %rax
movq 0x18(%rax), %r9
movl $0x4, %edx
xorl %eax, %eax
movl %eax, %r8d
callq 0xd730
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x20(%rbp), %rcx
movq -0x28(%rbp), %r8
movq -0x60(%rbp), %rax
movq 0x20(%rax), %r9
movl $0x1, %edx
callq 0xd730
jmp 0xda0a
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x20(%rbp), %rcx
movq -0x28(%rbp), %r8
movq -0x60(%rbp), %rax
movq 0x18(%rax), %r9
movl $0x1, %edx
callq 0xd730
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x20(%rbp), %rcx
movq -0x28(%rbp), %r8
movq -0x60(%rbp), %rax
movq 0x20(%rax), %r9
movl $0x1, %edx
callq 0xd730
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x68(%rbp), %rcx
movq -0x60(%rbp), %rax
movq 0x28(%rax), %r9
movl $0x1, %r8d
movq %r8, %rdx
callq 0xd730
jmp 0xe517
movq -0x30(%rbp), %rax
movq %rax, -0x70(%rbp)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x20(%rbp), %rcx
movq -0x28(%rbp), %r8
movq -0x70(%rbp), %rax
movq 0x10(%rax), %r9
movl $0x1, %edx
callq 0xd730
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x20(%rbp), %rcx
movq -0x28(%rbp), %r8
movq -0x70(%rbp), %rax
movq 0x18(%rax), %r9
movl $0x1, %edx
callq 0xd730
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x20(%rbp), %rcx
movq -0x28(%rbp), %r8
movq -0x70(%rbp), %rax
movq 0x20(%rax), %r9
movl $0x1, %edx
callq 0xd730
jmp 0xe517
movq -0x30(%rbp), %rax
movq %rax, -0x78(%rbp)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x20(%rbp), %rcx
movq -0x28(%rbp), %r8
movq -0x78(%rbp), %rax
movq 0x18(%rax), %r9
movl $0x1, %edx
callq 0xd730
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x20(%rbp), %rcx
movq -0x28(%rbp), %r8
movq -0x78(%rbp), %rax
movq 0x20(%rax), %r9
movl $0x1, %edx
callq 0xd730
jmp 0xe517
movq -0x30(%rbp), %rax
movq %rax, -0x80(%rbp)
movq -0x10(%rbp), %rcx
movq -0x80(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x20(%rbp), %rcx
movq -0x28(%rbp), %r8
movq -0x80(%rbp), %rax
movq 0x18(%rax), %r9
movl $0x1, %edx
callq 0xd730
jmp 0xe517
movq -0x30(%rbp), %rax
movq %rax, -0x88(%rbp)
movq -0x88(%rbp), %rax
movq 0x20(%rax), %rcx
movq %rcx, -0x98(%rbp)
movq 0x28(%rax), %rax
movq %rax, -0x90(%rbp)
movq -0x8(%rbp), %rax
movq (%rax), %rdi
movq -0x98(%rbp), %rax
movq %rax, -0xb0(%rbp)
movq -0x90(%rbp), %rax
movq %rax, -0xa8(%rbp)
movq -0xb0(%rbp), %rsi
movq -0xa8(%rbp), %rdx
callq 0xd5f0
movq %rax, -0xa0(%rbp)
movq -0x88(%rbp), %rax
movq -0xa0(%rbp), %rcx
movq %rcx, 0x20(%rax)
movq -0x18(%rbp), %rcx
movq -0x88(%rbp), %rax
movq %rcx, 0x28(%rax)
movq -0x28(%rbp), %rcx
movq -0x88(%rbp), %rax
movq %rcx, 0x30(%rax)
movq -0x20(%rbp), %rcx
movq -0x88(%rbp), %rax
movq %rcx, 0x38(%rax)
cmpq $0x1, -0x18(%rbp)
je 0xdd19
movq -0xa0(%rbp), %rax
movq %rax, -0xc8(%rbp)
movq -0x28(%rbp), %rax
movq %rax, -0xc0(%rbp)
movq -0x88(%rbp), %rax
movq %rax, -0xb8(%rbp)
movq -0x20(%rbp), %rdi
movq -0xc8(%rbp), %rax
movq %rax, -0xe8(%rbp)
movq -0xc0(%rbp), %rax
movq %rax, -0xe0(%rbp)
movq -0xb8(%rbp), %rax
movq %rax, -0xd8(%rbp)
leaq -0xe8(%rbp), %rax
movq (%rax), %rcx
movq %rcx, (%rsp)
movq 0x8(%rax), %rcx
movq %rcx, 0x8(%rsp)
movq 0x10(%rax), %rax
movq %rax, 0x10(%rsp)
callq 0xd3d0
andb $0x1, %al
movb %al, -0xc9(%rbp)
testb $0x1, -0xc9(%rbp)
jne 0xdd17
movq -0x20(%rbp), %rdi
movq -0xa0(%rbp), %rax
movq %rax, -0xf8(%rbp)
movq -0x28(%rbp), %rdx
movq -0xf8(%rbp), %rsi
movl $0x1, %ecx
callq 0xd4d0
movq %rax, -0xf0(%rbp)
cmpq $0x0, -0xf0(%rbp)
je 0xdca8
jmp 0xdcc7
leaq 0xd609(%rip), %rdi      # 0x1b2b8
leaq 0xc828(%rip), %rsi      # 0x1a4de
movl $0xbe, %edx
leaq 0xd5fb(%rip), %rcx      # 0x1b2bd
callq 0x3080
movq -0x88(%rbp), %rax
movl 0x8(%rax), %esi
movq -0x88(%rbp), %rax
movl 0xc(%rax), %edx
movq -0x98(%rbp), %rcx
movq -0x90(%rbp), %r8
movq -0xf0(%rbp), %rax
movl 0x8(%rax), %r9d
movq -0xf0(%rbp), %rax
movl 0xc(%rax), %eax
leaq 0xd617(%rip), %rdi      # 0x1b31c
movl %eax, (%rsp)
movb $0x0, %al
callq 0x4990
movq -0x8(%rbp), %rax
movb $0x0, 0x10(%rax)
jmp 0xdd19
jmp 0xe517
movq -0x30(%rbp), %rax
movq %rax, -0x100(%rbp)
movq $0x0, -0x108(%rbp)
movq -0x108(%rbp), %rax
movq -0x100(%rbp), %rcx
cmpq 0x20(%rcx), %rax
jae 0xddcf
movq -0x8(%rbp), %rax
movq %rax, -0x208(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x200(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x1f8(%rbp)
movq -0x28(%rbp), %rax
movq %rax, -0x1f0(%rbp)
movq -0x100(%rbp), %rdi
addq $0x20, %rdi
movq -0x108(%rbp), %rsi
callq 0x17050
movq -0x208(%rbp), %rdi
movq -0x200(%rbp), %rsi
movq -0x1f8(%rbp), %rcx
movq -0x1f0(%rbp), %r8
movq (%rax), %r9
movl $0x1, %edx
callq 0xd730
movq -0x108(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x108(%rbp)
jmp 0xdd34
movq $0x0, -0x110(%rbp)
movq -0x110(%rbp), %rax
movq -0x100(%rbp), %rcx
cmpq 0x30(%rcx), %rax
jae 0xde75
movq -0x8(%rbp), %rax
movq %rax, -0x228(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x220(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x218(%rbp)
movq -0x28(%rbp), %rax
movq %rax, -0x210(%rbp)
movq -0x100(%rbp), %rdi
addq $0x30, %rdi
movq -0x110(%rbp), %rsi
callq 0x17050
movq -0x228(%rbp), %rdi
movq -0x220(%rbp), %rsi
movq -0x218(%rbp), %rcx
movq -0x210(%rbp), %r8
movq (%rax), %r9
movl $0x1, %edx
callq 0xd730
movq -0x110(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x110(%rbp)
jmp 0xddda
jmp 0xe517
movq -0x30(%rbp), %rax
movq %rax, -0x118(%rbp)
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rdi
movl $0x30, %esi
callq 0xcd80
movq %rax, -0x120(%rbp)
movq -0x120(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq -0x28(%rbp), %rdx
movl $0x8, %ecx
callq 0xd380
movq -0x8(%rbp), %rdi
movq -0x118(%rbp), %rsi
movq -0x120(%rbp), %rcx
movq -0x118(%rbp), %rax
movq 0x20(%rax), %r9
movl $0x1, %edx
xorl %eax, %eax
movl %eax, %r8d
callq 0xd730
movq $0x0, -0x128(%rbp)
movq -0x128(%rbp), %rax
movq -0x118(%rbp), %rcx
cmpq 0x28(%rcx), %rax
jae 0xdf7e
movq -0x8(%rbp), %rax
movq %rax, -0x240(%rbp)
movq -0x118(%rbp), %rax
movq %rax, -0x238(%rbp)
movq -0x120(%rbp), %rax
movq %rax, -0x230(%rbp)
movq -0x118(%rbp), %rdi
addq $0x28, %rdi
movq -0x128(%rbp), %rsi
callq 0x172d0
movq -0x240(%rbp), %rdi
movq -0x238(%rbp), %rsi
movq -0x230(%rbp), %rcx
movq (%rax), %r9
movl $0x5, %edx
xorl %eax, %eax
movl %eax, %r8d
callq 0xd730
movq -0x128(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x128(%rbp)
jmp 0xdeee
movq $0x0, -0x130(%rbp)
movq -0x130(%rbp), %rax
movq -0x118(%rbp), %rcx
cmpq 0x38(%rcx), %rax
jae 0xe018
movq -0x8(%rbp), %rax
movq %rax, -0x258(%rbp)
movq -0x118(%rbp), %rax
movq %rax, -0x250(%rbp)
movq -0x120(%rbp), %rax
movq %rax, -0x248(%rbp)
movq -0x118(%rbp), %rdi
addq $0x38, %rdi
movq -0x130(%rbp), %rsi
callq 0x17050
movq -0x258(%rbp), %rdi
movq -0x250(%rbp), %rsi
movq -0x248(%rbp), %rcx
movq (%rax), %r9
movl $0x1, %r8d
movq %r8, %rdx
callq 0xd730
movq -0x130(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x130(%rbp)
jmp 0xdf89
movq -0x8(%rbp), %rdi
movq -0x118(%rbp), %rsi
movq -0x120(%rbp), %rcx
movq -0x118(%rbp), %rax
movq 0x48(%rax), %r9
movl $0x1, %edx
movl $0x2, %r8d
callq 0xd730
jmp 0xe517
movq -0x30(%rbp), %rax
movq %rax, -0x138(%rbp)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x20(%rbp), %rcx
movq -0x28(%rbp), %r8
movq -0x138(%rbp), %rax
movq 0x20(%rax), %r9
movl $0x1, %edx
callq 0xd730
movq $0x0, -0x140(%rbp)
movq -0x140(%rbp), %rax
movq -0x138(%rbp), %rcx
cmpq 0x28(%rcx), %rax
jae 0xe120
movq -0x8(%rbp), %rax
movq %rax, -0x278(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x270(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x268(%rbp)
movq -0x28(%rbp), %rax
movq %rax, -0x260(%rbp)
movq -0x138(%rbp), %rdi
addq $0x28, %rdi
movq -0x140(%rbp), %rsi
callq 0x17050
movq -0x278(%rbp), %rdi
movq -0x270(%rbp), %rsi
movq -0x268(%rbp), %rcx
movq -0x260(%rbp), %r8
movq (%rax), %r9
movl $0x1, %edx
callq 0xd730
movq -0x140(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x140(%rbp)
jmp 0xe085
jmp 0xe517
movq -0x30(%rbp), %rax
movq %rax, -0x148(%rbp)
movq -0x148(%rbp), %rax
movq 0x28(%rax), %rcx
movq %rcx, -0x158(%rbp)
movq 0x30(%rax), %rax
movq %rax, -0x150(%rbp)
movq -0x8(%rbp), %rax
movq (%rax), %rdi
movq -0x158(%rbp), %rax
movq %rax, -0x170(%rbp)
movq -0x150(%rbp), %rax
movq %rax, -0x168(%rbp)
movq -0x170(%rbp), %rsi
movq -0x168(%rbp), %rdx
callq 0xd5f0
movq %rax, -0x160(%rbp)
movq -0x148(%rbp), %rax
movq -0x160(%rbp), %rcx
movq %rcx, 0x28(%rax)
movq -0x148(%rbp), %rax
movq $0x0, 0x30(%rax)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x20(%rbp), %rcx
movq -0x28(%rbp), %r8
movq -0x148(%rbp), %rax
movq 0x20(%rax), %r9
movl $0x1, %edx
callq 0xd730
jmp 0xe517
movq -0x30(%rbp), %rax
movq %rax, -0x178(%rbp)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x20(%rbp), %rcx
movq -0x28(%rbp), %r8
movq -0x178(%rbp), %rax
movq 0x28(%rax), %r9
movl $0x1, %edx
callq 0xd730
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x20(%rbp), %rcx
movq -0x28(%rbp), %r8
movq -0x178(%rbp), %rax
movq 0x30(%rax), %r9
movl $0x1, %edx
callq 0xd730
jmp 0xe517
movq -0x30(%rbp), %rax
movq %rax, -0x180(%rbp)
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rdi
movl $0x30, %esi
callq 0xcd80
movq %rax, -0x188(%rbp)
movq -0x188(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq -0x28(%rbp), %rdx
movl $0x8, %ecx
callq 0xd380
movq $0x0, -0x190(%rbp)
movq -0x190(%rbp), %rax
movq -0x180(%rbp), %rcx
cmpq 0x20(%rcx), %rax
jae 0xe304
movq -0x8(%rbp), %rax
movq %rax, -0x290(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x288(%rbp)
movq -0x188(%rbp), %rax
movq %rax, -0x280(%rbp)
movq -0x180(%rbp), %rdi
addq $0x20, %rdi
movq -0x190(%rbp), %rsi
callq 0x16fb0
movq -0x290(%rbp), %rdi
movq -0x288(%rbp), %rsi
movq -0x280(%rbp), %rcx
movq (%rax), %r9
movl $0x1, %edx
xorl %eax, %eax
movl %eax, %r8d
callq 0xd730
movq -0x190(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x190(%rbp)
jmp 0xe277
movq -0x188(%rbp), %rcx
movq -0x180(%rbp), %rax
movq %rcx, 0x30(%rax)
jmp 0xe517
movq -0x30(%rbp), %rax
movq %rax, -0x198(%rbp)
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rdi
movl $0x30, %esi
callq 0xcd80
movq %rax, -0x1a0(%rbp)
movq -0x1a0(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq -0x28(%rbp), %rdx
movl $0x8, %ecx
callq 0xd380
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rdi
movl $0x30, %esi
callq 0xcd80
movq %rax, -0x1a8(%rbp)
movq -0x1a8(%rbp), %rdi
movq -0x1a0(%rbp), %rsi
xorl %eax, %eax
movl %eax, %edx
movl $0x8, %ecx
callq 0xd380
movq $0x0, -0x1b0(%rbp)
movq -0x1b0(%rbp), %rax
movq -0x198(%rbp), %rcx
cmpq 0x20(%rcx), %rax
jae 0xe425
movq -0x8(%rbp), %rax
movq %rax, -0x2a8(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x2a0(%rbp)
movq -0x1a0(%rbp), %rax
movq %rax, -0x298(%rbp)
movq -0x198(%rbp), %rdi
addq $0x20, %rdi
movq -0x1b0(%rbp), %rsi
callq 0x16fb0
movq -0x2a8(%rbp), %rdi
movq -0x2a0(%rbp), %rsi
movq -0x298(%rbp), %rcx
movq (%rax), %r9
movl $0x2, %edx
xorl %eax, %eax
movl %eax, %r8d
callq 0xd730
movq -0x1b0(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x1b0(%rbp)
jmp 0xe398
movq $0x0, -0x1b8(%rbp)
movq -0x1b8(%rbp), %rax
movq -0x198(%rbp), %rcx
cmpq 0x30(%rcx), %rax
jae 0xe4bd
movq -0x8(%rbp), %rax
movq %rax, -0x2c0(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x2b8(%rbp)
movq -0x1a8(%rbp), %rax
movq %rax, -0x2b0(%rbp)
movq -0x198(%rbp), %rdi
addq $0x30, %rdi
movq -0x1b8(%rbp), %rsi
callq 0x16fb0
movq -0x2c0(%rbp), %rdi
movq -0x2b8(%rbp), %rsi
movq -0x2b0(%rbp), %rcx
movq (%rax), %r9
movl $0x3, %edx
xorl %eax, %eax
movl %eax, %r8d
callq 0xd730
movq -0x1b8(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x1b8(%rbp)
jmp 0xe430
movq -0x1a0(%rbp), %rcx
movq -0x198(%rbp), %rax
movq %rcx, 0x40(%rax)
movq -0x1a8(%rbp), %rcx
movq -0x198(%rbp), %rax
movq %rcx, 0x48(%rax)
jmp 0xe517
movq -0x30(%rbp), %rax
movq %rax, -0x1c0(%rbp)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x20(%rbp), %rcx
movq -0x28(%rbp), %r8
movq -0x1c0(%rbp), %rax
movq 0x28(%rax), %r9
movl $0x1, %edx
callq 0xd730
jmp 0xe517
jmp 0xe517
addq $0x2e0, %rsp            # imm = 0x2E0
popq %rbp
retq