// File: /workspace/github_cpp_makefile_star2_O1/kram[P]kram/./src/vm/vm.cpp
// Function: VM::call(Instruction*, vm::ON)
Value* VM::call(Instruction* ins, vm::ON on) {

	this->env_push();

	// Get the method name or function declaration
	Value* fun = this->name(ins->left[0], on);

	// Result pointer
	Value* res;

	// Function and class methods
	if (fun->type == Type::FUNCTION) {
		// Parse arguments first
		auto arguments = this->run_vector(ins->right);

		// Assign "self" to the parent
		if (on == vm::ON::PUSHED_CLASS) {
			this->name_create("self", this->lib_stack.back());
		}

		// Execute function
		res = fun->exec_method("exec", arguments);

	// Pushed classes (the class has to be fetched from the stack)
	} else if (on == vm::ON::PUSHED_CLASS && fun->type == Type::NAME) {
		Value* top = this->lib_stack.back();

		switch (top->type) {
			case Type::NUMBER:
			case Type::STRING:
			case Type::BOOL:
				res = this->call_builtin(ins, fun);
				break;

			default:
				res = top->exec_method(fun->getString(), this->run_vector(ins->right));
				break;
		}

	// Default action is built in libraries
	} else {
		res = this->call_library(ins);
	}

	this->env_pop();

	return res;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0xe0, %rsp
movl %edx, %ebp
movq %rsi, %r15
movq %rdi, %rbx
callq 0x7b30
movq 0x38(%r15), %rax
movq (%rax), %rsi
movq %rbx, %rdi
movl %ebp, %edx
callq 0x7e00
movq %rax, %r14
movl 0x8(%rax), %eax
cmpl $0x5, %eax
jne 0x91e1
addq $0x50, %r15
leaq 0xc8(%rsp), %r12
movq %r12, %rdi
movq %r15, %rsi
callq 0x450e
leaq 0x50(%rsp), %rdi
movq %rbx, %rsi
movq %r12, %rdx
callq 0x900c
movq 0xc8(%rsp), %rdi
testq %rdi, %rdi
je 0x9117
callq 0x3230
cmpl $0x1, %ebp
jne 0x9166
leaq 0xb8(%rsp), %r15
movq %r15, -0x10(%r15)
movl $0x666c6573, (%r15)     # imm = 0x666C6573
movq $0x4, -0x8(%r15)
movb $0x0, 0x4(%r15)
movq 0x8(%rbx), %rax
movq -0x8(%rax), %rdx
leaq 0xa8(%rsp), %rsi
movq %rbx, %rdi
callq 0x7924
movq 0xa8(%rsp), %rdi
cmpq %r15, %rdi
je 0x9166
callq 0x3230
leaq 0x98(%rsp), %r15
movq %r15, -0x10(%r15)
movl $0x63657865, (%r15)     # imm = 0x63657865
movq $0x4, -0x8(%r15)
movb $0x0, 0x4(%r15)
leaq 0x38(%rsp), %rdi
leaq 0x50(%rsp), %rsi
callq 0xa09c
leaq 0x88(%rsp), %rsi
leaq 0x38(%rsp), %rdx
movq %r14, %rdi
callq 0xd046
movq %rax, %r14
movq 0x38(%rsp), %rdi
testq %rdi, %rdi
je 0x91bc
callq 0x3230
movq 0x88(%rsp), %rdi
cmpq %r15, %rdi
je 0x91ce
callq 0x3230
movq 0x50(%rsp), %rdi
testq %rdi, %rdi
jne 0x9290
jmp 0x9295
cmpl $0x1, %ebp
jne 0x920f
cmpl $0x7, %eax
jne 0x920f
movq 0x8(%rbx), %rax
movq -0x8(%rax), %r12
movl 0x8(%r12), %eax
decl %eax
cmpl $0x2, %eax
ja 0x921f
movq %rbx, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x9346
jmp 0x921a
movq %rbx, %rdi
movq %r15, %rsi
callq 0x95a2
movq %rax, %r14
jmp 0x9295
leaq 0x68(%rsp), %rdi
movq %r14, %rsi
callq 0xd4ba
addq $0x50, %r15
leaq 0x8(%rsp), %rdi
movq %r15, %rsi
callq 0x450e
leaq 0x20(%rsp), %rdi
leaq 0x8(%rsp), %rdx
movq %rbx, %rsi
callq 0x900c
leaq 0x68(%rsp), %rsi
leaq 0x20(%rsp), %rdx
movq %r12, %rdi
callq 0xd046
movq %rax, %r14
movq 0x20(%rsp), %rdi
testq %rdi, %rdi
je 0x9273
callq 0x3230
movq 0x8(%rsp), %rdi
testq %rdi, %rdi
je 0x9282
callq 0x3230
leaq 0x78(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x9295
callq 0x3230
movq %rbx, %rdi
callq 0x7b1c
movq %r14, %rax
addq $0xe0, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
movq 0x20(%rsp), %rdi
testq %rdi, %rdi
je 0x92c7
callq 0x3230
jmp 0x92c7
movq %rax, %rbx
movq 0x8(%rsp), %rdi
testq %rdi, %rdi
je 0x92db
callq 0x3230
jmp 0x92db
movq %rax, %rbx
leaq 0x78(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
jne 0x9338
jmp 0x933d
movq %rax, %rbx
movq 0xa8(%rsp), %rdi
jmp 0x9317
movq %rax, %rbx
movq 0x38(%rsp), %rdi
testq %rdi, %rdi
je 0x930f
callq 0x3230
jmp 0x930f
movq %rax, %rbx
movq 0x88(%rsp), %rdi
cmpq %r15, %rdi
je 0x9321
callq 0x3230
movq 0x50(%rsp), %rdi
jmp 0x9333
movq %rax, %rbx
movq 0xc8(%rsp), %rdi
testq %rdi, %rdi
je 0x933d
callq 0x3230
movq %rbx, %rdi
callq 0x33c0
nop