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; } }