// Perform a function call private FuncFrame func_call(WFunction func) { ASSERT_ERR(this.state.func_depth > MAX_RECURSION, CoreErrorType.MAX_RECURSION, "Maxmimum recursion depth achieved!"); this.state.func_depth++; // Set the size of the locals to the args count & locals count this.locals = new WItem[func.args_size + func.locals_size]; // Then define the function arguments passed in that were on the exec stack for (int i = 0; i < func.args_size; i++) { this.locals[i] = exec_stack.pop(); } // First create a new FuncFrame to push to the function stack FuncFrame frame = new FuncFrame(this, func.name, this.pc, this.locals, this.exec_stack, this.bytecode); // Then push the frame to the FuncStack this.func_stack.push(frame); // Check if the function is native if (func.is_native) { // Natively call the func push_exec(this.native_interface.call_native_func(VM.state.current_file, func.name, this.locals)); // Becuase native functions can't implement Opcode.RETURN, we need to manually return & advance func_return(); goto_next(); } else { this.pc = 0; this.exec_stack = new ExecStack(this); this.bytecode = func.bytecode; this.state.opcode_count = this.bytecode.Length; } return(frame); }
public Core(VM vm, int id) : base("Core", id) { this.vm = vm; this.native_interface = new NativeInterface(this.vm, this); this.state = new CoreState(id, new CoreErrorHandler(), 0, false, 0); this.pc = 0; this.locals = new WItem[0]; this.traceback = new TraceBack(); this.func_stack = new FuncStack(this); this.exec_stack = new ExecStack(this); }
private void func_return() { this.state.func_depth--; // First get the return value, by poping it from the exec stack WItem return_value = this.exec_stack.pop(); // Then restore the state of the core FuncFrame previous_frame = this.func_stack.pop(); this.pc = previous_frame.pc; this.locals = previous_frame.locals; this.exec_stack = previous_frame.exec_stack; this.bytecode = previous_frame.bytecode; this.state.opcode_count = this.bytecode.Length; // Then push the returned value to the exec stack this.exec_stack.push(return_value); }