Example #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);
        }