internal override TypeSymbol Emit(CodeGenerator cg) { if (TargetMethod != null) { return EmitDirectCall(cg, ILOpCode.Newobj, TargetMethod); } else { if (_typeref.ResolvedType != null) { // context.Create<T>(params) var create_t = cg.CoreTypes.Context.Symbol.GetMembers("Create") .OfType<MethodSymbol>() .Where(s => s.Arity == 1 && s.ParameterCount == 1 && s.Parameters[0].IsParams) .Single() .Construct(_typeref.ResolvedType); cg.EmitLoadContext(); // Context cg.Emit_NewArray(cg.CoreTypes.PhpValue, _arguments.Select(a => a.Value).ToArray()); // PhpValue[] return cg.EmitCall(ILOpCode.Call, create_t); } else { // ctx.Create(classname, params) var create = cg.CoreTypes.Context.Symbol.GetMembers("Create") .OfType<MethodSymbol>() .Where(s => s.Arity == 0 && s.ParameterCount == 2 && s.Parameters[0].Type.PrimitiveTypeCode == Microsoft.Cci.PrimitiveTypeCode.String && s.Parameters[1].IsParams && ((ArrayTypeSymbol)s.Parameters[1].Type).ElementType == cg.CoreTypes.PhpValue) .Single(); cg.EmitLoadContext(); // Context _typeref.EmitClassName(cg); // String cg.Emit_NewArray(cg.CoreTypes.PhpValue, _arguments.Select(a => a.Value).ToArray()); // PhpValue[] return cg.EmitCall(ILOpCode.Call, create); } } }
internal override TypeSymbol EmitCallsiteCall(CodeGenerator cg) { if (_name.IsDirect) { return base.EmitCallsiteCall(cg); } else { Debug.Assert(_name.NameExpression != null); // faster to emit PhpCallback.Invoke // NameExpression.AsCallback().Invoke(Context, PhpValue[]) cg.EmitConvert(_name.NameExpression, cg.CoreTypes.IPhpCallable); // (IPhpCallable)Name cg.EmitLoadContext(); // Context cg.Emit_NewArray(cg.CoreTypes.PhpValue, _arguments.Select(a => a.Value).ToArray()); // PhpValue[] return cg.EmitCall(ILOpCode.Callvirt, cg.CoreTypes.IPhpCallable.Symbol.LookupMember<MethodSymbol>("Invoke")); } }