public void EmitExtract(IBlockContext context, List <IBlockVariable> targetVariables) { IBlockVariable target = targetVariables[0]; Type generatedType = optionType.GeneratedType(context.ModuleContext); context.IL.Emit(OpCodes.Dup); context.IL.Emit(OpCodes.Ldfld, generatedType.GetField("defined")); if (target == null) { context.IL.Emit(OpCodes.Pop); } else { LabelRef onUndefined = context.IL.DefineLabel(true); LabelRef end = context.IL.DefineLabel(true); context.IL.Emit(OpCodes.Brfalse_S, onUndefined); context.IL.Emit(OpCodes.Ldfld, generatedType.GetField("value")); target.EmitStore(context); context.IL.Emit(OpCodes.Ldc_I4_1); context.IL.Emit(OpCodes.Br_S, end); context.IL.MarkLabel(onUndefined); context.IL.Emit(OpCodes.Pop); context.IL.Emit(OpCodes.Ldc_I4_0); context.IL.MarkLabel(end); } }
public void EmitExtract(IBlockContext context, List <IBlockVariable> targetVariables) { IBlockVariable target = targetVariables[0]; Type generatedType = resultType.GeneratedType(context.ModuleContext); context.IL.Emit(OpCodes.Dup); context.IL.Emit(OpCodes.Ldfld, generatedType.GetField("success")); if (target == null) { context.IL.Emit(OpCodes.Ldc_I4_0); context.IL.Emit(OpCodes.Ceq); context.IL.Emit(OpCodes.Pop); } else { LabelRef onOk = context.IL.DefineLabel(true); LabelRef end = context.IL.DefineLabel(true); context.IL.Emit(OpCodes.Brtrue_S, onOk); context.IL.Emit(OpCodes.Ldfld, generatedType.GetField("error")); target.EmitStore(context); context.IL.Emit(OpCodes.Ldc_I4_1); context.IL.Emit(OpCodes.Br_S, end); context.IL.MarkLabel(onOk); context.IL.Emit(OpCodes.Pop); context.IL.Emit(OpCodes.Ldc_I4_0); context.IL.MarkLabel(end); } }
/// <summary> /// Initializes a new instance of the <see cref="ReduceActionItem"/> class. /// </summary> public ReduceActionItem(LabelRef label, IReadOnlyList<IReadOnlySet<CodePoint>> followRestriction) { #region Contract Contract.Requires<ArgumentNullException>(followRestriction != null); #endregion this.Label = label; this.FollowRestriction = followRestriction.ToArray(); }
public void Emit(OpCode opCode, LabelRef labelRef) { ilSize += InstructionSize.Get(opCode); AdjustStack(opCode); commands.Add(new ILCommand { opCode = opCode, args = $"<label>{labelRef.label.GetHashCode()}" }); }
public bool HasValidLayout(LabelRef? label, IReadOnlyList<IParseNode> children) { if (label == null) return true; var layoutConstraint = parseTable.Labels[((LabelRef)label).Index].Attributes.LayoutConstraint; if (layoutConstraint == null) return true; return EvalConstraint(layoutConstraint, children, new Dictionary<string, object>()); }
public void EmitCheckDone(IBlockContext context, LabelRef loop) { currentIndex.EmitLoad(context); context.IL.Emit(OpCodes.Ldc_I4_1); context.IL.Emit(OpCodes.Conv_I8); context.IL.Emit(OpCodes.Add); context.IL.Emit(OpCodes.Dup); currentIndex.EmitStore(context); rangeRef.EmitLoad(context); context.IL.Emit(OpCodes.Ldfld, typeof(Range).GetField("to")); context.IL.Emit(loop.isShort ? OpCodes.Blt_S : OpCodes.Blt, loop); }
private object OnLabelRef(LabelRef labelRef) { INiCommandBarControl control; ErrorUtil.ThrowOnFailure(_commandManager.FindCommandBarControl( labelRef.Guid, out control )); if (control == null) { throw new NetIdeException(String.Format(NeutralResources.CannotFindCommand, labelRef.Guid)); } return(control); }
private ILCount EstimateLoop(IBlockContext context, IForInSource source) { IBlockContext prepContext = context.CloneCountingContext(); sourceExpression.EmitCode(prepContext, false); source.EmitInitialize(prepContext); IBlockContext countingContext = prepContext.CloneCountingContext() .CreateLoopContext(context.IL.DefineLabel(false), context.IL.DefineLabel(false)); IBlockVariable loopVariable = countingContext.DeclaredVariable(variableName, true, source.ElementType); LabelRef loop = countingContext.IL.DefineLabel(false); source.EmitNext(countingContext); loopVariable.EmitStore(countingContext); loopExpression.EmitCode(countingContext, true); source.EmitCheckDone(countingContext, loop); return(new ILCount { opCodes = countingContext.IL.ILSize, stack = countingContext.IL.StackCount }); }
internal static AsyncClass Create(IBlockContext parent, string name, TO2Type declaredReturn, List <FunctionParameter> parameters, Expression expression) { Type returnType = declaredReturn.GeneratedType(parent.ModuleContext); Type typeParameter = returnType == typeof(void) ? typeof(object) : returnType; ModuleContext asyncModuleContext = parent.ModuleContext.DefineSubContext($"AsyncFunction_{name}", typeof(Future <>).MakeGenericType(typeParameter)); List <ClonedFieldVariable> clonedParameters = new List <ClonedFieldVariable>(); foreach (FunctionParameter parameter in parameters) { FieldBuilder field = asyncModuleContext.typeBuilder.DefineField(parameter.name, parameter.type.GeneratedType(parent.ModuleContext), FieldAttributes.Private); clonedParameters.Add( new ClonedFieldVariable(parameter.type.UnderlyingType(parent.ModuleContext), field)); } // ------------- PollValue ------------- AsyncBlockContext asyncContext = new AsyncBlockContext(asyncModuleContext, FunctionModifier.Public, "PollValue", declaredReturn, typeof(FutureResult <>).MakeGenericType(typeParameter), clonedParameters); LabelRef applyState = asyncContext.IL.DefineLabel(false); LabelRef initialState = asyncContext.IL.DefineLabel(false); asyncContext.IL.Emit(OpCodes.Br, applyState); asyncContext.IL.MarkLabel(initialState); expression.EmitCode(asyncContext, false); if (!asyncContext.HasErrors) { declaredReturn.AssignFrom(asyncContext.ModuleContext, expression.ResultType(asyncContext)) .EmitConvert(asyncContext); } asyncContext.IL.EmitNew(OpCodes.Newobj, asyncContext.MethodBuilder.ReturnType.GetConstructor(new[] { typeParameter })); asyncContext.IL.EmitReturn(asyncContext.MethodBuilder.ReturnType); // Apply state asyncContext.IL.MarkLabel(applyState); asyncContext.IL.Emit(OpCodes.Ldarg_0); asyncContext.IL.Emit(OpCodes.Ldfld, asyncContext.stateField); asyncContext.IL.Emit(OpCodes.Switch, initialState.Yield().Concat(asyncContext.asyncResumes.Select(ar => ar.pollLabel))); asyncContext.IL.Emit(OpCodes.Ldarg_0); asyncContext.IL.Emit(OpCodes.Ldfld, asyncContext.stateField); asyncContext.IL.EmitNew(OpCodes.Newobj, typeof(InvalidAsyncStateException).GetConstructor(new[] { typeof(int) }), 1); asyncContext.IL.Emit(OpCodes.Throw); foreach (AsyncResume asyncResume in asyncContext.asyncResumes) { asyncResume.EmitPoll(asyncContext); } // Restore state asyncContext.IL.MarkLabel(asyncContext.resume); foreach (StateRef stateRef in asyncContext.stateRefs) { stateRef.EmitRestore(asyncContext); } asyncContext.IL.Emit(OpCodes.Ldarg_0); asyncContext.IL.Emit(OpCodes.Ldfld, asyncContext.stateField); asyncContext.IL.Emit(OpCodes.Switch, initialState.Yield().Concat(asyncContext.asyncResumes.Select(ar => ar.resumeLabel))); asyncContext.IL.Emit(OpCodes.Ldarg_0); asyncContext.IL.Emit(OpCodes.Ldfld, asyncContext.stateField); asyncContext.IL.EmitNew(OpCodes.Newobj, typeof(InvalidAsyncStateException).GetConstructor(new[] { typeof(int) }), 1); asyncContext.IL.Emit(OpCodes.Throw); // Store state asyncContext.IL.MarkLabel(asyncContext.storeState); foreach (StateRef stateRef in asyncContext.stateRefs) { stateRef.EmitStore(asyncContext); } asyncContext.IL.MarkLabel(asyncContext.notReady); using (ITempLocalRef notReady = asyncContext.IL.TempLocal(asyncContext.MethodBuilder.ReturnType)) { notReady.EmitLoadPtr(asyncContext); asyncContext.IL.Emit(OpCodes.Initobj, asyncContext.MethodBuilder.ReturnType, 1, 0); notReady.EmitLoad(asyncContext); asyncContext.IL.EmitReturn(asyncContext.MethodBuilder.ReturnType); } foreach (StructuralError error in asyncContext.AllErrors) { parent.AddError(error); } // ------------- Constructor ------------- List <FieldInfo> parameterFields = clonedParameters.Select(c => c.valueField).ToList(); ConstructorBuilder constructorBuilder = asyncModuleContext.typeBuilder.DefineConstructor( MethodAttributes.Public, CallingConventions.Standard, parameterFields.Select(f => f.FieldType).ToArray()); IILEmitter constructorEmitter = new GeneratorILEmitter(constructorBuilder.GetILGenerator()); int argIndex = 1; foreach (FieldInfo field in parameterFields) { constructorEmitter.Emit(OpCodes.Ldarg_0); MethodParameter.EmitLoadArg(constructorEmitter, argIndex++); constructorEmitter.Emit(OpCodes.Stfld, field); } constructorEmitter.Emit(OpCodes.Ldarg_0); constructorEmitter.Emit(OpCodes.Ldc_I4_0); constructorEmitter.Emit(OpCodes.Stfld, asyncContext.stateField); constructorEmitter.EmitReturn(typeof(void)); return(new AsyncClass(asyncModuleContext.typeBuilder, constructorBuilder)); }
public override void EmitCode(IBlockContext context, bool dropResult) { RealizedType sourceType = sourceExpression.ResultType(context).UnderlyingType(context.ModuleContext); IForInSource source = sourceType.ForInSource(context.ModuleContext, variableType); if (source == null) { context.AddError( new StructuralError( StructuralError.ErrorType.InvalidType, $"{sourceType} cannot be use as for ... in source", Start, End ) ); } if (context.FindVariable(variableName) != null) { context.AddError(new StructuralError( StructuralError.ErrorType.DuplicateVariableName, $"Variable '{variableName}' already declared in this scope", Start, End )); } if (source != null && variableType != null && !variableType.IsAssignableFrom(context.ModuleContext, source.ElementType)) { context.AddError( new StructuralError( StructuralError.ErrorType.InvalidType, $"{sourceType} has elements of type {source.ElementType}, expected {variableType}", Start, End ) ); } if (context.HasErrors) { return; } using ITempLocalRef loopCounter = context.IL.TempLocal(typeof(int)); ILCount loopSize = EstimateLoop(context, source); LabelRef start = context.IL.DefineLabel(loopSize.opCodes < 110); LabelRef end = context.IL.DefineLabel(loopSize.opCodes < 110); LabelRef loop = context.IL.DefineLabel(loopSize.opCodes < 100); IBlockContext loopContext = context.CreateLoopContext(start, end); IBlockVariable loopVariable = loopContext.DeclaredVariable(variableName, true, source !.ElementType); sourceExpression.EmitCode(context, false); if (context.HasErrors) { return; } source.EmitInitialize(loopContext); loopContext.IL.Emit(start.isShort ? OpCodes.Br_S : OpCodes.Br, start); loopContext.IL.MarkLabel(loop); // Timeout check LabelRef skipCheck = context.IL.DefineLabel(true); loopCounter.EmitLoad(loopContext); loopContext.IL.Emit(OpCodes.Ldc_I4_1); loopContext.IL.Emit(OpCodes.Add); loopContext.IL.Emit(OpCodes.Dup); loopCounter.EmitStore(loopContext); loopContext.IL.Emit(OpCodes.Ldc_I4, 10000); loopContext.IL.Emit(OpCodes.Cgt); loopContext.IL.Emit(OpCodes.Brfalse, skipCheck); loopContext.IL.Emit(OpCodes.Ldc_I4_0); loopCounter.EmitStore(loopContext); context.IL.EmitCall(OpCodes.Call, typeof(Runtime.ContextHolder).GetMethod("CheckTimeout"), 0); loopContext.IL.MarkLabel(skipCheck); source.EmitNext(loopContext); loopVariable.EmitStore(loopContext); loopExpression.EmitCode(loopContext, true); loopContext.IL.MarkLabel(start); source.EmitCheckDone(loopContext, loop); loopContext.IL.MarkLabel(end); if (!dropResult) { context.IL.Emit(OpCodes.Ldnull); } }
// Emit a switch statement. public virtual void Emit(OpCode opcode, Label[] labels) { // Determine where the switch statement ends. int switchEnd = offset + opcode.size + labels.Length * 4; // Emit the opcode and the table length. EmitOpcode(ref opcode); EmitToken(labels.Length); // Output the table of switch labels. int posn; Label label; LabelInfo info; LabelRef newRef; for(posn = 0; posn < labels.Length; ++posn) { // Skip the label if it is invalid (shouldn't happen). label = labels[posn]; if(label.index < 0 || label.index >= numLabels) { continue; } // Fetch the label information block. info = this.labels[label.index]; // If it is already defined, output the offset now. // Otherwise add a reference and output a placeholder. if(info.offset != 0) { EmitToken(info.offset - switchEnd); } else { newRef = new LabelRef(); newRef.next = this.labels[label.index].refs; newRef.address = offset; newRef.switchEnd = switchEnd; this.labels[label.index].refs = newRef; EmitToken(0); } } }
// Emit code for a branch instruction. Note: unlike other implementations, // we always output the branch in such a way that an out of range error // can never occur. This makes it easier to process forward references // in a single pass through the code. public virtual void Emit(OpCode opcode, Label label) { int index = label.index; int shortForm, longForm; if(index < 0 || index >= numLabels) { return; } if((OperandType)(opcode.operandType) == OperandType.ShortInlineBrTarget) { // Convert a short opcode into its long form. shortForm = opcode.value; if(shortForm >= 0x2B && shortForm <= 0x37) { longForm = shortForm - 0x2B + 0x38; } else { longForm = 0xDD; } } else if((OperandType)(opcode.operandType) == OperandType.InlineBrTarget) { // Convert a long opcode into its short form. longForm = opcode.value; if(longForm >= 0x38 && longForm <= 0x44) { shortForm = longForm + 0x2B - 0x38; } else { shortForm = 0xDE; } } else { // Ignore non-branch opcodes. return; } if(labels[index].offset != 0) { // The label is already defined. Determine if the // branch is long or short. int dest = (labels[index].offset - 1) - (offset + 2); if(dest >= -128 && dest <= 127) { EmitByte(shortForm); EmitByte(dest); } else { dest = (labels[index].offset - 1) - (offset + 5); EmitByte(longForm); EmitByte(dest); EmitByte(dest >> 8); EmitByte(dest >> 16); EmitByte(dest >> 24); } } else { // Output the long form and add a reference to the label. EmitByte(longForm); EmitByte(0); EmitByte(0); EmitByte(0); EmitByte(0); LabelRef newRef = new LabelRef(); newRef.next = labels[index].refs; newRef.address = offset - 4; newRef.switchEnd = -1; labels[index].refs = newRef; } switch((StackBehaviour)(opcode.stackPop)) { case StackBehaviour.Popi: --height; break; case StackBehaviour.Pop1_pop1: height -= 2; break; default: break; } }
/// <summary> /// Parses the priorities items from the parse table. /// </summary> /// <param name="listTerm">A list of priority terms.</param> /// <returns>The parsed priorities.</returns> /// <example> /// The term might look like this: /// <code> /// [arg-gtr-prio(286,2,286), gtr-prio(301,295)] /// </code> /// </example> private IReadOnlyList<Priority> ParsePriorities(IListTerm listTerm) { #region Contract Contract.Requires<ArgumentNullException>(listTerm != null); Contract.Ensures(Contract.Result<IReadOnlyList<Priority>>() != null); #endregion var result = new List<Priority>(listTerm.Count); foreach (var term in listTerm.SubTerms.Cast<IConsTerm>()) { switch (term.Name) { case "left-prio": case "right-prio": case "non-assoc": // Not supported. break; case "gtr-prio": { var left = new LabelRef(term[0].ToInt32() - SpoofaxParseTableFormat.LabelBase); var right = new LabelRef(term[1].ToInt32() - SpoofaxParseTableFormat.LabelBase); if (left != right) result.Add(new Priority(left, right, PriorityType.Greater)); break; } case "arg-gtr-prio": { var left = new LabelRef(term[0].ToInt32() - SpoofaxParseTableFormat.LabelBase); var arg = term[1].ToInt32(); var right = new LabelRef(term[2].ToInt32() - SpoofaxParseTableFormat.LabelBase); if (left != right) result.Add(new Priority(left, right, arg, PriorityType.Greater)); break; } default: throw new InvalidParseTableException("Unknown priority: " + term); } } return result; }
/// <summary> /// Parses a reduce action item. /// </summary> /// <param name="term">The term.</param> /// <param name="labels">The labels in the parse table.</param> /// <returns>The parsed action item.</returns> /// <example> /// The term might look like this (without lookahead) /// <code> /// reduce(0,280,0) /// </code> /// or this (with lookahead) /// <code> /// reduce(0,280,0,[follow-restriction([char-class([42,47])])]) /// </code> /// </example> private ActionItem ParseReduce(IConsTerm term, IReadOnlyList<Label> labels) { #region Contract Contract.Requires<ArgumentNullException>(term != null); Contract.Requires<ArgumentException>(term.IsCons("reduce", 3) || term.IsCons("reduce", 4)); Contract.Requires<ArgumentNullException>(labels != null); Contract.Ensures(Contract.Result<ActionItem>() != null); #endregion int productionArity = term[0].ToInt32(); var label = new LabelRef(term[1].ToInt32() - SpoofaxParseTableFormat.LabelBase); ProductionType status = (ProductionType)term[2].ToInt32(); bool isRecover = labels[label.Index].Production.IsRecover; bool isCompletion = labels[label.Index].Production.IsCompletion; var followRestriction = term.SubTerms.Count == 4 ? ParseLookaheadCharRanges((IListTerm)term[3]) : ArrayExt.Empty<IReadOnlySet<CodePoint>>(); // Redundant information. Let's check it while we're at it. var production = labels[label.Index].Production; Contract.Assert(production.Arity == productionArity); Contract.Assert(production.IsCompletion == isCompletion); Contract.Assert(production.IsRecover == isRecover); Contract.Assert(production.Type == status); return new ReduceActionItem(label, followRestriction); }
public void MarkLabel(LabelRef labelRef) => generator.MarkLabel(labelRef.label);
private void ReduceAllPaths(LabelRef label, IEnumerable<Path> paths) { foreach (Path path in paths) { var kids = path.GetAncestorParseNodes(); var st0 = path.Frame; var nextState = this.parseTable.Go(st0.State, label); Reducer(st0, nextState, label, kids, path); } }
// TODO: Rename to DoReductions? /// <summary> /// /// </summary> /// <param name="stack"></param> /// <param name="label"></param> /// <param name="link">; or <see langword="null"/>.</param> public void DoLimitedReductions(Frame stack, LabelRef label, Link link) { #region Contract Contract.Requires<ArgumentNullException>(stack != null); Contract.Requires<ArgumentNullException>(label != null); #endregion var production = this.parseTable.Labels[label.Index].Production; if (!RecoverModeOk(stack, production)) return; var paths = stack.FindPathsToRoot(production.Arity, link); ReduceAllPaths(label, paths); }
public override void EmitCode(IBlockContext context, bool dropResult) { TO2Type leftType = left.ResultType(context); TO2Type rightType = right.ResultType(context); if (leftType != BuiltinType.Bool) { context.AddError(new StructuralError( StructuralError.ErrorType.IncompatibleTypes, "Expected boolean", left.Start, left.End )); } if (rightType != BuiltinType.Bool) { context.AddError(new StructuralError( StructuralError.ErrorType.IncompatibleTypes, "Expected boolean", right.Start, right.End )); } if (context.HasErrors) { return; } left.EmitCode(context, false); if (!dropResult) { context.IL.Emit(OpCodes.Dup); } ILCount rightCount = right.GetILCount(context, dropResult); LabelRef skipRight = context.IL.DefineLabel(rightCount.opCodes < 124); if (context.HasErrors) { return; } switch (op) { case Operator.BoolAnd: context.IL.Emit(skipRight.isShort ? OpCodes.Brfalse_S : OpCodes.Brfalse, skipRight); break; case Operator.BoolOr: context.IL.Emit(skipRight.isShort ? OpCodes.Brtrue_S : OpCodes.Brtrue, skipRight); break; default: context.AddError(new StructuralError( StructuralError.ErrorType.InvalidOperator, $"Invalid boolean operator {op}", Start, End )); return; } if (!dropResult) { context.IL.Emit(OpCodes.Pop); } right.EmitCode(context, dropResult); context.IL.MarkLabel(skipRight); }
/// <param name="st0"></param> /// <param name="nextState"></param> /// <param name="label"></param> /// <param name="kids">A list of trees.</param> /// <param name="path"></param> private void Reducer(Frame st0, StateRef nextState, LabelRef label, IReadOnlyList<IParseNode> kids, Path path) { var production = this.parseTable.Labels[label.Index].Production; Contract.Assert(!production.IsRecover); // t := application of a -> A to kids IParseNode t = ApplyProduction(production, kids, /* TODO */ 0, /* TODO */ 0, /* TODO */ false, /* TODO */ false); Frame st1 = GetActiveFrame(nextState); if (st1 != null) { // A stack with state nextState exists. Check for ambiguities. Link nl = st1.TryGetParentLink(st0); if (nl != null) { // There exists a direct link from st1 to st0. // TODO: Add `t` to the possiblities of the ambiguity node at `tree(nl)` if (production.IsReject) nl.Reject(); // TODO: Can't modify a link. //nl.Label = t; } else { // There is no direct link from st1 to st0. nl = new Link(st0, t, path.Length); st1.Links.Add(nl); if (production.IsReject) nl.Reject(); ActorOnActiveStacksOverNewLink(nl); } } else { // Found no existing stack frame with state nextState. st1 = new Frame(nextState); this.activeStacks.PushFront(st1); this.forActorDelayed.PushFront(st1); var nl = new Link(st0, t, path.Length); st1.Links.Add(nl); if (production.IsReject) nl.Reject(); } }
public void Emit(OpCode opCode, LabelRef labelRef) { generator.Emit(opCode, labelRef.label); AdjustStack(opCode); }
public override void EmitCode(IBlockContext context, bool dropResult) { if (condition.ResultType(context) != BuiltinType.Bool) { context.AddError( new StructuralError( StructuralError.ErrorType.InvalidType, "Condition of while is not a boolean", Start, End ) ); } IBlockContext tmpContext = context.CreateLoopContext(context.IL.DefineLabel(false), context.IL.DefineLabel(false)); Dictionary <string, TO2Type> scopeVariables = condition.GetScopeVariables(tmpContext); if (scopeVariables != null) { foreach (var(name, type) in scopeVariables) { tmpContext.DeclaredVariable(name, true, type.UnderlyingType(context.ModuleContext)); } } ILCount conditionCount = condition.GetILCount(tmpContext, false); ILCount loopCount = loopExpression.GetILCount(tmpContext, true); if (loopCount.stack > 0) { context.AddError( new StructuralError( StructuralError.ErrorType.CoreGeneration, "Body of the while expression leaves values on stack. This must not happen", Start, End ) ); return; } if (context.HasErrors) { return; } using ITempLocalRef loopCounter = context.IL.TempLocal(typeof(int)); LabelRef whileStart = context.IL.DefineLabel(conditionCount.opCodes + loopCount.opCodes < 110); LabelRef whileEnd = context.IL.DefineLabel(conditionCount.opCodes + loopCount.opCodes < 110); LabelRef whileLoop = context.IL.DefineLabel(conditionCount.opCodes + loopCount.opCodes < 100); IBlockContext loopContext = context.CreateLoopContext(whileStart, whileEnd); if (scopeVariables != null) { foreach (var(name, type) in scopeVariables) { if (loopContext.FindVariable(name) != null) { loopContext.AddError(new StructuralError( StructuralError.ErrorType.DuplicateVariableName, $"Variable '{name}' already declared in this scope", Start, End )); return; } loopContext.DeclaredVariable(name, true, type.UnderlyingType(context.ModuleContext)); } } loopContext.IL.Emit(whileStart.isShort ? OpCodes.Br_S : OpCodes.Br, whileStart); context.IL.MarkLabel(whileLoop); // Timeout check LabelRef skipCheck = context.IL.DefineLabel(true); loopCounter.EmitLoad(loopContext); loopContext.IL.Emit(OpCodes.Ldc_I4_1); loopContext.IL.Emit(OpCodes.Add); loopContext.IL.Emit(OpCodes.Dup); loopCounter.EmitStore(loopContext); loopContext.IL.Emit(OpCodes.Ldc_I4, 10000); loopContext.IL.Emit(OpCodes.Cgt); loopContext.IL.Emit(OpCodes.Brfalse, skipCheck); loopContext.IL.Emit(OpCodes.Ldc_I4_0); loopCounter.EmitStore(loopContext); context.IL.EmitCall(OpCodes.Call, typeof(Runtime.ContextHolder).GetMethod("CheckTimeout"), 0); loopContext.IL.MarkLabel(skipCheck); loopExpression.EmitCode(loopContext, true); loopContext.IL.MarkLabel(whileStart); condition.EmitCode(loopContext, false); loopContext.IL.Emit(whileLoop.isShort ? OpCodes.Brtrue_S : OpCodes.Brtrue, whileLoop); loopContext.IL.MarkLabel(whileEnd); if (!dropResult) { context.IL.Emit(OpCodes.Ldnull); } }
public override void EmitCode(IBlockContext context, bool dropResult) { if (condition.ResultType(context) != BuiltinType.Bool) { context.AddError( new StructuralError( StructuralError.ErrorType.InvalidType, "Condition of if is not a boolean", Start, End ) ); return; } IBlockContext thenContext = context.CreateChildContext(); Dictionary <string, TO2Type> scopeVariables = condition.GetScopeVariables(thenContext); if (scopeVariables != null) { foreach (var(name, type) in scopeVariables) { if (thenContext.FindVariable(name) != null) { thenContext.AddError(new StructuralError( StructuralError.ErrorType.DuplicateVariableName, $"Variable '{name}' already declared in this scope", Start, End )); return; } thenContext.DeclaredVariable(name, true, type.UnderlyingType(context.ModuleContext)); } } ILCount thenCount = thenExpression.GetILCount(thenContext, true); if (!context.HasErrors && thenCount.stack > 0) { context.AddError( new StructuralError( StructuralError.ErrorType.CoreGeneration, "Then expression leaves values on stack. This must not happen", Start, End ) ); return; } condition.EmitCode(thenContext, false); if (context.HasErrors) { return; } TO2Type thenResultType = thenExpression.ResultType(thenContext); if (dropResult) { LabelRef skipThen = context.IL.DefineLabel(thenCount.opCodes < 124); thenContext.IL.Emit(skipThen.isShort ? OpCodes.Brfalse_S : OpCodes.Brfalse, skipThen); thenExpression.EmitCode(thenContext, true); thenContext.IL.MarkLabel(skipThen); } else { OptionType optionType = new OptionType(thenResultType); Type generatedType = optionType.GeneratedType(thenContext.ModuleContext); using ITempLocalRef tempResult = thenContext.IL.TempLocal(generatedType); LabelRef skipThen = thenContext.IL.DefineLabel(thenCount.opCodes < 114); thenContext.IL.Emit(skipThen.isShort ? OpCodes.Brfalse_S : OpCodes.Brfalse, skipThen); thenExpression.Prepare(thenContext); tempResult.EmitLoadPtr(context); thenContext.IL.Emit(OpCodes.Dup); thenContext.IL.Emit(OpCodes.Initobj, generatedType, 1, 0); thenContext.IL.Emit(OpCodes.Dup); thenContext.IL.Emit(OpCodes.Ldc_I4_1); thenContext.IL.Emit(OpCodes.Stfld, generatedType.GetField("defined")); thenExpression.EmitCode(thenContext, false); thenContext.IL.Emit(OpCodes.Stfld, generatedType.GetField("value")); LabelRef ifEnd = context.IL.DefineLabel(true); thenContext.IL.Emit(OpCodes.Br_S, ifEnd); thenContext.IL.MarkLabel(skipThen); tempResult.EmitLoadPtr(context); thenContext.IL.Emit(OpCodes.Initobj, generatedType, 1, 0); thenContext.IL.MarkLabel(ifEnd); tempResult.EmitLoad(thenContext); } }
/// <summary> /// Reduces the specified stack frame /// </summary> /// <param name="stack"></param> /// <param name="label"></param> public void DoReductions(Frame stack, LabelRef label) { DoLimitedReductions(stack, label, null); }
/// <summary> /// Gets the label that corresponds to the specified label reference. /// </summary> /// <param name="labelRef">The label reference.</param> /// <returns>The corresponding <see cref="Label"/>.</returns> private Label GetLabel(LabelRef labelRef) { #region Contract Contract.Ensures(Contract.Result<Label>() != null); #endregion return this.parseTable.Labels[labelRef.Index]; }
public void MarkLabel(LabelRef label) { }
public override void EmitCode(IBlockContext context, bool dropResult) { if (condition.ResultType(context) != BuiltinType.Bool) { context.AddError( new StructuralError( StructuralError.ErrorType.InvalidType, "Condition of if is not a boolean", Start, End ) ); return; } IBlockContext thenContext = context.CreateChildContext(); IBlockContext elseContext = context.CreateChildContext(); Dictionary <string, TO2Type> scopeVariables = condition.GetScopeVariables(thenContext); if (scopeVariables != null) { foreach (var(name, type) in scopeVariables) { if (thenContext.FindVariable(name) != null) { thenContext.AddError(new StructuralError( StructuralError.ErrorType.DuplicateVariableName, $"Variable '{name}' already declared in this scope", Start, End )); return; } thenContext.DeclaredVariable(name, true, type.UnderlyingType(context.ModuleContext)); } } ILCount thenCount = thenExpression.GetILCount(thenContext, dropResult); ILCount elseCount = elseExpression.GetILCount(elseContext, dropResult); if (!context.HasErrors && thenCount.stack > 1) { context.AddError( new StructuralError( StructuralError.ErrorType.CoreGeneration, "Then expression leaves too many values on stack. This must not happen", Start, End ) ); return; } if (!context.HasErrors && elseCount.stack > 1) { context.AddError( new StructuralError( StructuralError.ErrorType.CoreGeneration, "Else expression leaves too many values on stack. This must not happen", Start, End ) ); return; } condition.EmitCode(thenContext, false); if (context.HasErrors) { return; } TO2Type thenType = thenExpression.ResultType(thenContext); TO2Type elseType = elseExpression.ResultType(elseContext); if (!dropResult) { if (!thenType.IsAssignableFrom(context.ModuleContext, elseType)) { context.AddError(new StructuralError( StructuralError.ErrorType.IncompatibleTypes, $"If condition has incompatible result {thenType} != {elseType}", Start, End )); } } if (context.HasErrors) { return; } LabelRef thenEnd = context.IL.DefineLabel(thenCount.opCodes < 124); LabelRef elseEnd = context.IL.DefineLabel(elseCount.opCodes < 124); context.IL.Emit(thenEnd.isShort ? OpCodes.Brfalse_S : OpCodes.Brfalse, thenEnd); thenExpression.EmitCode(thenContext, dropResult); context.IL.Emit(elseEnd.isShort ? OpCodes.Br_S : OpCodes.Br, elseEnd); context.IL.MarkLabel(thenEnd); if (!dropResult) { context.IL.AdjustStack(-1); // Then leave its result on the stack, so is else supposed to } elseExpression.EmitCode(elseContext, dropResult); if (!dropResult) { thenType.AssignFrom(context.ModuleContext, elseType).EmitConvert(context); } context.IL.MarkLabel(elseEnd); }
private object OnLabelRef(LabelRef labelRef) { INiCommandBarControl control; ErrorUtil.ThrowOnFailure(_commandManager.FindCommandBarControl( labelRef.Guid, out control )); if (control == null) throw new NetIdeException(String.Format(NeutralResources.CannotFindCommand, labelRef.Guid)); return control; }
private ITerm GetProduction(LabelRef label) { return this.parseTable.Labels[label.Index].Production; }