void EmitInit(Emit.PEModuleBuilder module)
        {
            // void Init(Context)

            var tt = DeclaringCompilation.CoreTypes;
            var diagnostic = DiagnosticBag.GetInstance();

            // override IStaticInit.Init(Context) { .. }

            var initMethod = new SynthesizedMethodSymbol(this, "Init", false, true, tt.Void, Accessibility.Public);
            initMethod.SetParameters(new SynthesizedParameterSymbol(initMethod, tt.Context, 0, RefKind.None, "ctx"));

            var body = MethodGenerator.GenerateMethodBody(module, initMethod, (il) =>
            {
                var cg = new CodeGenerator(il, module, diagnostic, OptimizationLevel.Release, false, this, new ArgPlace(tt.Context, 1), new ArgPlace(this, 0));

                foreach (var fld in this.Fields)
                {
                    if (fld.RequiresContext)
                    {
                        fld.EmitInit(cg);
                    }
                }

                //
                il.EmitRet(true);
            },
            null, diagnostic, false);
            module.SetMethodBody(initMethod, body);
            module.SynthesizedManager.AddMethod(this, initMethod);
        }
Beispiel #2
0
        void EmitInvoke(MethodSymbol invoke, Emit.PEModuleBuilder module)
        {
            if (invoke == null)
            {
                return;
            }

            module.SetMethodBody(invoke, MethodGenerator.GenerateMethodBody(module, invoke, il =>
            {
                var cg = new CodeGenerator(il, module, DiagnosticBag.GetInstance(), OptimizationLevel.Release, false, this, new ParamPlace(invoke.Parameters[0]), new ArgPlace(this, 0));
                //var __invoke = (MethodSymbol)GetMembers(Pchp.Syntax.Name.SpecialMethodNames.Invoke.Value).Single(s => s is MethodSymbol);

                // TODO: call __invoke() directly

                // context.Call<T>(T, TypeMethods.MagicMethods, params PhpValue[])
                var call_t = cg.CoreTypes.Context.Symbol.GetMembers("Call")
                    .OfType<MethodSymbol>()
                    .Where(s => s.Arity == 1 && s.ParameterCount == 3 && s.Parameters[2].IsParams)
                    .Single()
                    .Construct(this);

                // return context.Call<T>(this, __invoke, args)
                cg.EmitLoadContext();
                cg.EmitThis();
                cg.Builder.EmitIntConstant((int)Core.Reflection.TypeMethods.MagicMethods.__invoke);
                cg.Builder.EmitLoadArgumentOpcode(2);
                cg.EmitCall(ILOpCode.Call, call_t);
                cg.EmitRet(invoke.ReturnType);

            }, null, DiagnosticBag.GetInstance(), false));
        }
        /// <summary>
        /// A field representing the function info at runtime.
        /// Lazily associated with index by runtime.
        /// </summary>
        internal FieldSymbol EnsureRoutineInfoField(Emit.PEModuleBuilder module)
        {
            if (_lazyRoutineInfoField == null)
            {
                _lazyRoutineInfoField = module.SynthesizedManager
                    .GetOrCreateSynthesizedField(_file, this.DeclaringCompilation.CoreTypes.RoutineInfo, "!" + this.MetadataName, Accessibility.Internal, true, true);
            }

            return _lazyRoutineInfoField;
        }
        public void EmitCtor(Emit.PEModuleBuilder module, Action<Microsoft.CodeAnalysis.CodeGen.ILBuilder> builder)
        {
            Debug.Assert(_ctor == null);

            // emit default .ctor

            _ctor = new SynthesizedCtorSymbol(this);
            _ctor.SetParameters();// empty params (default ctor)
            
            var body = CodeGen.MethodGenerator.GenerateMethodBody(module, _ctor, builder, null, DiagnosticBag.GetInstance(), false);
            module.SetMethodBody(_ctor, body);
        }
        public void EmitInit(Emit.PEModuleBuilder module, Action<Microsoft.CodeAnalysis.CodeGen.ILBuilder> builder)
        {
            Debug.Assert(_initMethod == null);

            var tt = DeclaringCompilation.CoreTypes;

            // override IStaticInit.Init(Context)

            _initMethod = new SynthesizedMethodSymbol(this, "Init", false, true, tt.Void, Accessibility.Public);
            _initMethod.SetParameters(new SynthesizedParameterSymbol(_initMethod, tt.Context, 0, RefKind.None, "ctx"));

            var body = CodeGen.MethodGenerator.GenerateMethodBody(module, _initMethod, builder, null, DiagnosticBag.GetInstance(), false);
            module.SetMethodBody(_initMethod, body);
        }
Beispiel #6
0
        public Cci.IImportScope Translate(Emit.PEModuleBuilder moduleBuilder, DiagnosticBag diagnostics)
        {
            for (var scope = this; scope != null; scope = scope.ParentOpt)
            {
                if (!scope._lazyTranslatedImports.IsDefault)
                {
                    break;
                }

                ImmutableInterlocked.InterlockedInitialize(ref scope._lazyTranslatedImports, scope.TranslateImports(moduleBuilder, diagnostics));
            }

            return this;
        }
Beispiel #7
0
        void EmitFieldsCctor(Emit.PEModuleBuilder module)
        {
            var sflds = GetMembers().OfType<SourceFieldSymbol>().Where(f => f.IsStatic && !f.RequiresHolder).ToList();
            if (sflds.Count != 0)
            {
                // emit initialization of app static fields
                // note, their initializers do not have Context available, since they are not bound to a Context

                var cctor = module.GetStaticCtorBuilder(this);
                var cg = new CodeGenerator(cctor, module, DiagnosticBag.GetInstance(), OptimizationLevel.Release, false, this, null, null);

                foreach (var f in sflds)
                {
                    f.EmitInit(cg);
                }
            }
        }
Beispiel #8
0
        internal void EmitInit(Emit.PEModuleBuilder module)
        {
            // .cctor
            EmitFieldsCctor(module);

            // __statics.Init
            ((SynthesizedStaticFieldsHolder)this.StaticsContainer)?.EmitCtors(module);

            // IPhpCallable.Invoke
            EmitInvoke(EnsureInvokeMethod(module), module);

            // .phpnew
            EmitPhpNew((SynthesizedPhpNewMethodSymbol)InitializeInstanceMethod, module);

            // .ctor
            EmitPhpCtor(PhpCtorMethodSymbol, module);
        }
        internal void EmitCtors(Emit.PEModuleBuilder module)
        {
            bool requiresInit = false;

            // .ctor()

            var tt = DeclaringCompilation.CoreTypes;
            var diagnostic = DiagnosticBag.GetInstance();

            var ctor = new SynthesizedCtorSymbol(this);
                        
            var body = MethodGenerator.GenerateMethodBody(module, ctor, (il) =>
            {
                var cg = new CodeGenerator(il, module, diagnostic, OptimizationLevel.Release, false, this, null, new ArgPlace(this, 0));

                foreach (var fld in this.Fields)
                {
                    if (fld.RequiresContext)
                    {
                        requiresInit = true;
                    }
                    else
                    {
                        fld.EmitInit(cg);
                    }
                }

                //
                il.EmitRet(true);
            },
            null, diagnostic, false);
            module.SetMethodBody(ctor, body);
            module.SynthesizedManager.AddMethod(this, ctor);

            //
            if (requiresInit)
            {
                EmitInit(module);
            }
        }
Beispiel #10
0
        private void GenerateFunctionInner(Emit<MuftecFunction> funcDef, Queue<MuftecStackItem> execStack, Local runtimeStack, MuftecStackItem lastItem = default(MuftecStackItem))
        {
            DebugMsg("- Call stack -> {0}", String.Join(", ", execStack.ToArray()));

            var stackPush = typeof (Stack<MuftecStackItem>).GetMethod("Push");

            while (execStack.Count > 0)
            {
                var currStackItem = execStack.Dequeue();
                DebugMsg("- Popping stack item: " + currStackItem.ToDebugString());

                switch (currStackItem.Type)
                {
                    // Run a user defined function
                    case MuftecType.Function:
                        // Find the function and create an IL call
                        var funcName = currStackItem.Item.ToString();
                        DebugMsg(" -- Call function {0}", funcName);
                        var func = _funcCache[funcName];
                        funcDef.LoadArgument(0); // Load OpCodeData into stack
                        funcDef.Call(func);
                        break;

                    // Execute a library opcode
                    case MuftecType.OpCode:
                        // Translate opcode into direct call
                        var opCodeName = currStackItem.Item.ToString();
                        DebugMsg(" >> Call opcode {0}", opCodeName);
                        var opCode = _system.FindOpCode(opCodeName);

                        // If this is an internal opcode, we need to handle it at this level
                        if (opCode.Attribute.Extern)
                        {
                            switch (opCode.Attribute.OpCodeName)
                            {
                                case "!":
                                case "@":
                                    throw new MuftecCompilerException("Variables not supported in the fabricator at line " + currStackItem.LineNumber);
                                case "loadlibdll":
                                    funcDef.LoadLocal(runtimeStack);
                                    funcDef.Call(typeof (Shared).GetMethod("PopStr"));
                                    _system.AddLibrary(lastItem.ToString());
                                    break;
                            }
                        }
                        else
                        {
                            funcDef.LoadArgument(0); // Load OpCodeData into the stack
                            funcDef.Call(opCode.Pointer.Method); // Call OpCode function
                        }

                        // Handle post-execution magic
                        var magic = opCode.Attribute.Magic;
                        switch (magic)
                        {
                            case MagicOpcodes.Abort:
                                // End exeuction
                                DebugMsg(" ---- Abort");
                                funcDef.LoadConstant(0);
                                funcDef.Call(typeof (Environment).GetMethod("Exit"));
                                return;
                            case MagicOpcodes.Exit:
                                DebugMsg(" ---- Exit");
                                // Exit out of this loop
                                return;
                        }
                        break;

                    // Handle a conditional container
                    case MuftecType.Conditional:
                        var container = currStackItem.Item as ConditionalContainer;
                        if (container == null)
                            throw new MuftecCompilerException("Unable to process conditional statement at line " + currStackItem.LineNumber);

                        DebugMsg(" -- Container");
                        var ltLabel = funcDef.DefineLabel();
                        var endLabel = funcDef.DefineLabel();
                        funcDef.LoadLocal(runtimeStack); // Get the RuntimeStack
                        funcDef.Call(typeof (Shared).GetMethod("PopInt")); // Call PopInt on RuntimeStack
                        funcDef.BranchIfFalse(ltLabel);

                        // GT operations
                        DebugMsg(" -- Starting true condition");
                        GenerateFunctionInner(funcDef, container.TrueQueue, runtimeStack, lastItem);
                        funcDef.Branch(endLabel);

                        // LT operations
                        funcDef.MarkLabel(ltLabel);
                        DebugMsg(" -- Starting false condition");
                        GenerateFunctionInner(funcDef, container.FalseQueue, runtimeStack, lastItem);

                        funcDef.MarkLabel(endLabel);
                        DebugMsg(" -- Conditions done");
                        break;

                    // Add item to the runtime stack
                    case MuftecType.Integer:
                        DebugMsg(" -- Pushing int {0} to RS", currStackItem.ToString());
                        funcDef.LoadLocal(runtimeStack); // Get the RuntimeStack
                        funcDef.LoadConstant((int)currStackItem.Item);
                        funcDef.LoadConstant(currStackItem.LineNumber);
                        funcDef.NewObject<MuftecStackItem, int, int>();
                        funcDef.Call(stackPush);
                        break;
                    case MuftecType.Float:
                        DebugMsg(" -- Pushing float {0} to RS", currStackItem.ToString());
                        funcDef.LoadLocal(runtimeStack); // Get the RuntimeStack
                        funcDef.LoadConstant((double)currStackItem.Item);
                        funcDef.LoadConstant(currStackItem.LineNumber);
                        funcDef.NewObject<MuftecStackItem, double, int>();
                        funcDef.Call(stackPush);
                        break;
                    case MuftecType.String:
                        DebugMsg(" -- Pushing string {0} to RS", currStackItem.ToString());
                        funcDef.LoadLocal(runtimeStack); // Get the RuntimeStackp =
                        funcDef.LoadConstant((string)currStackItem.Item);
                        funcDef.LoadConstant(currStackItem.LineNumber);
                        funcDef.NewObject<MuftecStackItem, string, int>();
                        funcDef.Call(stackPush);
                        break;
                    case MuftecType.ArrayMarker:
                        DebugMsg(" -- Pushing array marker to RS");
                        funcDef.LoadLocal(runtimeStack); // Get the RuntimeStack
                        funcDef.LoadConstant((int)currStackItem.Item);
                        funcDef.Call(typeof(MuftecStackItem).GetMethod("CreateArrayMarker"));
                        funcDef.Call(stackPush);
                        break;
                }

                lastItem = currStackItem;
            }
        }
Beispiel #11
0
        /// <summary>
        /// In case the class implements <c>__invoke</c> method, we create special Invoke() method that is compatible with IPhpCallable interface.
        /// </summary>
        internal SynthesizedMethodSymbol EnsureInvokeMethod(Emit.PEModuleBuilder module)
        {
            if (_lazyInvokeSymbol == null)
            {
                if (IsInvokable)
                {
                    _lazyInvokeSymbol = new SynthesizedMethodSymbol(this, "IPhpCallable.Invoke", false, true, DeclaringCompilation.CoreTypes.PhpValue)
                    {
                        ExplicitOverride = (MethodSymbol)DeclaringCompilation.CoreTypes.IPhpCallable.Symbol.GetMembers("Invoke").Single(),
                    };
                    _lazyInvokeSymbol.SetParameters(
                        new SpecialParameterSymbol(_lazyInvokeSymbol, DeclaringCompilation.CoreTypes.Context, SpecialParameterSymbol.ContextName, 0),
                        new SynthesizedParameterSymbol(_lazyInvokeSymbol, ArrayTypeSymbol.CreateSZArray(ContainingAssembly, DeclaringCompilation.CoreTypes.PhpValue.Symbol), 1, RefKind.None, "arguments"));

                    //
                    module.SynthesizedManager.AddMethod(this, _lazyInvokeSymbol);
                }
            }
            return _lazyInvokeSymbol;
        }
Beispiel #12
0
        internal void EmitInit(Emit.PEModuleBuilder module)
        {
            var cctor = module.GetStaticCtorBuilder(_file);
            var field = new FieldPlace(null, this.EnsureRoutineInfoField(module));

            // {RoutineInfoField} = RoutineInfo.CreateUserRoutine(name, handle)
            field.EmitStorePrepare(cctor);

            cctor.EmitStringConstant(this.QualifiedName.ToString());
            cctor.EmitLoadToken(module, DiagnosticBag.GetInstance(), this, null);
            cctor.EmitCall(module, DiagnosticBag.GetInstance(), System.Reflection.Metadata.ILOpCode.Call, module.Compilation.CoreMethods.Reflection.CreateUserRoutine_string_RuntimeMethodHandle);

            field.EmitStore(cctor);
        }
Beispiel #13
0
        static TableDataRecordCollection()
        {
            var assembly = AppDomain.CurrentDomain.GetAssemblies()
                           .First(a => a.ManifestModule.Name == "Peloton.AppFrame.IO.dll");

            var tableDataRecordType           = assembly.GetType("Peloton.AppFrame.IO.TableDataRecord");
            var tableDataRecordCollectionType = assembly.GetType("Peloton.AppFrame.IO.TableDataRecordCollection");

            var count          = tableDataRecordCollectionType.GetProperty("Count");
            var parentIdFilter = tableDataRecordCollectionType.GetProperty("ParentIdFilter");

            var itemIndex =
                tableDataRecordCollectionType.GetProperty("Item", tableDataRecordType, new[] { typeof(int) });
            var itemId =
                tableDataRecordCollectionType.GetProperty("Item", tableDataRecordType, new[] { typeof(string) });

            var eGetCount = Emit <Func <object, int> >
                            .NewDynamicMethod("GetCount")
                            .LoadArgument(0)
                            .CastClass(tableDataRecordCollectionType)
                            .Call(count.GetGetMethod(true))
                            .Return();

            var eGetParentIdFilter = Emit <Func <object, string> >
                                     .NewDynamicMethod("GetParentIdFilter")
                                     .LoadArgument(0)
                                     .CastClass(tableDataRecordCollectionType)
                                     .Call(parentIdFilter.GetGetMethod(true))
                                     .Return();

            var eSetParentIdFilter = Emit <Action <object, string> >
                                     .NewDynamicMethod("SetParentIdFilter")
                                     .LoadArgument(0)
                                     .CastClass(tableDataRecordCollectionType)
                                     .LoadArgument(1)
                                     .Call(parentIdFilter.GetSetMethod(true))
                                     .Return();

            var eGetItemIndex = Emit <Func <object, int, object> >
                                .NewDynamicMethod("GetItemByIndex")
                                .LoadArgument(0)
                                .CastClass(tableDataRecordCollectionType)
                                .LoadArgument(1)
                                .Call(itemIndex.GetGetMethod(true))
                                .Return();

            var eGetItemId = Emit <Func <object, string, object> >
                             .NewDynamicMethod("GetItemByIndex")
                             .LoadArgument(0)
                             .CastClass(tableDataRecordCollectionType)
                             .LoadArgument(1)
                             .Call(itemId.GetGetMethod(true))
                             .Return();

            GetCount          = eGetCount.CreateDelegate();
            GetParentIdFilter = eGetParentIdFilter.CreateDelegate();
            SetParentIdFilter = eSetParentIdFilter.CreateDelegate();
            GetItemIndex      = eGetItemIndex.CreateDelegate();
            GetItemId         = eGetItemId.CreateDelegate();

            var add      = tableDataRecordCollectionType.GetMethod("Add");
            var contains = tableDataRecordCollectionType.GetMethod("Contains");
            var filter   = tableDataRecordCollectionType.GetMethod("Filter");
            var remove   = tableDataRecordCollectionType.GetMethod("Remove");
            var sort     = tableDataRecordCollectionType.GetMethod("Sort");

            var eFuncAdd = Emit <Func <object, string, object> >
                           .NewDynamicMethod("FuncAdd")
                           .LoadArgument(0)
                           .CastClass(tableDataRecordCollectionType)
                           .LoadArgument(1)
                           .Call(add)
                           .Return();

            var eFuncContains = Emit <Func <object, string, bool> >
                                .NewDynamicMethod("FuncContains")
                                .LoadArgument(0)
                                .CastClass(tableDataRecordCollectionType)
                                .LoadArgument(1)
                                .Call(contains)
                                .Return();

            var eActFilter = Emit <Action <object, string> >
                             .NewDynamicMethod("ActFilter")
                             .LoadArgument(0)
                             .CastClass(tableDataRecordCollectionType)
                             .LoadArgument(1)
                             .Call(filter)
                             .Return();

            var eFuncRemove = Emit <Func <object, string, bool> >
                              .NewDynamicMethod("FuncContains")
                              .LoadArgument(0)
                              .CastClass(tableDataRecordCollectionType)
                              .LoadArgument(1)
                              .Call(remove)
                              .Return();

            var eActSort = Emit <Action <object, string> >
                           .NewDynamicMethod("ActSort")
                           .LoadArgument(0)
                           .CastClass(tableDataRecordCollectionType)
                           .LoadArgument(1)
                           .Call(sort)
                           .Return();

            FuncAdd      = eFuncAdd.CreateDelegate();
            FuncContains = eFuncContains.CreateDelegate();
            ActFilter    = eActFilter.CreateDelegate();
            FuncRemove   = eFuncRemove.CreateDelegate();
            ActSort      = eActSort.CreateDelegate();
        }
		internal override int ImportTo(Emit.ModuleBuilder module)
		{
			if (methodArgs == null)
			{
				return module.ImportMethodOrField(declaringType, method.Name, method.MethodSignature);
			}
			else
			{
				return module.ImportMethodSpec(declaringType, method, methodArgs);
			}
		}
 public ILBuilder(Emit.Module moduleBeingBuilt)
 {
     this.ilBits = new Microsoft.Cci.MemoryStream();
     this.writer = new Microsoft.Cci.BinaryWriter(this.ilBits);
     this.moduleBeingBuilt = moduleBeingBuilt;
 }
Beispiel #16
0
 public Emit <Func <int> > EmitByteCode(CompilerContext context, Emit <Func <int> > emiter)
 {
     emiter.LoadConstant(Value);
     return(emiter);
 }
 public abstract void Emit <TEmit>(Emit <TEmit> emitter);
Beispiel #18
0
 public VariablePool(Emit emiter)
 {
     g           = emiter;
     currentPool = new Dictionary <Type, List <VariableStatus> >();
 }
Beispiel #19
0
        public Emit <Func <int> > EmitByteCode(CompilerContext context, Emit <Func <int> > emiter)
        {
            if (Operator == BinaryOperator.CONCAT)
            {
                return(EmitConcat(context, emiter));
            }
            emiter = Left.EmitByteCode(context, emiter);
            emiter = Right.EmitByteCode(context, emiter);
            switch (Operator)
            {
            case BinaryOperator.ADD:
            {
                emiter = emiter.Add();
                break;
            }

            case BinaryOperator.SUB:
            {
                emiter = emiter.Subtract();
                break;
            }

            case BinaryOperator.MULTIPLY:
            {
                emiter = emiter.Multiply();
                break;
            }

            case BinaryOperator.DIVIDE:
            {
                emiter = emiter.Divide();
                break;
            }

            case BinaryOperator.EQUALS:
            {
                emiter = emiter.CompareEqual();
                break;
            }

            case BinaryOperator.DIFFERENT:
            {
                emiter = emiter.CompareEqual();
                emiter = emiter.Not();
                break;
            }

            case BinaryOperator.OR:
            {
                emiter = emiter.Or();
                break;
            }

            case BinaryOperator.AND:
            {
                emiter = emiter.And();
                break;
            }

            case BinaryOperator.LESSER:
            {
                emiter = emiter.CompareLessThan();
                break;
            }

            case BinaryOperator.GREATER:
            {
                emiter = emiter.CompareGreaterThan();
                break;
            }
            }

            return(emiter);
        }
Beispiel #20
0
    protected override ICfgNode Build(Name name)
    {
        var e = Event.Parse(name.Value);

        return(Emit.Event(e));
    }
Beispiel #21
0
 public Emit <Func <int> > EmitByteCode(CompilerContext context, Emit <Func <int> > emiter)
 {
     emiter = Value.EmitByteCode(context, emiter);
     emiter.Return();
     return(emiter);
 }
Beispiel #22
0
        static Func <object, string> BuildDelegate(Type targetType)
        {
            var targetProperties = targetType.GetMembers(Public | Instance)
                                   .Where(it => it is PropertyInfo)
                                   .Select(it => (PropertyInfo)it)
                                   .Where(it => it.CanRead && it.GetIndexParameters().Length == 0);

            var e = Emit <Func <object, string> > .NewDynamicMethod();

            using (var target = e.DeclareLocal(targetType))
                using (var builder = e.DeclareLocal <StringBuilder>())
                {
                    // target = (Target)value;
                    e.LoadArgument(0);
                    e.CastClass(targetType);
                    e.StoreLocal(target);

                    // builder = new StringBuilder();
                    e.NewObject <StringBuilder>();
                    e.StoreLocal(builder);

                    // builder.Append(nameof(Target) + ":{")
                    e.LoadLocal(builder);
                    e.LoadConstant(targetType.Name + "{");
                    e.CallVirtual(GetAppend(typeof(string)));

                    var isNotFirst = false;
                    foreach (var it in targetProperties)
                    {
                        if (isNotFirst)
                        {
                            // builder.Append(",")
                            e.LoadConstant(",");
                            e.CallVirtual(GetAppend(typeof(string)));
                        }
                        isNotFirst = true;

                        // builder.Append(nameof(Target.Property) + "=")
                        e.LoadConstant(it.Name + "=");
                        e.CallVirtual(GetAppend(typeof(string)));

                        // builder.Append(target.Property)
                        e.LoadLocal(target);
                        e.CallVirtual(it.GetGetMethod());
                        if (it.PropertyType.IsValueType && !IsSupportedType(it.PropertyType))
                        {
                            e.Box(it.PropertyType);
                        }
                        e.CallVirtual(GetAppend(it.PropertyType));
                    }

                    // // builder.Append("}")
                    e.LoadConstant("}");
                    e.CallVirtual(GetAppend(typeof(string)));

                    // return builder.ToString()
                    var toString = typeof(object).GetMethod("ToString");
                    e.CallVirtual(toString);
                    e.Return();
                }

            Console.WriteLine($".maxstack {e.MaxStackSize}");
            Console.WriteLine(e.Instructions());

            return(e.CreateDelegate());
        }
Beispiel #23
0
 [Fact] public void NegationNameTest() => TestRoundTrip("!foo", Emit.Negation(Emit.Name("foo")), ScriptParser.Negation);
Beispiel #24
0
        public static bool LoadConstantOfType <T>(Emit <T> emit, object val, Type type)
        {
            if (type == typeof(byte))
            {
                try
                {
                    var v = (byte)val;
                    emit.LoadConstant(v);
                    return(true);
                }
                catch { }

                try
                {
                    var v = (byte?)val;
                    emit.LoadConstant(v.Value);
                    return(true);
                }
                catch { }

                return(false);
            }

            if (type == typeof(sbyte))
            {
                try
                {
                    var v = (sbyte)val;
                    emit.LoadConstant(v);
                    return(true);
                }
                catch { }

                try
                {
                    var v = (sbyte?)val;
                    emit.LoadConstant(v.Value);
                    return(true);
                }
                catch { }

                return(false);
            }

            if (type == typeof(short))
            {
                try
                {
                    var v = (short)val;
                    emit.LoadConstant(v);
                    return(true);
                }
                catch { }

                try
                {
                    var v = (short?)val;
                    emit.LoadConstant(v.Value);
                    return(true);
                }
                catch { }

                return(false);
            }

            if (type == typeof(ushort))
            {
                try
                {
                    var v = (ushort)val;
                    emit.LoadConstant(v);
                    return(true);
                }
                catch { }

                try
                {
                    var v = (ushort?)val;
                    emit.LoadConstant(v.Value);
                    return(true);
                }
                catch { }

                return(false);
            }

            if (type == typeof(int))
            {
                try
                {
                    var v = (int)val;
                    emit.LoadConstant(v);
                    return(true);
                }
                catch { }

                try
                {
                    var v = (int?)val;
                    emit.LoadConstant(v.Value);
                    return(true);
                }
                catch { }

                return(false);
            }

            if (type == typeof(uint))
            {
                try
                {
                    var v = (uint)val;
                    emit.LoadConstant(v);
                    return(true);
                }
                catch { }

                try
                {
                    var v = (uint?)val;
                    emit.LoadConstant(v.Value);
                    return(true);
                }
                catch { }

                return(false);
            }

            if (type == typeof(long))
            {
                try
                {
                    var v = (long)val;
                    emit.LoadConstant(v);
                    return(true);
                }
                catch { }

                try
                {
                    var v = (long?)val;
                    emit.LoadConstant(v.Value);
                    return(true);
                }
                catch { }

                return(false);
            }

            if (type == typeof(ulong))
            {
                try
                {
                    var v = (ulong)val;
                    emit.LoadConstant(v);
                    return(true);
                }
                catch { }

                try
                {
                    var v = (ulong?)val;
                    emit.LoadConstant(v.Value);
                    return(true);
                }
                catch { }

                return(false);
            }

            return(false);
        }
Beispiel #25
0
 public override void Emit <T>(Emit <T> emitter)
 {
     emitter.WriteLine(_format, _args);
 }
Beispiel #26
0
		internal override int ImportTo(Emit.ModuleBuilder module)
		{
			return method.ImportTo(module);
		}
Beispiel #27
0
 public override void Emit <T>(Emit <T> emitter)
 {
     emitter.BranchIfTrue(_label);
 }
Beispiel #28
0
        void EmitPhpNew(SynthesizedPhpNewMethodSymbol phpnew, Emit.PEModuleBuilder module)
        {
            if (phpnew == null) return; // static class

            module.SetMethodBody(phpnew, MethodGenerator.GenerateMethodBody(module, phpnew, (Action<Microsoft.CodeAnalysis.CodeGen.ILBuilder>)(il =>
            {
                Debug.Assert(SpecialParameterSymbol.IsContextParameter(phpnew.Parameters[0]));

                var cg = new CodeGenerator(il, module, DiagnosticBag.GetInstance(), OptimizationLevel.Release, false, this, new ParamPlace(phpnew.Parameters[0]), new ArgPlace(this, 0));

                // initialize <ctx> field,
                // if field is declared within this type
                var ctxField = this.ContextStore;
                if (ctxField != null && object.ReferenceEquals((object)ctxField.ContainingType, this))
                {
                    var ctxFieldPlace = new FieldPlace(cg.ThisPlaceOpt, (IFieldSymbol)ctxField);

                    // Debug.Assert(<ctx> != null)
                    cg.EmitDebugAssertNotNull(cg.ContextPlaceOpt, "Context cannot be null.");

                    // <this>.<ctx> = <ctx>
                    ctxFieldPlace.EmitStorePrepare(il);
                    cg.EmitLoadContext();
                    ctxFieldPlace.EmitStore(il);
                }

                // initialize class fields
                foreach (var fld in this.GetFieldsToEmit().OfType<SourceFieldSymbol>().Where(fld => !fld.RequiresHolder && !fld.IsStatic && !fld.IsConst))
                {
                    fld.EmitInit(cg);
                }

                // base..phpnew ?? base..ctor
                var basenew = phpnew.BasePhpNew;
                Debug.Assert(basenew != null);
                cg.EmitPop(cg.EmitThisCall(basenew, phpnew));

                Debug.Assert(phpnew.ReturnsVoid);
                cg.EmitRet(phpnew.ReturnType);

            }), null, DiagnosticBag.GetInstance(), false));
        }
Beispiel #29
0
 public void EmitDeserialize(Emit emiter, Local value)
 {
     emiter.LoadArgument(1);
     emiter.Call(ReflectionHelper.GetMethod((BinaryReader x) => x.ReadProudString()));
     emiter.StoreLocal(value);
 }
Beispiel #30
0
        public static Func <TextReader, T> CreateFold(IEnumerable <AutomataName> names, Action <Emit <Func <TextReader, T> > > initialize, Action <Emit <Func <TextReader, T> > > doReturn, bool skipWhitespace, bool foldMultipleValues, bool caseSensitive, object defaultValue)
        {
            var sorted =
                names
                .OrderBy(kv => kv.Name)
                .ToList();

            var             stack     = new Stack <Action>();
            Action <Action> addAction =
                action => stack.Push(action);

            var emit = Emit <Func <TextReader, T> > .NewDynamicMethod(doVerify : Utils.DoVerify);

            initialize(emit);

            var ch      = emit.DeclareLocal(typeof(int), "ch");
            var failure = emit.DefineLabel("failure");

            if (defaultValue == null)
            {
                // no default? throw a deserialization exception
                addAction(
                    () =>
                {
                    emit.MarkLabel(failure);

                    emit.LoadArgument(0);
                    emit.LoadLocal(ch);
                    emit.Call(Helper_Consume);

                    emit.LoadConstant("Unexpected value for " + typeof(T).Name);
                    emit.LoadArgument(0);
                    emit.NewObject <DeserializationException, string, TextReader>();
                    emit.Throw();
                }
                    );
            }
            else
            {
                addAction(
                    () =>
                {
                    emit.MarkLabel(failure);

                    emit.LoadArgument(0);
                    emit.LoadLocal(ch);
                    emit.Call(Helper_Consume);

                    // strip of the ? if it exists
                    var type = typeof(T);
                    type     = Nullable.GetUnderlyingType(type) ?? type;

                    Utils.LoadConstantOfType(emit, defaultValue, type);

                    emit.Return();
                }
                    );
            }

            var start = emit.DefineLabel("start");
            var d     = new Data(addAction, emit, doReturn, start, failure, ch, skipWhitespace, foldMultipleValues, caseSensitive);

            NextChar(d, sorted, 0, start);

            foreach (var action in stack)
            {
                action();
            }

            return(emit.CreateDelegate(Utils.DelegateOptimizationOptions));
        }
Beispiel #31
0
        public unsafe void All()
        {
            {
                var e1 = Emit <Action <sbyte[], int, sbyte> > .NewDynamicMethod();

                e1.LoadArgument(0);
                e1.LoadArgument(1);
                e1.LoadArgument(2);
                e1.StoreElement <sbyte>();
                e1.Return();

                var d1 = e1.CreateDelegate();

                var x = new sbyte[] { 5 };
                d1(x, 0, 10);

                Assert.AreEqual((sbyte)10, x[0]);
            }

            {
                var e1 = Emit <Action <byte[], int, byte> > .NewDynamicMethod();

                e1.LoadArgument(0);
                e1.LoadArgument(1);
                e1.LoadArgument(2);
                e1.StoreElement <byte>();
                e1.Return();

                var d1 = e1.CreateDelegate();

                var x = new byte[] { 5 };
                d1(x, 0, 10);

                Assert.AreEqual((byte)10, x[0]);
            }

            {
                var e1 = Emit <Action <short[], int, short> > .NewDynamicMethod();

                e1.LoadArgument(0);
                e1.LoadArgument(1);
                e1.LoadArgument(2);
                e1.StoreElement <short>();
                e1.Return();

                var d1 = e1.CreateDelegate();

                var x = new short[] { 5 };
                d1(x, 0, 10);

                Assert.AreEqual((short)10, x[0]);
            }

            {
                var e1 = Emit <Action <ushort[], int, ushort> > .NewDynamicMethod();

                e1.LoadArgument(0);
                e1.LoadArgument(1);
                e1.LoadArgument(2);
                e1.StoreElement <ushort>();
                e1.Return();

                var d1 = e1.CreateDelegate();

                var x = new ushort[] { 5 };
                d1(x, 0, 10);

                Assert.AreEqual((ushort)10, x[0]);
            }

            {
                var e1 = Emit <Action <int[], int, int> > .NewDynamicMethod();

                e1.LoadArgument(0);
                e1.LoadArgument(1);
                e1.LoadArgument(2);
                e1.StoreElement <int>();
                e1.Return();

                var d1 = e1.CreateDelegate();

                var x = new int[] { 5 };
                d1(x, 0, 10);

                Assert.AreEqual((int)10, x[0]);
            }

            {
                var e1 = Emit <Action <uint[], int, uint> > .NewDynamicMethod();

                e1.LoadArgument(0);
                e1.LoadArgument(1);
                e1.LoadArgument(2);
                e1.StoreElement <uint>();
                e1.Return();

                var d1 = e1.CreateDelegate();

                var x = new uint[] { 5 };
                d1(x, 0, 10);

                Assert.AreEqual((uint)10, x[0]);
            }

            {
                var e1 = Emit <Action <long[], int, long> > .NewDynamicMethod();

                e1.LoadArgument(0);
                e1.LoadArgument(1);
                e1.LoadArgument(2);
                e1.StoreElement <long>();
                e1.Return();

                var d1 = e1.CreateDelegate();

                var x = new long[] { 5 };
                d1(x, 0, 10);

                Assert.AreEqual((long)10, x[0]);
            }

            {
                var e1 = Emit <Action <ulong[], int, ulong> > .NewDynamicMethod();

                e1.LoadArgument(0);
                e1.LoadArgument(1);
                e1.LoadArgument(2);
                e1.StoreElement <ulong>();
                e1.Return();

                var d1 = e1.CreateDelegate();

                var x = new ulong[] { 5 };
                d1(x, 0, 10);

                Assert.AreEqual((ulong)10, x[0]);
            }

            {
                var e1 = Emit <Action <float[], int, float> > .NewDynamicMethod();

                e1.LoadArgument(0);
                e1.LoadArgument(1);
                e1.LoadArgument(2);
                e1.StoreElement <float>();
                e1.Return();

                var d1 = e1.CreateDelegate();

                var x = new float[] { 5 };
                d1(x, 0, 10);

                Assert.AreEqual((float)10, x[0]);
            }

            {
                var e1 = Emit <Action <double[], int, double> > .NewDynamicMethod();

                e1.LoadArgument(0);
                e1.LoadArgument(1);
                e1.LoadArgument(2);
                e1.StoreElement <double>();
                e1.Return();

                var d1 = e1.CreateDelegate();

                var x = new double[] { 5 };
                d1(x, 0, 10);

                Assert.AreEqual((double)10, x[0]);
            }

            {
                var e1 = Emit <Action <object[], int, object> > .NewDynamicMethod();

                e1.LoadArgument(0);
                e1.LoadArgument(1);
                e1.LoadArgument(2);
                e1.StoreElement <object>();
                e1.Return();

                var d1 = e1.CreateDelegate();

                var x = new object[] { "hello" };
                d1(x, 0, "world");

                Assert.AreEqual("world", (string)x[0]);
            }

            {
                var e1 = Emit <Action <DateTime[], int, DateTime> > .NewDynamicMethod();

                e1.LoadArgument(0);
                e1.LoadArgument(1);
                e1.LoadArgument(2);
                e1.StoreElement <DateTime>();
                e1.Return();

                var d1 = e1.CreateDelegate();

                var now = DateTime.UtcNow;

                var x = new DateTime[] { DateTime.MinValue };
                d1(x, 0, now);

                Assert.AreEqual(now, x[0]);
            }

            {
                var e1 = Emit <Action <int *[], int, IntPtr> > .NewDynamicMethod();

                e1.LoadArgument(0);
                e1.LoadArgument(1);
                e1.LoadArgument(2);
                e1.StoreElement(typeof(int *));
                e1.Return();

                var d1 = e1.CreateDelegate();

                var ptr = new IntPtr(123);

                var x = new int *[] { (int *)new IntPtr(456) };
                d1(x, 0, ptr);

                var y = (int *)ptr == x[0];

                Assert.IsTrue(y);
            }
        }
Beispiel #32
0
        public void EmitDeserialize(Emit emiter, Local value)
        {
            var elementType = value.LocalType.GetElementType();
            var emptyArray  = emiter.DefineLabel();
            var end         = emiter.DefineLabel();

            using (var length = emiter.DeclareLocal <int>("length"))
            {
                emiter.CallDeserializerForType(length.LocalType, length);

                // if(length < 1) {
                //  value = Array.Empty<>()
                //  return
                // }
                emiter.LoadLocal(length);
                emiter.LoadConstant(1);
                emiter.BranchIfLess(emptyArray);

                // value = new [length]
                emiter.LoadLocal(length);
                emiter.NewArray(elementType);
                emiter.StoreLocal(value);

                var loop      = emiter.DefineLabel();
                var loopCheck = emiter.DefineLabel();

                // Little optimization for byte arrays
                if (elementType == typeof(byte))
                {
                    // value = reader.ReadBytes(length);
                    emiter.LoadArgument(1);
                    emiter.LoadLocal(length);
                    emiter.CallVirtual(typeof(BinaryReader).GetMethod(nameof(BinaryReader.ReadBytes)));
                    emiter.StoreLocal(value);
                    emiter.Branch(end);
                }
                else
                {
                    using (var element = emiter.DeclareLocal(elementType, "element"))
                        using (var i = emiter.DeclareLocal <int>("i"))
                        {
                            emiter.MarkLabel(loop);

                            if (_compiler != null)
                            {
                                _compiler.EmitDeserialize(emiter, element);
                            }
                            else if (_serializer != null)
                            {
                                emiter.CallDeserializer(_serializer, element);
                            }
                            else
                            {
                                emiter.CallDeserializerForType(elementType, element);
                            }

                            // value[i] = element
                            emiter.LoadLocal(value);
                            emiter.LoadLocal(i);
                            emiter.LoadLocal(element);
                            emiter.StoreElement(elementType);

                            // ++i
                            emiter.LoadLocal(i);
                            emiter.LoadConstant(1);
                            emiter.Add();
                            emiter.StoreLocal(i);

                            // i < length
                            emiter.MarkLabel(loopCheck);
                            emiter.LoadLocal(i);
                            emiter.LoadLocal(length);
                            emiter.BranchIfLess(loop);
                        }
                }
                emiter.Branch(end);
            }

            // value = Array.Empty<>()
            emiter.MarkLabel(emptyArray);
            emiter.Call(typeof(Array)
                        .GetMethod(nameof(Array.Empty))
                        .GetGenericMethodDefinition()
                        .MakeGenericMethod(elementType));
            emiter.StoreLocal(value);
            emiter.MarkLabel(end);
        }
 public ConstructionState(Stack <State> stateStack, Dictionary <string, Type> definedTypes, AssemblyBuilder asmBuilder, Type typeBuilder, Emit method) : base(stateStack, definedTypes, asmBuilder, typeBuilder, method)
 {
 }
Beispiel #34
0
 public EnumAttribute(Emit emit)
 {
 }
        private TDelegate EmitDelegate()
        {
            var requiresBestEffortMatching = false;

            if (_resolutionModule != null)
            {
                try
                {
                    // Don't resolve until we build, as it may be an unnecessary lookup because of the cache
                    // We also may need the generics which were specified
                    if (_forceMethodDefResolve || (_declaringTypeGenerics == null && _methodGenerics == null))
                    {
                        _methodBase =
                            _resolutionModule.ResolveMethod(metadataToken: _mdToken);
                    }
                    else
                    {
                        _methodBase =
                            _resolutionModule.ResolveMethod(
                                metadataToken: _mdToken,
                                genericTypeArguments: _declaringTypeGenerics,
                                genericMethodArguments: _methodGenerics);
                    }
                }
                catch (Exception ex)
                {
                    var message = $"Unable to resolve method {_concreteTypeName}.{_methodName} by metadata token: {_mdToken}";
                    Log.Error(ex, message);
                    requiresBestEffortMatching = true;
                }
            }
            else
            {
                Log.Warning($"Unable to resolve module version id {_moduleVersionId}. Using method builder fallback.");
            }

            MethodInfo methodInfo = null;

            if (!requiresBestEffortMatching && _methodBase is MethodInfo info)
            {
                if (info.IsGenericMethodDefinition)
                {
                    info = MakeGenericMethod(info);
                }

                methodInfo = VerifyMethodFromToken(info);
            }

            if (methodInfo == null && ForceMdTokenLookup)
            {
                throw new Exception($"Unable to resolve method {_concreteTypeName}.{_methodName} by metadata token: {_mdToken}. Exiting because {nameof(ForceMdTokenLookup)}() is true.");
            }
            else if (methodInfo == null || ForceFallbackLookup)
            {
                // mdToken didn't work out, fallback
                methodInfo = TryFindMethod();
            }

            Type delegateType = typeof(TDelegate);

            Type[] delegateGenericArgs = delegateType.GenericTypeArguments;

            Type[] delegateParameterTypes;
            Type   returnType;

            if (delegateType.Name.StartsWith("Func`"))
            {
                // last generic type argument is the return type
                int parameterCount = delegateGenericArgs.Length - 1;
                delegateParameterTypes = new Type[parameterCount];
                Array.Copy(delegateGenericArgs, delegateParameterTypes, parameterCount);

                returnType = delegateGenericArgs[parameterCount];
            }
            else if (delegateType.Name.StartsWith("Action`"))
            {
                delegateParameterTypes = delegateGenericArgs;
                returnType             = typeof(void);
            }
            else
            {
                throw new Exception($"Only Func<> or Action<> are supported in {nameof(MethodBuilder)}.");
            }

            if (methodInfo.IsGenericMethodDefinition)
            {
                methodInfo = MakeGenericMethod(methodInfo);
            }

            Type[] effectiveParameterTypes;

            var reflectedParameterTypes =
                methodInfo.GetParameters().Select(p => p.ParameterType);

            if (methodInfo.IsStatic)
            {
                effectiveParameterTypes = reflectedParameterTypes.ToArray();
            }
            else
            {
                // for instance methods, insert object's type as first element in array
                effectiveParameterTypes = new[] { _concreteType }
                .Concat(reflectedParameterTypes)
                .ToArray();
            }

            var dynamicMethod = Emit <TDelegate> .NewDynamicMethod(methodInfo.Name);

            // load each argument and cast or unbox as necessary
            for (ushort argumentIndex = 0; argumentIndex < delegateParameterTypes.Length; argumentIndex++)
            {
                Type delegateParameterType   = delegateParameterTypes[argumentIndex];
                Type underlyingParameterType = effectiveParameterTypes[argumentIndex];

                dynamicMethod.LoadArgument(argumentIndex);

                if (underlyingParameterType.IsValueType && delegateParameterType == typeof(object))
                {
                    dynamicMethod.UnboxAny(underlyingParameterType);
                }
                else if (underlyingParameterType != delegateParameterType)
                {
                    dynamicMethod.CastClass(underlyingParameterType);
                }
            }

            if (_opCode == OpCodeValue.Call || methodInfo.IsStatic)
            {
                // non-virtual call (e.g. static method, or method override calling overriden implementation)
                dynamicMethod.Call(methodInfo);
            }
            else if (_opCode == OpCodeValue.Callvirt)
            {
                // Note: C# compiler uses CALLVIRT for non-virtual
                // instance methods to get the cheap null check
                dynamicMethod.CallVirtual(methodInfo);
            }
            else
            {
                throw new NotSupportedException($"OpCode {_originalOpCodeValue} not supported when calling a method.");
            }

            if (methodInfo.ReturnType.IsValueType && returnType == typeof(object))
            {
                dynamicMethod.Box(methodInfo.ReturnType);
            }
            else if (methodInfo.ReturnType != returnType)
            {
                dynamicMethod.CastClass(returnType);
            }

            dynamicMethod.Return();
            return(dynamicMethod.CreateDelegate());
        }
Beispiel #36
0
        void EmitInit(Emit.PEModuleBuilder module, DiagnosticBag diagnostic, PhpCompilation compilation, SynthesizedStaticLocHolder holder, BoundExpression initializer)
        {
            var loctype = holder.ValueField.Type;

            bool requiresContext = initializer != null && initializer.RequiresContext;

            if (requiresContext)
            {
                // emit Init only if it needs Context

                holder.EmitInit(module, (il) =>
                {
                    var cg = new CodeGenerator(il, module, diagnostic, OptimizationLevel.Release, false,
                        holder.ContainingType, new ArgPlace(compilation.CoreTypes.Context, 1), new ArgPlace(holder, 0));

                    var valuePlace = new FieldPlace(cg.ThisPlaceOpt, holder.ValueField);
                    
                    // Template: this.value = <initilizer>;

                    valuePlace.EmitStorePrepare(il);
                    cg.EmitConvert(initializer, valuePlace.TypeOpt);                    
                    valuePlace.EmitStore(il);

                    //
                    il.EmitRet(true);
                });
            }

            // default .ctor
            holder.EmitCtor(module, (il) =>
            {
                if (!requiresContext)
                {
                    // emit default value only if it won't be initialized by Init above

                    var cg = new CodeGenerator(il, module, diagnostic, OptimizationLevel.Release, false,
                        holder.ContainingType, null, new ArgPlace(holder, 0));

                    var valuePlace = new FieldPlace(cg.ThisPlaceOpt, holder.ValueField);

                    // Template: this.value = default(T);

                    valuePlace.EmitStorePrepare(il);
                    if (initializer != null)
                    {
                        cg.EmitConvert(initializer, valuePlace.TypeOpt);
                    }
                    else
                    {
                        cg.EmitLoadDefault(valuePlace.TypeOpt, 0);
                    }
                    valuePlace.EmitStore(il);
                }

                //
                il.EmitRet(true);
            });
        }
Beispiel #37
0
        public unsafe void All()
        {
            {
                var e1 = Emit <Func <sbyte> > .NewDynamicMethod("E1");

                var a = e1.DeclareLocal <sbyte>("a");
                e1.LoadLocalAddress(a);
                e1.LoadConstant((sbyte)1);
                e1.StoreIndirect <sbyte>();
                e1.LoadLocal(a);
                e1.Return();

                var d1 = e1.CreateDelegate();

                Assert.AreEqual((sbyte)1, d1());
            }

            {
                var e1 = Emit <Func <byte> > .NewDynamicMethod("E1");

                var a = e1.DeclareLocal <byte>("a");
                e1.LoadLocalAddress(a);
                e1.LoadConstant((byte)1);
                e1.StoreIndirect <byte>();
                e1.LoadLocal(a);
                e1.Return();

                var d1 = e1.CreateDelegate();

                Assert.AreEqual((byte)1, d1());
            }

            {
                var e1 = Emit <Func <short> > .NewDynamicMethod("E1");

                var a = e1.DeclareLocal <short>("a");
                e1.LoadLocalAddress(a);
                e1.LoadConstant((short)1);
                e1.StoreIndirect <short>();
                e1.LoadLocal(a);
                e1.Return();

                var d1 = e1.CreateDelegate();

                Assert.AreEqual((short)1, d1());
            }

            {
                var e1 = Emit <Func <ushort> > .NewDynamicMethod("E1");

                var a = e1.DeclareLocal <ushort>("a");
                e1.LoadLocalAddress(a);
                e1.LoadConstant((ushort)1);
                e1.StoreIndirect <ushort>();
                e1.LoadLocal(a);
                e1.Return();

                var d1 = e1.CreateDelegate();

                Assert.AreEqual((ushort)1, d1());
            }

            {
                var e1 = Emit <Func <int> > .NewDynamicMethod("E1");

                var a = e1.DeclareLocal <int>("a");
                e1.LoadLocalAddress(a);
                e1.LoadConstant((int)1);
                e1.StoreIndirect <int>();
                e1.LoadLocal(a);
                e1.Return();

                var d1 = e1.CreateDelegate();

                Assert.AreEqual((int)1, d1());
            }

            {
                var e1 = Emit <Func <uint> > .NewDynamicMethod("E1");

                var a = e1.DeclareLocal <uint>("a");
                e1.LoadLocalAddress(a);
                e1.LoadConstant((uint)1);
                e1.StoreIndirect <uint>();
                e1.LoadLocal(a);
                e1.Return();

                var d1 = e1.CreateDelegate();

                Assert.AreEqual((uint)1, d1());
            }

            {
                var e1 = Emit <Func <long> > .NewDynamicMethod("E1");

                var a = e1.DeclareLocal <long>("a");
                e1.LoadLocalAddress(a);
                e1.LoadConstant((long)1);
                e1.StoreIndirect <long>();
                e1.LoadLocal(a);
                e1.Return();

                var d1 = e1.CreateDelegate();

                Assert.AreEqual((long)1, d1());
            }

            {
                var e1 = Emit <Func <ulong> > .NewDynamicMethod("E1");

                var a = e1.DeclareLocal <ulong>("a");
                e1.LoadLocalAddress(a);
                e1.LoadConstant((ulong)1);
                e1.StoreIndirect <ulong>();
                e1.LoadLocal(a);
                e1.Return();

                var d1 = e1.CreateDelegate();

                Assert.AreEqual((ulong)1, d1());
            }

            {
                var e1 = Emit <Func <float> > .NewDynamicMethod("E1");

                var a = e1.DeclareLocal <float>("a");
                e1.LoadLocalAddress(a);
                e1.LoadConstant((float)1);
                e1.StoreIndirect <float>();
                e1.LoadLocal(a);
                e1.Return();

                var d1 = e1.CreateDelegate();

                Assert.AreEqual((float)1, d1());
            }

            {
                var e1 = Emit <Func <double> > .NewDynamicMethod("E1");

                var a = e1.DeclareLocal <double>("a");
                e1.LoadLocalAddress(a);
                e1.LoadConstant(3.1415926);
                e1.StoreIndirect <double>();
                e1.LoadLocal(a);
                e1.Return();

                var d1 = e1.CreateDelegate();

                Assert.AreEqual(3.1415926, d1());
            }

            {
                var e1 = Emit <Func <object> > .NewDynamicMethod("E1");

                var a = e1.DeclareLocal <object>("a");
                e1.LoadLocalAddress(a);
                e1.LoadConstant("hello world");
                e1.StoreIndirect <object>();
                e1.LoadLocal(a);
                e1.Return();

                var d1 = e1.CreateDelegate();

                Assert.AreEqual("hello world", d1());
            }

            {
                var e1 = Emit <Func <IntPtr> > .NewDynamicMethod("E1");

                var a = e1.DeclareLocal(typeof(int *), "a");
                e1.LoadLocalAddress(a);
                e1.LoadConstant(123);
                e1.Convert <IntPtr>();
                e1.StoreIndirect(typeof(int *));
                e1.LoadLocal(a);
                e1.Return();

                var d1 = e1.CreateDelegate();

                var x = (int *)d1();

                Assert.IsTrue(x == (int *)123);
            }
        }
Beispiel #38
0
		internal override int ImportTo(Emit.ModuleBuilder module)
		{
			if (methodArgs == null)
			{
				return module.ImportMethodOrField(declaringType, method.Name, method.MethodSignature);
			}
			else
			{
				Writer.ByteBuffer spec = new Writer.ByteBuffer(10);
				Signature.WriteMethodSpec(module, spec, methodArgs);
				Metadata.MethodSpecTable.Record rec = new Metadata.MethodSpecTable.Record();
				Emit.MethodBuilder mb = method as Emit.MethodBuilder;
				if (mb != null && mb.ModuleBuilder == module && !declaringType.IsGenericType)
				{
					rec.Method = mb.MetadataToken;
				}
				else
				{
					rec.Method = module.ImportMember(GetGenericMethodDefinition());
				}
				rec.Instantiation = module.Blobs.Add(spec);
				return 0x2B000000 | module.MethodSpec.FindOrAddRecord(rec);
			}
		}
Beispiel #39
0
        public static Dictionary <FieldInfo, int> FieldOffsetsInMemory(Type t)
        {
            try
            {
                var fields = t.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);

                var emit = Emit <Func <object, ulong[]> > .NewDynamicMethod("_GetOffsetsInMemory" + t.FullName);

                var retLoc = emit.DeclareLocal <ulong[]>("ret");

                emit.LoadConstant(fields.Length);       // ulong
                emit.NewArray(typeof(ulong));           // ulong[]
                emit.StoreLocal(retLoc);                // --empty--

                for (var i = 0; i < fields.Length; i++)
                {
                    var field = fields[i];

                    emit.LoadLocal(retLoc);         // ulong[]
                    emit.LoadConstant(i);           // ulong[] ulong

                    emit.LoadArgument(0);           // ulong[] ulong param#0
                    emit.CastClass(t);              // ulong[] ulong param#0

                    emit.LoadFieldAddress(field);   // ulong[] ulong field&
                    emit.Convert <ulong>();         // ulong[] ulong ulong

                    emit.StoreElement <ulong>();    // --empty--
                }

                emit.LoadLocal(retLoc);                 // ulong[]
                emit.Return();                          // --empty--

                var getAddrs = emit.CreateDelegate();

                var cons           = t.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).OrderBy(p => p.GetParameters().Count()).FirstOrDefault();
                var consParameters = cons != null?cons.GetParameters().Select(p => p.ParameterType.DefaultValue()).ToArray() : null;

                object obj;
                if (cons != null)
                {
                    obj = cons.Invoke(consParameters);
                }
                else
                {
                    obj = Activator.CreateInstance(t);
                }

                var addrs = getAddrs(obj);

                if (addrs.Length == 0)
                {
                    return(new Dictionary <FieldInfo, int>());
                }

                var min = addrs.Min();

                var ret = new Dictionary <FieldInfo, int>();

                for (var i = 0; i < fields.Length; i++)
                {
                    var field = fields[i];

                    var addr   = addrs[i];
                    var offset = addr - min;

                    ret[field] = (int)offset;
                }

                return(ret);
            }
            catch
            {
                // A lot can go wrong during this, and the common response is just to bail
                // This catch is much simpler than trying (and probably failing) to enumerate
                //    all the exceptional cases
                return(new Dictionary <FieldInfo, int>());
            }
        }
Beispiel #40
0
 [Fact] public void StatementGotoTest() => TestRoundTrip("goto foo", Emit.Goto("foo"), ScriptParser.Statement);
Beispiel #41
0
        private static Func <T, byte[], int, byte[]> GetToBytesFunc(List <PackInfo> infos)
        {
            var type      = typeof(T);
            var blockCopy = typeof(Buffer).GetMethod("BlockCopy");

            var emit = Emit <Func <T, byte[], int, byte[]> > .NewDynamicMethod(type.Name + "_ToBytes");

            const int objArg    = 0; // T obj
            const int bytesArg  = 1; // bytes[] bytes
            const int offsetArg = 2; // int offset

            // write data for each property
            foreach (var info in infos)
            {
                if (info.IsBool && s_packBools)
                {
                    // the property is a bool, and we're bit-packing bools

                    // get property value
                    emit.LoadArgument(objArg);                     // [objArg]
                    emit.CallVirtual(info.PropertyInfo.GetMethod); // [value]

                    // we only want to do anything if the value is true (no reason to OR a zero)
                    var endIf = emit.DefineLabel();
                    emit.BranchIfFalse(endIf); // empty

                    // load the array index address
                    emit.LoadArgument(bytesArg);        // [bytesArg]
                    emit.LoadConstant(info.ByteOffset); // [bytesArg] [info-offset]
                    emit.LoadArgument(offsetArg);       // [bytesArg] [info-offset] [offsetArg]
                    emit.Add();                         // [bytesArg] [offset]
                    emit.LoadElementAddress <byte>();   // [ref bytesArg[offset]]

                    // OR the existing value of the byte with the bit flag
                    var flag = (byte)(1 << info.Bit);
                    emit.Duplicate();         // [ref bytesArg[offset]] [ref bytesArg[offset]]
                    emit.LoadObject <byte>(); // [ref bytesArg[offset]] [bytesArg[offset]]
                    emit.LoadConstant(flag);  // [ref bytesArg[offset]] [bytesArg[offset]] [flag]
                    emit.Or();                // [ref bytesArg[offset]] [OR'd-int]
                    emit.Convert <byte>();    // [ref bytesArg[offset]] [OR'd-byte]

                    // write the OR'd byte back to the array
                    emit.StoreObject <byte>(); // empty

                    // end of if statement
                    emit.MarkLabel(endIf);
                }
                else if (info.BackingType == typeof(byte) || info.BackingType == typeof(sbyte))
                {
                    // byte types can be written directly with no conversion

                    // load the array index address
                    emit.LoadArgument(bytesArg);        // [bytesArg]
                    emit.LoadConstant(info.ByteOffset); // [bytesArg] [offset]
                    emit.LoadArgument(offsetArg);       // [bytesArg] [info-offset] [offsetArg]
                    emit.Add();                         // [bytesArg] [offset]
                    emit.LoadElementAddress <byte>();   // [ref bytesArg[offset]]

                    // get property value
                    emit.LoadArgument(objArg);                     // [ref bytesArg[offset]] [objArg]
                    emit.CallVirtual(info.PropertyInfo.GetMethod); // [ref bytesArg[offset]] [value]

                    // store the property value into the array address
                    emit.StoreObject <byte>(); // empty
                }
                else
                {
                    // this is a type we need to convert to bytes

                    // get converter method
                    var getBytes = typeof(BitConverter).GetMethod("GetBytes", new[] { info.BackingType });

                    // get property value
                    emit.LoadArgument(objArg);                     // [objArg]
                    emit.CallVirtual(info.PropertyInfo.GetMethod); // [value]

                    // convert the value to bytes
                    emit.Call(getBytes); // [bytes]

                    // copy the bytes to the overall array
                    // Buffer.BlockCopy(Array src, int srcOffset, Array dst, int dstOffset, int count)
                    emit.LoadConstant(0);               // [bytes] [0]
                    emit.LoadArgument(bytesArg);        // [bytes] [0] [bytesArg]
                    emit.LoadConstant(info.ByteOffset); // [bytes] [0] [bytesArg] [info-offset]
                    emit.LoadArgument(offsetArg);       // [bytes] [0] [bytesArg] [info-offset] [offsetArg]
                    emit.Add();                         // [bytes] [0] [bytesArg] [offset]
                    emit.LoadConstant(info.Size);       // [bytes] [0] [bytesArg] [offset] [size]
                    emit.Call(blockCopy);               // empty
                }
            }

            emit.LoadArgument(bytesArg); // [bytesArg]
            emit.Return();

            return(emit.CreateDelegate());
        }
Beispiel #42
0
 [Fact] public void StatementLabelTest() => TestRoundTrip("foo:", Emit.Label("foo"), ScriptParser.Statement);
Beispiel #43
0
        public void BranchingOverExceptions()
        {
            {
                var hasNormalBranch = new Regex("^br ", RegexOptions.Multiline);

                for (var i = 0; i < 127 - 10; i++)
                {
                    var e1 = Emit <Action> .NewDynamicMethod("E1");

                    var end = e1.DefineLabel("end");

                    e1.Branch(end);

                    var t = e1.BeginExceptionBlock();
                    var c = e1.BeginCatchBlock <Exception>(t);
                    e1.Pop();
                    e1.EndCatchBlock(c);
                    e1.EndExceptionBlock(t);

                    for (var j = 0; j < i; j++)
                    {
                        e1.Nop();
                    }

                    e1.MarkLabel(end);
                    e1.Return();

                    string instrs;
                    var    d1 = e1.CreateDelegate(out instrs);

                    d1();

                    var shouldFail = hasNormalBranch.IsMatch(instrs);
                    if (shouldFail)
                    {
                        Assert.Fail();
                    }
                }
            }

            {
                var hasNormalBranch = new Regex("^br ", RegexOptions.Multiline);

                for (var i = 0; i < 127 - 16; i++)
                {
                    var e1 = Emit <Action> .NewDynamicMethod("E1");

                    var end = e1.DefineLabel("end");

                    e1.Branch(end);

                    var t = e1.BeginExceptionBlock();
                    var c = e1.BeginCatchBlock <Exception>(t);
                    e1.Pop();
                    e1.EndCatchBlock(c);
                    var f = e1.BeginFinallyBlock(t);
                    e1.EndFinallyBlock(f);
                    e1.EndExceptionBlock(t);

                    for (var j = 0; j < i; j++)
                    {
                        e1.Nop();
                    }

                    e1.MarkLabel(end);
                    e1.Return();

                    string instrs;
                    var    d1 = e1.CreateDelegate(out instrs);

                    d1();

                    var shouldFail = hasNormalBranch.IsMatch(instrs);
                    if (shouldFail)
                    {
                        Assert.Fail();
                    }
                }
            }
        }
		internal abstract int ImportTo(Emit.ModuleBuilder module);
Beispiel #45
0
        private Cci.IAssemblyReference TryGetAssemblyScope(NamespaceSymbol @namespace, Emit.PEModuleBuilder moduleBuilder, DiagnosticBag diagnostics)
        {
            AssemblySymbol containingAssembly = @namespace.ContainingAssembly;
            if ((object)containingAssembly != null && (object)containingAssembly != moduleBuilder.CommonCompilation.Assembly)
            {
                var referenceManager = ((CSharpCompilation)moduleBuilder.CommonCompilation).GetBoundReferenceManager();

                for (int i = 0; i < referenceManager.ReferencedAssemblies.Length; i++)
                {
                    if ((object)referenceManager.ReferencedAssemblies[i] == containingAssembly)
                    {
                        if (!referenceManager.DeclarationsAccessibleWithoutAlias(i))
                        {
                            return moduleBuilder.Translate(containingAssembly, diagnostics);
                        }
                    }
                }
            }

            return null;
        }
Beispiel #46
0
        /// <summary>
        /// Emit instantiation and initialization of NamingContext. Leaves reference to new NamingContext on the top of evaluation stack.
        /// </summary>
        /// <param name="il"></param>
        /// <param name="currentNamespace">Namespace to be passed as current namespace to the new instance of <see cref="NamingContext"/>.</param>
        /// <param name="aliases">Aliases to be passed to the new instance of <see cref="NamingContext"/>.</param>
        internal static void EmitNewNamingContext(Emit.ILEmitter/*!*/il, QualifiedName? currentNamespace, Dictionary<string, QualifiedName> aliases)
        {
            if (!NeedsNamingContext(currentNamespace, aliases))
            {
                il.Emit(OpCodes.Ldnull);
                return;
            }

            //
            // new NamingContext( currentNamespace.NamespacePhpName, aliases.Count )

            if (currentNamespace.HasValue && currentNamespace.Value.Namespaces.Length > 0)
                il.Emit(OpCodes.Ldstr, currentNamespace.Value.NamespacePhpName);
            else
                il.Emit(OpCodes.Ldnull);

            il.LdcI4((aliases != null) ? aliases.Count : 0);

            il.Emit(OpCodes.Newobj, Constructors.NamingContext);

            // tmp.AddAlias( aliases[i].Key, aliases[i].Value.NamespacePhpName
            if (aliases != null)
            {
                foreach (var alias in aliases)
                {
                    il.Emit(OpCodes.Dup);                                   // the NamingContext instance
                    il.Emit(OpCodes.Ldstr, alias.Key);                      // alias
                    il.Emit(OpCodes.Ldstr, alias.Value.ToString());         // qualifiedName
                    il.Emit(OpCodes.Call, Methods.NamingContext.AddAlias);  // AddAlias( <alias>, <qualifiedName> )
                }
            }

        }
Beispiel #47
0
        private ImmutableArray<Cci.UsedNamespaceOrType> TranslateImports(Emit.PEModuleBuilder moduleBuilder, DiagnosticBag diagnostics)
        {
            var usedNamespaces = ArrayBuilder<Cci.UsedNamespaceOrType>.GetInstance();

            // NOTE: order based on dev12: extern aliases, then usings, then aliases namespaces and types

            ImmutableArray<AliasAndExternAliasDirective> externAliases = Imports.ExternAliases;
            if (!externAliases.IsDefault)
            {
                foreach (var alias in externAliases)
                {
                    usedNamespaces.Add(Cci.UsedNamespaceOrType.CreateExternAlias(alias.Alias.Name));
                }
            }

            ImmutableArray<NamespaceOrTypeAndUsingDirective> usings = Imports.Usings;
            if (!usings.IsDefault)
            {
                foreach (var nsOrType in usings)
                {
                    NamespaceOrTypeSymbol namespaceOrType = nsOrType.NamespaceOrType;
                    if (namespaceOrType.IsNamespace)
                    {
                        var ns = (NamespaceSymbol)namespaceOrType;
                        var assemblyRef = TryGetAssemblyScope(ns, moduleBuilder, diagnostics);
                        usedNamespaces.Add(Cci.UsedNamespaceOrType.CreateNamespace(ns, assemblyRef));
                    }
                    else if (!namespaceOrType.ContainingAssembly.IsLinked)
                    {
                        // We skip alias imports of embedded types to be consistent with imports of aliased embedded types and with VB.
                        var typeRef = GetTypeReference((TypeSymbol)namespaceOrType, nsOrType.UsingDirective, moduleBuilder, diagnostics);
                        usedNamespaces.Add(Cci.UsedNamespaceOrType.CreateType(typeRef));
                    }
                }
            }

            ImmutableDictionary<string, AliasAndUsingDirective> aliasSymbols = Imports.UsingAliases;
            if (!aliasSymbols.IsEmpty)
            {
                var aliases = ArrayBuilder<string>.GetInstance(aliasSymbols.Count);
                aliases.AddRange(aliasSymbols.Keys);
                aliases.Sort(StringComparer.Ordinal); // Actual order doesn't matter - just want to be deterministic.

                foreach (var alias in aliases)
                {
                    var aliasAndUsingDirective = aliasSymbols[alias];
                    var symbol = aliasAndUsingDirective.Alias;
                    var syntax = aliasAndUsingDirective.UsingDirective;
                    Debug.Assert(!symbol.IsExtern);

                    NamespaceOrTypeSymbol target = symbol.Target;
                    if (target.Kind == SymbolKind.Namespace)
                    {
                        var ns = (NamespaceSymbol)target;
                        var assemblyRef = TryGetAssemblyScope(ns, moduleBuilder, diagnostics);
                        usedNamespaces.Add(Cci.UsedNamespaceOrType.CreateNamespace(ns, assemblyRef, alias));
                    }
                    else if (!target.ContainingAssembly.IsLinked)
                    {
                        // We skip alias imports of embedded types to avoid breaking existing code that
                        // imports types that can't be embedded but doesn't use them anywhere else in the code.
                        var typeRef = GetTypeReference((TypeSymbol)target, syntax, moduleBuilder, diagnostics);
                        usedNamespaces.Add(Cci.UsedNamespaceOrType.CreateType(typeRef, alias));
                    }
                }

                aliases.Free();
            }

            return usedNamespaces.ToImmutableAndFree();
        }
Beispiel #48
0
		internal override int ImportTo(Emit.ModuleBuilder module)
		{
			return module.ImportMethodOrField(declaringType, this.Name, this.MethodSignature);
		}
Beispiel #49
0
 [Fact] public void StatementStatementTest() => TestRoundTrip("a b c", S(Emit.Name("a"), Emit.Name("b"), Emit.Name("c")), ScriptParser.Statement);
Beispiel #50
0
        void EmitPhpCtor(MethodSymbol ctor, Emit.PEModuleBuilder module)
        {
            if (ctor == null) return;   // static class
            Debug.Assert(ctor.MethodKind == MethodKind.Constructor);

            module.SetMethodBody(ctor, MethodGenerator.GenerateMethodBody(module, ctor, il =>
            {
                Debug.Assert(SpecialParameterSymbol.IsContextParameter(ctor.Parameters[0]));

                var cg = new CodeGenerator(il, module, DiagnosticBag.GetInstance(), OptimizationLevel.Release, false, this, new ParamPlace(ctor.Parameters[0]), new ArgPlace(this, 0));

                // call .phpnew
                var phpnew = this.InitializeInstanceMethod;
                cg.EmitPop(cg.EmitThisCall(phpnew, ctor));

                // call __construct
                var phpctor = this.ResolvePhpCtor(true);
                cg.EmitPop(cg.EmitThisCall(phpctor, ctor));

                Debug.Assert(ctor.ReturnsVoid);
                cg.EmitRet(ctor.ReturnType);

            }, null, DiagnosticBag.GetInstance(), false));
        }
        public static TypeSymbol EmitConvertToPhpValue(TypeSymbol from, TypeRefMask fromHint, ILBuilder il, Emit.PEModuleBuilder module, DiagnosticBag diagnostic)
        {
            Contract.ThrowIfNull(from);

            var compilation = module.Compilation;

            switch (from.SpecialType)
            {
                case SpecialType.System_Boolean:
                    il.EmitCall(module, diagnostic, ILOpCode.Call, compilation.CoreMethods.PhpValue.Create_Boolean);
                    break;
                case SpecialType.System_Int32:
                    il.EmitOpCode(ILOpCode.Conv_i8);   // Int32 -> Int64
                    goto case SpecialType.System_Int64; // PhpValue.Create((long)<stack>)
                case SpecialType.System_Int64:
                    il.EmitCall(module, diagnostic, ILOpCode.Call, compilation.CoreMethods.PhpValue.Create_Long);
                    break;
                case SpecialType.System_Double:
                    il.EmitCall(module, diagnostic, ILOpCode.Call, compilation.CoreMethods.PhpValue.Create_Double);
                    break;
                case SpecialType.System_Void:
                    Emit_PhpValue_Void(il, module, diagnostic);
                    break;
                default:
                    if (from == compilation.CoreTypes.PhpAlias)
                    {
                        il.EmitCall(module, diagnostic, ILOpCode.Call, compilation.CoreMethods.PhpValue.Create_PhpAlias)
                            .Expect(compilation.CoreTypes.PhpValue);
                        break;
                    }
                    else if (from == compilation.CoreTypes.PhpValue)
                    {
                        // nop
                        break;
                    }
                    else if (from == compilation.CoreTypes.String)
                    {
                        il.EmitCall(module, diagnostic, ILOpCode.Call, compilation.CoreMethods.PhpValue.Create_String)
                            .Expect(compilation.CoreTypes.PhpValue);
                        break;
                    }
                    else if (from == compilation.CoreTypes.PhpString)
                    {
                        il.EmitCall(module, diagnostic, ILOpCode.Call, compilation.CoreMethods.PhpValue.Create_PhpString)
                            .Expect(compilation.CoreTypes.PhpValue);
                        break;
                    }
                    else if (from == compilation.CoreTypes.PhpNumber)
                    {
                        il.EmitCall(module, diagnostic, ILOpCode.Call, compilation.CoreMethods.PhpValue.Create_PhpNumber)
                            .Expect(compilation.CoreTypes.PhpValue);
                        break;
                    }
                    else if (from.IsOfType(compilation.CoreTypes.PhpArray))
                    {
                        il.EmitCall(module, diagnostic, ILOpCode.Call, compilation.CoreMethods.PhpValue.Create_PhpArray)
                            .Expect(compilation.CoreTypes.PhpValue);
                        break;
                    }
                    else if (from == compilation.CoreTypes.IntStringKey)
                    {
                        il.EmitCall(module, diagnostic, ILOpCode.Call, compilation.CoreMethods.PhpValue.Create_IntStringKey)
                            .Expect(compilation.CoreTypes.PhpValue);
                        break;
                    }
                    else if (from.IsReferenceType)
                    {
                        il.EmitCall(module, diagnostic, ILOpCode.Call, compilation.CoreMethods.PhpValue.FromClass_Object)
                            .Expect(compilation.CoreTypes.PhpValue);
                        break;
                    }
                    else
                    {
                        throw new NotImplementedException($"{from.Name}");
                    }
            }

            //
            return compilation.CoreTypes.PhpValue;
        }
Beispiel #52
0
        private static Func <byte[], int, T> GetFromBytesFunc(List <PackInfo> infos)
        {
            var emit = Emit <Func <byte[], int, T> > .NewDynamicMethod(typeof(T).Name + "_ToBytes");

            const int bytesArg  = 0; // bytes[] bytes
            const int offsetArg = 1; // int offset

            // create instance of object
            var obj = emit.DeclareLocal <T>("obj");

            emit.NewObject <T>(); // [new T]
            emit.StoreLocal(obj); // empty

            // read each property from the byte array
            foreach (var info in infos)
            {
                if (info.IsBool && s_packBools)
                {
                    // property is a bit flag

                    // load the object
                    emit.LoadLocal(obj); // [obj]

                    // load the appropriate byte
                    emit.LoadArgument(bytesArg);        // [obj] [bytesArg]
                    emit.LoadConstant(info.ByteOffset); // [obj] [bytesArg] [info-offset]
                    emit.LoadArgument(offsetArg);       // [obj] [bytesArg] [info-offset] [offsetArg]
                    emit.Add();                         // [obj] [bytesArg] [offset]
                    emit.LoadElement <byte>();          // [obj] [byte]

                    // check if the flag is set
                    var flag = 1 << info.Bit;
                    emit.LoadConstant(flag); // [obj] [byte] [flag]
                    emit.And();              // [obj] [byte & flag]
                    emit.LoadConstant(flag); // [obj] [byte & flag] [flag]
                    emit.CompareEqual();     // [obj] [isEqual]

                    // set the property
                    emit.CallVirtual(info.PropertyInfo.SetMethod); // empty
                }
                else if (info.BackingType == typeof(byte) || info.BackingType == typeof(sbyte))
                {
                    // just read the byte directly

                    // load the object
                    emit.LoadLocal(obj); // [obj]

                    // load the byte
                    emit.LoadArgument(bytesArg);        // [obj] [bytesArg]
                    emit.LoadConstant(info.ByteOffset); // [obj] [bytesArg] [info-offset]
                    emit.LoadArgument(offsetArg);       // [obj] [bytesArg] [info-offset] [offsetArg]
                    emit.Add();                         // [obj] [bytesArg] [offset]
                    emit.LoadElement <byte>();          // [obj] [byte]

                    // set the property
                    emit.CallVirtual(info.PropertyInfo.SetMethod); // empty
                }
                else
                {
                    // need to convert from a byte array

                    // load the object
                    emit.LoadLocal(obj); // [obj]

                    // load the arguments for the converter
                    emit.LoadArgument(bytesArg);        // [obj] [bytesArg]
                    emit.LoadConstant(info.ByteOffset); // [obj] [bytesArg] [info-offset]
                    emit.LoadArgument(offsetArg);       // [obj] [bytesArg] [info-offset] [offsetArg]
                    emit.Add();                         // [obj] [bytesArg] [offset]

                    // convert to the value
                    emit.Call(s_acceptedTypes[info.BackingType].FromBytes); // [obj] [value]

                    // set the property
                    emit.CallVirtual(info.PropertyInfo.SetMethod); // empty
                }
            }

            emit.LoadLocal(obj); // [obj]
            emit.Return();

            return(emit.CreateDelegate());
        }
Beispiel #53
0
 public override void Emit <T>(Emit <T> emitter)
 {
     emitter.LoadConstant(_value);
 }
Beispiel #54
0
 private static Cci.ITypeReference GetTypeReference(TypeSymbol type, SyntaxNode syntaxNode, Emit.PEModuleBuilder moduleBuilder, DiagnosticBag diagnostics)
 {
     return moduleBuilder.Translate(type, syntaxNode, diagnostics);
 }
Beispiel #55
0
        public override void GenerateDeserializer()
        {
            try
            {
                var deserializationEmitter = Emit <Func <Packet, T> > .NewDynamicMethod();

                var deserializationResultLocal = deserializationEmitter.DeclareLocal <T>();
                deserializationEmitter.NewObject <T>();
                deserializationEmitter.StoreLocal(deserializationResultLocal);

                foreach (var propInfo in typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance))
                {
                    if (propInfo.GetGetMethod() == null || propInfo.GetSetMethod() == null || !ShouldRead(propInfo))
                    {
                        continue;
                    }

                    var propType = propInfo.PropertyType;
                    var isArray  = propType.IsArray;

                    if (!isArray)
                    {
                        var typeCode = Type.GetTypeCode(propType);

                        if (typeCode == TypeCode.String)
                        {
                            var conditionLabel = deserializationEmitter.DefineLabel();
                            deserializationEmitter.LoadArgument(0);
                            deserializationEmitter.CallVirtual(typeof(Packet).GetMethod("ReadInt16", Type.EmptyTypes));
                            deserializationEmitter.LoadConstant(0);
                            deserializationEmitter.BranchIfLessOrEqual(conditionLabel);
                            deserializationEmitter.LoadLocal(deserializationResultLocal);
                            deserializationEmitter.LoadArgument(0);
                            deserializationEmitter.LoadConstant(propInfo.Name);
                            deserializationEmitter.LoadConstant(0);
                            deserializationEmitter.NewArray <object>();
                            deserializationEmitter.CallVirtual(_binaryReaders[typeCode]);
                            deserializationEmitter.Call(propInfo.GetSetMethod());
                            deserializationEmitter.MarkLabel(conditionLabel);
                        }
                        else
                        {
                            deserializationEmitter.LoadLocal(deserializationResultLocal);
                            deserializationEmitter.LoadArgument(0);
                            deserializationEmitter.LoadConstant(propInfo.Name);
                            deserializationEmitter.LoadConstant(0);
                            deserializationEmitter.NewArray <object>();
                            deserializationEmitter.CallVirtual(_binaryReaders[typeCode]);
                            deserializationEmitter.Call(propInfo.GetSetMethod());
                        }
                    }
                    else
                    {
                        var hotfixAttr = propInfo.GetCustomAttribute <HotfixArrayAttribute>();
                        Trace.Assert(hotfixAttr != null);
                        var typeCode = Type.GetTypeCode(propType.GetElementType());

                        deserializationEmitter.LoadLocal(deserializationResultLocal);
                        deserializationEmitter.LoadConstant(hotfixAttr.Size);
                        deserializationEmitter.NewArray(propType.GetElementType());
                        deserializationEmitter.CallVirtual(propInfo.GetSetMethod());

                        var loopBodyLabel      = deserializationEmitter.DefineLabel();
                        var loopConditionLabel = deserializationEmitter.DefineLabel();

                        using (var iterationLocal = deserializationEmitter.DeclareLocal <int>())
                        {
                            // for (var i = 0; ...; ...)
                            deserializationEmitter.LoadConstant(0);
                            deserializationEmitter.StoreLocal(iterationLocal);

                            deserializationEmitter.Branch(loopConditionLabel);
                            deserializationEmitter.MarkLabel(loopBodyLabel);
                            if (typeCode == TypeCode.String)
                            {
                                var conditionLabel = deserializationEmitter.DefineLabel();

                                // if (packet.ReadInt16() > 0)
                                deserializationEmitter.LoadArgument(0); // Packet
                                deserializationEmitter.CallVirtual(typeof(Packet).GetMethod("ReadInt16", Type.EmptyTypes));
                                deserializationEmitter.LoadConstant(0);
                                deserializationEmitter.CompareGreaterThan();
                                deserializationEmitter.BranchIfFalse(conditionLabel);

                                // instance.Property[i] = packet.<Reader>("PropertyName", i);
                                deserializationEmitter.LoadLocal(deserializationResultLocal);
                                deserializationEmitter.CallVirtual(propInfo.GetGetMethod());
                                deserializationEmitter.LoadLocal(iterationLocal);
                                deserializationEmitter.LoadArgument(0); // Packet
                                deserializationEmitter.LoadConstant(propInfo.Name);
                                deserializationEmitter.LoadConstant(1);
                                deserializationEmitter.NewArray <object>();
                                deserializationEmitter.Duplicate();
                                deserializationEmitter.LoadConstant(0);
                                deserializationEmitter.LoadLocal(iterationLocal);
                                deserializationEmitter.Box <int>();
                                deserializationEmitter.StoreElement <object>();
                                deserializationEmitter.CallVirtual(_binaryReaders[typeCode]);
                                deserializationEmitter.StoreElement <string>();

                                deserializationEmitter.MarkLabel(conditionLabel);
                            }
                            else
                            {
                                // instance.Property[i] = packet.<Reader>("PropertyName", i);
                                deserializationEmitter.LoadLocal(deserializationResultLocal);
                                deserializationEmitter.CallVirtual(propInfo.GetGetMethod());
                                deserializationEmitter.LoadLocal(iterationLocal);
                                deserializationEmitter.LoadArgument(0);
                                deserializationEmitter.LoadConstant(propInfo.Name);
                                deserializationEmitter.LoadConstant(1);
                                deserializationEmitter.NewArray <object>();
                                deserializationEmitter.Duplicate();
                                deserializationEmitter.LoadConstant(0);
                                deserializationEmitter.LoadLocal(iterationLocal);
                                deserializationEmitter.Box <int>();
                                deserializationEmitter.StoreElement <object>();
                                deserializationEmitter.CallVirtual(_binaryReaders[typeCode]);
                                deserializationEmitter.StoreElement(propType.GetElementType());
                            }

                            // for (...; ...; i += 1)
                            deserializationEmitter.LoadLocal(iterationLocal);
                            deserializationEmitter.LoadConstant(1);
                            deserializationEmitter.Add();
                            deserializationEmitter.StoreLocal(iterationLocal);
                            deserializationEmitter.MarkLabel(loopConditionLabel);
                            // for (...; i < arraySize; ...)
                            deserializationEmitter.LoadLocal(iterationLocal);
                            deserializationEmitter.LoadConstant(hotfixAttr.Size);
                            deserializationEmitter.CompareLessThan();
                            deserializationEmitter.BranchIfTrue(loopBodyLabel);
                        }
                    }
                }

                // return instance;
                deserializationEmitter.LoadLocal(deserializationResultLocal);
                deserializationEmitter.Return();

                _deserializer = deserializationEmitter.CreateDelegate();
            }
            catch (SigilVerificationException sve)
            {
                Console.WriteLine(sve);
            }
        }
Beispiel #56
0
 public override void Emit <T>(Emit <T> emitter)
 {
     emitter.Return();
 }
Beispiel #57
0
 /// <summary>
 /// Ensure that the correct dictionary is put into the local dictionary variable
 /// such that accesses work from there. This was done either in <see cref="FromEmbeddedNode"/>
 /// or <see cref="DirectlyFromRecord"/>.
 /// </summary>
 public void EmitLoad(Emit <Func <IRecord, TReturn> > emit, Local dictionary)
 {
     _emitter(emit, dictionary);
 }
		internal sealed override int ImportTo(Emit.ModuleBuilder module)
		{
			return GetMethodInfo().ImportTo(module);
		}
Beispiel #59
0
 /// <summary>
 /// Emits load of PhpValue representing void.
 /// </summary>
 static TypeSymbol Emit_PhpValue_Void(ILBuilder il, Emit.PEModuleBuilder module, DiagnosticBag diagnostic)
 {
     il.EmitOpCode(ILOpCode.Ldsfld);
     il.EmitSymbolToken(module, diagnostic, module.Compilation.CoreMethods.PhpValue.Void, null);
     return module.Compilation.CoreTypes.PhpValue;
 }