public override void EmitPtr(IBlockContext context) { TO2Type targetType = target.ResultType(context); IIndexAccessEmitter indexAccess = targetType.AllowedIndexAccess(context.ModuleContext, indexSpec); if (indexAccess == null) { context.AddError(new StructuralError( StructuralError.ErrorType.NoIndexAccess, $"Type '{targetType.Name}' does not support access by index", Start, End )); return; } if (indexAccess.RequiresPtr) { target.EmitPtr(context); } else { target.EmitCode(context, false); } if (context.HasErrors) { return; } indexAccess.EmitPtr(context); }
public override void Prepare(IBlockContext context) { foreach (Expression element in Elements) { element.Prepare(context); } }
public override void Prepare(IBlockContext context) { foreach (Expression item in items) { item.Prepare(context); } }
public override TO2Type ResultType(IBlockContext context) { TO2Type targetType = target.ResultType(context); IFieldAccessEmitter fieldAccess = targetType.FindField(context.ModuleContext, fieldName)?.Create(context.ModuleContext); if (fieldAccess == null) { context.AddError(new StructuralError( StructuralError.ErrorType.NoSuchField, $"Type '{targetType.Name}' does not have a field '{fieldName}'", Start, End )); return(BuiltinType.Unit); } if (!fieldAccess.CanStore) { context.AddError(new StructuralError( StructuralError.ErrorType.NoSuchField, $"Type '{targetType.Name}' field '{fieldName}' is read-only", Start, End )); return(BuiltinType.Unit); } return(fieldAccess.FieldType); }
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 EmitCode(IBlockContext context, Node target) { foreach (OpCode opCode in opCodes) { context.IL.Emit(opCode); } }
public TO2Type FindVariableLocal(IBlockContext context, string name) { for (int i = 0; i < declarations.Count; i++) { DeclarationParameter declaration = declarations[i]; if (declaration.IsPlaceholder || name != declaration.target) { continue; } if (declaration.type != null) { return(declaration.type); } RealizedType elementType = sourceExpression.ResultType(context) ?.ForInSource(context.ModuleContext, null).ElementType; if (elementType == null) { return(null); } switch (elementType) { case TupleType tupleType: return(i < tupleType.itemTypes.Count ? tupleType.itemTypes[i] : null); case RecordType recordType: return(recordType.ItemTypes.Get(declaration.source)); } } return(null); }
public void EmitLoad(IBlockContext context) { foreach (OpCode opCode in loadOpCodes) { context.IL.Emit(opCode); } }
public void EmitCode(IBlockContext context) { TO2Type valueType = expression.ResultType(context); if (declaredReturn != BuiltinType.Unit && !declaredReturn.IsAssignableFrom(context.ModuleContext, valueType)) { context.AddError(new StructuralError( StructuralError.ErrorType.IncompatibleTypes, $"Function '{name}' returns {valueType} but should return {declaredReturn}", Start, End )); return; } if (isAsync) { EmitCodeAsync(context); } else { EmitCodeSync(context); } }
public void EmitPtr(IBlockContext context) { foreach (FieldInfo fieldInfo in fieldInfos) { context.IL.Emit(OpCodes.Ldflda, fieldInfo); } }
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); } }
protected override void EmitAssignToPtr(IBlockContext context, IBlockVariable tempSource) { foreach (var kv in targetType.fields) { IFieldAccessFactory sourceFieldFactory = sourceType.FindField(context.ModuleContext, kv.Key); if (sourceFieldFactory == null) { continue; } IFieldAccessEmitter sourceField = sourceFieldFactory.Create(context.ModuleContext); context.IL.Emit(OpCodes.Dup); if (sourceField.RequiresPtr) { tempSource.EmitLoadPtr(context); } else { tempSource.EmitLoad(context); } sourceField.EmitLoad(context); targetType.ItemTypes[kv.Key].AssignFrom(context.ModuleContext, sourceType.ItemTypes[kv.Key]) .EmitConvert(context); context.IL.Emit(OpCodes.Stfld, kv.Value); } context.IL.Emit(OpCodes.Pop); }
public static void EmitStore(this ILocalRef localRef, IBlockContext context) { switch (localRef.LocalIndex) { case 0: context.IL.Emit(OpCodes.Stloc_0); return; case 1: context.IL.Emit(OpCodes.Stloc_1); return; case 2: context.IL.Emit(OpCodes.Stloc_2); return; case 3: context.IL.Emit(OpCodes.Stloc_3); return; case { } n when n < 256: context.IL.Emit(OpCodes.Stloc_S, localRef); return; default: context.IL.Emit(OpCodes.Stloc, localRef); return; } }
public void EmitPtr(IBlockContext context) { EmitLoad(context); using ITempBlockVariable tempLocal = context.MakeTempVariable(FieldType.UnderlyingType(context.ModuleContext)); tempLocal.EmitStore(context); tempLocal.EmitLoadPtr(context); }
public void EmitLoad(IBlockContext context) { context.IL.EmitCall(getter.IsVirtual ? OpCodes.Callvirt : OpCodes.Call, getter, 1); foreach (OpCode opCode in opCodes) { context.IL.Emit(opCode); } }
public void EmitConvert(IBlockContext context) { if (context.IL.StackCount > 0) { context.IL.Emit(OpCodes.Pop); } context.IL.Emit(OpCodes.Ldnull); }
public void EmitCode(IBlockContext context, Node target) { context.IL.EmitCall(OpCodes.Call, methodInfo, methodInfo.GetParameters().Length); foreach (OpCode opCOde in postOpCodes) { context.IL.Emit(opCOde); } }
public void EmitAssign(IBlockContext context, IBlockVariable variable, Node target) { using ITempBlockVariable tempRight = context.MakeTempVariable(sourceType); tempRight.EmitStore(context); context.IL.Emit(OpCodes.Pop); // Left side is just the variable we are about to override variable.EmitLoadPtr(context); EmitAssignToPtr(context, tempRight); }
public DeclaredKontrolStructConstructor(DeclaredKontrolModule module, IBlockContext methodContext, StructDeclaration to2Struct) { this.module = module; Parameters = to2Struct.constructorParameters.Select(p => new RealizedParameter(methodContext, p)).ToList(); ReturnType = to2Struct.typeDelegate.UnderlyingType(methodContext.ModuleContext); this.methodContext = methodContext; this.to2Struct = to2Struct; }
public TO2Type FindVariableLocal(IBlockContext context, string name) { if (name != variableName) { return(null); } return(variableType ?? sourceExpression.ResultType(context)?.ForInSource(context.ModuleContext, null) .ElementType); }
public DeclaredKontrolFunction(DeclaredKontrolModule module, IBlockContext methodContext, FunctionDeclaration to2Function) { this.module = module; Parameters = to2Function.parameters.Select(p => new RealizedParameter(methodContext, p)).ToList(); ReturnType = to2Function.declaredReturn.UnderlyingType(methodContext.ModuleContext); this.methodContext = methodContext; this.to2Function = to2Function; }
public override void EmitInitialize(IBlockContext context, IBlockVariable variable) { if (runtimeType.IsValueType) { return; } context.IL.EmitNew(OpCodes.Newobj, constructor, 0, 1); variable.EmitStore(context); }
public override void EmitCode(IBlockContext context, bool dropResult) { if (dropResult) { return; } using ITempBlockVariable tempVariable = context.MakeTempVariable(BuiltinType.Range); EmitStore(context, tempVariable, false); }
public void EmitStore(IBlockContext context) { if (index < 256) { context.IL.Emit(OpCodes.Starg_S, (byte)index); } else { context.IL.Emit(OpCodes.Starg, (short)index); } }
public static void EmitLoadPtr(this ILocalRef localRef, IBlockContext context) { if (localRef.LocalIndex < 256) { context.IL.Emit(OpCodes.Ldloca_S, localRef); } else { context.IL.Emit(OpCodes.Ldloca, localRef); } }
public void EmitLoadPtr(IBlockContext context) { if (index < 256) { context.IL.Emit(OpCodes.Ldarga_S, (byte)index); } else { context.IL.Emit(OpCodes.Ldarga, (short)index); } }
public void EmitStore(IBlockContext context) { var fieldCount = fieldInfos.Count; foreach (var fieldInfo in fieldInfos.Take(fieldCount - 1)) { context.IL.Emit(OpCodes.Ldflda, fieldInfo); } context.IL.Emit(OpCodes.Stfld, fieldInfos[fieldCount - 1]); }
private void EmitCodeAsync(IBlockContext context) { asyncClass ??= AsyncClass.Create(context, name, declaredReturn, parameters, expression); for (int idx = 0; idx < parameters.Count; idx++) { MethodParameter.EmitLoadArg(context.IL, idx); } context.IL.EmitNew(OpCodes.Newobj, asyncClass.Value.constructor, parameters.Count); context.IL.EmitReturn(asyncClass.Value.type); }
/// <summary> /// Get the size of the IL opcodes for this expression. /// <param name="context">The context of the block containing the expression</param> /// <param name="dropResult">Toggles if the result of the expression should be also put on the stack or just dropped.</param> /// </summary> public ILCount GetILCount(IBlockContext context, bool dropResult) { IBlockContext countingContext = context.CloneCountingContext(); EmitCode(countingContext, dropResult); return(new ILCount { opCodes = countingContext.IL.ILSize, stack = countingContext.IL.StackCount }); }
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); }