Ejemplo n.º 1
0
        static IImportTypeHandler _Import(VM vm, Type t, string name = null)
        {
            var handler = vm.m_import_manager.GetOrCreateHandler(t);

            if (string.IsNullOrWhiteSpace(name) == false)
            {
                var segments = name.Split('.');
                var table    = vm.m_global;
                for (int i = 0; i < segments.Length - 1; ++i)
                {
                    Table tmp = table.Get(segments[i]) as Table;
                    if (tmp == null)
                    {
                        tmp = vm.NewTable();
                        table.Set(segments[i], tmp);
                    }
                    table = tmp;
                }
                table.Set(segments.Last(), handler);
            }
            return(handler);
        }
Ejemplo n.º 2
0
        void ExecuteFrame()
        {
            CallInfo call      = _calls.Last();
            Closure  closure   = call.closure;
            Function func      = closure.func;
            int      code_size = func.OpCodeSize();

            int     a, b, c, bx;
            UpValue upvalue;

            while (call.pc < code_size)
            {
                VM.CallDebugHook(this);
                Instruction i = func.GetInstruction(call.pc);
                ++call.pc;

                a  = call.register_idx + i.GetA();
                b  = call.register_idx + i.GetB();
                c  = call.register_idx + i.GetC();
                bx = i.GetBx();

                switch (i.GetOp())
                {
                case OpType.OpType_LoadNil:
                    _stack[a] = null;
                    break;

                case OpType.OpType_LoadBool:
                    _stack[a] = (bx == 1 ? true : false);
                    break;

                case OpType.OpType_LoadInt:
                    _stack[a] = (double)bx;
                    break;

                case OpType.OpType_LoadConst:
                    _stack[a] = func.GetConstValue(bx);
                    break;

                case OpType.OpType_Move:
                    _stack[a] = _stack[b];
                    break;

                case OpType.OpType_Closure:
                    OpGenerateClosure(a, func.GetChildFunction(bx));
                    break;

                case OpType.OpType_Call:
                    if (OpCall(a, i.GetB(), i.GetC() == 1))
                    {
                        // will enter next frame
                        return;
                    }
                    if (_status == ThreadStatus.Stop)
                    {
                        return;    // pause
                    }
                    break;

                case OpType.OpType_AsyncCall:
                    // new thread to run, and return nothing
                    OpAsyncCall(a, i.GetB(), i.GetC() == 1);
                    break;

                case OpType.OpType_GetUpvalue:
                    upvalue   = closure.GetUpvalue(bx);
                    _stack[a] = upvalue.Read();
                    break;

                case OpType.OpType_SetUpvalue:
                    upvalue = closure.GetUpvalue(bx);
                    upvalue.Write(_stack[a]);
                    break;

                case OpType.OpType_GetGlobal:
                    _stack[a] = closure.env_table.Get(func.GetConstValue(bx));
                    break;

                case OpType.OpType_SetGlobal:
                    closure.env_table.Set(func.GetConstValue(bx), _stack[a]);
                    break;

                case OpType.OpType_VarArg:
                    OpCopyVarArg(a, call);
                    break;

                case OpType.OpType_Ret:
                    OpReturn(call.func_idx, a, i.GetB(), i.GetC() == 1);
                    return;    // finish

                //break;
                case OpType.OpType_Jmp:
                    call.pc += -1 + bx;
                    break;

                case OpType.OpType_JmpFalse:
                    if (ValueUtils.IsFalse(_stack[a]))
                    {
                        call.pc += -1 + bx;
                    }
                    break;

                case OpType.OpType_JmpTrue:
                    if (!ValueUtils.IsFalse(_stack[a]))
                    {
                        call.pc += -1 + bx;
                    }
                    break;

                case OpType.OpType_JmpNil:
                    if (null == _stack[a])
                    {
                        call.pc += -1 + bx;
                    }
                    break;

                case OpType.OpType_Neg:
                    OpNeg(a);
                    break;

                case OpType.OpType_Not:
                    _stack[a] = ValueUtils.IsFalse(_stack[a]);
                    break;

                case OpType.OpType_Len:
                    if (_stack[a] is Table)
                    {
                        _stack[a] = (_stack[a] as Table).Count();
                    }
                    else
                    {
                        throw NewOpTypeError("get length of ", a);
                    }
                    break;

                case OpType.OpType_Add:
                    CheckArithType(b, c, "add");
                    _stack[a] = (double)(_stack[b]) + (double)(_stack[c]);
                    break;

                case OpType.OpType_Sub:
                    CheckArithType(b, c, "sub");
                    _stack[a] = (double)(_stack[b]) - (double)(_stack[c]);
                    break;

                case OpType.OpType_Mul:
                    CheckArithType(b, c, "multiply");
                    _stack[a] = (double)(_stack[b]) * (double)(_stack[c]);
                    break;

                case OpType.OpType_Div:
                    CheckArithType(b, c, "div");
                    _stack[a] = (double)(_stack[b]) / (double)(_stack[c]);
                    break;

                case OpType.OpType_Pow:
                    CheckArithType(b, c, "power");
                    _stack[a] = Math.Pow((double)(_stack[b]), (double)(_stack[c]));
                    break;

                case OpType.OpType_Mod:
                    CheckArithType(b, c, "mod");
                    _stack[a] = (double)(_stack[b]) % (double)(_stack[c]);
                    break;

                case OpType.OpType_Concat:
                    OpConcat(a, b, c);
                    break;

                case OpType.OpType_Less:
                    CheckCompareType(b, c, "<");
                    _stack[a] = ValueUtils.ToNumber(_stack[b]) < ValueUtils.ToNumber(_stack[c]);
                    break;

                case OpType.OpType_Greater:
                    CheckCompareType(b, c, ">");
                    _stack[a] = ValueUtils.ToNumber(_stack[b]) > ValueUtils.ToNumber(_stack[c]);
                    break;

                case OpType.OpType_Equal:
                    _stack[a] = Object.Equals(_stack[b], _stack[c]);
                    break;

                case OpType.OpType_UnEqual:
                    _stack[a] = !Object.Equals(_stack[b], _stack[c]);
                    break;

                case OpType.OpType_LessEqual:
                    CheckCompareType(b, c, "<=");
                    _stack[a] = ValueUtils.ToNumber(_stack[b]) <= ValueUtils.ToNumber(_stack[c]);
                    break;

                case OpType.OpType_GreaterEqual:
                    CheckCompareType(b, c, ">=");
                    _stack[a] = ValueUtils.ToNumber(_stack[b]) >= ValueUtils.ToNumber(_stack[c]);
                    break;

                case OpType.OpType_NewTable:
                    _stack[a] = _vm.NewTable();
                    break;

                case OpType.OpType_AppendTable:
                    OpTableAppend(a, b, _active_top - b);
                    break;

                case OpType.OpType_SetTable:
                    OpSetTable(a, b, c);
                    break;

                case OpType.OpType_GetTable:
                    OpGetTable(a, b, c);
                    break;

                case OpType.OpType_TableIter:
                    if (_stack[b] is IForEach)
                    {
                        _stack[a] = (_stack[b] as IForEach).GetIter();
                    }
                    else
                    {
                        throw NewOpTypeError("foreach ", a);
                    }
                    break;

                case OpType.OpType_TableIterNext:
                    Debug.Assert(_stack[a] is INext);
                    (_stack[a] as INext).Next(out _stack[b], out _stack[c]);
                    break;

                case OpType.OpType_ForInit:
                    if (!(_stack[a] is double))
                    {
                        throw NewRuntimeError("'for' init need be number");
                    }
                    if (!(_stack[b] is double))
                    {
                        throw NewRuntimeError("'for' limit need be number");
                    }
                    if (!(_stack[c] is double))
                    {
                        throw NewRuntimeError("'for' step need be number");
                    }
                    if (((double)_stack[c] == 0))
                    {
                        throw NewRuntimeError("'for' step should be nozero");
                    }
                    break;

                case OpType.OpType_ForCheck:
                    if (OpForCheck(a, b, c))
                    {
                        ++call.pc;    // jump over JumpTail instruction
                    }
                    break;

                case OpType.OpType_FillNilFromTopToA:
                    while (_active_top < a)
                    {
                        _stack[_active_top++] = null;
                    }
                    break;

                case OpType.OpType_CloseUpvalue:
                    OpCloseUpvalueTo(a);
                    break;

                default:
                    Debug.Assert(false);
                    break;
                }
            }

            // return nil
            OpReturn(call.func_idx, -1, 0, false);
        }