AstNode ParseLabelledStatement(Position nodeStart, string maybeName, AstSymbol expr) { foreach (var label in _labels) { if (label.Name == maybeName) { Raise(expr.Start, "Label '" + maybeName + "' is already declared"); } } var newlabel = new AstLabel(this, nodeStart, _lastTokEnd, maybeName); newlabel.IsLoop = TokenInformation.Types[Type].IsLoop; _labels.Add(newlabel); var body = ParseStatement(true); if (body is AstClass || body is AstLet || body is AstConst || body is AstFunction functionDeclaration && (_strict || functionDeclaration.IsGenerator)) { RaiseRecoverable(body.Start, "Invalid labelled declaration"); } _labels.Pop(); return(new AstLabeledStatement(this, nodeStart, _lastTokEnd, (AstStatement)body, newlabel)); }
public void CheckLabel(AstLabel label) { if (!GetLabel().Equals(label)) { throw new Exception("Expected label " + label.ToString() + " but instead have label " + GetLabel().ToString()); } }
protected void MarkLabel(AstLabel Label) { MarkLabelHook(Label); if (ILGenerator != null) { ILGenerator.MarkLabel(_GetLabelFromAstLabel(Label)); } }
protected void MarkLabelHook(AstLabel label) { if (GenerateLines) { Lines.Add($"Label_{label.Name}:;"); } }
protected void Emit(OpCode OpCode, AstLabel Value) { EmitHook(OpCode, Value); if (ILGenerator != null) { ILGenerator.Emit(OpCode, _GetLabelFromAstLabel(Value)); } }
/// <summary> /// Create the body of the valueOf(string) method. /// </summary> private AstBlock CreateValueOfBody(XSyntheticMethodDefinition method, XTypeSystem typeSystem) { var fields = XType.Fields.Where(x => x.IsStatic && !(x is XSyntheticFieldDefinition)).ToList(); var ast = AstBlock.Create <AstExpression>(); // Find name foreach (var field in fields) { var notEqualLabel = new AstLabel(AstNode.NoSource, "not_equal_to" + field.Name); var equalsExpr = new AstExpression(AstNode.NoSource, AstCode.Call, FrameworkReferences.StringEquals(typeSystem), new AstExpression(AstNode.NoSource, AstCode.Ldstr, field.Name), new AstExpression(AstNode.NoSource, AstCode.Ldloc, method.AstParameters[0])); // If !equals(name, field.name) goto notEqualLabel ast.Body.Add(new AstExpression(AstNode.NoSource, AstCode.Brfalse, notEqualLabel, equalsExpr)); // Return field object ast.Body.Add(new AstExpression(AstNode.NoSource, AstCode.Ret, null, new AstExpression(AstNode.NoSource, AstCode.Ldsfld, field))); // notEqualLabel: ast.Body.Add(notEqualLabel); } // Return null ast.Body.Add(new AstExpression(AstNode.NoSource, AstCode.Ret, null, new AstExpression(AstNode.NoSource, AstCode.Ldnull, null))); return(ast); }
/// <summary> /// Create the body of the unbox(object) method. /// </summary> private AstBlock CreateUnboxBody(XSyntheticMethodDefinition method, bool isWide, AssemblyCompiler compiler) { // Prepare var loc = AstNode.NoSource; Func <AstExpression> ldValue = () => new AstExpression(loc, AstCode.Ldloc, method.AstParameters[0]); var afterMyEnum = new AstLabel(loc, "_afterMyEnum"); // value instanceof MyEnumType? var ifNotInstanceOfMyEnum = new AstExpression(loc, AstCode.Brfalse, afterMyEnum, new AstExpression(loc, AstCode.SimpleInstanceOf, XType, ldValue())); var returnMyEnum = new AstExpression(loc, AstCode.Ret, null, new AstExpression(loc, AstCode.SimpleCastclass, XType, ldValue())); // boxToMyEnum(UnboxInteger(value)) var boxingType = compiler.GetDot42InternalType("Boxing").Resolve(); var unboxNumericMethod = boxingType.Methods.First(x => x.Name == (isWide ? "UnboxLong" : "UnboxInteger")); var unboxToNumeric = new AstExpression(loc, AstCode.Call, unboxNumericMethod, ldValue()); var numericToMyEnum = new AstExpression(loc, isWide ? AstCode.Long_to_enum : AstCode.Int_to_enum, XType, unboxToNumeric).SetType(XType); var returnX = new AstExpression(loc, AstCode.Ret, null, numericToMyEnum); var ast = new AstBlock(loc, new AstNode[] { ifNotInstanceOfMyEnum, returnMyEnum, afterMyEnum, returnX }); return(ast); }
/// <summary> /// Record the given label /// </summary> public override RLRange Visit(AstLabel node, AstNode parent) { var nop = this.Add(node.SourceLocation, RCode.Nop); labelManager.SetTarget(node, nop); return(new RLRange(nop, null)); }
protected void MarkLabelHook(AstLabel Label) { if (GenerateLines) { Lines.Add(String.Format("Label_{0}:;", Label.Name)); } }
private Label _GetLabelFromAstLabel(AstLabel AstLabel) { if (!_LabelCache.ContainsKey(AstLabel)) { _LabelCache[AstLabel] = ILGenerator.DefineLabel(); } return(_LabelCache[AstLabel]); }
public AstLabel Label(bool create) { if ((label != null) || !create) { return(label); } return(label = new AstLabel(SourceLocation, Name)); }
private Label _GetLabelFromAstLabel(AstLabel astLabel) { if (!_labelCache.ContainsKey(astLabel)) { _labelCache[astLabel] = IlGenerator.DefineLabel(); } return(_labelCache[astLabel]); }
private void ValidateLabel(AstLabel label) { if (label.Index < 0 || label.Index >= this.labels.Count || this.labels[label.Index] != label) { throw new ArgumentException("AstLabel not created by this AstBodyBuilder.", nameof(label)); } }
public RLRange BranchToFinally_Leave(ISourceLocation sourceLocation, AstLabel labelTarget, List <RLRange> args) { int insIdx = _compiler.instructions.Count; var target = new FinallyTarget { IsLeave = true }; _compiler.labelManager.AddResolveAction(labelTarget, ins => target.Destination = ins); return(BranchToFinally(target, args, sourceLocation, ref insIdx)); }
/// <summary> /// Get/create an entry for the given label. /// </summary> private Entry GetLabel(AstLabel label) { Entry result; var name = contextStack.Peek() + label.Name; if (!labels.TryGetValue(name, out result)) { result = new Entry(); labels.Add(name, result); } return result; }
/// <summary> /// Get/create an entry for the given label. /// </summary> private Entry GetLabel(AstLabel label) { Entry result; var name = contextStack.Peek() + label.Name; if (!labels.TryGetValue(name, out result)) { result = new Entry(); labels.Add(name, result); } return(result); }
public CatAstNode(PegAstNode node) { if (node.GetLabel() != null) { mLabel = (AstLabel)node.GetLabel(); } else { mLabel = AstLabel.AstRoot; } msText = node.ToString(); }
public void MarkLabel(AstLabel label) { ValidateLabel(label); if (this.markedLabels[label.Index]) { throw new ArgumentException($"Label {label.Index} is already marked.", nameof(label)); } this.markedLabels[label.Index] = true; AddStatement( AstFactory.LabelStatement(label)); }
/// <summary> /// Replace endfinally with jump to the end of the finally block /// </summary> void RemoveEndFinally(AstBlock method) { // Go thought the list in reverse so that we do the nested blocks first foreach (var tryCatch in method.GetSelfAndChildrenRecursive <AstTryCatchBlock>(tc => tc.FinallyBlock != null).Reverse()) { var label = new AstLabel(tryCatch.FinallyBlock.SourceLocation, "EndFinally_" + nextLabelIndex++); tryCatch.FinallyBlock.Body.Add(label); foreach (var block in tryCatch.FinallyBlock.GetSelfAndChildrenRecursive <AstBlock>()) { for (int i = 0; i < block.Body.Count; i++) { if (block.Body[i].Match(AstCode.Endfinally)) { block.Body[i] = new AstExpression(block.Body[i].SourceLocation, AstCode.Br, label).WithILRanges(((AstExpression)block.Body[i]).ILRanges); } } } } }
// Code executed after the delayed slot. public AstNodeStm _branch_post(AstLabel branchLabel, uint branchPc) { if (_andLink) { return(_ast.If( BranchFlag(), _ast.StatementsInline( _ast.AssignGpr(31, branchPc + 8), CallFixedAddress(branchPc) ) )); } else { return(_ast.Statements( //ast.AssignPC(PC), //ast.GetTickCall(), _ast.GotoIfTrue(branchLabel, BranchFlag()) )); } }
private static void AddJumpInstruction(List <AstNode> body, ISourceLocation currentLoc, AstGeneratedVariable setInstructionTarget, ref int idx, ref AstLabel label, int firstValidExpression, AstExpression initExpr, ref int labelCount) { if (label == null) { label = new AstLabel(AstNode.NoSource, "setInstructionTarget_" + (++labelCount)); body.Insert(firstValidExpression, label); body.Insert(firstValidExpression + 1, initExpr); idx += 2; } var branch = new AstExpression(currentLoc, AstCode.Brtrue, label, new AstExpression(currentLoc, AstCode.Ldloc, setInstructionTarget) { InferredType = setInstructionTarget.Type }); body.Insert(idx, branch); idx += 1; }
public void Berecne() { if (null == AstMission) { return; } AstLabel = Optimat.EveOnline.AuswertGbs.Extension.FirstMatchingNodeFromSubtreeBreadthFirst( AstMission, (kandidaat) => string.Equals("EveLabelMedium", kandidaat.PyObjTypName, StringComparison.InvariantCultureIgnoreCase), 3, 1); if (null == AstLabel) { return; } var AstLabelBescriftung = AstLabel.LabelText(); Ergeebnis = new UIElementText(AstMission.AsUIElementIfVisible(), AstLabelBescriftung); this.Ergeebnis = Ergeebnis; }
public static CatAstNode Create(PegAstNode node) { AstLabel label = (AstLabel)node.GetLabel(); switch (label) { case AstLabel.AstRoot: return(new AstRoot(node)); case AstLabel.Def: return(new AstDef(node)); case AstLabel.Name: return(new AstName(node)); case AstLabel.Param: return(new AstParam(node)); case AstLabel.Lambda: return(new AstLambda(node)); case AstLabel.Quote: return(new AstQuote(node)); case AstLabel.Char: return(new AstChar(node)); case AstLabel.String: return(new AstString(node)); case AstLabel.Float: return(new AstFloat(node)); case AstLabel.Int: return(new AstInt(node)); case AstLabel.Bin: return(new AstBin(node)); case AstLabel.Hex: return(new AstHex(node)); case AstLabel.Stack: return(new AstStack(node)); case AstLabel.FxnType: return(new AstFxnType(node)); case AstLabel.TypeVar: return(new AstTypeVar(node)); case AstLabel.TypeName: return(new AstSimpleType(node)); case AstLabel.StackVar: return(new AstStackVar(node)); case AstLabel.MacroRule: return(new AstMacro(node)); case AstLabel.MacroProp: return(new AstMacro(node)); case AstLabel.MacroPattern: return(new AstMacroPattern(node)); case AstLabel.MacroQuote: return(new AstMacroQuote(node)); case AstLabel.MacroTypeVar: return(new AstMacroTypeVar(node)); case AstLabel.MacroStackVar: return(new AstMacroStackVar(node)); case AstLabel.MacroName: return(new AstMacroName(node)); case AstLabel.MetaDataContent: return(new AstMetaDataContent(node)); case AstLabel.MetaDataLabel: return(new AstMetaDataLabel(node)); case AstLabel.MetaDataBlock: return(new AstMetaDataBlock(node)); default: throw new Exception("unrecognized node type in AST tree: " + label); } }
public CatAstNode(AstLabel label, string sText) { mLabel = label; msText = sText; }
public AstNodeStmGotoIf(AstLabel AstLabel, AstNodeExpr Condition) : base(AstLabel) { this.Condition = Condition; }
public RLRange BranchToFinally_Leave(ISourceLocation sourceLocation, AstLabel labelTarget, List<RLRange> args) { int insIdx = _compiler.instructions.Count; var target = new FinallyTarget {IsLeave = true }; _compiler.labelManager.AddResolveAction(labelTarget, ins=> target.Destination = ins); return BranchToFinally(target, args, sourceLocation, ref insIdx); }
public static Rule CatAstNode(AstLabel label, Rule x) { return new AstNodeRule(label, x); }
public AstLabel Label(bool create) { if ((label != null) || !create) return label; return (label = new AstLabel(SourceLocation, Name)); }
public AstLiteral(AstLabel label, string sText) : base(label, sText) { }
public CatAstNode(PegAstNode node) { if (node.GetLabel() != null) mLabel = (AstLabel)node.GetLabel(); else mLabel = AstLabel.AstRoot; msText = node.ToString(); }
public AstNodeStmGoto(AstLabel AstLabel) { this.AstLabel = AstLabel; }
/// <summary> /// Create the body of the unbox(object) method. /// </summary> private AstBlock CreateUnboxBody(XSyntheticMethodDefinition method, bool isWide, AssemblyCompiler compiler) { // Prepare var loc = AstNode.NoSource; Func<AstExpression> ldValue = () => new AstExpression(loc, AstCode.Ldloc, method.AstParameters[0]); var afterMyEnum = new AstLabel(loc, "_afterMyEnum"); // value instanceof MyEnumType? var ifNotInstanceOfMyEnum = new AstExpression(loc, AstCode.Brfalse, afterMyEnum, new AstExpression(loc, AstCode.SimpleInstanceOf, XType, ldValue())); var returnMyEnum = new AstExpression(loc, AstCode.Ret, null, new AstExpression(loc, AstCode.SimpleCastclass, XType, ldValue())); // boxToMyEnum(UnboxInteger(value)) var boxingType = compiler.GetDot42InternalType("Boxing").Resolve(); var unboxNumericMethod = boxingType.Methods.First(x => x.Name == (isWide ? "UnboxLong" : "UnboxInteger")); var unboxToNumeric = new AstExpression(loc, AstCode.Call, unboxNumericMethod, ldValue()); var numericToMyEnum = new AstExpression(loc, isWide ? AstCode.Long_to_enum : AstCode.Int_to_enum, XType, unboxToNumeric).SetType(XType); var returnX = new AstExpression(loc, AstCode.Ret, null, numericToMyEnum); var ast = new AstBlock(loc, new AstNode[] { ifNotInstanceOfMyEnum, returnMyEnum, afterMyEnum, returnX }); return ast; }
public AstNodeStmGotoAlways(AstLabel AstLabel) : base(AstLabel) { }
/// <summary> /// Set the target of the given label, resolving any pending actions. /// </summary> public void SetTarget(AstLabel label, Instruction target) { GetLabel(label).Target = target; }
public void CheckLabel(AstLabel label) { if (!GetLabel().Equals(label)) throw new Exception("Expected label " + label.ToString() + " but instead have label " + GetLabel().ToString()); }
public AstExpr(AstLabel label, string sText) : base(label, sText) { }
protected void Emit(OpCode opCode, AstLabel value) { EmitHook(opCode, value); IlGenerator?.Emit(opCode, _GetLabelFromAstLabel(value)); }
public virtual TReturn Visit(AstLabel node, TData data) { return(default(TReturn)); }
public AstNodeStmLabel(AstLabel AstLabel) { this.AstLabel = AstLabel; }
/// <summary> /// PASS 1: Analyze Branches /// </summary> private void AnalyzeBranches() { _skipPc = new HashSet <uint>(); _analyzedPc = new HashSet <uint>(); var branchesToAnalyze = new Queue <uint>(); _labels[_entryPc] = AstLabel.CreateLabel("EntryPoint"); var endPc = _instructionReader.EndPc; _pc = _entryPc; _minPc = uint.MaxValue; _maxPc = uint.MinValue; branchesToAnalyze.Enqueue(_entryPc); while (true) { HandleNewBranch: var endOfBranchFound = false; if (branchesToAnalyze.Count == 0) { break; } for (_pc = branchesToAnalyze.Dequeue(); _pc <= endPc; _pc += 4) { // If already analyzed, stop scanning this branch. if (_analyzedPc.Contains(_pc)) { break; } _analyzedPc.Add(_pc); //Console.WriteLine("%08X".Sprintf(PC)); if (_analyzedPc.Count > MaxNumberOfInstructions) { throw new InvalidDataException( $"Code sequence too long: >= {MaxNumberOfInstructions} at 0x{_entryPc:X8}"); } UpdateMinMax(_pc); //Console.WriteLine(" PC:{0:X}", PC); var instruction = _instructionReader[_pc]; var branchInfo = DynarecBranchAnalyzer.GetBranchInfo(instruction); var disassemblerInfo = _mipsDisassembler.Disassemble(_pc, instruction); LogInstruction(_pc, instruction); // Break if (disassemblerInfo.InstructionInfo.Name == "break") { break; } // Branch instruction. //else if (BranchInfo.HasFlag(DynarecBranchAnalyzer.JumpFlags.JumpAlways)) else if (branchInfo.HasFlag(DynarecBranchAnalyzer.JumpFlags.JumpInstruction)) { //Console.WriteLine("Instruction"); var jumpAddress = instruction.GetJumpAddress(_memory, _pc); // Located a jump-always instruction with a delayed slot. Process next instruction too. if (branchInfo.HasFlag(DynarecBranchAnalyzer.JumpFlags.AndLink)) { // Just a function call. Continue analyzing. } else { if (PspMemory.IsAddressValid(jumpAddress)) { if (!_labelsJump.ContainsKey(jumpAddress)) { if (AddressInsideFunction(jumpAddress)) { //Console.WriteLine("JumpAddress: {0:X8}", JumpAddress); _labelsJump[jumpAddress] = AstLabel.CreateLabel($"Jump_0x{jumpAddress:X8}"); branchesToAnalyze.Enqueue(jumpAddress); } } } endOfBranchFound = true; continue; } } else if (branchInfo.HasFlag(DynarecBranchAnalyzer.JumpFlags.BranchOrJumpInstruction)) { var branchAddress = instruction.GetBranchAddress(_pc); if (!_labels.ContainsKey(branchAddress)) { //Console.WriteLine("BranchAddress: {0:X8}", BranchAddress); UpdateMinMax(branchAddress); _labels[branchAddress] = AstLabel.CreateLabel($"Label_0x{branchAddress:X8}"); branchesToAnalyze.Enqueue(branchAddress); } } else if (branchInfo.HasFlag(DynarecBranchAnalyzer.JumpFlags.SyscallInstruction)) { // On this special Syscall if (instruction.Code == SyscallInfo.NativeCallSyscallCode) { //PC += 4; goto HandleNewBranch; } } // Jump-Always found. And we have also processed the delayed branch slot. End the branch. if (endOfBranchFound) { endOfBranchFound = false; goto HandleNewBranch; } } } //Console.WriteLine("FunctionSegment({0:X8}-{1:X8})", MinPC, MaxPC); foreach (var labelAddress in _labelsJump.Keys.ToArray()) { if (!AddressInsideFunction(labelAddress)) { _labelsJump.Remove(labelAddress); } } _cpuEmitter.BranchCount = _labels.Count; }
public AstNodeStmLabel(AstLabel astLabel) => AstLabel = astLabel;
public AstNodeStmGotoIfFalse(AstLabel AstLabel, AstNodeExpr Condition) : base(AstLabel, Condition) { }
/// <summary> /// Record an action to be called when the target is known. /// </summary> public void AddResolveAction(AstLabel label, Action<Instruction> action) { GetLabel(label).AddResolveAction(action); }
private static void AddJumpInstruction(List<AstNode> body, ISourceLocation currentLoc, AstGeneratedVariable setInstructionTarget, ref int idx, ref AstLabel label, int firstValidExpression, AstExpression initExpr, ref int labelCount) { if (label == null) { label = new AstLabel(AstNode.NoSource, "setInstructionTarget_" + (++labelCount)); body.Insert(firstValidExpression, label); body.Insert(firstValidExpression + 1, initExpr); idx += 2; } var branch = new AstExpression(currentLoc, AstCode.Brtrue, label, new AstExpression(currentLoc, AstCode.Ldloc, setInstructionTarget) { InferredType = setInstructionTarget.Type }); body.Insert(idx, branch); idx += 1; }
public override void VisitLabel(AstLabel node) { Append($"label_{node.Index}"); }
/// <summary> /// Create the body of the valueOf(string) method. /// </summary> private AstBlock CreateValueOfBody(XSyntheticMethodDefinition method, XTypeSystem typeSystem) { var fields = XType.Fields.Where(x => x.IsStatic && !(x is XSyntheticFieldDefinition)).ToList(); var ast = AstBlock.Create<AstExpression>(); // Find name foreach (var field in fields) { var notEqualLabel = new AstLabel(AstNode.NoSource, "not_equal_to" + field.Name); var equalsExpr = new AstExpression(AstNode.NoSource, AstCode.Call, FrameworkReferences.StringEquals(typeSystem), new AstExpression(AstNode.NoSource, AstCode.Ldstr, field.Name), new AstExpression(AstNode.NoSource, AstCode.Ldloc, method.AstParameters[0])); // If !equals(name, field.name) goto notEqualLabel ast.Body.Add(new AstExpression(AstNode.NoSource, AstCode.Brfalse, notEqualLabel, equalsExpr)); // Return field object ast.Body.Add(new AstExpression(AstNode.NoSource, AstCode.Ret, null, new AstExpression(AstNode.NoSource, AstCode.Ldsfld, field))); // notEqualLabel: ast.Body.Add(notEqualLabel); } // Return null ast.Body.Add(new AstExpression(AstNode.NoSource, AstCode.Ret, null, new AstExpression(AstNode.NoSource, AstCode.Ldnull, null))); return ast; }