Esempio n. 1
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);
        }
Esempio n. 2
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();
		}
Esempio n. 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);
		}
Esempio n. 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();
            }
        }