Пример #1
0
        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);
        }
Пример #2
0
        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);
        }
Пример #3
0
        // ---------------- 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);
            }
        }
Пример #4
0
        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);
            }
        }
Пример #5
0
        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);
            }
        }
Пример #6
0
        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);
            }
        }