Пример #1
0
        private static Upvalue[] GetUpvalues(FuncInfo fi)
        {
            var upvals = new Upvalue[fi.Upvalues.Count];

            foreach (var kv in fi.Upvalues)
            {
                if (kv.Value.LocVarSlot >= 0)
                {
                    upvals[kv.Value.Index] = new Upvalue
                    {
                        Instack = 1,
                        Idx     = (byte)kv.Value.LocVarSlot
                    };
                }
                else
                {
                    upvals[kv.Value.Index] = new Upvalue
                    {
                        Instack = 0,
                        Idx     = (byte)kv.Value.UpvalIndex
                    };
                }
            }

            return(upvals);
        }
Пример #2
0
        /// <summary>
        /// Creates a closure from a bytecode address.
        /// </summary>
        /// <param name="address">The address.</param>
        /// <param name="envTable">The env table to create a 0-upvalue</param>
        /// <returns></returns>
        private DynValue MakeClosure(int address, Table envTable = null)
        {
            this.CheckScriptOwnership(envTable);
            Closure c;

            if (envTable == null)
            {
                Instruction?meta = m_MainProcessor.FindMeta(ref address);

                // if we find the meta for a new chunk, we use the value in the meta for the _ENV upvalue
                if ((meta != null) && (meta.Value.NumVal2 == (int)OpCodeMetadataType.ChunkEntrypoint))
                {
                    c = new Closure(this, address,
                                    new SymbolRef[] { SymbolRef.Upvalue(WellKnownSymbols.ENV, 0) },
                                    new Upvalue[1]);
                }
                else
                {
                    c = new Closure(this, address, new SymbolRef[0], new Upvalue[0]);
                }
            }
            else
            {
                var syms = new SymbolRef[] {
                    new SymbolRef()
                    {
                        i_Env = null, i_Index = 0, i_Name = WellKnownSymbols.ENV, i_Type = SymbolRefType.DefaultEnv
                    },
                };

                var vals = new Upvalue[] {
                    Upvalue.Create(DynValue.NewTable(envTable))
                };

                c = new Closure(this, address, syms, vals);
            }

            return(DynValue.NewClosure(c));
        }
Пример #3
0
        public void AssignGenericSymbol(SymbolRef symref, DynValue value)
        {
            switch (symref.i_Type)
            {
            case SymbolRefType.Global:
                SetGlobalSymbol(GetGenericSymbol(symref.i_Env), symref.i_Name, value);
                break;

            case SymbolRefType.Local:
            {
                var stackframe = GetTopNonClrFunction();
                m_ValueStack[stackframe.BasePointer + symref.i_Index] = value;
            }
            break;

            case SymbolRefType.Upvalue:
            {
                var stackframe = GetTopNonClrFunction();
                if (stackframe.ClosureScope[symref.i_Index] == null)
                {
                    stackframe.ClosureScope[symref.i_Index] = Upvalue.NewNil();
                }

                stackframe.ClosureScope[symref.i_Index].Value() = value;
            }
            break;

            case SymbolRefType.DefaultEnv:
            {
                throw new ArgumentException("Can't AssignGenericSymbol on a DefaultEnv symbol");
            }

            default:
                throw new InternalErrorException("Unexpected {0} LRef at resolution: {1}", symref.i_Type, symref.i_Name);
            }
        }
Пример #4
0
            private void ReadLua53Smash(LuaFile file, BinaryReaderEx br)
            {
                Name        = LuaFile.ReadLuaString(br, LuaVersion.Lua53Smash, false);
                LineDefined = br.ReadInt32();
                br.ReadInt32(); // last line
                NumParams    = br.ReadByte();
                IsVarArg     = br.ReadByte();
                MaxStackSize = br.ReadByte();
                int bytecodeCount = br.ReadInt32();

                Bytecode = br.ReadBytes(bytecodeCount * 4);
                int constantsCount = br.ReadInt32();

                Constants = new Constant[constantsCount];
                for (int i = 0; i < constantsCount; i++)
                {
                    Constants[i] = new Constant(file, br, LuaVersion.Lua53Smash);
                }
                int upvalct = br.ReadInt32();

                Upvalues = new Upvalue[upvalct];
                for (int i = 0; i < upvalct; i++)
                {
                    Upvalues[i] = new Upvalue(br);
                }
                int funcCount = br.ReadInt32();

                ChildFunctions = new Function[funcCount];
                for (int i = 0; i < funcCount; i++)
                {
                    ChildFunctions[i] = new Function(file, LuaVersion.Lua53Smash, br);
                }

                SizeLineInfo = br.ReadInt32();
                // Eat line numbers
                br.ReadInt32s(SizeLineInfo);

                LocalVarsCount = br.ReadInt32();
                Locals         = new Local[LocalVarsCount];
                LocalMap       = new Dictionary <int, List <Local> >();
                for (int i = 0; i < LocalVarsCount; i++)
                {
                    Locals[i] = new Local(br, LuaVersion.Lua53Smash);
                    if (!Locals[i].Name.StartsWith("("))
                    {
                        if (!LocalMap.ContainsKey(Locals[i].Start))
                        {
                            LocalMap[Locals[i].Start] = new List <Local>();
                        }
                        LocalMap[Locals[i].Start].Add(Locals[i]);
                    }
                }

                //br.ReadUInt32(); // upval names
                UpValuesCount = br.ReadInt32();
                UpvalueNames  = new UpvalueName[UpValuesCount];
                for (int i = 0; i < UpValuesCount; i++)
                {
                    UpvalueNames[i] = new UpvalueName(br, LuaVersion.Lua53Smash);
                }
            }