Esempio n. 1
0
        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);
        }
Esempio n. 2
0
 public override void Prepare(IBlockContext context)
 {
     foreach (Expression element in Elements)
     {
         element.Prepare(context);
     }
 }
Esempio n. 3
0
 public override void Prepare(IBlockContext context)
 {
     foreach (Expression item in items)
     {
         item.Prepare(context);
     }
 }
Esempio n. 4
0
        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);
        }
Esempio n. 5
0
        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);
            }
        }
Esempio n. 6
0
 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);
     }
 }
Esempio n. 9
0
        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);
     }
 }
Esempio n. 11
0
        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);
            }
        }
Esempio n. 12
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);
        }
        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);
     }
 }
Esempio n. 16
0
 public void EmitConvert(IBlockContext context)
 {
     if (context.IL.StackCount > 0)
     {
         context.IL.Emit(OpCodes.Pop);
     }
     context.IL.Emit(OpCodes.Ldnull);
 }
Esempio n. 17
0
 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);
     }
 }
Esempio n. 18
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);
        }
Esempio n. 19
0
 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;
 }
Esempio n. 20
0
 public TO2Type FindVariableLocal(IBlockContext context, string name)
 {
     if (name != variableName)
     {
         return(null);
     }
     return(variableType ?? sourceExpression.ResultType(context)?.ForInSource(context.ModuleContext, null)
            .ElementType);
 }
Esempio n. 21
0
 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;
 }
Esempio n. 22
0
        public override void EmitInitialize(IBlockContext context, IBlockVariable variable)
        {
            if (runtimeType.IsValueType)
            {
                return;
            }

            context.IL.EmitNew(OpCodes.Newobj, constructor, 0, 1);
            variable.EmitStore(context);
        }
Esempio n. 23
0
        public override void EmitCode(IBlockContext context, bool dropResult)
        {
            if (dropResult)
            {
                return;
            }

            using ITempBlockVariable tempVariable = context.MakeTempVariable(BuiltinType.Range);
            EmitStore(context, tempVariable, false);
        }
Esempio n. 24
0
 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);
     }
 }
Esempio n. 26
0
 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]);
        }
Esempio n. 28
0
        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);
        }
Esempio n. 29
0
        /// <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
            });
        }
Esempio n. 30
0
 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);
 }