Пример #1
0
        private void CGNameExp(FuncInfo funcInfo, ConstExpNode node, int a)
        {
            LocalVarInfo varInfo = null;
            int          r       = 0;

            if (funcInfo.VarDic1.TryGetValue(node.name, out varInfo))
            {
                funcInfo.EmitMove(a, varInfo.RegIndex);
            }
            else if (funcInfo.UpValOfIndex(node.name) != -1)
            {
                r = funcInfo.UpValOfIndex(node.name);
                funcInfo.EmitGetUpval(a, r);
            }
            //else if (funcInfo.ConstDic.TryGetValue(node.name, out r))
            //   {
            //       funcInfo.EmitLoadK(a, node.name);
            //   }
            else
            {
                var exp = new TableAccessExpNode();
                exp.PreExp = new ConstExpNode(new Token(TokenType.Identifier, "_ENV", -1));
                exp.Exp    = new ConstExpNode(new Token(TokenType.String, node.name, -1));
                CGTableAccessExp(funcInfo, exp, a);
            }
        }
Пример #2
0
        private static void Parse(MoveInfo parentInfo, ParsingInfo parsingInfo, ScriptInfo scriptInfo)
        {
            Assign assign = new Assign();

            int startIndex;
            int length;

            // find var define
            MoveInfo varInfo = new MoveInfo(parentInfo);
            IElement var     = varInfo.FindNextBlack(SearchDirection.RightToLeft);

            if (var == null || !(var is ExpressionOperand) || !(var is VarName))
            {
                throw new SyntaxException("Could not parse Assign VarName", parentInfo.GetErrorInfo());
            }

            assign.VarName = (VarName)var;

            startIndex = varInfo.CurrentIndex;

            // parse expression
            MoveInfo moveInfo = new MoveInfo(parentInfo);

            moveInfo.FindNextBlack(SearchDirection.LeftToRight); // move behind =
            Expression exp = Expression.Parse(moveInfo, parsingInfo, scriptInfo, false, true, true);

            if (exp == null)
            {
                throw new SyntaxException("Could not parse Assign Expression", parentInfo.GetErrorInfo());
            }

            assign.Exp = exp;

            // build
            length = (moveInfo.CurrentIndex + 1) - startIndex;
            assign.AddChildren(parentInfo.CurrentElements.GetRange(startIndex, length));

            parentInfo.MoveToIndex(startIndex);
            parentInfo.Replace(length, assign);

            // add local var def
            IElement baseVar     = ((VarName)var).GetChildren()[0];
            string   baseVarName = baseVar.ToString();

            foreach (string tStr in ScriptManager.GlobalVariables)
            {
                if (baseVarName.EqualCode(tStr))
                {
                    return;
                }
            }

            LocalVarInfo tryVarInfo = parsingInfo.CurrentFunc.LocalVars.Find(a => a.Name.EqualCode(baseVarName)); // there is maybe var with this name...

            if (tryVarInfo == null)
            {
                parsingInfo.CurrentFunc.LocalVars.Add(new LocalVarInfo(parsingInfo.SF, baseVarName, baseVar.CharIndex, baseVar.CharLength, assign, (VarName)var));
            }
        }
Пример #3
0
        private static bool GetLocalsInfoForMethod(string assemblyPath, int methodToken, out List <LocalVarInfo> locals)
        {
            locals = null;

            OpenedReader openedReader = GetReader(assemblyPath, isFileLayout: true, peStream: null, pdbStream: null);

            if (openedReader == null)
            {
                return(false);
            }

            using (openedReader)
            {
                try
                {
                    Handle handle = MetadataTokens.Handle(methodToken);
                    if (handle.Kind != HandleKind.MethodDefinition)
                    {
                        return(false);
                    }

                    locals = new List <LocalVarInfo>();

                    MethodDebugInformationHandle methodDebugHandle =
                        ((MethodDefinitionHandle)handle).ToDebugInformationHandle();
                    LocalScopeHandleCollection localScopes = openedReader.Reader.GetLocalScopes(methodDebugHandle);
                    foreach (LocalScopeHandle scopeHandle in localScopes)
                    {
                        LocalScope scope = openedReader.Reader.GetLocalScope(scopeHandle);
                        LocalVariableHandleCollection localVars = scope.GetLocalVariables();
                        foreach (LocalVariableHandle varHandle in localVars)
                        {
                            LocalVariable localVar = openedReader.Reader.GetLocalVariable(varHandle);
                            if (localVar.Attributes == LocalVariableAttributes.DebuggerHidden)
                            {
                                continue;
                            }
                            LocalVarInfo info = new LocalVarInfo();
                            info.startOffset = scope.StartOffset;
                            info.endOffset   = scope.EndOffset;
                            info.name        = openedReader.Reader.GetString(localVar.Name);
                            locals.Add(info);
                        }
                    }
                }
                catch
                {
                    return(false);
                }
            }
            return(true);
        }
Пример #4
0
        public override void CheckSemantic(MoveInfo treeInfo, ScriptInfo scriptInfo, CheckingInfo checkingInfo)
        {
            IElement baseVar     = this.GetChildren()[0];
            string   baseVarName = baseVar.ToString();

            foreach (string tStr in ScriptManager.GlobalVariables)
            {
                if (baseVarName.EqualCode(tStr))
                {
                    return;
                }
            }

            if (checkingInfo.CurrentFunc != null) // inside func
            {
                LocalVarInfo tryVarInfo = checkingInfo.CurrentFunc.LocalVars.Find(a => a.Name.EqualCode(baseVarName));
                if (tryVarInfo != null && this.CharIndex >= tryVarInfo.StartIndex)
                {
                    // check "var = var;" | "var[5] = var[5] + 10"; | etc.
                    if (tryVarInfo.VarNameDef == null) // it is reference
                    {
                        tryVarInfo.RefCount++;
                        return;
                    }
                    else if (tryVarInfo.VarNameDef == this) // it is definition
                    {
                        return;
                    }
                    else if (tryVarInfo.AssignDef == null) // it is reference
                    {
                        tryVarInfo.RefCount++;
                        return;
                    }
                    else if (!treeInfo.IsInBlock(tryVarInfo.AssignDef)) // it is reference
                    {
                        tryVarInfo.RefCount++;
                        return;
                    }
                }
            }

            ConstInfo constInfo = scriptInfo.FindLocalConst(baseVarName);

            if (constInfo == null)
            {
                constInfo = scriptInfo.FindIncludesConst(baseVarName);
                if (constInfo == null)
                {
                    constInfo = scriptInfo.FindGlobalsConst(baseVarName);
                    if (constInfo == null)
                    {
                        scriptInfo.SF.Errors.Add(
                            new SemanticError("Unknown variable/constant '" + baseVarName + "'",
                                              treeInfo.GetErrorInfo(treeInfo.Current)));
                        return;
                    }
                }

                if (constInfo.Access == MemberAccess.Private)
                {
                    scriptInfo.SF.Errors.Add(
                        new SemanticError("Cannot access member '" + baseVarName + "'",
                                          treeInfo.GetErrorInfo(treeInfo.Current)));
                }
            }

            ToConstant(treeInfo, constInfo);
            scriptInfo.References.Add(new ConstRefInfo(scriptInfo.SF, constInfo,
                                                       this.CharIndex, this.CharLength, checkingInfo.SC.SourceCode.Substring(this.CharIndex, this.CharLength)));
        }
Пример #5
0
        private void CGAssignStat(FuncInfo funcInfo, AssignStatNode node)
        {
            int nExps   = node.ExpList.Count;
            int nVars   = node.VarList.Count;
            int oldRegs = funcInfo.UsedReg;
            var tRegs   = new int[nVars];
            var kRegs   = new int[nVars];
            var vRegs   = new int[nVars];

            int i = 0;

            foreach (var exp in node.VarList)
            {
                TableAccessExpNode taExp    = null;
                ConstExpNode       constExp = null;
                if ((taExp = exp as TableAccessExpNode) != null)
                {
                    tRegs[i] = funcInfo.AllocReg();
                    CGExp(funcInfo, taExp.PreExp, tRegs[i], 1);

                    kRegs[i] = funcInfo.AllocReg();
                    CGExp(funcInfo, taExp.Exp, kRegs[i], 1);
                }
                i++;
            }
            for (int j = 0; j < nVars; j++)
            {
                vRegs[j] = funcInfo.UsedReg + j;
            }
            if (nExps >= nVars)
            {
                i = 0;
                foreach (var exp in node.ExpList)
                {
                    int a = funcInfo.AllocReg();
                    if (i > nVars && i == nExps - 1 && IsVarargOrFuncCall(exp))
                    {
                        CGExp(funcInfo, exp, a, 0);
                    }
                    else
                    {
                        CGExp(funcInfo, exp, a, 1);
                    }
                    i++;
                }
            }
            else
            {
                bool multRet = false;
                i = 0;
                foreach (var exp in node.ExpList)
                {
                    int a = funcInfo.AllocReg();
                    if (i == nExps - 1 && IsVarargOrFuncCall(exp))
                    {
                        multRet = true;
                        int n = nVars - nExps + 1;
                        CGExp(funcInfo, exp, a, n);
                        funcInfo.AllocRegs(n - 1);
                    }
                    else
                    {
                        CGExp(funcInfo, exp, a, 1);
                    }
                    i++;
                }
                if (!multRet)
                {
                    int n = nVars - nExps;
                    int a = funcInfo.AllocRegs(n);
                    funcInfo.EmitLoadNil(a, n);
                }
            }

            i = 0;
            foreach (var exp in node.VarList)
            {
                ConstExpNode varNode = null;
                int          r       = 0;
                if ((varNode = exp as ConstExpNode) != null)
                {
                    var          name = varNode.name;
                    LocalVarInfo info = null;
                    if (funcInfo.VarDic1.TryGetValue(name, out info))
                    {
                        funcInfo.EmitMove(info.RegIndex, vRegs[i]);
                    }
                    else if (funcInfo.UpValOfIndex(name) >= 0)
                    {
                        int b = funcInfo.UpValOfIndex(name);
                        funcInfo.EmitSetUpval(vRegs[i], b);
                    }
                    else if (funcInfo.ConstDic.TryGetValue(varNode.name, out r))
                    {
                        funcInfo.EmitLoadK(vRegs[i], varNode.name);
                    }
                    else //全局变量
                    {
                        int a = funcInfo.UpValOfIndex("_ENV");
                        if (kRegs[i] <= 0)
                        {
                            int b = 0x100 + funcInfo.IndexOfConstVar(name);
                            funcInfo.EmitSetTabUp(a, b, vRegs[i]);
                        }
                        else
                        {
                            funcInfo.EmitSetTabUp(a, kRegs[i], vRegs[i]);
                        }
                    }
                }
                else
                {
                    funcInfo.EmitSetTable(tRegs[i], kRegs[i], vRegs[i]);
                }
                i++;
            }
            funcInfo.UsedReg = oldRegs;
        }
Пример #6
0
        private static void Parse(MoveInfo parentInfo, ParsingInfo parsingInfo, ScriptInfo scriptInfo)
        {
            ForEachStatement foreachStatement = new ForEachStatement();
            MoveInfo         moveInfo         = new MoveInfo(parentInfo);

            foreachStatement._foreachKeyword = (Token)moveInfo.Current;

            // expression
            IElement expGroupTry = moveInfo.FindNextBlack(SearchDirection.LeftToRight);

            if (expGroupTry == null || !(expGroupTry is ParenthesesGroup))
            {
                throw new SyntaxException("Could not find foreach expression", parentInfo.GetErrorInfo());
            }

            ParenthesesGroup expGroup     = (ParenthesesGroup)expGroupTry;
            MoveInfo         expGroupInfo = new MoveInfo(expGroup, SearchTree.ContentBlock, 0, parentInfo);

            foreachStatement._foreachGroup = expGroup;

            // var define
            IElement tryVar = expGroupInfo.Find(SearchDirection.LeftToRight, SearchVisibility.Visible);

            if (tryVar == null || !tryVar.IsTT(TokenType.Word))
            {
                throw new SyntaxException("Could not parse foreach var", parentInfo.GetErrorInfo());
            }

            VarName.Parse(expGroupInfo, parsingInfo, scriptInfo);
            VarName varName = (VarName)expGroupInfo.Current;

            LocalVarInfo localVar = parsingInfo.CurrentFunc.LocalVars.Find(a => a.Name.EqualCode(tryVar.ToString()));     // there is already var with this name...

            if (localVar == null)
            {
                parsingInfo.CurrentFunc.LocalVars.Add(new LocalVarInfo(scriptInfo.SF, tryVar.ToString(), tryVar.CharIndex, tryVar.CharLength, null, varName));
            }

            foreachStatement._currentVar = varName;

            // in keyword
            IElement tryIn = expGroupInfo.FindNextBlack(SearchDirection.LeftToRight);

            if (tryIn == null || !tryIn.IsTT(TokenType.Word) || !tryIn.ToString().EqualCode("in"))
            {
                throw new SyntaxException("Could not find foreach 'in'", parentInfo.GetErrorInfo());
            }

            // array
            IElement   tryArray    = expGroupInfo.FindNextBlack(SearchDirection.LeftToRight);
            Expression tryArrayExp = Expression.Parse(expGroupInfo, parsingInfo, scriptInfo);

            if (tryArrayExp == null || expGroupInfo.FindNextBlack(SearchDirection.LeftToRight) != null)
            {
                throw new SyntaxException("Could not parse foreach array", parentInfo.GetErrorInfo());
            }

            foreachStatement._array = tryArrayExp;

            // statement
            moveInfo.FindNextBlack(SearchDirection.LeftToRight);
            if (!Statement.Check(moveInfo, parsingInfo, scriptInfo))
            {
                throw new SyntaxException("Could not parse foreach statement", parentInfo.GetErrorInfo());
            }

            foreachStatement._statement = (Statement)moveInfo.Current;

            // build
            int startIndex = parentInfo.CurrentIndex;
            int length     = (moveInfo.CurrentIndex + 1) - startIndex;

            foreachStatement.AddChildren(parentInfo.CurrentElements.GetRange(startIndex, length));
            parentInfo.Replace(length, foreachStatement);
        }