Beispiel #1
0
        RuntimeException NewOpTypeError(string op, int idx)
        {
            var info = GetOperandNameAndScope(idx);

            return(NewRuntimeError("attempt to {0} {1} '{2}' (a {3} value) ",
                                   op, info.Item1, info.Item2, ValueUtils.GetTypeName(_stack[idx])));
        }
Beispiel #2
0
 void CheckCompareType(int b, int c, string op)
 {
     if (_stack[b] is double && _stack[c] is double)
     {
     }
     else
     {
         throw NewRuntimeError("attemp to compare({0}) {1} with {2}",
                               op, ValueUtils.GetTypeName(_stack[b]), ValueUtils.GetTypeName(_stack[c]));
     }
 }
Beispiel #3
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);
        }
Beispiel #4
0
 private void OpConcat(int a, int b, int c)
 {
     _stack[a] = ValueUtils.ToString(_stack[b]) + ValueUtils.ToString(_stack[c]);
 }