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, module.Compilation.Options.OptimizationLevel, 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);
        }
        public GenDeserializeContext(
            MethodGenerator generator,
            PartDefinition part,
            IExpression instance,
            IExpression args,
            IVariable header)
            : base(generator)
        {
            ArgumentAssert.IsNotNull(generator, "generator");
            ArgumentAssert.IsNotNull(part, "part");
            ArgumentAssert.IsNotNull(instance, "instance");
            ArgumentAssert.IsNotNull(args, "args");
            ArgumentAssert.IsNotNull(header, "header");

            DeserializationArgs = args;
            Reader   = args.Copy().AddMember("Reader");
            Instance = instance;
            Member   = part.IsBaseType
                                ? instance
                       .MakeReadOnly()
                                : instance
                       .Copy()
                       .AddMember(part.Member);
            IsBaseType = part.IsBaseType;
            Header     = header;
        }
Beispiel #3
0
        public void If_Condition_And()
        {
            DynamicMethod   method = new DynamicMethod("temp", typeof(int), Type.EmptyTypes);
            MethodGenerator g      = new MethodGenerator(method);
            var             a      = g.Declare(5);

            g.If(() => {//a<10 && a>6
                g.And(() => {
                    g.Load(a);
                    g.Load(10);
                    return(LogicOperator.LessThan);
                }, () => {
                    g.Load(a);
                    g.Load(6);
                    return(LogicOperator.GreaterThan);
                });
                return(LogicOperator.IsTrue);
            }, () => {
                g.Increment(a);
            });
            g.Load(a);
            g.Return();
            int result = (int)method.Invoke(null, new object[] { });

            Assert.AreEqual(5, result);
        }
Beispiel #4
0
        /// <summary>
        /// Emit body of enumeration of referenced types.
        /// </summary>
        internal void CreateBuiltinTypes(DiagnosticBag diagnostic)
        {
            var method = this.ScriptType.EnumerateBuiltinTypesSymbol;
            var types  = this.Compilation.GlobalSemantics.GetReferencedTypes();

            // void (Action<string, RuntimeTypeHandle> callback)
            var body = MethodGenerator.GenerateMethodBody(this, method,
                                                          (il) =>
            {
                var action_string_method = method.Parameters[0].Type;
                Debug.Assert(action_string_method.Name == "Action");
                var invoke = action_string_method.DelegateInvokeMethod();
                Debug.Assert(invoke != null);

                foreach (var t in types)
                {
                    if (t.IsPhpUserType())
                    {
                        continue;       // the type is a PHP user type, do not export as app type
                    }

                    // callback.Invoke(t)
                    il.EmitLoadArgumentOpcode(0);
                    il.EmitCall(this, diagnostic, ILOpCode.Call, Compilation.CoreMethods.Dynamic.GetPhpTypeInfo_T.Symbol.Construct(t));
                    il.EmitCall(this, diagnostic, ILOpCode.Callvirt, invoke);
                }

                //
                il.EmitRet(true);
            },
                                                          null, diagnostic, false);

            SetMethodBody(method, body);
        }
        /// <summary>
        /// Emit body of enumeration of referenced types.
        /// </summary>
        internal void CreateEnumerateReferencedTypes(DiagnosticBag diagnostic)
        {
            var method = this.ScriptType.EnumerateReferencedTypesSymbol;
            var types  = this.Compilation.GlobalSemantics.GetReferencedTypes();

            // void (Action<string, RuntimeTypeHandle> callback)
            var body = MethodGenerator.GenerateMethodBody(this, method,
                                                          (il) =>
            {
                var action_string_method = method.Parameters[0].Type;
                Debug.Assert(action_string_method.Name == "Action");
                var invoke = action_string_method.DelegateInvokeMethod();
                Debug.Assert(invoke != null);

                foreach (var t in types)
                {
                    // callback.Invoke(t.Name, t)
                    il.EmitLoadArgumentOpcode(0);
                    il.EmitStringConstant(t.Name);
                    il.EmitLoadToken(this, diagnostic, t, null);
                    il.EmitCall(this, diagnostic, ILOpCode.Callvirt, invoke);
                }

                //
                il.EmitRet(true);
            },
                                                          null, diagnostic, false);

            SetMethodBody(method, body);
        }
Beispiel #6
0
        public static void GenerateCode1()
        {
            MethodGenerator method = new MethodGenerator("Test");

            method.SetAuthority(MethodAuthorityType.Internal);
            method.SetDecorate(MethodDecorateType.Virtual);
            method.SetParms(new string[] { "int", "string" });
            method.SetReturn("bool");
            MethodGenerator method1 = new MethodGenerator("Test1");

            method1.SetAuthority(MethodAuthorityType.Internal);
            method1.SetDecorate(MethodDecorateType.Virtual);
            method1.SetParms(new string[] { "int", "string" });
            method1.SetReturn("bool");
            ClassGenerator textClass = new ClassGenerator("TestClass");

            textClass.SetUsingName(new string[] { "xxxx", "aaaa" });
            textClass.SetBaseClass("xxcvsdf");
            textClass.SetDecorate(ClassDecorateType.Abstract);
            textClass.SetAuthority(AuthorityType.Public);
            textClass.SetInterfaces(new string[] { "asdfsadf", "asdfasdf" });
            textClass.SetNamespace("masdjf");
            textClass.AddMethod(method);
            textClass.AddMethod(method1);
            string classValue = textClass.ToString();

            TxtUtility.StringToFile(classValue);
        }
        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(false);
            }, null, DiagnosticBag.GetInstance(), false));
        }
Beispiel #8
0
        private static PropertyValueMethod GenerateGetPropertyValueMethod <T>(Type objectType, string propertyName)
        {
            DynamicMethod method = new DynamicMethod(string.Format("GetPropertyValue_{0}", Guid.NewGuid().ToString("n"))
                                                     , typeof(T)
                                                     , new Type[] { typeof(object) }
                                                     , true);

            MethodGenerator g = new MethodGenerator(method);

            var result = g.Declare <T>("result");

            g.Assign(result, () =>
            {
                g.LoadParameter(0);
                g.Cast(objectType);
                g.LoadMember(propertyName);
            });

            g.LoadVariable("result");
            g.Return();

            var invoke = method.CreateDelegate(typeof(Func <object, T>));

            return(new PropertyValueMethod(propertyName, invoke));
        }
        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.PhpNewMethodSymbol;
                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(true);
            }, null, DiagnosticBag.GetInstance(), false));
        }
        /// <summary>
        /// Emit body of enumeration of scripts Main function.
        /// </summary>
        internal void CreateEnumerateScriptsSymbol(DiagnosticBag diagnostic)
        {
            var method = this.ScriptType.EnumerateScriptsSymbol;
            var files  = this.Compilation.SourceSymbolCollection.GetFiles();

            // void (Action<string, RuntimeMethodHandle> callback)
            var body = MethodGenerator.GenerateMethodBody(this, method,
                                                          (il) =>
            {
                var action_string_method = method.Parameters[0].Type;
                Debug.Assert(action_string_method.Name == "Action");
                var invoke = action_string_method.DelegateInvokeMethod();
                Debug.Assert(invoke != null);

                foreach (var f in files)
                {
                    // callback.Invoke(f.Name, f)
                    il.EmitLoadArgumentOpcode(0);
                    il.EmitStringConstant(f.RelativeFilePath);
                    il.EmitLoadToken(this, diagnostic, f.MainMethod, null);
                    il.EmitCall(this, diagnostic, ILOpCode.Callvirt, invoke);
                }

                //
                il.EmitRet(true);
            },
                                                          null, diagnostic, false);

            SetMethodBody(method, body);
        }
Beispiel #11
0
        void GenerateFieldAccessorProperty(Emit.PEModuleBuilder module, DiagnosticBag diagnostics, SourceFieldSymbol srcf, PropertySymbol paccessor)
        {
            //
            module.SynthesizedManager.AddProperty(this, paccessor);

            //
            var get_body = MethodGenerator.GenerateMethodBody(module, paccessor.GetMethod, (il) =>
            {
                // Template: return field;
                var place = new FieldPlace(new ArgPlace(this, 0), srcf.OverridenDefinition, module);
                place.EmitLoad(il);
                il.EmitRet(false);
            }, null, diagnostics, false);

            module.SetMethodBody(paccessor.GetMethod, get_body);
            module.SynthesizedManager.AddMethod(this, paccessor.GetMethod);

            //
            var set_body = MethodGenerator.GenerateMethodBody(module, paccessor.SetMethod, (il) =>
            {
                // Template: field = value;
                var place = new FieldPlace(new ArgPlace(this, 0), srcf.OverridenDefinition, module);
                place.EmitStorePrepare(il);
                new ArgPlace(this, 1).EmitLoad(il);
                place.EmitStore(il);
                il.EmitRet(true);
            }, null, diagnostics, false);

            module.SetMethodBody(paccessor.SetMethod, set_body);
            module.SynthesizedManager.AddMethod(this, paccessor.SetMethod);
        }
Beispiel #12
0
 private static void WriteMembers(MethodGenerator g, TypeSerializationInfo typeInfo)
 {
     if (typeInfo.ClassAttribute.Mode == DTOSerializableMode.General)
     {
         foreach (var member in typeInfo.MemberInfos)
         {
             if (member.CanRead)
             {
                 g.BeginScope();
                 member.GenerateSerializeIL(g);
                 g.EndScope();
             }
         }
     }
     else
     {
         //在函数模式,只有标记了ReturnValue的成员才会被写入到dto中
         foreach (var member in typeInfo.MemberInfos)
         {
             if (member.MemberAttribute.Type == DTOMemberType.ReturnValue && member.CanRead)
             {
                 g.BeginScope();
                 member.GenerateSerializeIL(g);
                 g.EndScope();
             }
         }
     }
 }
        /// <summary>
        /// Emit body of enumeration of referenced functions.
        /// </summary>
        internal void CreateEnumerateReferencedFunctions(DiagnosticBag diagnostic)
        {
            var method    = this.ScriptType.EnumerateReferencedFunctionsSymbol;
            var functions = GlobalSymbolProvider.ResolveExtensionContainers(this.Compilation)
                            .SelectMany(c => c.GetMembers().OfType <MethodSymbol>())
                            .Where(GlobalSymbolProvider.IsFunction);

            // void (Action<string, RuntimeMethodHandle> callback)
            var body = MethodGenerator.GenerateMethodBody(this, method,
                                                          (il) =>
            {
                var action_string_method = method.Parameters[0].Type;
                Debug.Assert(action_string_method.Name == "Action");
                var invoke = action_string_method.DelegateInvokeMethod();
                Debug.Assert(invoke != null);

                foreach (var f in functions)
                {
                    // callback.Invoke(f.Name, f)
                    il.EmitLoadArgumentOpcode(0);
                    il.EmitStringConstant(f.Name);
                    il.EmitLoadToken(this, diagnostic, f, null);
                    il.EmitCall(this, diagnostic, ILOpCode.Callvirt, invoke);
                }

                //
                il.EmitRet(true);
            },
                                                          null, diagnostic, false);

            SetMethodBody(method, body);
        }
Beispiel #14
0
        private static PropertyValueMethod GenerateSetPropertyValueMethod(Type objectType, string propertyName)
        {
            var propertyInfo = objectType.ResolveProperty(propertyName);
            var propertyType = propertyInfo.PropertyType;

            DynamicMethod method = new DynamicMethod(string.Format("SetPropertyValue_{0}", Guid.NewGuid().ToString("n"))
                                                     , null
                                                     , new Type[] { typeof(object), typeof(object) } //obj  value
                                                     , true);

            MethodGenerator g = new MethodGenerator(method);

            g.LoadParameter(0);
            g.Cast(objectType);
            g.Assign(propertyName, () =>
            {
                g.LoadParameter(1);
                g.Cast(propertyType);
            });
            g.Return();

            var invoke = method.CreateDelegate(typeof(Action <object, object>));

            return(new PropertyValueMethod(propertyName, invoke));
        }
Beispiel #15
0
        void EmitInit(Emit.PEModuleBuilder module)
        {
            EnsureMembers();

            // 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));

                GetMembers().OfType <SourceFieldSymbol>().Where(f => f.InitializerRequiresContext).ForEach(f => f.EmitInit(cg));

                //
                il.EmitRet(true);
            },
                                                          null, diagnostic, false);

            module.SetMethodBody(initMethod, body);

            //
            _lazyMembers = _lazyMembers.Add(initMethod);
        }
 /// <summary>
 /// 生成反序列化代码
 /// </summary>
 /// <param name="g"></param>
 public virtual void GenerateDeserializeIL(MethodGenerator g)
 {
     SetMember(g, () =>
     {
         SerializationMethodHelper.Read(g, this.DTOMemberName, this.TargetType);
     });
 }
        //private static void DeclareInstance(MethodGenerator g, TypeSerializationInfo typeInfo)
        //{
        //    if (typeInfo.ClassType.IsValueType)
        //    {
        //        var instance = g.Declare(typeInfo.ClassType, SerializationArgs.InstanceName);
        //        //g.LoadVariable(instance, LoadOptions.ValueAsAddress);
        //        //g.InitValue();
        //    }
        //    else
        //    {
        //        var instance = g.Declare(typeInfo.ClassType, SerializationArgs.InstanceName);
        //        g.Assign(instance, () =>
        //        {
        //            g.NewObject(typeInfo.ClassType);
        //        });
        //    }
        //}

        private static void ReadMembers(MethodGenerator g, TypeSerializationInfo typeInfo)
        {
            if (typeInfo.ClassAttribute.Mode == DTOSerializableMode.General)
            {
                foreach (var member in typeInfo.MemberInfos)
                {
                    if (member.CanWrite)
                    {
                        g.BeginScope();
                        member.GenerateDeserializeIL(g);
                        g.EndScope();
                    }
                }
            }
            else
            {
                //在函数模式,只有标记了Parameter的成员才会被反序列化到对象实例中
                foreach (var member in typeInfo.MemberInfos)
                {
                    if (member.MemberAttribute.Type == DTOMemberType.Parameter && member.CanWrite)
                    {
                        g.BeginScope();
                        member.GenerateDeserializeIL(g);
                        g.EndScope();
                    }
                }
            }
        }
        void EmitPhpCallable(Emit.PEModuleBuilder module, DiagnosticBag diagnostics)
        {
            var __invoke = TryGetMagicInvoke();

            if (__invoke == null ||
                IsAlreadyImplemented(__invoke) ||
                IsAlreadyImplemented(DeclaringCompilation.CoreTypes.IPhpCallable))
            {
                // already implemented in a base class
                return;
            }

            //
            // IPhpCallable.Invoke(Context <ctx>, PhpVaue[] arguments)
            //
            var invoke = new SynthesizedMethodSymbol(this, "IPhpCallable.Invoke", false, true, DeclaringCompilation.CoreTypes.PhpValue, isfinal: false)
            {
                ExplicitOverride = (MethodSymbol)DeclaringCompilation.CoreTypes.IPhpCallable.Symbol.GetMembers("Invoke").Single(),
                ForwardedCall    = __invoke,
            };

            invoke.SetParameters(
                new SpecialParameterSymbol(invoke, DeclaringCompilation.CoreTypes.Context, SpecialParameterSymbol.ContextName, 0),
                new SynthesizedParameterSymbol(invoke, ArrayTypeSymbol.CreateSZArray(ContainingAssembly, DeclaringCompilation.CoreTypes.PhpValue.Symbol), 1, RefKind.None, name: "arguments", isParams: true));

            module.SetMethodBody(invoke, MethodGenerator.GenerateMethodBody(module, invoke, il =>
            {
                var cg = new CodeGenerator(il, module, diagnostics, module.Compilation.Options.OptimizationLevel, false, this, new ParamPlace(invoke.Parameters[0]), new ArgPlace(this, 0))
                {
                    CallerType = this,
                };

                cg.EmitRet(cg.EmitForwardCall(__invoke, invoke, callvirt: true));
            }, null, diagnostics, false));

            module.SynthesizedManager.AddMethod(this, invoke);

            //
            // IPhpCallable.ToPhpValue()
            //
            var tophpvalue = new SynthesizedMethodSymbol(this, "IPhpCallable.ToPhpValue", false, true, DeclaringCompilation.CoreTypes.PhpValue, isfinal: false)
            {
                ExplicitOverride = (MethodSymbol)DeclaringCompilation.CoreTypes.IPhpCallable.Symbol.GetMembers("ToPhpValue").Single(),
            };

            //
            module.SetMethodBody(tophpvalue, MethodGenerator.GenerateMethodBody(module, tophpvalue, il =>
            {
                var thisPlace = new ArgPlace(this, 0);
                var ctxPlace  = new FieldPlace(thisPlace, this.ContextStore, module);
                var cg        = new CodeGenerator(il, module, diagnostics, module.Compilation.Options.OptimizationLevel, false, this, ctxPlace, thisPlace);

                // return PhpValue.FromClass(this)
                cg.EmitThis();
                cg.EmitRet(cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpValue.FromClass_Object));
            }, null, diagnostics, false));

            module.SynthesizedManager.AddMethod(this, tophpvalue);
        }
        public override void TranslateInput()
        {
            // Parse the expression first to determine the result type
            MethodGenerator.SetOutputEnabled(false);
            IrisType resultType = ParseExpressionAndReadFormatSpecifiers();

            MethodGenerator.SetOutputEnabled(true);

            if (_context.ErrorCount == 0)
            {
                // No errors: Now that we know the result type, parse again and generate code this time

                _context.Emitter.BeginProgram(_context.ClassName, _context.Importer.ImportedAssemblies);
                _lexer.Reset();

                MethodGenerator.BeginMethod(_context.MethodName, resultType, _context.ParameterVariables, _context.LocalVariables, false, string.Empty);
                ParseExpression();
                MethodGenerator.EndMethod();

                bool readOnly = resultType.IsArray || resultType == IrisType.Void;
                if (_context.ErrorCount == 0)
                {
                    _context.Emitter.EndProgram();

                    if (!readOnly)
                    {
                        // As a final step, see if this expression is something that can be assigned
                        // to.  We only support very simple L-Values for assignments so if the syntax
                        // doesn't match exactly, make the result read only.
                        _lexer.Reset();
                        readOnly = !TryParseAsLValue();
                    }
                }

                if (resultType == IrisType.Boolean)
                {
                    // Setting the "BoolResult" flag allows the expression to be used for a
                    // "when true" breakpoint condition.
                    _context.ResultFlags |= DkmClrCompilationResultFlags.BoolResult;
                }

                if (ParsedCallSyntax)
                {
                    // If we parsed call syntax, this expression has the potential to have side
                    // effects.  Setting the PotentialSideEffect flag prevents the debugger from
                    // implicitly evaluating the expression without user interaction.
                    // Instead of implicity evaluating the expression, the debugger will show the
                    // message "This expression has side effects and will not be evaluated"
                    _context.ResultFlags |= DkmClrCompilationResultFlags.PotentialSideEffect;

                    readOnly = true; // Can't modify return value of call
                }

                if (readOnly)
                {
                    _context.ResultFlags |= DkmClrCompilationResultFlags.ReadOnlyResult;
                }
            }
        }
Beispiel #20
0
 /// <summary>
 /// 生成序列化代码
 /// </summary>
 /// <param name="g"></param>
 public virtual void GenerateSerializeIL(MethodGenerator g)
 {
     //serializer.serialize(v); 或 //writer.Writer(v);
     SerializationMethodHelper.Write(g, this.DTOMemberName, this.TargetType, () =>
     {
         LoadMemberValue(g);
     });
 }
Beispiel #21
0
        public void TestInitialize()
        {
            _generator = new MethodGenerator();
            _generator.InjectDependency(_modifierGenerator  = new ModifierGeneratorStub());
            _generator.InjectDependency(_parameterGenerator = new ParameterGeneratorStub());
            _generator.InjectDependency(_statementGenerator = new StatementGeneratorStub());

            _modifierGenerator.Results = new[] { "private" };
        }
Beispiel #22
0
        /// <summary>
        /// Generates analyzed method.
        /// </summary>
        void EmitMethodBody(SourceRoutineSymbol routine)
        {
            Contract.ThrowIfNull(routine);
            Debug.Assert(routine.ControlFlowGraph.Start.FlowState != null);

            var body = MethodGenerator.GenerateMethodBody(_moduleBuilder, routine, 0, null, _diagnostics, _emittingPdb);

            _moduleBuilder.SetMethodBody(routine, body);
        }
Beispiel #23
0
        void EmitTraitImplementations(Emit.PEModuleBuilder module)
        {
            foreach (var t in TraitUses)
            {
                foreach (var m in t.GetMembers().OfType <SynthesizedMethodSymbol>())
                {
                    Debug.Assert(m.ForwardedCall != null);

                    module.SetMethodBody(m, MethodGenerator.GenerateMethodBody(module, m, il =>
                    {
                        IPlace thisPlace          = null;
                        IPlace traitInstancePlace = null;
                        IPlace ctxPlace;

                        if (m.IsStatic)
                        {
                            // Template: return TRAIT.method(...)
                            Debug.Assert(SpecialParameterSymbol.IsContextParameter(m.Parameters[0]));
                            ctxPlace = new ParamPlace(m.Parameters[0]);
                        }
                        else
                        {
                            // Template: return this.<>trait.method(...)
                            thisPlace          = new ArgPlace(this, 0);                                   // this
                            ctxPlace           = new FieldPlace(thisPlace, this.ContextStore, module);    // this.<ctx>
                            traitInstancePlace = new FieldPlace(thisPlace, t.TraitInstanceField, module); // this.<>trait
                        }

                        using (var cg = new CodeGenerator(il, module, DiagnosticBag.GetInstance(), module.Compilation.Options.OptimizationLevel, false, this, ctxPlace, thisPlace)
                        {
                            CallerType = this,
                        })
                        {
                            var forwarded_type = cg.EmitForwardCall(m.ForwardedCall, m, thisPlaceExplicit: traitInstancePlace);
                            var target_type    = m.ReturnType;

                            cg.EmitConvert(forwarded_type, 0, target_type); // always (forwarded_type === target_type)
                            cg.EmitRet(target_type);
                        }
                    }, null, DiagnosticBag.GetInstance(), false));
                    module.SynthesizedManager.AddMethod(this, m);

                    // NOTE: following is not needed anymore:
                    //// ghost stubs: // ... resolve this already in SourceTypeSymbol.GetMembers(), now it does not get overloaded properly
                    //var ps = m.Parameters;
                    //for (int i = 0; i < ps.Length; i++)
                    //{
                    //    if (ps[i].HasUnmappedDefaultValue())  // => ConstantValue couldn't be resolved for optional parameter
                    //    {
                    //        // create ghost stub foo(p0, .. pi-1) => foo(p0, .. , pN)
                    //        GhostMethodBuilder.CreateGhostOverload(m, module, DiagnosticBag.GetInstance(), i);
                    //    }
                    //}
                }
            }
        }
Beispiel #24
0
        private void MaybeGenerateEntryForSymbol(Symbol symbol)
        {
            if (_context.ArgumentsOnly && symbol.StorageClass != StorageClass.Argument)
            {
                // We are only showing arguments
                return;
            }

            IrisType symbolType = symbol.Type;

            if (symbolType.IsMethod || symbolType == IrisType.Invalid || symbolType == IrisType.Void)
            {
                // This symbol doesn't belong in the Locals window.
                // Don't generate an entry for it.
                return;
            }

            if (symbol.Name.StartsWith("$."))
            {
                // Don't show compiler internal symbols
                return;
            }

            string   methodName = _context.NextMethodName();
            IrisType derefType  = DerefType(symbolType);

            // Emit code for the method to get the symbol value.
            MethodGenerator.BeginMethod(methodName, derefType, _context.ParameterVariables, _context.LocalVariables, entryPoint: false, methodFileName: null);
            EmitLoadSymbol(symbol, SymbolLoadMode.Dereference);
            MethodGenerator.EndMethod();

            // Generate the local entry to pass back to the debug engine
            DkmClrCompilationResultFlags resultFlags = DkmClrCompilationResultFlags.None;

            if (derefType == IrisType.Boolean)
            {
                // The debugger uses "BoolResult" for breakpoint conditions so setting the flag
                // here has no effect currently, but we set it for the sake of consistency.
                resultFlags |= DkmClrCompilationResultFlags.BoolResult;
            }
            else if (derefType.IsArray)
            {
                // Iris doesn't support modification of an array itself
                resultFlags |= DkmClrCompilationResultFlags.ReadOnlyResult;
            }

            string fullName = symbol.Name;

            _context.GeneratedLocals.Add(DkmClrLocalVariableInfo.Create(
                                             fullName,
                                             fullName,
                                             methodName,
                                             resultFlags,
                                             DkmEvaluationResultCategory.Data,
                                             null));
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="Generator"/> class.
 /// </summary>
 /// <param name="generatorMode">The generator mode.</param>
 private Generator(GeneratorMode generatorMode)
 {
     GeneratorMode       = generatorMode;
     _fieldGenerator     = new FieldGenerator(this);
     _eventGenerator     = new EventGenerator(this);
     _methodGenerator    = new MethodGenerator(this);
     _parameterGenerator = new ParameterGenerator(this);
     _propertyGenerator  = new PropertyGenerator(this);
     _typeNameGenerator  = new TypeNameGenerator(this);
 }
        public Translator(CompilerContext context)
        {
            MethodGenerator = new MethodGenerator(context);

            _context            = context;
            _lexer              = context.Lexer;
            _symbolTable        = context.SymbolTable;
            _lastParsedPosition = _lexer.TokenStartPosition;
            _lexeme             = string.Empty;
        }
        void EmitToString(Emit.PEModuleBuilder module)
        {
            if (this.IsInterface || this.IsTrait)
            {
                return;
            }

            var __tostring = this.GetMembersByPhpName(SpecialMethodNames.Tostring.Value).OfType <MethodSymbol>().FirstOrDefault();

            if (__tostring != null)    // implement ToString if: there is __toString() function
            {
                // lookup base string ToString()
                var overriden = this.LookupMember <MethodSymbol>(
                    WellKnownMemberNames.ObjectToString,
                    m => OverrideHelper.SignaturesMatch(m, (MethodSymbol)DeclaringCompilation.GetSpecialTypeMember(SpecialMember.System_Object__ToString)));

                Debug.Assert(overriden != null);

                if (overriden == null || overriden.IsSealed || overriden.ContainingType == this)
                {
                    // cannot be overriden
                    return;
                }

                // public sealed override string ToString()
                var tostring = new SynthesizedMethodSymbol(this, WellKnownMemberNames.ObjectToString, false, true, DeclaringCompilation.CoreTypes.String, Accessibility.Public, isfinal: false, phphidden: true)
                {
                    ExplicitOverride = overriden,
                    ForwardedCall    = __tostring,
                };

                module.SetMethodBody(tostring, MethodGenerator.GenerateMethodBody(module, tostring, il =>
                {
                    var thisPlace = new ArgPlace(this, 0);
                    var cg        = new CodeGenerator(il, module, DiagnosticBag.GetInstance(), module.Compilation.Options.OptimizationLevel, false, this, new FieldPlace(thisPlace, this.ContextStore, module), thisPlace);

                    if (__tostring != null)
                    {
                        // __tostring().ToString()
                        cg.EmitConvert(cg.EmitForwardCall(__tostring, tostring, callvirt: true), 0, tostring.ReturnType);
                    }
                    else
                    {
                        // PhpException.ObjectToStringNotSupported(this)
                        cg.EmitThis();
                        cg.EmitPop(cg.EmitCall(ILOpCode.Call, cg.CoreTypes.PhpException.Method("ObjectToStringNotSupported", cg.CoreTypes.Object)));

                        // return ""
                        cg.Builder.EmitStringConstant(string.Empty);
                    }
                    cg.EmitRet(tostring.ReturnType);
                }, null, DiagnosticBag.GetInstance(), false));
                module.SynthesizedManager.AddMethod(this, tostring);
            }
        }
        /// <summary>
        /// 读取数组的长度
        /// </summary>
        /// <param name="g"></param>
        /// <param name="dtoMemberName"></param>
        /// <param name="valueType"></param>
        public static void ReadLength(MethodGenerator g, string dtoMemberName)
        {
            var method   = typeof(IDTOReader).ResolveMethod("ReadLength", _readArgs);
            var prmIndex = SerializationArgs.ReaderIndex;

            g.Call(method, () =>
            {
                g.LoadParameter(prmIndex);
                g.Load(dtoMemberName);
            });
        }
Beispiel #29
0
        /// <summary>
        /// 声明强类型的instance变量留待后续代码使用,避免频繁类型转换
        /// </summary>
        private static void DeclareInstance(MethodGenerator g, TypeSerializationInfo typeInfo)
        {
            //TypeClassName instance = (TypeClassName)instance;
            var instance = g.Declare(typeInfo.ClassType, SerializationArgs.InstanceName);

            g.Assign(instance, () =>
            {
                g.LoadParameter(SerializationArgs.InstanceIndex);
                g.UnboxAny(typeInfo.ClassType);
            });
        }
Beispiel #30
0
 public static void RunMethodTest(MethodGenerator method, string name = null)
 {
     ExecutableTestHelper.Generator gen = ag =>
     {
         TypeGen t = ag.Class("Test");
         {
             method(t.Public.Static.Method(typeof(void), "Main"));
         }
     };
     RunTest(gen, ExecutableTestHelper.GetTestName(method.Method));
 }
Beispiel #31
0
        public override void GenerateDeserializeIL(MethodGenerator g)
        {
            SetMember(g, () =>
            {
                var count = g.Declare <int>();
                g.Assign(count, () =>
                {
                    SerializationMethodHelper.ReadLength(g, this.DTOMemberName);//读取数量
                });

                var list = g.Declare(this.TargetType);

                g.If(() =>
                {
                    g.Load(count);
                    g.Load(0);
                    return(LogicOperator.LessThan);
                }, () =>
                {
                    //数量小于1
                    //list = new List<T>();
                    var elementType = this.TargetType.ResolveElementType();
                    g.Assign(list, () =>
                    {
                        g.NewObject(this.TargetType);
                    });
                }, () =>
                {
                    //list = new List<T>();
                    g.Assign(list, () =>
                    {
                        g.NewObject(this.TargetType);
                    });

                    var elementType = this.TargetType.ResolveElementType();

                    g.For(count, (index) =>
                    {
                        var item = g.Declare(elementType);

                        g.Assign(item, () =>
                        {
                            SerializationMethodHelper.ReadElement(g, this.DTOMemberName, elementType, index);
                        });

                        g.Load(list);
                        g.Load(item);
                        g.Call(this.TargetType.ResolveMethod("Add", elementType));
                    });
                });

                g.Load(list);
            });
        }
Beispiel #32
0
 public IPhp54Function GenerateFunction(Action Action, bool DoDebug)
 {
     var OldMethodGenerator = MethodGenerator;
     var NewMethodGenerator = new MethodGenerator(DoDebug);
     OldMethodGenerator = MethodGenerator;
     MethodGenerator = NewMethodGenerator;
     try
     {
         Action();
     }
     finally
     {
         MethodGenerator = OldMethodGenerator;
     }
     return NewMethodGenerator.GenerateMethod();
 }
		/// <summary>
		/// Add a virtualizable method.
		/// </summary>
		/// <param name="name">Method name</param>
		/// <param name="func">Callback which generates the method body</param>
		public void AddMethod(String name, MethodGenerator func)
		{
			if (_methods.ContainsKey(name))
				_methods[name] = func;
			else _methods.Add(name, func);
		}