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 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); }
// ---------------- IAssignEmitter ----------------- public void EmitAssign(IBlockContext context, IBlockVariable variable, Expression expression, bool dropResult) { using ITempBlockVariable valueTemp = context.MakeTempVariable(sourceType); expression.EmitStore(context, valueTemp, true); variable.EmitLoadPtr(context); EmitAssignToPtr(context, valueTemp); if (!dropResult) { variable.EmitLoad(context); } }
public override void EmitStore(IBlockContext context, IBlockVariable variable, bool dropResult) { if (!BuiltinType.Int.IsAssignableFrom(context.ModuleContext, from.ResultType(context))) { context.AddError(new StructuralError( StructuralError.ErrorType.IncompatibleTypes, "Range can only be created from int values", from.Start, from.End )); } if (!BuiltinType.Int.IsAssignableFrom(context.ModuleContext, to.ResultType(context))) { context.AddError(new StructuralError( StructuralError.ErrorType.IncompatibleTypes, "Range can only be created from int values", to.Start, to.End )); } if (context.HasErrors) { return; } variable.EmitLoadPtr(context); context.IL.Emit(OpCodes.Dup); from.EmitCode(context, false); context.IL.Emit(OpCodes.Stfld, typeof(Range).GetField("from")); to.EmitCode(context, false); if (inclusive) { context.IL.Emit(OpCodes.Ldc_I4_1); context.IL.Emit(OpCodes.Conv_I8); context.IL.Emit(OpCodes.Add); } context.IL.Emit(OpCodes.Stfld, typeof(Range).GetField("to")); if (!dropResult) { variable.EmitLoad(context); } }
public void EmitAssign(IBlockContext context, IBlockVariable variable, Expression expression, bool dropResult) { Type generatedType = optionType.GeneratedType(context.ModuleContext); using ITempBlockVariable valueTemp = context.MakeTempVariable(optionType.elementType.UnderlyingType(context.ModuleContext)); optionType.elementType.AssignFrom(context.ModuleContext, otherType) .EmitAssign(context, valueTemp, expression, true); variable.EmitLoadPtr(context); context.IL.Emit(OpCodes.Dup); context.IL.Emit(OpCodes.Initobj, generatedType, 1, 0); context.IL.Emit(OpCodes.Dup); context.IL.Emit(OpCodes.Ldc_I4_1); context.IL.Emit(OpCodes.Stfld, generatedType.GetField("defined")); valueTemp.EmitLoad(context); context.IL.Emit(OpCodes.Stfld, generatedType.GetField("value")); if (!dropResult) { variable.EmitLoad(context); } }
public override void EmitStore(IBlockContext context, IBlockVariable variable, bool dropResult) { TupleType tupleType = variable.Type as TupleType; if (tupleType == null) { context.AddError(new StructuralError( StructuralError.ErrorType.InvalidType, $"{variable.Type} is not a tuple", Start, End )); return; } else { if (items.Count != tupleType.itemTypes.Count) { context.AddError(new StructuralError( StructuralError.ErrorType.InvalidType, $"Expected tuple of {tupleType.itemTypes.Count} items, found {items.Count} items", Start, End )); } for (int i = 0; i < items.Count; i++) { TO2Type valueType = items[i].ResultType(context); if (!tupleType.itemTypes[i].IsAssignableFrom(context.ModuleContext, valueType)) { context.AddError(new StructuralError( StructuralError.ErrorType.InvalidType, $"Expected item {i} of {tupleType} to be a {tupleType.itemTypes[i]}, found {valueType}", Start, End )); } } } if (context.HasErrors) { return; } foreach (Expression item in items) { item.Prepare(context); } Type type = tupleType.GeneratedType(context.ModuleContext); variable.EmitLoadPtr(context); // Note: Potentially overoptimized: Since all fields will be set, initialization should not be necessary // context.IL.Emit(OpCodes.Dup); // context.IL.Emit(OpCodes.Initobj, type, 1, 0); for (int i = 0; i < items.Count; i++) { if (i > 0 && i % 7 == 0) { context.IL.Emit(OpCodes.Ldflda, type.GetField("Rest")); type = type.GetGenericArguments()[7]; // context.IL.Emit(OpCodes.Dup); // context.IL.Emit(OpCodes.Initobj, type, 1, 0); } if (i < items.Count - 1) { context.IL.Emit(OpCodes.Dup); } items[i].EmitCode(context, false); tupleType.itemTypes[i].AssignFrom(context.ModuleContext, items[i].ResultType(context)) .EmitConvert(context); context.IL.Emit(OpCodes.Stfld, type.GetField($"Item{i % 7 + 1}")); } if (context.HasErrors) { return; } if (!dropResult) { variable.EmitLoad(context); } }