Exemplo n.º 1
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;
            }
		}