Example #1
0
        // 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);
        }
Example #2
0
        // Perform a function call with a trace
        private Trace func_call_trace(WFunction func)
        {
            // Then create a new Trace instance referencing that frame
            Trace trace = new Trace(func_call(func));

            // Push the trace to the traceback
            this.traceback.push_call_trace(trace);
            return(trace);
        }
Example #3
0
 public WindowFunction(string Caption, WFunction function)
 {
     Act = function;
     caption = Caption;
 }
Example #4
0
        // Main fde cycle
        public void evaluate_sequence()
        {
            // Initialise the state of the multi_core_state
            this.state.multi_core_state = MultiCoreState.RUNNING;

            // Check we have not reached the end
            while (!end())
            {
                // Only execute if the core has not been suspended
                if (this.state.multi_core_state != MultiCoreState.SUSPENDED)
                {
                    Int32 op = get_next();

#if CORE_INSTR_DEBUG
                    Console.ForegroundColor = ConsoleColor.Blue;
                    Console.WriteLine("op: " + (Opcode)op);
                    Console.ForegroundColor = ConsoleColor.Yellow;
#endif

                    // Surround the execute phase in a try catch, this is so the vm can return safely to the error handling
                    // without breaking other vm components
                    try
                    {
                        switch ((Opcode)op)
                        {
                        case Opcode.PRINT:
                        {
                            Console.ForegroundColor = ConsoleColor.Green;
#if VM_MULTI_CORE
                            Console.WriteLine("{core " + this.state.id + "} " + peek_exec());
#else
                            Console.WriteLine(peek_exec());
#endif
                            Console.ForegroundColor = ConsoleColor.Yellow;
                            goto_next();
                            break;
                        }

                        case Opcode.END:
                        {
                            // Return an END state
                            this.state.currently_interpreting = false;
                            break;
                        }

                        case Opcode.NOP:
                        {
                            goto_next();
                            break;
                        }

                        case Opcode.POP_EXEC:
                        {
                            pop_exec();
                            goto_next();
                            break;
                        }

                        case Opcode.LD_CONST:
                        {
                            Int32 id = get_arg();
                            push_exec(this.vm.bank_manager.request_c_item(this, id));
                            this.vm.bank_manager.release_c_item(this, id);
                            goto_next();
                            break;
                        }

                        case Opcode.LD_VAR:
                        {
                            Int32 id = get_arg();
                            push_exec(this.vm.bank_manager.request_m_item(this, id));
                            this.vm.bank_manager.release_m_item(this, id);
                            goto_next();
                            break;
                        }

                        case Opcode.LD_LOC:
                        {
                            // Check if we are actually in a function
                            ASSERT_ERR(this.state.func_depth > 0, CoreErrorType.INVALID_LOCAL, "Cannot load local from non-function state!");
                            Int32 index = get_arg();
                            // Check if we have a valid local index
                            ASSERT_ERR(index > this.locals.Length - 1, CoreErrorType.INVALID_LOCAL, "Local index is larger than locals size!");
                            push_exec(this.locals[index]);
                            goto_next();
                            break;
                        }

                        case Opcode.BANK_VAR:
                        {
                            Int32 id = get_arg();
                            this.vm.bank_manager.request_m_item(this, id);
                            this.vm.bank_manager.assign_item(this, id, pop_exec());
                            this.vm.bank_manager.request_m_item(this, id);
                            goto_next();
                            break;
                        }

                        case Opcode.BANK_ASSIGN:
                        {
                            goto_next();
                            break;
                        }

                        case Opcode.LOCAL_ASSIGN:
                        {
                            goto_next();
                            break;
                        }

                        case Opcode.MAKE_CLASS:
                        {
                            break;
                        }

                        case Opcode.MAKE_FUNC:
                        {
                            break;
                        }

                        case Opcode.NEW:
                        {
                            break;
                        }

                        case Opcode.INVOKE_FUNC:
                        {
                            WFunction func = expect_wfunc(pop_exec());
#if CORE_TRACE_DEBUG
                            func_call_trace(func);
#else
                            func_call(func);
#endif
                            break;
                        }

                        case Opcode.RETURN:
                        {
                            func_return();
                            goto_next();
                            break;
                        }

                        case Opcode.GOTO:
                        {
                            this.pc += get_arg();
                            break;
                        }

                        case Opcode.IF_ZERO:
                        {
                            Int32 arg = get_arg();
                            if (expect_numeric(pop_exec()) == 0)
                            {
                                goto_next(); break;
                            }
                            this.pc += arg; break;
                        }

                        case Opcode.IF_NZERO:
                        {
                            Int32 arg = get_arg();
                            if (expect_numeric(pop_exec()) != 0)
                            {
                                goto_next(); break;
                            }
                            this.pc += arg; break;
                        }

                        case Opcode.IF_GRT:
                        {
                            Int32 arg = get_arg();
                            if (expect_numeric(pop_exec()) > expect_numeric(pop_exec()))
                            {
                                goto_next(); break;
                            }
                            this.pc += arg; break;
                        }

                        case Opcode.IF_GRTE:
                        {
                            Int32 arg = get_arg();
                            if (expect_numeric(pop_exec()) >= expect_numeric(pop_exec()))
                            {
                                goto_next(); break;
                            }
                            this.pc += arg; break;
                        }

                        case Opcode.IF_LT:
                        {
                            Int32 arg = get_arg();
                            if (expect_numeric(pop_exec()) < expect_numeric(pop_exec()))
                            {
                                goto_next(); break;
                            }
                            this.pc += arg; break;
                        }

                        case Opcode.IF_LTE:
                        {
                            Int32 arg = get_arg();
                            if (expect_numeric(pop_exec()) <= expect_numeric(pop_exec()))
                            {
                                goto_next(); break;
                            }
                            this.pc += arg; break;
                        }

                        case Opcode.INCREMENT:
                        {
                            WItem num = expect_numeric(peek_exec());
                            num.value = num.value + 1;
                            goto_next();
                            break;
                        }

                        case Opcode.DECREMENT:
                        {
                            WItem num = expect_numeric(peek_exec());
                            num.value = num.value - 1;
                            goto_next();
                            break;
                        }

                        case Opcode.PSH_ZERO:
                        {
                            push_exec((Wint)0);
                            goto_next();
                            break;
                        }

                        case Opcode.PSH_NULL:
                        {
                            push_exec((Wnull)null);
                            goto_next();
                            break;
                        }

                        default:
                        {
                            // We have an invalid opcode
                            push_err(CoreErrorType.INVALID_OP, "op: " + op);
                            break;
                        }
                        }

                        // Program counter is out of range
                        ASSERT_ERR(pc <0 || pc> MAX_PC, CoreErrorType.INVALID_PC_RANGE);
                    }
                    catch (CoreErrException e)
                    {
                        if (e.err.is_fatal())
                        {
                            this.vm.core_manager.isolate(this.state.id);
                        }
                        this.state.err_handler.say_latest();
                        break;
                    }
                }
            }
            close();
        }