Exemple #1
0
        void ICilCompilerAware.ImplementInCil(CompilerState state, Instruction ins)
        {
            if (ins.Arguments > 0)
                throw new PrexoniteException("The meta command no longer accepts arguments.");

            state.EmitLoadLocal(state.SctxLocal);
            state.EmitLoadArg(CompilerState.ParamSourceIndex);
            var getMeta = typeof (PFunction).GetProperty("Meta").GetGetMethod();
            state.Il.EmitCall(OpCodes.Callvirt, getMeta, null);
            state.Il.EmitCall(OpCodes.Call, Compiler.Cil.Compiler.CreateNativePValue, null);
        }
Exemple #2
0
        private static void _parseParameters(CompilerState state)
        {
            for (var i = 0; i < state.Source.Parameters.Count; i++)
            {
                var id = state.Source.Parameters[i];
                var sym = state.Symbols[id];
                LocalBuilder local;

                //Determine whether local variables for parameters have already been created and create them if necessary
                switch (sym.Kind)
                {
                    case SymbolKind.Local:
                        local = sym.Local ?? state.Il.DeclareLocal(typeof (PValue));
                        break;
                    case SymbolKind.LocalRef:
                        if (sym.Local == null)
                        {
                            local = state.Il.DeclareLocal(typeof (PVariable));
                            state.Il.Emit(OpCodes.Newobj, NewPVariableCtor);
                            state.EmitStoreLocal(local);
                            //PVariable objects already contain PValue.Null and need not be initialized if no
                            //  argument has been passed.
                        }
                        else
                        {
                            local = sym.Local;
                        }
                        break;
                    default:
                        throw new PrexoniteException("Cannot create variable to represent symbol");
                }

                sym.Local = local;

                var hasArg = state.Il.DefineLabel();
                var end = state.Il.DefineLabel();

                if (sym.Kind == SymbolKind.Local) // var = idx < len ? args[idx] : null;
                {
                    //The closure below is only accessed once. The capture is therefore transparent.
                    // ReSharper disable AccessToModifiedClosure
                    state.EmitStorePValue
                        (
                            sym,
                            delegate
                                {
                                    //(idx < argc) ? args[idx] : null; 
                                    state.EmitLdcI4(i);
                                    state.EmitLoadLocal(state.ArgcLocal);
                                    state.Il.Emit(OpCodes.Blt_S, hasArg);
                                    state.EmitLoadNullAsPValue();
                                    state.Il.Emit(OpCodes.Br_S, end);
                                    state.Il.MarkLabel(hasArg);
                                    state.EmitLoadArg(CompilerState.ParamArgsIndex);
                                    state.EmitLdcI4(i);
                                    state.Il.Emit(OpCodes.Ldelem_Ref);
                                    state.Il.MarkLabel(end);
                                }
                        );
                    // ReSharper restore AccessToModifiedClosure
                }
                else // if(idx < len) var = args[idx];
                {
                    state.EmitLdcI4(i);
                    state.EmitLoadLocal(state.ArgcLocal);
                    state.Il.Emit(OpCodes.Bge_S, end);

                    //The following closure is only accessed once. The capture is therefore transparent.
                    // ReSharper disable AccessToModifiedClosure
                    state.EmitStorePValue
                        (
                            sym,
                            delegate
                                {
                                    state.EmitLoadArg(CompilerState.ParamArgsIndex);
                                    state.EmitLdcI4(i);
                                    state.Il.Emit(OpCodes.Ldelem_Ref);
                                });
                    // ReSharper restore AccessToModifiedClosure
                    state.Il.MarkLabel(end);
                }
            }
        }
Exemple #3
0
        private static void _analysisAndPreparation(CompilerState state)
        {
            var tempMaxOrder = 1; // 
            var needsSharedVariables = false;

            foreach (var ins in state.Source.Code.InReverse())
            {
                string toConvert;
                switch (ins.OpCode)
                {
                    case OpCode.ldr_loci:
                        //see ldr_loc
                        toConvert = state.IndexMap[ins.Arguments];
                        goto Convert;
                    case OpCode.ldr_loc:
                        toConvert = ins.Id;
                        Convert:

                        //Normal local variables are implemented as CIL locals.
                        // If the function uses variable references, they must be converted to reference variables.
                        state.Symbols[toConvert].Kind = SymbolKind.LocalRef;
                        break;
                    case OpCode.rot:
                        //Determine the maximum number of temporary variables for the implementation of rot[ate]
                        var order = (int) ins.GenericArgument;
                        if (order > tempMaxOrder)
                            tempMaxOrder = order;
                        break;
                    case OpCode.newclo:
                        MetaEntry[] entries;
                        var func = state.Source.ParentApplication.Functions[ins.Id];
                        MetaEntry entry;
                        if (func.Meta.ContainsKey(PFunction.SharedNamesKey) &&
                            (entry = func.Meta[PFunction.SharedNamesKey]).IsList)
                            entries = entry.List;
                        else
                            entries = new MetaEntry[] {};
                        foreach (var t in entries)
                        {
                            var symbolName = t.Text;
                            if (!state.Symbols.ContainsKey(symbolName))
                                throw new PrexoniteException
                                    (func + " does not contain a mapping for the symbol " +
                                        symbolName);

                            //In order for variables to be shared, they too, need to be converted to reference locals.
                            state.Symbols[symbolName].Kind = SymbolKind.LocalRef;
                        }

                        //Notify the compiler of the presence of closures with shared variables
                        needsSharedVariables = needsSharedVariables || entries.Length > 0;
                        break;
                }
            }

            //Create temporary variables for rotation
            state.TempLocals = new LocalBuilder[tempMaxOrder];
            for (var i = 0; i < tempMaxOrder; i++)
            {
                var rotTemp = state.Il.DeclareLocal(typeof (PValue));
                state.TempLocals[i] = rotTemp;
            }

            //Create temporary variable for argv and sharedVariables
            state.ArgvLocal = state.Il.DeclareLocal(typeof (PValue[]));
            state.SharedLocal = needsSharedVariables
                ? state.Il.DeclareLocal(typeof (PVariable[]))
                : null;

            //Create argc local variable and initialize it, if needed
            if (state.Source.Parameters.Count > 0)
            {
                state.ArgcLocal = state.Il.DeclareLocal(typeof (Int32));
                state.EmitLoadArg(CompilerState.ParamArgsIndex);
                state.Il.Emit(OpCodes.Ldlen);
                state.Il.Emit(OpCodes.Conv_I4);
                state.EmitStoreLocal(state.ArgcLocal);
            }

            //Determine stack size at every instruction
            _determineStackSize(state);
        }
Exemple #4
0
        private static void _buildSymbolTable(CompilerState state)
        {
            //Create local ref variables for shared names
            //  and populate them with the contents of the sharedVariables parameter
            if (state.Source.Meta.ContainsKey(PFunction.SharedNamesKey))
            {
                var sharedNames = state.Source.Meta[PFunction.SharedNamesKey].List;
                for (var i = 0; i < sharedNames.Length; i++)
                {
                    if (state.Source.Variables.Contains(sharedNames[i]))
                        continue; //Arguments are redeclarations.
                    var sym = new CilSymbol(SymbolKind.LocalRef)
                        {
                            Local = state.Il.DeclareLocal(typeof (PVariable))
                        };
                    var id = sharedNames[i].Text;

                    state.EmitLoadArg(CompilerState.ParamSharedVariablesIndex);
                    state.Il.Emit(OpCodes.Ldc_I4, i);
                    state.Il.Emit(OpCodes.Ldelem_Ref);
                    state.EmitStoreLocal(sym.Local.LocalIndex);

                    state.Symbols.Add(id, sym);
                }
            }

            //Create index -> id map
            foreach (var mapping in state.Source.LocalVariableMapping)
                state.IndexMap.Add(mapping.Value, mapping.Key);

            //Add entries for paramters
            foreach (var parameter in state.Source.Parameters)
                if (!state.Symbols.ContainsKey(parameter))
                    state.Symbols.Add(parameter, new CilSymbol(SymbolKind.Local));

            //Add entries for enumerator variables
            foreach (var hint in state._ForeachHints)
            {
                if (state.Symbols.ContainsKey(hint.EnumVar))
                    throw new PrexoniteException(
                        "Invalid foreach hint. Enumerator variable is shared.");
                state.Symbols.Add(hint.EnumVar, new CilSymbol(SymbolKind.LocalEnum));
            }

            //Add entries for non-shared local variables
            foreach (var variable in state.Source.Variables)
                if (!state.Symbols.ContainsKey(variable))
                    state.Symbols.Add(variable, new CilSymbol(SymbolKind.Local));
        }
Exemple #5
0
        private static void _emitCilImplementationHeader(CompilerState state)
        {
            //Create local cil function stack context
            //  CilFunctionContext cfctx = CilFunctionContext.New(sctx, source);
            state.SctxLocal = state.Il.DeclareLocal(typeof (CilFunctionContext));
            state.EmitLoadArg(CompilerState.ParamSctxIndex);
            state.EmitLoadArg(CompilerState.ParamSourceIndex);
            state.Il.EmitCall(OpCodes.Call, CilFunctionContext.NewMethod, null);
            state.EmitStoreLocal(state.SctxLocal.LocalIndex);

            //Initialize result and assign default return mode
            //  Result = null;
            state._EmitAssignReturnMode(ReturnMode.Exit);
            state.EmitLoadArg(CompilerState.ParamResultIndex);
            state.EmitLoadNullAsPValue();
            state.Il.Emit(OpCodes.Stind_Ref);
        }
Exemple #6
0
 private static void _emitLoadArgV(CompilerState state)
 {
     state.EmitLoadArg(CompilerState.ParamArgsIndex);
     state.Il.Emit(OpCodes.Newobj, NewPValueListCtor);
     state.Il.EmitCall(OpCodes.Call, GetPTypeListMethod, null);
     state.Il.Emit(OpCodes.Newobj, NewPValue);
 }