// File: /workspace/github_cpp_makefile_star2_O3/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 0x7adc
movq 0x38(%r15), %rax
movq (%rax), %rsi
movq %rbx, %rdi
movl %ebp, %edx
callq 0x7dac
movq %rax, %r14
movl 0x8(%rax), %eax
cmpl $0x5, %eax
jne 0x913b
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 0x8f66
movq 0xc8(%rsp), %rdi
testq %rdi, %rdi
je 0x9071
callq 0x3230
cmpl $0x1, %ebp
jne 0x90c0
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 0x78d0
movq 0xa8(%rsp), %rdi
cmpq %r15, %rdi
je 0x90c0
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 0x9fe4
leaq 0x88(%rsp), %rsi
leaq 0x38(%rsp), %rdx
movq %r14, %rdi
callq 0xced6
movq %rax, %r14
movq 0x38(%rsp), %rdi
testq %rdi, %rdi
je 0x9116
callq 0x3230
movq 0x88(%rsp), %rdi
cmpq %r15, %rdi
je 0x9128
callq 0x3230
movq 0x50(%rsp), %rdi
testq %rdi, %rdi
jne 0x91ea
jmp 0x91ef
cmpl $0x1, %ebp
jne 0x9169
cmpl $0x7, %eax
jne 0x9169
movq 0x8(%rbx), %rax
movq -0x8(%rax), %r12
movl 0x8(%r12), %eax
decl %eax
cmpl $0x2, %eax
ja 0x9179
movq %rbx, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x92a0
jmp 0x9174
movq %rbx, %rdi
movq %r15, %rsi
callq 0x94fc
movq %rax, %r14
jmp 0x91ef
leaq 0x68(%rsp), %rdi
movq %r14, %rsi
callq 0xd34a
addq $0x50, %r15
leaq 0x8(%rsp), %rdi
movq %r15, %rsi
callq 0x450e
leaq 0x20(%rsp), %rdi
leaq 0x8(%rsp), %rdx
movq %rbx, %rsi
callq 0x8f66
leaq 0x68(%rsp), %rsi
leaq 0x20(%rsp), %rdx
movq %r12, %rdi
callq 0xced6
movq %rax, %r14
movq 0x20(%rsp), %rdi
testq %rdi, %rdi
je 0x91cd
callq 0x3230
movq 0x8(%rsp), %rdi
testq %rdi, %rdi
je 0x91dc
callq 0x3230
leaq 0x78(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x91ef
callq 0x3230
movq %rbx, %rdi
callq 0x7ac8
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 0x9221
callq 0x3230
jmp 0x9221
movq %rax, %rbx
movq 0x8(%rsp), %rdi
testq %rdi, %rdi
je 0x9235
callq 0x3230
jmp 0x9235
movq %rax, %rbx
leaq 0x78(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
jne 0x9292
jmp 0x9297
movq %rax, %rbx
movq 0xa8(%rsp), %rdi
jmp 0x9271
movq %rax, %rbx
movq 0x38(%rsp), %rdi
testq %rdi, %rdi
je 0x9269
callq 0x3230
jmp 0x9269
movq %rax, %rbx
movq 0x88(%rsp), %rdi
cmpq %r15, %rdi
je 0x927b
callq 0x3230
movq 0x50(%rsp), %rdi
jmp 0x928d
movq %rax, %rbx
movq 0xc8(%rsp), %rdi
testq %rdi, %rdi
je 0x9297
callq 0x3230
movq %rbx, %rdi
callq 0x33c0
nop