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); } }
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)); } }
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); }
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))); }
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; }
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); }