// File: kram[P]kram/./src/vm/libraries/user/function.h
// Function: Function::exec(Value*, std::vector<Value*, std::allocator<Value*>>)
static Value* exec(Value* self, std::vector<Value*> arguments) {
		Function* fn = static_cast<Function*>(self);

		if (arguments.size() < fn->required_parameter_count) {
			std::cout << "Got fewer arguments than the required count\n";
			exit(1);
		}

		// Assign function parameters as variables
		size_t key = 0;
		for (Instruction* param : fn->parameters) {

			if (arguments.size() > key) {

				// Caller defined value
				fn->vm->name_create(param->name, arguments[key]);

			} else if (param->right.size() == 1) {

				// Use default value
				fn->vm->name_create(param->name, fn->vm->run(param->right[0]));

			} else {
				std::cout << "No value for parameter '" << param->name << "'\n";
				exit(1);
			}

			++key;
		}

		fn->vm->in_function_push();
		auto res = fn->vm->run(fn->content);
		fn->vm->in_function_pop();

		return res;
	}

// Assembly:
subq $0xc8, %rsp
movq %rsi, 0x48(%rsp)
movq %rdi, %rax
movq 0x48(%rsp), %rdi
movq %rdi, 0x50(%rsp)
movq %rax, 0xc0(%rsp)
movq %rdi, 0xb8(%rsp)
movq 0xc0(%rsp), %rax
movq %rax, 0xb0(%rsp)
callq 0x16fc0
movq 0xb0(%rsp), %rcx
cmpq 0x40(%rcx), %rax
jae 0x16d49
movq 0x232a5(%rip), %rdi     # 0x39fd8
leaq 0x14a64(%rip), %rsi     # 0x2b79e
callq 0x32d0
movl $0x1, %edi
callq 0x3330
movq $0x0, 0xa8(%rsp)
movq 0xb0(%rsp), %rax
addq $0x28, %rax
movq %rax, 0xa0(%rsp)
movq 0xa0(%rsp), %rdi
callq 0x4240
movq %rax, 0x98(%rsp)
movq 0xa0(%rsp), %rdi
callq 0x4270
movq %rax, 0x90(%rsp)
leaq 0x98(%rsp), %rdi
leaq 0x90(%rsp), %rsi
callq 0x42a0
testb $0x1, %al
jne 0x16db1
jmp 0x16f10
leaq 0x98(%rsp), %rdi
callq 0x42e0
movq 0x50(%rsp), %rdi
movq (%rax), %rax
movq %rax, 0x88(%rsp)
callq 0x16fc0
cmpq 0xa8(%rsp), %rax
jbe 0x16e28
movq 0x50(%rsp), %rdi
movq 0xb0(%rsp), %rax
movq 0x48(%rax), %rax
movq %rax, 0x38(%rsp)
movq 0x88(%rsp), %rax
addq $0x8, %rax
movq %rax, 0x40(%rsp)
movq 0xa8(%rsp), %rsi
callq 0x16fe0
movq 0x38(%rsp), %rdi
movq 0x40(%rsp), %rsi
movq (%rax), %rdx
callq 0xfc10
jmp 0x16eea
movq 0x88(%rsp), %rdi
addq $0x50, %rdi
callq 0x56b0
cmpq $0x1, %rax
jne 0x16ea8
movq 0xb0(%rsp), %rax
movq 0x48(%rax), %rax
movq %rax, 0x28(%rsp)
movq 0x88(%rsp), %rax
addq $0x8, %rax
movq %rax, 0x30(%rsp)
movq 0xb0(%rsp), %rax
movq 0x48(%rax), %rax
movq %rax, 0x20(%rsp)
movq 0x88(%rsp), %rdi
addq $0x50, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x13710
movq 0x20(%rsp), %rdi
movq (%rax), %rsi
callq 0x10220
movq 0x28(%rsp), %rdi
movq 0x30(%rsp), %rsi
movq %rax, %rdx
callq 0xfc10
jmp 0x16ee8
movq 0x23129(%rip), %rdi     # 0x39fd8
leaq 0x14915(%rip), %rsi     # 0x2b7cb
callq 0x32d0
movq %rax, %rdi
movq 0x88(%rsp), %rsi
addq $0x8, %rsi
callq 0x32a0
movq %rax, %rdi
leaq 0x1490b(%rip), %rsi     # 0x2b7e4
callq 0x32d0
movl $0x1, %edi
callq 0x3330
jmp 0x16eea
movq 0xa8(%rsp), %rax
addq $0x1, %rax
movq %rax, 0xa8(%rsp)
leaq 0x98(%rsp), %rdi
callq 0x5410
jmp 0x16d93
movq 0xb0(%rsp), %rax
movq 0x48(%rax), %rdi
callq 0x11410
movq 0xb0(%rsp), %rsi
movq 0x48(%rsi), %rax
movq %rax, 0x8(%rsp)
addq $0x10, %rsi
leaq 0x68(%rsp), %rdi
movq %rdi, 0x10(%rsp)
callq 0x5460
movq 0x8(%rsp), %rdi
movq 0x10(%rsp), %rsi
callq 0x11170
movq %rax, 0x18(%rsp)
jmp 0x16f5b
leaq 0x68(%rsp), %rdi
callq 0x5560
movq 0x18(%rsp), %rax
movq %rax, 0x80(%rsp)
movq 0xb0(%rsp), %rax
movq 0x48(%rax), %rdi
callq 0x11430
movq 0x80(%rsp), %rax
addq $0xc8, %rsp
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x60(%rsp)
movl %eax, 0x5c(%rsp)
leaq 0x68(%rsp), %rdi
callq 0x5560
movq 0x60(%rsp), %rdi
callq 0x3490
nopw %cs:(%rax,%rax)
nop