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); } }
public override void EmitInitialize(IBlockContext context, IBlockVariable variable) { if (runtimeType.IsValueType) { return; } context.IL.EmitNew(OpCodes.Newobj, constructor, 0, 1); variable.EmitStore(context); }
public void EmitAssign(IBlockContext context, IBlockVariable variable, Expression expression, bool dropResult) { expression.EmitCode(context, false); context.IL.Emit(OpCodes.Conv_R8); if (!dropResult) { context.IL.Emit(OpCodes.Dup); } variable.EmitStore(context); }
/// <summary> /// Variant of Emit when the result of the expression should be directly stored to a local variable. /// </summary> public virtual void EmitStore(IBlockContext context, IBlockVariable variable, bool dropResult) { EmitCode(context, false); if (context.HasErrors) { return; } if (!dropResult) { context.IL.Emit(OpCodes.Dup); } variable.EmitStore(context); }
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 }); }
public void EmitAssign(IBlockContext context, IBlockVariable variable, Node target) { EmitCode(context, target); variable.Type.AssignFrom(context.ModuleContext, ResultType).EmitConvert(context); variable.EmitStore(context); }
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); } }