Beispiel #1
0
		public LinqBuilder(CodeGenerator/*!*/ cg)
		{
			this.cg = cg;

			IPlace this_place = new IndexedPlace(PlaceHolder.Argument, 0);

			this.rtVariablesPlace = new Place(this_place, Fields.LinqContext_variables);
			this.scriptContextPlace = new Place(this_place, Fields.LinqContext_context);
			this.classContextPlace = new Place(this_place, Fields.LinqContext_typeHandle);
			this.selfPlace = new Place(this_place, Fields.LinqContext_outerType);
		}
Beispiel #2
0
        public LinqBuilder(CodeGenerator /*!*/ cg)
        {
            this.cg = cg;

            IPlace this_place = new IndexedPlace(PlaceHolder.Argument, 0);

            this.rtVariablesPlace   = new Place(this_place, Fields.LinqContext_variables);
            this.scriptContextPlace = new Place(this_place, Fields.LinqContext_context);
            this.classContextPlace  = new Place(this_place, Fields.LinqContext_typeHandle);
            this.selfPlace          = new Place(this_place, Fields.LinqContext_outerType);
        }
Beispiel #3
0
        internal void EmitHelpers()
        {
            CompilationUnit unit = this.CompilationUnit;
            ILEmitter       il   = new ILEmitter(DeclareHelperBuilder);
            IndexedPlace    script_context_place = new IndexedPlace(PlaceHolder.Argument, 0);

            foreach (PhpFunction function in unit.GetDeclaredFunctions())
            {
                if (function.IsDefinite)
                {
                    CodeGenerator.EmitDeclareFunction(il, script_context_place, function);
                }
            }

            foreach (PhpType type in unit.GetDeclaredTypes())
            {
                if (type.IsDefinite)
                {
                    // CALL <context>.DeclareType(<type desc>, <name>);
                    type.EmitAutoDeclareOnScriptContext(il, script_context_place);
                }
                else if (!type.IsComplete)
                {
                    if (type.IncompleteClassDeclareMethodInfo != null)
                    {
                        // check whether base class is known at this point of execution,
                        // if so, declare this incomplete class immediately. As PHP does.

                        type.EmitDeclareIncompleteOnScriptContext(il, script_context_place);
                    }
                }
            }

            foreach (GlobalConstant constant in unit.GetDeclaredConstants())
            {
                if (constant.IsDefinite)
                {
                    var field = constant.RealField;
                    Debug.Assert(field != null);
                    Debug.Assert(field.IsStatic);

                    // CALL <context>.DeclareConstant(<name>, <value>);
                    script_context_place.EmitLoad(il);

                    il.Emit(OpCodes.Ldstr, constant.FullName);
                    il.LoadLiteralBox(constant.Value);  //il.Emit(OpCodes.Ldsfld, field);   // const field cannot be referenced in IL
                    il.Emit(OpCodes.Call, Methods.ScriptContext.DeclareConstant);
                }
            }

            il.Emit(OpCodes.Ret);
        }
Beispiel #4
0
		/// <summary>
		/// Emits helper declaring all single-declared functions and classes in the script being built.
		/// </summary>
		/// <remarks>
		/// For each function and class emits a call to <see cref="ApplicationContext.DeclareFunction"/> and 
        /// <see cref="ApplicationContext.DeclareType"/>, respectively, which declares it.
		/// The helper is called as the first instruction of Main helper. 
		/// </remarks>		
		private void EmitDeclareHelper()
		{
			PureCompilationUnit unit = this.PureCompilationUnit;
			ILEmitter il = new ILEmitter(declareHelperBuilder);
			IndexedPlace app_context_place = new IndexedPlace(PlaceHolder.Argument, 0);
            TypeBuilder publicsContainer = null;    // container type for public stubs of global declarations (which are inaccessible from other assemblies)

			foreach (PhpFunction function in unit.GetDeclaredFunctions())
			{
				if (function.IsDefinite)
				{
					app_context_place.EmitLoad(il);

					// NEW RoutineDelegate(<static method>);
					il.Emit(OpCodes.Ldnull);
					il.Emit(OpCodes.Ldftn, function.ArgLessInfo);
					il.Emit(OpCodes.Newobj, Constructors.RoutineDelegate);

					// LOAD <full name>;
					il.Emit(OpCodes.Ldstr, function.FullName);

					// LOAD <attributes>;
					il.LdcI4((int)function.MemberDesc.MemberAttributes);

                    // LOAD <argfull>
                    if (function.ArgFullInfo != null)
                        CodeGenerator.EmitLoadMethodInfo(
                            il,
                            (function.ArgFullInfo.DeclaringType != null)
                                ? function.ArgFullInfo
                                : EmitPhpFunctionPublicStub(ref publicsContainer, function) // function.ArgFullInfo is real global method not accessible from other assemblies, must be wrapped
                            /*, AssemblyBuilder.DelegateBuilder*/);
                    else
                        il.Emit(OpCodes.Ldnull);
                    
					// CALL <application context>.DeclareFunction(<stub>, <name>, <member attributes>, <argfull>)
					il.Emit(OpCodes.Call, Methods.ApplicationContext.DeclareFunction);
				}
			}

			foreach (PhpType type in unit.GetDeclaredTypes())
			{
				if (type.IsDefinite)
				{
					// CALL <application context>.DeclareType(<type desc>, <name>);
					type.EmitAutoDeclareOnApplicationContext(il, app_context_place);
				}
			}

			foreach (GlobalConstant constant in unit.GetDeclaredConstants())
			{
				if (constant.IsDefinite)
				{
					app_context_place.EmitLoad(il);

					// CALL <application context>.DeclareConstant(<name>, <value>);
					il.Emit(OpCodes.Ldstr, constant.FullName);
                    //il.Emit(OpCodes.Ldsfld, constant.RealField);
                    //if (constant.RealField.FieldType.IsValueType) il.Emit(OpCodes.Box, constant.RealField.FieldType);
                    il.LoadLiteralBox(constant.Value);
					il.Emit(OpCodes.Call, Methods.ApplicationContext.DeclareConstant);
				}
			}

			il.Emit(OpCodes.Ret);

            // complete the publicsContainer type, if created:
            if (publicsContainer != null)
                publicsContainer.CreateType();
		}
Beispiel #5
0
		internal void EmitHelpers()
		{
			CompilationUnit unit = this.CompilationUnit;
			ILEmitter il = new ILEmitter(DeclareHelperBuilder);
			IndexedPlace script_context_place = new IndexedPlace(PlaceHolder.Argument, 0);

			foreach (PhpFunction function in unit.GetDeclaredFunctions())
			{
				if (function.IsDefinite)
				{
                    CodeGenerator.EmitDeclareFunction(il, script_context_place, function);
				}
			}

			foreach (PhpType type in unit.GetDeclaredTypes())
			{
				if (type.IsDefinite)
				{
					// CALL <context>.DeclareType(<type desc>, <name>);
					type.EmitAutoDeclareOnScriptContext(il, script_context_place);
				}
                else if (!type.IsComplete)
                {
                    if (type.IncompleteClassDeclareMethodInfo != null)
                    {
                        // check whether base class is known at this point of execution,
                        // if so, declare this incomplete class immediately. As PHP does.

                        type.EmitDeclareIncompleteOnScriptContext(il, script_context_place);
                    }
                }
			}

            foreach (GlobalConstant constant in unit.GetDeclaredConstants())
            {
                if (constant.IsDefinite)
                {
                    var field = constant.RealField;
                    Debug.Assert(field != null);
                    Debug.Assert(field.IsStatic);

                    // CALL <context>.DeclareConstant(<name>, <value>);
                    script_context_place.EmitLoad(il);

                    il.Emit(OpCodes.Ldstr, constant.FullName);
                    il.LoadLiteralBox(constant.Value);  //il.Emit(OpCodes.Ldsfld, field);   // const field cannot be referenced in IL
                    il.Emit(OpCodes.Call, Methods.ScriptContext.DeclareConstant);
                }
            }

			il.Emit(OpCodes.Ret);
		}
Beispiel #6
0
        /// <summary>
        /// Emits helper declaring all single-declared functions and classes in the script being built.
        /// </summary>
        /// <remarks>
        /// For each function and class emits a call to <see cref="ApplicationContext.DeclareFunction"/> and
        /// <see cref="ApplicationContext.DeclareType"/>, respectively, which declares it.
        /// The helper is called as the first instruction of Main helper.
        /// </remarks>
        private void EmitDeclareHelper()
        {
            PureCompilationUnit unit = this.PureCompilationUnit;
            ILEmitter           il   = new ILEmitter(declareHelperBuilder);
            IndexedPlace        app_context_place = new IndexedPlace(PlaceHolder.Argument, 0);
            TypeBuilder         publicsContainer  = null; // container type for public stubs of global declarations (which are inaccessible from other assemblies)

            foreach (PhpFunction function in unit.GetDeclaredFunctions())
            {
                if (function.IsDefinite)
                {
                    app_context_place.EmitLoad(il);

                    // NEW RoutineDelegate(<static method>);
                    il.Emit(OpCodes.Ldnull);
                    il.Emit(OpCodes.Ldftn, function.ArgLessInfo);
                    il.Emit(OpCodes.Newobj, Constructors.RoutineDelegate);

                    // LOAD <full name>;
                    il.Emit(OpCodes.Ldstr, function.FullName);

                    // LOAD <attributes>;
                    il.LdcI4((int)function.MemberDesc.MemberAttributes);

                    // LOAD <argfull>
                    if (function.ArgFullInfo != null)
                    {
                        CodeGenerator.EmitLoadMethodInfo(
                            il,
                            (function.ArgFullInfo.DeclaringType != null)
                                ? function.ArgFullInfo
                                : EmitPhpFunctionPublicStub(ref publicsContainer, function) // function.ArgFullInfo is real global method not accessible from other assemblies, must be wrapped
                            /*, AssemblyBuilder.DelegateBuilder*/);
                    }
                    else
                    {
                        il.Emit(OpCodes.Ldnull);
                    }

                    // CALL <application context>.DeclareFunction(<stub>, <name>, <member attributes>, <argfull>)
                    il.Emit(OpCodes.Call, Methods.ApplicationContext.DeclareFunction);
                }
            }

            foreach (PhpType type in unit.GetDeclaredTypes())
            {
                if (type.IsDefinite)
                {
                    // CALL <application context>.DeclareType(<type desc>, <name>);
                    type.EmitAutoDeclareOnApplicationContext(il, app_context_place);
                }
            }

            foreach (GlobalConstant constant in unit.GetDeclaredConstants())
            {
                if (constant.IsDefinite)
                {
                    app_context_place.EmitLoad(il);

                    // CALL <application context>.DeclareConstant(<name>, <value>);
                    il.Emit(OpCodes.Ldstr, constant.FullName);
                    //il.Emit(OpCodes.Ldsfld, constant.RealField);
                    //if (constant.RealField.FieldType.IsValueType) il.Emit(OpCodes.Box, constant.RealField.FieldType);
                    il.LoadLiteralBox(constant.Value);
                    il.Emit(OpCodes.Call, Methods.ApplicationContext.DeclareConstant);
                }
            }

            il.Emit(OpCodes.Ret);

            // complete the publicsContainer type, if created:
            if (publicsContainer != null)
            {
                publicsContainer.CreateType();
            }
        }
Beispiel #7
0
		protected virtual SetterDelegate/*!*/ GenerateSetterStub()
		{
			if (Member is ClrEvent) return new SetterDelegate(EventSetter);

#if SILVERLIGHT
			DynamicMethod stub = new DynamicMethod("<^SetterStub>", Types.Void, Types.Object_Object);

            /*DynamicMethod stub = new DynamicMethod("<^SetterStub>", PhpFunctionUtils.DynamicStubAttributes, CallingConventions.Standard,
                Types.Void, Types.Object_Object, this.declaringType.RealType, true);*/
#else
			DynamicMethod stub = new DynamicMethod("<^SetterStub>", PhpFunctionUtils.DynamicStubAttributes, CallingConventions.Standard,
				Types.Void, Types.Object_Object, this.declaringType.RealType, true);
#endif
#if DEBUG_DYNAMIC_STUBS

			// Debugging - save the generated stub to TEMP
			AssemblyName name = new AssemblyName("SetterStub_" + Property.FullName.ToString().Replace(':', '_'));
			AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Save, "C:\\Temp");
			ModuleBuilder mb = ab.DefineDynamicModule(name.Name, name.Name + ".dll");
			TypeBuilder tb = mb.DefineType("Stub");
			MethodBuilder meb = tb.DefineMethod(DeclaringType.ToString() + "::" + Property.FullName,
				MethodAttributes.PrivateScope | MethodAttributes.Static, Types.Void, Types.Object_Object);

			ILEmitter il_dbg = new ILEmitter(meb);
			IndexedPlace instance2 = new IndexedPlace(PlaceHolder.Argument, 0);
			IndexedPlace stack = new IndexedPlace(PlaceHolder.Argument, 1);

			ClrProperty clr_property_dbg = Member as ClrProperty;
			if (clr_property_dbg != null && clr_property_dbg.HasSetter)
			{
				if (!clr_property_dbg.Setter.IsStatic)
				{
					il_dbg.Emit(OpCodes.Ldarg_0);
                    if (declaringType.RealType.IsValueType)
                        il_dbg.Emit(OpCodes.Unbox, declaringType.RealType);
#if EMIT_VERIFIABLE_STUBS
                    else
                        il_dbg.Emit(OpCodes.Castclass, declaringType.RealType);
#endif
				}
				il_dbg.Emit(OpCodes.Ldarg_1);
				EmitSetConversion(il_dbg, PhpTypeCode.Object, clr_property_dbg.Setter.GetParameters()[0].ParameterType);
				il_dbg.Emit(OpCodes.Call, clr_property_dbg.Setter);
			}

			il_dbg.Emit(OpCodes.Ret);
			tb.CreateType();
			ab.Save("SetterStub_" + Property.FullName.ToString().Replace(':', '_') + ".dll");
#endif

			ILEmitter il = new ILEmitter(stub);

			ClrProperty clr_property = Member as ClrProperty;
			Type arg_type;

			if (clr_property != null)
			{
				// return error-throwing setter if the property is read-only
				if (!clr_property.HasSetter) return new SetterDelegate(MissingSetter);

				if (!clr_property.Setter.IsStatic)
				{
                    ClrOverloadBuilder.EmitLoadInstance(il, IndexedPlace.ThisArg, declaringType.RealType);
//                    il.Emit(OpCodes.Ldarg_0);

//                    if (declaringType.RealType.IsValueType) 
//                        il.Emit(OpCodes.Unbox, declaringType.RealType);
//#if EMIT_VERIFIABLE_STUBS
//                    else
//                        il.Emit(OpCodes.Castclass, declaringType.RealType);
//#endif

				}

				il.Emit(OpCodes.Ldarg_1);

				arg_type = clr_property.Setter.GetParameters()[0].ParameterType;
				EmitSetConversion(il, PhpTypeCode.Object, arg_type);

				il.Emit(OpCodes.Call, clr_property.Setter);
			}
			else
			{
				ClrField clr_field = ClrField;

				// return error-throwing setter if the field is initonly
				if (clr_field.FieldInfo.IsInitOnly) return new SetterDelegate(MissingSetter);

				if (!clr_field.FieldInfo.IsStatic)
				{
                    ClrOverloadBuilder.EmitLoadInstance(il, IndexedPlace.ThisArg, declaringType.RealType);
                    //il.Emit(OpCodes.Ldarg_0);
                    ////il.Emit(OpCodes.Castclass, this.declaringType.RealType);

                    //if (declaringType.RealType.IsValueType) il.Emit(OpCodes.Unbox, declaringType.RealType);
				}

				il.Emit(OpCodes.Ldarg_1);

				arg_type = clr_field.FieldInfo.FieldType;
				EmitSetConversion(il, PhpTypeCode.Object, arg_type);

				il.Emit((clr_field.FieldInfo.IsStatic ? OpCodes.Stsfld : OpCodes.Stfld), clr_field.FieldInfo);
			}

			il.Emit(OpCodes.Ret);

			return (SetterDelegate)stub.CreateDelegate(typeof(SetterDelegate));
		}
Beispiel #8
0
		/// <summary>
		/// Called when a <see cref="PHP.Core.AST.FieldDecl"/> AST node is visited during the emit phase.
		/// </summary>
		public void InitializeField(PhpField/*!*/ field, AST.Expression initVal)
		{
			ILEmitter cil;
			IPlace sc_place;
            
			if (field.IsStatic)
			{
                // (J) even overiding static field is created again in derivating type
				// there is no initialization taking place if the implementing CLI field does not live in current class
				//if (field.Overrides != null) return;

				if (field.IsAppStatic)
				{
					// app-static field initialization is emitted into the static ctor
					cil = field.DeclaringPhpType.Builder.StaticCtorEmitter;

					sc_place = new LazyLoadSCPlace();
				}
				else
				{
					// thread-static field initialization is emitted into the __InitializeStaticFields method
					cil = new ILEmitter(field.DeclaringPhpType.StaticFieldInitMethodBuilder);

					sc_place = new IndexedPlace(PlaceHolder.Argument, ScriptBuilder.ArgContext);
				}
			}
			else
			{
                if (initVal == null && field.Implementor != field.DeclaringType)
                    return;

				// instance field initialization is emitted into the <InitializeInstanceFields> method
				cil = field.DeclaringPhpType.Builder.InstanceFieldInitEmitter;

				sc_place = new IndexedPlace(PlaceHolder.Argument, FunctionBuilder.ArgContextInstance);

				cil.Ldarg(FunctionBuilder.ArgThis);
			}

			if (initVal != null)
			{
				// emit the expression evaluating code
				ILEmitter old_il = il;
				IPlace old_sc_place = ScriptContextPlace;

				try
				{
					// set il and SC-emitter appropriately
					il = cil;
					ScriptContextPlace = sc_place;

					EmitBoxing(initVal.Emit(this));
				}
				finally
				{
					// restore the saved il and SC-emitter
					il = old_il;
					ScriptContextPlace = old_sc_place;
				}

				cil.Emit(OpCodes.Newobj, Constructors.PhpSmartReference.Object);
			}
			else cil.Emit(OpCodes.Newobj, Constructors.PhpSmartReference.Void);

			// store it in the field
            Debug.Assert(field.IsStatic == field.RealField.IsStatic);
			cil.Emit(field.IsStatic ? OpCodes.Stsfld : OpCodes.Stfld, field.RealField);
		}
Beispiel #9
0
        protected override RoutineDelegate GenerateArglessStub()
		{
			ClrMethod clr_method = ClrMethod;
			Debug.Assert(clr_method != null, "CLR method should be fully reflected");

#if DEBUG_METHOD_STUBS
			AssemblyName name = new AssemblyName("MethodStub_" + clr_method.ToString().Replace(':','_'));
			AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Save, "C:\\Temp");
			ModuleBuilder mb = ab.DefineDynamicModule(name.Name, name.Name + ".dll");
			TypeBuilder tb = mb.DefineType(clr_method.Name.ToString());
			MethodBuilder mmb = tb.DefineMethod("<^MethodStub>", PhpFunctionUtils.DynamicStubAttributes,
				CallingConventions.Standard, Types.Object[0], Types.Object_PhpStack);

			ILEmitter tmpil = new ILEmitter(mmb);

			IndexedPlace tmpinstance = new IndexedPlace(PlaceHolder.Argument, 0);
			IndexedPlace tmpstack = new IndexedPlace(PlaceHolder.Argument, 1);

			clr_method.EmitArglessStub(tmpil, tmpstack, tmpinstance);

			tb.CreateType();
			ab.Save(name.Name + ".dll");
#endif

#if SILVERLIGHT
			DynamicMethod stub = new DynamicMethod("<^>." + clr_method.Name.Value, Types.Object[0], Types.Object_PhpStack);
#else
			DynamicMethod stub = new DynamicMethod("<^>." + clr_method.Name.Value, PhpFunctionUtils.DynamicStubAttributes,
				CallingConventions.Standard, Types.Object[0], Types.Object_PhpStack, this.declaringType.RealType, true);
#endif
            ILEmitter il = new ILEmitter(stub);

			IndexedPlace instance = new IndexedPlace(PlaceHolder.Argument, 0);
			IndexedPlace stack = new IndexedPlace(PlaceHolder.Argument, 1);

			clr_method.EmitArglessStub(il, stack, instance);

			// TODO: is it possible to drop the member?
			// the compiler may get activated:
			// member = null; 

            this.arglessStubMethod = stub;
            return (RoutineDelegate)stub.CreateDelegate(typeof(RoutineDelegate));
		}
Beispiel #10
0
        private static string CreateDynamicWrapperInternal(Type /*!*/ attr, Assembly /*!*/ assembly, string directory, string filename)
#endif
        {
            string          assembly_base_name;
            AssemblyBuilder assembly_builder;
            ModuleBuilder   module_builder;
            TypeBuilder     type_builder;
            MethodBuilder   method_builder;

            IndexedPlace stack_place = new IndexedPlace(PlaceHolder.Argument, 1);

            // TODO: if function requires this reference, we need to pass it somehow
            IPlace self_ref       = LiteralPlace.Null;
            IPlace script_context = new Place(stack_place, Fields.PhpStack_Context);
            IPlace rt_variables   = new Place(stack_place, Fields.PhpStack_Variables);
            IPlace naming_context = new Place(stack_place, Fields.PhpStack_NamingContext);
            IPlace class_context  = new Place(null, Fields.UnknownTypeDesc.Singleton);

#if !SILVERLIGHT
            if (directory == null)
            {
                directory = Configuration.GetPathsNoLoad().DynamicWrappers;
            }
            Directory.CreateDirectory(directory);
#endif

            Dictionary <string, List <PhpLibraryFunction.Overload> > functions = GetLibraryFunctions(attr, assembly);

            OverloadsBuilder overloads_builder = new OverloadsBuilder(
                false,
                stack_place,
                new OverloadsBuilder.ParameterLoader(PhpStackBuilder.EmitValuePeekUnchecked),
                new OverloadsBuilder.ParameterLoader(PhpStackBuilder.EmitReferencePeekUnchecked),
                new OverloadsBuilder.ParametersLoader(PhpStackBuilder.EmitPeekAllArguments));

#if SILVERLIGHT
            int commaIdx = assembly.FullName.IndexOf(',');
            assembly_base_name = commaIdx == -1 ? assembly.FullName : assembly.FullName.Substring(0, commaIdx);
#else
            // securitycritical
            assembly_base_name = assembly.GetName().Name;
#endif

            // appends assembly name with the suffix:
            AssemblyName name = new AssemblyName();
#if !SILVERLIGHT
            name.Version = assembly.GetName().Version;
#endif
            name.Name = assembly_base_name + PhpLibraryModule.DynamicAssemblySuffix;

#if SILVERLIGHT
            // defines assembly with storage in the dynamic code path:
            assembly_builder = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run);

            // defines a module:
            module_builder = assembly_builder.DefineDynamicModule(PhpLibraryModule.DynamicWrapperModuleName);
#else
            // defines assembly with storage in the dynamic code path:
            assembly_builder = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Save, directory);

            // defines a module:
            module_builder = assembly_builder.DefineDynamicModule(PhpLibraryModule.DynamicWrapperModuleName, filename);
#endif

            // defines type which will contain all mathods:
            type_builder = module_builder.DefineType(Namespaces.LibraryStubs + Type.Delimiter + assembly_base_name, DynamicTypeAttributes);

            try
            {
                foreach (KeyValuePair <string, List <PhpLibraryFunction.Overload> > function in functions)
                {
                    // defines method:
                    method_builder = type_builder.DefineMethod(function.Key, MethodAttributes.Public | MethodAttributes.Static,
                                                               Types.Object[0], Types.Object_PhpStack);

                    ILEmitter il = new ILEmitter(method_builder);
                    overloads_builder.IL           = il;
                    overloads_builder.Aux          = stack_place;
                    overloads_builder.FunctionName = new Name(function.Key);

                    // if run-time variables are needed by the overload sets a place where they are stored up:
                    overloads_builder.EmitCallSwitch(self_ref, script_context, rt_variables, naming_context, class_context, function.Value);

                    // RETURN:
                    il.Emit(OpCodes.Ret);
                }
            }
            catch (Exception e)
            {
                Debug.WriteLine("A", e.ToString());
            }
            type_builder.CreateType();

#if SILVERLIGHT
            return(assembly_builder);
#else
            assembly_builder.Save(filename);
            return(Path.Combine(directory, filename));
#endif
        }
Beispiel #11
0
        internal override PhpTypeCode EmitCall(CodeGenerator/*!*/ codeGenerator, string fallbackQualifiedName, CallSignature callSignature,
            IPlace instance, bool runtimeVisibilityCheck, int overloadIndex, DType type, Position position,
            AccessType access, bool callVirt)
		{
#if DEBUG_DYNAMIC_STUBS
			
			MethodBuilder mb = codeGenerator.IL.TypeBuilder.DefineMethod(DeclaringType.FullName + "::" + FullName,
				MethodAttributes.PrivateScope | MethodAttributes.Static, typeof(object), Types.Object_PhpStack);

			ILEmitter il = new ILEmitter(mb);
			IndexedPlace instance2 = new IndexedPlace(PlaceHolder.Argument, 0);
			IndexedPlace stack = new IndexedPlace(PlaceHolder.Argument, 1);

			EmitArglessStub(il, stack, instance2);
			
#endif
            Debug.Assert(instance == null || instance is ExpressionPlace || instance == IndexedPlace.ThisArg);
            Debug.Assert(fallbackQualifiedName == null);
			return codeGenerator.EmitRoutineOperatorCall(DeclaringType, ExpressionPlace.GetExpression(instance), this.FullName, null, null, callSignature, access);
		}
Beispiel #12
0
        internal override PhpTypeCode EmitCall(CodeGenerator/*!*/ codeGenerator, string fallbackQualifiedName, CallSignature callSignature,
            IPlace instance, bool runtimeVisibilityCheck, int overloadIndex, DType type, Position position,
            AccessType access, bool callVirt)
		{
			Overload overload = overloads[overloadIndex];
			Statistics.AST.AddLibraryFunctionCall(FullName, overload.ParamCount);

            if ((overload.Flags & OverloadFlags.NotSupported) != 0)
            {
                codeGenerator.IL.Emit(OpCodes.Ldstr, FullName);
                codeGenerator.IL.Emit(OpCodes.Call, Methods.PhpException.FunctionNotSupported_String);
                if (codeGenerator.Context.Config.Compiler.Debug)
                    codeGenerator.IL.Emit(OpCodes.Nop);

                return OverloadsBuilder.EmitLoadDefault(codeGenerator.IL, overload.Method);
            }

            //IPlace return_value;
            IPlace script_context = null;
			IPlace opt_arg_count = null;
            IPlace self_ref = null;
            IPlace rt_variables = null;
			IPlace naming_context = null;
            IPlace class_context = null;

            // 

			// captures eval info:
			if ((options & FunctionImplOptions.CaptureEvalInfo) != 0)
			{
				codeGenerator.EmitEvalInfoCapture(position.FirstLine, position.FirstColumn, false);
			}

            // current ScriptContext:
            if ((overload.Flags & OverloadFlags.NeedsScriptContext) != 0)
            {
                script_context = codeGenerator.ScriptContextPlace;
            }

			// number of optional arguments passed to a function (empty or a literal place):
			if ((overload.Flags & OverloadFlags.IsVararg) != 0)
			{
				opt_arg_count = new IndexedPlace(PlaceHolder.None, callSignature.Parameters.Count - overload.ParamCount);
			}

			// this reference?
			if ((options & FunctionImplOptions.NeedsThisReference) != 0)
			{
				self_ref = codeGenerator.SelfPlace;
			}

			// run-time variables table:
			if ((options & FunctionImplOptions.NeedsVariables) != 0)
			{
				rt_variables = codeGenerator.RTVariablesTablePlace;
			}

			// naming context
			if ((options & FunctionImplOptions.NeedsNamingContext) != 0)
			{
                naming_context =
                    (codeGenerator.SourceUnit.NamingContextFieldBuilder != null) ?
                        (IPlace)new Place(null, codeGenerator.SourceUnit.NamingContextFieldBuilder) : (IPlace)LiteralPlace.Null;
			}

            // call context
            if ((options & FunctionImplOptions.NeedsClassContext) != 0)
            {
                class_context = codeGenerator.TypeContextPlace;
            }


			OverloadsBuilder.ParameterLoader param_loader = new OverloadsBuilder.ParameterLoader(callSignature.EmitLibraryLoadArgument);
			OverloadsBuilder.ParametersLoader opt_param_loader = new OverloadsBuilder.ParametersLoader(callSignature.EmitLibraryLoadOptArguments);

			OverloadsBuilder builder = new OverloadsBuilder(
				codeGenerator.Context.Config.Compiler.Debug,
				null,                           // PHP stack is not used
				param_loader,                   // value parameter loader
				param_loader,                   // reference parameter loader
				opt_param_loader);              // optional parameter array loader

			// setups builder:
			builder.Aux = codeGenerator;
			builder.IL = codeGenerator.IL;
			builder.FunctionName = name;

			// emits overload call:
            Type/*!*/return_type = builder.EmitOverloadCall(overload.Method, overload.RealParameters, overload.ParamCount,
				script_context, rt_variables, naming_context, class_context, opt_arg_count, self_ref, access == AccessType.None);

            //if (return_value != null)
            //{
            //    // loads value on the stack:
            //    return_value.EmitLoad(codeGenerator.IL);

            //    return PhpTypeCodeEnum.FromType(return_value.PlaceType);
            //}
            if (return_type != Types.Void)
            {
                return PhpTypeCodeEnum.FromType(return_type);
            }
            else
            {
                if (codeGenerator.Context.Config.Compiler.Debug)
                {
                    codeGenerator.IL.Emit(OpCodes.Nop);
                }
                return PhpTypeCode.Void;
            }
		}
Beispiel #13
0
        private static string CreateDynamicWrapperInternal(Type/*!*/ attr, Assembly/*!*/ assembly, string directory, string filename)
#endif
		{
			string assembly_base_name;
			AssemblyBuilder assembly_builder;
			ModuleBuilder module_builder;
			TypeBuilder type_builder;
			MethodBuilder method_builder;

			IndexedPlace stack_place = new IndexedPlace(PlaceHolder.Argument, 1);
			
			// TODO: if function requires this reference, we need to pass it somehow
			IPlace self_ref = LiteralPlace.Null;
            IPlace script_context = new Place(stack_place, Fields.PhpStack_Context);
			IPlace rt_variables = new Place(stack_place, Fields.PhpStack_Variables);
			IPlace naming_context = new Place(stack_place, Fields.PhpStack_NamingContext);
            IPlace class_context = new Place(null, Fields.UnknownTypeDesc.Singleton);

#if !SILVERLIGHT
			if (directory == null)
				directory = Configuration.GetPathsNoLoad().DynamicWrappers;
			Directory.CreateDirectory(directory);
#endif

			Dictionary<string, List<PhpLibraryFunction.Overload>> functions = GetLibraryFunctions(attr, assembly);

			OverloadsBuilder overloads_builder = new OverloadsBuilder(
				false,
				stack_place,
				new OverloadsBuilder.ParameterLoader(PhpStackBuilder.EmitValuePeekUnchecked),
				new OverloadsBuilder.ParameterLoader(PhpStackBuilder.EmitReferencePeekUnchecked),
				new OverloadsBuilder.ParametersLoader(PhpStackBuilder.EmitPeekAllArguments));

#if SILVERLIGHT
			int commaIdx = assembly.FullName.IndexOf(',');
			assembly_base_name = commaIdx == -1 ? assembly.FullName : assembly.FullName.Substring(0, commaIdx);
#else
			// securitycritical
			assembly_base_name = assembly.GetName().Name;
#endif

			// appends assembly name with the suffix:
			AssemblyName name = new AssemblyName();
#if !SILVERLIGHT
			name.Version = assembly.GetName().Version;
#endif
			name.Name = assembly_base_name + PhpLibraryModule.DynamicAssemblySuffix;

#if SILVERLIGHT

            // defines assembly with storage in the dynamic code path:
            assembly_builder = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run);

            // defines a module:
            module_builder = assembly_builder.DefineDynamicModule(PhpLibraryModule.DynamicWrapperModuleName);

#else
			// defines assembly with storage in the dynamic code path:
			assembly_builder = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Save, directory);

			// defines a module:
            module_builder = assembly_builder.DefineDynamicModule(PhpLibraryModule.DynamicWrapperModuleName, filename);
#endif

			// defines type which will contain all mathods:  
			type_builder = module_builder.DefineType(Namespaces.LibraryStubs + Type.Delimiter + assembly_base_name, DynamicTypeAttributes);

			try
			{
				foreach (KeyValuePair<string, List<PhpLibraryFunction.Overload>> function in functions)
				{
					// defines method:
					method_builder = type_builder.DefineMethod(function.Key, MethodAttributes.Public | MethodAttributes.Static,
						Types.Object[0], Types.Object_PhpStack);

					ILEmitter il = new ILEmitter(method_builder);
					overloads_builder.IL = il;
					overloads_builder.Aux = stack_place;
					overloads_builder.FunctionName = new Name(function.Key);

					// if run-time variables are needed by the overload sets a place where they are stored up:
                    overloads_builder.EmitCallSwitch(self_ref, script_context, rt_variables, naming_context, class_context, function.Value);

					// RETURN:
					il.Emit(OpCodes.Ret);
				}

			}
			catch (Exception e)
			{
				Debug.WriteLine("A", e.ToString());
			}
			type_builder.CreateType();

#if SILVERLIGHT
			return assembly_builder;
#else
            assembly_builder.Save(filename);
            return Path.Combine(directory, filename);
#endif
		}