Ejemplo n.º 1
0
		public void Set(ref TValue key, ref TValue val)
		{
			var cell = Get(ref key);
			if(cell == TheNilValue) {
				cell = NewTableKey(ref key);
			}
			cell.V.SetObj(ref val);
		}
Ejemplo n.º 2
0
		public void SetInt(int key, ref TValue val)
		{
			var cell = GetInt(key);
			if(cell == TheNilValue) {
				var k = new TValue();
				k.SetNValue(key);
				cell = NewTableKey(ref k);
			}
			cell.V.SetObj(ref val);
			// ULDebug.Log(string.Format("---------------- SetInt {0} -> {1}", key, val));
			// DumpParts();
		}
Ejemplo n.º 3
0
        public bool Equals(TValue o)
        {
            if(Tt != o.Tt || NValue != o.NValue)
                { return false; }

            switch(Tt) {
                case (int)LuaType.LUA_TNIL:
                    return true;
                case (int)LuaType.LUA_TSTRING:
                    return SValue() == o.SValue();
                default:
                    return System.Object.ReferenceEquals(OValue, o.OValue);
            }
        }
Ejemplo n.º 4
0
        public bool Equals(TValue o)
        {
            if(Tt != o.Tt || NValue != o.NValue || UInt64Value != o.UInt64Value)
                { return false; }

            switch(Tt) {
                case (int)LuaType.LUA_TNIL: return true;
                case (int)LuaType.LUA_TBOOLEAN: return BValue() == o.BValue();
                case (int)LuaType.LUA_TNUMBER: return NValue == o.NValue;
                case (int)LuaType.LUA_TUINT64: return UInt64Value == o.UInt64Value;
                case (int)LuaType.LUA_TSTRING: return SValue() == o.SValue();
                default: return System.Object.ReferenceEquals(OValue, o.OValue);
            }
        }
Ejemplo n.º 5
0
		public StkId GetInt(int key)
		{
			if(0 < key && key-1 < ArrayPart.Length)
				{ return ArrayPart[key-1]; }

			var k = new TValue();
			k.SetNValue(key);
			for(var node = GetHashNode(ref k); node != null; node = node.Next) {
				if(node.Key.V.TtIsNumber() && node.Key.V.NValue == (double)key) {
					return node.Val;
				}
			}

			return TheNilValue;
		}
Ejemplo n.º 6
0
 private void CallTM( ref TValue f, ref TValue p1, ref TValue p2, StkId p3, bool hasres )
 {
     var result = p3.Index;
     var func = Top;
     StkId.inc(ref Top).V.SetObj(ref f); 	// push function
     StkId.inc(ref Top).V.SetObj(ref p1);	// push 1st argument
     StkId.inc(ref Top).V.SetObj(ref p2);	// push 2nd argument
     if( !hasres ) 		// no result? p3 is 3rd argument
         StkId.inc(ref Top).V.SetObj(ref p3.V);
     D_CheckStack(0);
     D_Call( func, (hasres ? 1 : 0), CI.IsLua );
     if( hasres )		// if has result, move it ot its place
     {
         Top = Stack[Top.Index - 1];
         Stack[result].V.SetObj(ref Top.V);
     }
 }
Ejemplo n.º 7
0
		public StkId Get(ref TValue key)
		{
			if(key.Tt == (int)LuaType.LUA_TNIL) { return TheNilValue; }

			if(IsPositiveInteger(ref key))
				{ return GetInt((int)key.NValue); }

			if(key.Tt == (int)LuaType.LUA_TSTRING)
				{ return GetStr(key.SValue()); }

			var h = key.GetHashCode();
			for(var node = GetHashNode(h); node != null; node = node.Next) {
				if(node.Key.V == key) {
					{ return node.Val; }
				}
			}

			return TheNilValue;
		}
Ejemplo n.º 8
0
 /*
 ** returns the index for `key' if `key' is an appropriate key to live in
 ** the array part of the table, -1 otherwise.
 */
 private int ArrayIndex(ref TValue k)
 {
     if(IsPositiveInteger(ref k))
         return (int)k.NValue;
     else
         return -1;
 }
Ejemplo n.º 9
0
 public void SetInt(int key, ref TValue val)
 {
     var cell = GetInt(key);
     if(cell == TheNilValue) {
         var k = new TValue();
         k.SetNValue(key);
         cell = NewTableKey(ref k);
     }
     cell.V.SetObj(ref val);
 }
Ejemplo n.º 10
0
		internal bool V_RawEqualObj( ref TValue t1, ref TValue t2 )
		{
			return (t1.Tt == t2.Tt) && V_EqualObject( ref t1, ref t2, true );
		}
Ejemplo n.º 11
0
 private bool ToString(ref TValue o)
 {
     if(o.TtIsString()) { return true; }
     return V_ToString(ref o);
 }
Ejemplo n.º 12
0
        private bool IsFalse(ref TValue v)
        {
            if( v.TtIsNil() )
                return true;

            if((v.TtIsBoolean() && v.BValue() == false))
                return true;

            return false;
        }
Ejemplo n.º 13
0
 public static TValue Clone(TValue other)
 {
     return((TValue)other.MemberwiseClone());
 }
Ejemplo n.º 14
0
		private void V_Execute()
		{
			ExecuteEnvironment env;
			CallInfo ci = CI;
newframe:
			Utl.Assert(ci == CI);
			var cl = Stack[ci.FuncIndex].V.ClLValue();

			env.Stack = Stack;
			env.K = cl.Proto.K;
			env.Base = ci.BaseIndex;

#if DEBUG_NEW_FRAME
			ULDebug.Log( "#### NEW FRAME #########################################################################" );
			ULDebug.Log( "## cl:" + cl );
			ULDebug.Log( "## Base:" + env.Base );
			ULDebug.Log( "########################################################################################" );
#endif

			while( true )
			{
				Instruction i = ci.SavedPc.ValueInc;
				env.I = i;

#if DEBUG_SRC_INFO
				int line = 0;
				string src = "";
				if(ci.IsLua) {
					line = GetCurrentLine(ci);
					src = GetCurrentLuaFunc(ci).Proto.Source;
				}
#endif

				StkId ra = env.RA;

#if DEBUG_DUMP_INS_STACK
#if DEBUG_DUMP_INS_STACK_EX
				DumpStack( env.Base, i.ToString() );
#else
				DumpStack( env.Base );
#endif
#endif

#if DEBUG_INSTRUCTION
				ULDebug.Log( System.DateTime.Now + " [VM] ======================================================================== Instruction: " + i
#if DEBUG_INSTRUCTION_WITH_STACK
				+ "\n" + DumpStackToString( env.Base.Index )
#endif
				);
#endif

#if DEBUG_RECORD_INS
				InstructionHistory.Enqueue(i);
				if( InstructionHistory.Count > 100 ) {
					InstructionHistory.Dequeue();
				}
#endif

				switch( i.GET_OPCODE() )
				{
					case OpCode.OP_MOVE:
					{
						var rb = env.RB;

#if DEBUG_OP_MOVE
						ULDebug.Log( "[VM] ==== OP_MOVE rb:" + rb );
						ULDebug.Log( "[VM] ==== OP_MOVE ra:" + ra );
#endif

						ra.V.SetObj(ref rb.V);
						break;
					}

					case OpCode.OP_LOADK:
					{
						var rb = env.K[i.GETARG_Bx()];
						ra.V.SetObj(ref rb.V);
						break;
					}

					case OpCode.OP_LOADKX:
					{
						Utl.Assert( ci.SavedPc.Value.GET_OPCODE() == OpCode.OP_EXTRAARG );
						var rb = env.K[ci.SavedPc.ValueInc.GETARG_Ax()];
						ra.V.SetObj(ref rb.V);
						break;
					}

					case OpCode.OP_LOADBOOL:
					{
						ra.V.SetBValue(i.GETARG_B() != 0);
						if( i.GETARG_C() != 0 )
							ci.SavedPc.Index += 1; // skip next instruction (if C)
						break;
					}

					case OpCode.OP_LOADNIL:
					{
						int b = i.GETARG_B();
						int index = ra.Index;
						do {
							Stack[index++].V.SetNilValue();
						} while (b-- > 0);
						break;
					}

					case OpCode.OP_GETUPVAL:
					{
						int b = i.GETARG_B();
						ra.V.SetObj(ref cl.Upvals[b].V.V);
						
#if DEBUG_OP_GETUPVAL
						// for( var j=0; j<cl.Upvals.Length; ++j)
						// {
						// 	ULDebug.Log("[VM] ==== GETUPVAL upval:" + cl.Upvals[j] );
						// }
						ULDebug.Log( "[VM] ==== GETUPVAL b:" + b );
						ULDebug.Log( "[VM] ==== GETUPVAL ra:" + ra );
#endif
						break;
					}

					case OpCode.OP_GETTABUP:
					{
						int b = i.GETARG_B();
						var key = env.RKC;
						V_GetTable( cl.Upvals[b].V, key, ra );
#if DEBUG_OP_GETTABUP
						ULDebug.Log( "[VM] ==== OP_GETTABUP key:" + key );
						ULDebug.Log( "[VM] ==== OP_GETTABUP val:" + ra );
#endif
						env.Base = ci.BaseIndex;
						break;
					}

					case OpCode.OP_GETTABLE:
					{
						var tbl = env.RB;
						var key = env.RKC;
						var val = ra;
						V_GetTable( tbl, key, val );
#if DEBUG_OP_GETTABLE
						ULDebug.Log("[VM] ==== OP_GETTABLE key:"+key.ToString());
						ULDebug.Log("[VM] ==== OP_GETTABLE val:"+val.ToString());
#endif
						break;
					}

					case OpCode.OP_SETTABUP:
					{
						int a = i.GETARG_A();

						var key = env.RKB;
						var val = env.RKC;
						V_SetTable( cl.Upvals[a].V, key, val );
#if DEBUG_OP_SETTABUP
						ULDebug.Log( "[VM] ==== OP_SETTABUP key:" + key.Value );
						ULDebug.Log( "[VM] ==== OP_SETTABUP val:" + val.Value );
#endif
						env.Base = ci.BaseIndex;
						break;
					}

					case OpCode.OP_SETUPVAL:
					{
						int b = i.GETARG_B();
						var uv = cl.Upvals[b];
						uv.V.V.SetObj(ref ra.V);
#if DEBUG_OP_SETUPVAL
						ULDebug.Log( "[VM] ==== SETUPVAL b:" + b );
						ULDebug.Log( "[VM] ==== SETUPVAL ra:" + ra );
#endif
						break;
					}

					case OpCode.OP_SETTABLE:
					{
						var key = env.RKB;
						var val = env.RKC;
#if DEBUG_OP_SETTABLE
						ULDebug.Log( "[VM] ==== OP_SETTABLE key:" + key.ToString() );
						ULDebug.Log( "[VM] ==== OP_SETTABLE val:" + val.ToString() );
#endif
						V_SetTable( ra, key, val );
						break;
					}

					case OpCode.OP_NEWTABLE:
					{
						int b = i.GETARG_B();
						int c = i.GETARG_C();
						var tbl = new LuaTable(this);
						ra.V.SetHValue(tbl);
						if(b > 0 || c > 0)
							{ tbl.Resize(b, c); }
						break;
					}

					case OpCode.OP_SELF:
					{
						// OP_SELF put function referenced by a table on ra
						// and the table on ra+1
						//
						// RB:  table
						// RKC: key
						var ra1 = Stack[ra.Index+1];
						var rb  = env.RB;
						ra1.V.SetObj(ref rb.V);
						V_GetTable( rb, env.RKC, ra );
						env.Base = ci.BaseIndex;
						break;
					}

					case OpCode.OP_ADD:
					{
						var rkb = env.RKB;
						var rkc = env.RKC;
						if(rkb.V.TtIsNumber() && rkc.V.TtIsNumber())
							{ ra.V.SetNValue(rkb.V.NValue + rkc.V.NValue); }
						else
							{ V_Arith(ra, rkb, rkc, TMS.TM_ADD); }

						env.Base = ci.BaseIndex;
						break;
					}

					case OpCode.OP_SUB:
					{
						var rkb = env.RKB;
						var rkc = env.RKC;
						if(rkb.V.TtIsNumber() && rkc.V.TtIsNumber())
							{ ra.V.SetNValue(rkb.V.NValue - rkc.V.NValue); }
						else
							{ V_Arith(ra, rkb, rkc, TMS.TM_SUB); }
						env.Base = ci.BaseIndex;
						break;
					}

					case OpCode.OP_MUL:
					{
						var rkb = env.RKB;
						var rkc = env.RKC;
						if(rkb.V.TtIsNumber() && rkc.V.TtIsNumber())
							{ ra.V.SetNValue(rkb.V.NValue * rkc.V.NValue); }
						else
							{ V_Arith(ra, rkb, rkc, TMS.TM_MUL); }
						env.Base = ci.BaseIndex;
						break;
					}

					case OpCode.OP_DIV:
					{
						var rkb = env.RKB;
						var rkc = env.RKC;
						if(rkb.V.TtIsNumber() && rkc.V.TtIsNumber())
							{ ra.V.SetNValue(rkb.V.NValue / rkc.V.NValue); }
						else
							{ V_Arith(ra, rkb, rkc, TMS.TM_DIV); }
						env.Base = ci.BaseIndex;
						break;
					}

					case OpCode.OP_MOD:
					{
						var rkb = env.RKB;
						var rkc = env.RKC;
						if(rkb.V.TtIsNumber() && rkc.V.TtIsNumber())
							{ ra.V.SetNValue(rkb.V.NValue % rkc.V.NValue); }
						else
							{ V_Arith(ra, rkb, rkc, TMS.TM_MOD); }
						env.Base = ci.BaseIndex;
						break;
					}

					case OpCode.OP_POW:
					{
						var rkb = env.RKB;
						var rkc = env.RKC;
						if(rkb.V.TtIsNumber() && rkc.V.TtIsNumber())
							{ ra.V.SetNValue(Math.Pow(rkb.V.NValue, rkc.V.NValue)); }
						else
							{ V_Arith(ra, rkb, rkc, TMS.TM_POW); }
						env.Base = ci.BaseIndex;
						break;
					}

					case OpCode.OP_UNM:
					{
						var rb = env.RB;
						if(rb.V.TtIsNumber()) {
							ra.V.SetNValue(-rb.V.NValue);
						}
						else {
							V_Arith(ra, rb, rb, TMS.TM_UNM);
							env.Base = ci.BaseIndex;
						}
						break;
					}

					case OpCode.OP_NOT:
					{
						var rb = env.RB;
						ra.V.SetBValue(IsFalse(ref rb.V));
						break;
					}

					case OpCode.OP_LEN:
					{
						V_ObjLen( ra, env.RB );
						env.Base = ci.BaseIndex;
						break;
					}

					case OpCode.OP_CONCAT:
					{
						int b = i.GETARG_B();
						int c = i.GETARG_C();
						Top = Stack[env.Base + c + 1];
						V_Concat( c - b + 1 );
						env.Base = ci.BaseIndex;

						ra = env.RA; // 'V_Concat' may invoke TMs and move the stack
						StkId rb = env.RB;
						ra.V.SetObj(ref rb.V);

						Top = Stack[ci.TopIndex]; // restore top
						break;
					}

					case OpCode.OP_JMP:
					{
						V_DoJump( ci, i, 0 );
						break;
					}

					case OpCode.OP_EQ:
					{
						var lhs = env.RKB;
						var rhs = env.RKC;
						var expectEq = i.GETARG_A() != 0;
#if DEBUG_OP_EQ
						ULDebug.Log( "[VM] ==== OP_EQ lhs:" + lhs );
						ULDebug.Log( "[VM] ==== OP_EQ rhs:" + rhs );
						ULDebug.Log( "[VM] ==== OP_EQ expectEq:" + expectEq );
						ULDebug.Log( "[VM] ==== OP_EQ (lhs.V == rhs.V):" + (lhs.V == rhs.V) );
#endif
						if((lhs.V == rhs.V) != expectEq)
						{
							ci.SavedPc.Index += 1; // skip next jump instruction
						}
						else
						{
							V_DoNextJump( ci );
						}
						env.Base = ci.BaseIndex;
						break;
					}

					case OpCode.OP_LT:
					{
						var expectCmpResult = i.GETARG_A() != 0;
						if( V_LessThan( env.RKB, env.RKC ) != expectCmpResult )
							ci.SavedPc.Index += 1;
						else
							V_DoNextJump( ci );
						env.Base = ci.BaseIndex;
						break;
					}

					case OpCode.OP_LE:
					{
						var expectCmpResult = i.GETARG_A() != 0;
						if( V_LessEqual( env.RKB, env.RKC ) != expectCmpResult )
							ci.SavedPc.Index += 1;
						else
							V_DoNextJump( ci );
						env.Base = ci.BaseIndex;
						break;
					}

					case OpCode.OP_TEST:
					{
						if((i.GETARG_C() != 0) ?
							IsFalse(ref ra.V) : !IsFalse(ref ra.V))
						{
							ci.SavedPc.Index += 1;
						}
						else V_DoNextJump( ci );

						env.Base = ci.BaseIndex;
						break;
					}

					case OpCode.OP_TESTSET:
					{
						var rb = env.RB;
						if((i.GETARG_C() != 0) ?
							IsFalse(ref rb.V) : !IsFalse(ref rb.V))
						{
							ci.SavedPc.Index += 1;
						}
						else
						{
							ra.V.SetObj(ref rb.V);
							V_DoNextJump( ci );
						}
						env.Base = ci.BaseIndex;
						break;
					}

					case OpCode.OP_CALL:
					{
						int b = i.GETARG_B();
						int nresults = i.GETARG_C() - 1;
						if( b != 0) { Top = Stack[ra.Index + b]; } 	// else previous instruction set top
						if( D_PreCall( ra, nresults ) ) { // C# function?
							if( nresults >= 0 )
								Top = Stack[ci.TopIndex];
							env.Base = ci.BaseIndex;
						}
						else { // Lua function
							ci = CI;
							ci.CallStatus |= CallStatus.CIST_REENTRY;
							goto newframe;
						}
						break;
					}

					case OpCode.OP_TAILCALL:
					{
						int b = i.GETARG_B();
						if( b != 0) { Top = Stack[ra.Index + b]; } 	// else previous instruction set top
						
						Utl.Assert( i.GETARG_C() - 1 == LuaDef.LUA_MULTRET );

						var called = D_PreCall( ra, LuaDef.LUA_MULTRET );

						// C# function ?
						if( called )
						{
							env.Base = ci.BaseIndex;
						}

						// LuaFunciton
						else
						{
							var nci = CI;				// called frame
							var oci = BaseCI[CI.Index-1]; // caller frame
							StkId nfunc = Stack[nci.FuncIndex];// called function
							StkId ofunc = Stack[oci.FuncIndex];// caller function
							var ncl = nfunc.V.ClLValue();
							var ocl = ofunc.V.ClLValue();

							// last stack slot filled by 'precall'
							int lim = nci.BaseIndex + ncl.Proto.NumParams;

							if(cl.Proto.P.Count > 0)
								{ F_Close( Stack[env.Base] ); }

							// move new frame into old one
							var nindex = nfunc.Index;
							var oindex = ofunc.Index;
							while(nindex < lim) {
								Stack[oindex++].V.SetObj(ref Stack[nindex++].V);
							}

							oci.BaseIndex = ofunc.Index + (nci.BaseIndex - nfunc.Index);
							oci.TopIndex = ofunc.Index + (Top.Index - nfunc.Index);
							Top = Stack[oci.TopIndex];
							oci.SavedPc = nci.SavedPc;
							oci.CallStatus |= CallStatus.CIST_TAIL;
							ci = CI = oci;

							ocl = ofunc.V.ClLValue();
							Utl.Assert(Top.Index == oci.BaseIndex + ocl.Proto.MaxStackSize);

							goto newframe;
						}

						break;
					}

					case OpCode.OP_RETURN:
					{
						int b = i.GETARG_B();
						if( b != 0 ) { Top = Stack[ra.Index + b - 1]; }
						if( cl.Proto.P.Count > 0 ) { F_Close(Stack[env.Base]); }
						b = D_PosCall( ra.Index );
						if( (ci.CallStatus & CallStatus.CIST_REENTRY) == 0 )
						{
							return;
						}
						else
						{
							ci = CI;
							if( b != 0 ) Top = Stack[ci.TopIndex];
							goto newframe;
						}
					}

					case OpCode.OP_FORLOOP:
					{
						var ra1 = Stack[ra.Index + 1];
						var ra2 = Stack[ra.Index + 2];
						var ra3 = Stack[ra.Index + 3];
						
						var step 	= ra2.V.NValue;
						var idx 	= ra.V.NValue + step;	// increment index
						var limit 	= ra1.V.NValue;

						if( (0 < step) ? idx <= limit
									   : limit <= idx )
						{
							ci.SavedPc.Index += i.GETARG_sBx(); // jump back
							ra.V.SetNValue(idx);// updateinternal index...
							ra3.V.SetNValue(idx);// ... and external index
						}

						break;
					}

					case OpCode.OP_FORPREP:
					{
						var init = new TValue();
						var limit = new TValue();
						var step = new TValue();

						var ra1 = Stack[ra.Index + 1];
						var ra2 = Stack[ra.Index + 2];

						// WHY: why limit is not used ?

						if(!V_ToNumber(ra, ref init))
							G_RunError("'for' initial value must be a number");
						if(!V_ToNumber(ra1, ref limit))
							G_RunError("'for' limit must be a number");
						if(!V_ToNumber(ra2, ref step))
							G_RunError("'for' step must be a number");

						ra.V.SetNValue(init.NValue - step.NValue);
						ci.SavedPc.Index += i.GETARG_sBx();

						break;
					}

					case OpCode.OP_TFORCALL:
					{
						int rai = ra.Index;
						int cbi = ra.Index + 3;
						Stack[cbi+2].V.SetObj(ref Stack[rai+2].V);
						Stack[cbi+1].V.SetObj(ref Stack[rai+1].V);
						Stack[cbi].V.SetObj(ref Stack[rai].V);

						StkId callBase = Stack[cbi];
						Top = Stack[cbi+3]; // func. +2 args (state and index)

						D_Call( callBase, i.GETARG_C(), true );

						env.Base = ci.BaseIndex;

						Top = Stack[ci.TopIndex];
						i = ci.SavedPc.ValueInc;	// go to next instruction
						env.I = i;
						ra = env.RA;

						DumpStack( env.Base );
#if DEBUG_INSTRUCTION
						ULDebug.Log( "[VM] ============================================================ OP_TFORCALL Instruction: " + i );
#endif

						Utl.Assert( i.GET_OPCODE() == OpCode.OP_TFORLOOP );
						goto l_tforloop;
					}

					case OpCode.OP_TFORLOOP:
l_tforloop:
					{
						StkId ra1 = Stack[ra.Index + 1];
						if(!ra1.V.TtIsNil())	// continue loop?
						{
							ra.V.SetObj(ref ra1.V);
							ci.SavedPc += i.GETARG_sBx();
						}
						break;
					}

					// sets the values for a range of array elements in a table(RA)
					// RA -> table
					// RB -> number of elements to set
					// C  -> encodes the block number of the table to be initialized
					// the values used to initialize the table are located in
					//   R(A+1), R(A+2) ...
					case OpCode.OP_SETLIST:
					{
						int n = i.GETARG_B();
						int c = i.GETARG_C();
						if( n == 0 ) n = (Top.Index - ra.Index) - 1;
						if( c == 0 )
						{
							Utl.Assert( ci.SavedPc.Value.GET_OPCODE() == OpCode.OP_EXTRAARG );
							c = ci.SavedPc.ValueInc.GETARG_Ax();
						}

						var tbl = ra.V.HValue();
						Utl.Assert( tbl != null );

						int last = ((c-1) * LuaDef.LFIELDS_PER_FLUSH) + n;
						int rai = ra.Index;
						for(; n>0; --n) {
							tbl.SetInt(last--, ref Stack[rai+n].V);
						}
#if DEBUG_OP_SETLIST
						ULDebug.Log( "[VM] ==== OP_SETLIST ci.Top:" + ci.Top.Index );
						ULDebug.Log( "[VM] ==== OP_SETLIST Top:" + Top.Index );
#endif
						Top = Stack[ci.TopIndex]; // correct top (in case of previous open call)
						break;
					}

					case OpCode.OP_CLOSURE:
					{
						LuaProto p = cl.Proto.P[ i.GETARG_Bx() ];
						V_PushClosure( p, cl.Upvals, env.Base, ra );
#if DEBUG_OP_CLOSURE
						ULDebug.Log( "OP_CLOSURE:" + ra.Value );
						var racl = ra.Value as LuaLClosure;
						if( racl != null )
						{
							for( int ii=0; ii<racl.Upvals.Count; ++ii )
							{
								ULDebug.Log( ii + " ) " + racl.Upvals[ii] );
							}
						}
#endif
						break;
					}

					/// <summary>
					/// VARARG implements the vararg operator `...' in expressions.
					/// VARARG copies B-1 parameters into a number of registers
					/// starting from R(A), padding with nils if there aren't enough values.
					/// If B is 0, VARARG copies as many values as it can based on
					/// the number of parameters passed.
					/// If a fixed number of values is required, B is a value greater than 1.
					/// If any number of values is required, B is 0.
					/// </summary>
					case OpCode.OP_VARARG:
					{
						int b = i.GETARG_B() - 1;
						int n = (env.Base - ci.FuncIndex) - cl.Proto.NumParams - 1;
						if( b < 0 ) // B == 0?
						{
							b = n;
							D_CheckStack(n);
							ra = env.RA; // previous call may change the stack
							Top = Stack[ra.Index + n];
						}

						var p = ra.Index;
						var q = env.Base - n;
						for(int j=0; j<b; ++j) {
							if(j < n) {
								Stack[p++].V.SetObj(ref Stack[q++].V);
							}
							else {
								Stack[p++].V.SetNilValue();
							}
						}
						break;
					}

					case OpCode.OP_EXTRAARG:
					{
						Utl.Assert( false );
						V_NotImplemented( i );
						break;
					}

					default:
						V_NotImplemented( i );
						break;
				}
			}
		}
Ejemplo n.º 15
0
        private void Rehash(ref TValue k)
        {
            int[] nums = new int[MAXBITS+1];
            for(int i=0; i<=MAXBITS; ++i) { nums[i] = 0; }

            int nasize = NumUseArray(ref nums);
            int totaluse = nasize;
            totaluse += NumUseHash(ref nums, ref nasize);
            nasize += CountInt(ref k, ref nums);
            totaluse++;
            int na = ComputeSizes(ref nums, ref nasize);
            Resize(nasize, totaluse-na);
        }
Ejemplo n.º 16
0
 private bool IsPositiveInteger(ref TValue v)
 {
     return (v.TtIsNumber() && v.NValue > 0 && (v.NValue % 1) == 0 && v.NValue <= int.MaxValue); //fix large number key bug
 }
Ejemplo n.º 17
0
 internal string ObjTypeName( ref TValue v )
 {
     return TypeName((LuaType)v.Tt);
 }
Ejemplo n.º 18
0
        uint ILuaAPI.ToUnsignedX( int index, out bool isnum )
        {
            StkId addr;
            if( !Index2Addr( index, out addr ) ) {
                isnum = false;
                return 0;
            }

            if( addr.V.TtIsNumber() ) {
                isnum = true;
                return (uint)addr.V.NValue;
            }

            if( addr.V.TtIsString() ) {
                var n = new TValue();
                if(V_ToNumber(addr, ref n)) {
                    isnum = true;
                    return (uint)n.NValue;
                }
            }

            isnum = false;
            return 0;
        }
Ejemplo n.º 19
0
		private bool V_ToString(ref TValue v)
		{
			if(!v.TtIsNumber()) { return false; }

			v.SetSValue(v.NValue.ToString());
			return true;
		}
Ejemplo n.º 20
0
		private bool V_ToNumber( StkId obj, ref TValue n )
		{
			if( obj.V.TtIsNumber() ) {
				n.SetNValue( obj.V.NValue );
				return true;
			}
			if( obj.V.TtIsString() ) {
				double val;
				if( O_Str2Decimal(obj.V.SValue(), out val) ) {
					n.SetNValue( val );
					return true;
				}
			}

			return false;
		}
Ejemplo n.º 21
0
 private int CountInt(ref TValue key, ref int[] nums)
 {
     int k = ArrayIndex(ref key);
     if(0 < k && k <= MAXASIZE) {
         nums[CeilLog2(k)]++;
         return 1;
     }
     else return 0;
 }
Ejemplo n.º 22
0
		private bool EqualObj( ref TValue t1, ref TValue t2, bool rawEq )
		{
			return (t1.Tt == t2.Tt) && V_EqualObject( ref t1, ref t2, rawEq );
		}
Ejemplo n.º 23
0
        private HNode GetHashNode(ref TValue v)
        {
            if(IsPositiveInteger(ref v)) { return GetHashNode((int)v.NValue); }

            if(v.TtIsString()) { return GetHashNode(v.SValue().GetHashCode()); }

            return GetHashNode(v.GetHashCode());
        }
Ejemplo n.º 24
0
		private bool V_EqualObject( ref TValue t1, ref TValue t2, bool rawEq )
		{
			Utl.Assert( t1.Tt == t2.Tt );
			StkId tm = null;
			switch( t1.Tt )
			{
				case (int)LuaType.LUA_TNIL:
					return true;
				case (int)LuaType.LUA_TNUMBER:
					return t1.NValue == t2.NValue;
				case (int)LuaType.LUA_TUINT64:
					return t1.UInt64Value == t2.UInt64Value;
				case (int)LuaType.LUA_TBOOLEAN:
					return t1.BValue() == t2.BValue();
				case (int)LuaType.LUA_TSTRING:
					return t1.SValue() == t2.SValue();
				case (int)LuaType.LUA_TUSERDATA:
				{
					var ud1 = t1.RawUValue();
					var ud2 = t2.RawUValue();
					if(ud1.Value == ud2.Value)
						return true;
					if(rawEq)
						return false;
					tm = GetEqualTM( ud1.MetaTable, ud2.MetaTable, TMS.TM_EQ );
					break;
				}
				case (int)LuaType.LUA_TTABLE:
				{
					var tbl1 = t1.HValue();
					var tbl2 = t2.HValue();
					if( System.Object.ReferenceEquals( tbl1, tbl2 ) )
						return true;
					if( rawEq )
						return false;
					tm = GetEqualTM( tbl1.MetaTable, tbl2.MetaTable, TMS.TM_EQ );
					break;
				}
				default:
					return t1.OValue == t2.OValue;
			}
			if( tm == null ) // no TM?
				return false;
			CallTM(ref tm.V, ref t1, ref t2, Top, true ); // call TM
			return !IsFalse(ref Top.V);
		}
Ejemplo n.º 25
0
        private StkId NewTableKey(ref TValue k)
        {
            if(k.TtIsNil()) { L.G_RunError("table index is nil"); }

            if(k.TtIsNumber() && System.Double.IsNaN(k.NValue))
                { L.G_RunError("table index is NaN"); }

            var mp = GetHashNode(ref k);

            // if main position is taken
            if(!mp.Val.V.TtIsNil() || mp == DummyNode) {
                var n = GetFreePos();
                if(n == null) {
                    Rehash(ref k);
                    var cell = Get(ref k);
                    if(cell != TheNilValue) { return cell; }
                    return NewTableKey(ref k);
                }

                Utl.Assert(n != DummyNode);
                var othern = GetHashNode(ref mp.Key.V);
                // is colliding node out of its main position?
                if(othern != mp) {
                    while(othern.Next != mp) { othern = othern.Next; }
                    othern.Next = n;
                    n.CopyFrom(mp);
                    mp.Next = null;
                    mp.Val.V.SetNilValue();
                }
                // colliding node is in its own main position
                else {
                    n.Next = mp.Next;
                    mp.Next = n;
                    mp = n;
                }
            }

            mp.Key.V.SetObj(ref k);
            Utl.Assert(mp.Val.V.TtIsNil());
            return mp.Val;
        }
Ejemplo n.º 26
0
		public static int NumberK( FuncState fs, double r )
		{
			var o = new TValue();
			o.SetNValue(r);
			return AddK( fs, ref o, ref o );
		}
Ejemplo n.º 27
0
		public static int StringK( FuncState fs, string s )
		{
			// Debug.Log(" STRING K >>>> " + s );
			var o = new TValue();
			o.SetSValue(s);
			return AddK( fs, ref o, ref o );
		}
Ejemplo n.º 28
0
		private static int NilK( FuncState fs )
		{
			// // cannot use nil as key;
			// // instead use table itself to represent nil
			// var k = fs.H;
			// var o = new LuaNil();
			// return AddK( fs, k, o );

			var o = new TValue();
			o.SetNilValue();
			return AddK( fs, ref o, ref o );
		}
Ejemplo n.º 29
0
		private static int BoolK( FuncState fs, bool b )
		{
			var o = new TValue();
			o.SetBValue(b);
			return AddK( fs, ref o, ref o );
		}
Ejemplo n.º 30
0
 internal void SetObj(ref TValue v)
 {
     #if DEBUG_DUMMY_TVALUE_MODIFY
     CheckLock();
     #endif
     Tt = v.Tt;
     NValue = v.NValue;
     UInt64Value = v.UInt64Value;
     OValue = v.OValue;
 }
Ejemplo n.º 31
0
		public static int AddK( FuncState fs, ref TValue key, ref TValue v )
		{
			int idx;
			if( fs.H.TryGetValue( key, out idx ) )
				return idx;

			idx = fs.Proto.K.Count;
			fs.H.Add( key, idx );

			var newItem = new StkId();
			newItem.V.SetObj(ref v);
			fs.Proto.K.Add(newItem);
			// Debug.Log("--------- ADD K ------- " + fs.Proto.K.Count + " line:" + fs.Lexer.LineNumber + " key:" + key);
			return idx;
		}
 private bool IsPositiveInteger(ref TValue v)
 {
     return(v.TtIsNumber() && v.NValue > 0 && (v.NValue % 1) == 0 && v.NValue <= int.MaxValue);              //fix large number key bug
 }