public IfExpr( IPersistentMap sourceSpan, Expr testExpr, Expr thenExpr, Expr elseExpr) { _sourceSpan = sourceSpan; _testExpr = testExpr; _thenExpr = thenExpr; _elseExpr = elseExpr; }
public CaseExpr( IPersistentMap sourceSpan, LocalBindingExpr expr, int shift, int mask, int low, int high, Expr defaultExpr, SortedDictionary<int, Expr> tests, Dictionary<int, Expr> thens, Keyword switchType, Keyword testType, IPersistentSet skipCheck) { _sourceSpan = sourceSpan; _expr = expr; _shift = shift; _mask = mask; //_low = low; //_high = high; _defaultExpr = defaultExpr; _tests = tests; _thens = thens; if (switchType != _compactKey && switchType != _sparseKey) throw new ArgumentException("Unexpected switch type: " + switchType); //_switchType = switchType; if (testType != _intKey && testType != _hashEquivKey && testType != _hashIdentityKey) throw new ArgumentException("Unexpected test type: " + testType); _testType = testType; _skipCheck = skipCheck; ICollection<Expr> returns = new List<Expr>(thens.Values); returns.Add(defaultExpr); _returnType = Compiler.MaybeClrType(returns); if (RT.count(skipCheck) > 0 && RT.booleanCast(RT.WarnOnReflectionVar.deref())) { RT.errPrintWriter().WriteLine("Performance warning, {0}:{1} - hash collision of some case test constants; if selected, those entries will be tested sequentially.", Compiler.SourcePathVar.deref(),RT.get(sourceSpan,RT.StartLineKey)); } }
public InvokeExpr(string source, IPersistentMap spanMap, Symbol tag, Expr fexpr, IPersistentVector args) { _source = source; _spanMap = spanMap; _fexpr = fexpr; _args = args; VarExpr varFexpr = fexpr as VarExpr; if (varFexpr != null) { Var fvar = varFexpr.Var; Var pvar = (Var)RT.get(fvar.meta(), Compiler.ProtocolKeyword); if (pvar != null && Compiler.ProtocolCallsitesVar.isBound) { _isProtocol = true; _siteIndex = Compiler.RegisterProtocolCallsite(fvar); Object pon = RT.get(pvar.get(), _onKey); _protocolOn = HostExpr.MaybeType(pon, false); if (_protocolOn != null) { IPersistentMap mmap = (IPersistentMap)RT.get(pvar.get(), _methodMapKey); Keyword mmapVal = (Keyword)mmap.valAt(Keyword.intern(fvar.sym)); if (mmapVal == null) { throw new ArgumentException(String.Format("No method of interface: {0} found for function: {1} of protocol: {2} (The protocol method may have been defined before and removed.)", _protocolOn.FullName, fvar.Symbol, pvar.Symbol)); } String mname = Compiler.munge(mmapVal.Symbol.ToString()); IList<MethodBase> methods = Reflector.GetMethods(_protocolOn, mname, null, args.count() - 1, false); if (methods.Count != 1) throw new ArgumentException(String.Format("No single method: {0} of interface: {1} found for function: {2} of protocol: {3}", mname, _protocolOn.FullName, fvar.Symbol, pvar.Symbol)); _onMethod = (MethodInfo) methods[0]; } } } if (tag != null) _tag = tag; else if (varFexpr != null) { object arglists = RT.get(RT.meta(varFexpr.Var), Compiler.ArglistsKeyword); object sigTag = null; for (ISeq s = RT.seq(arglists); s != null; s = s.next()) { APersistentVector sig = (APersistentVector)s.first(); int restOffset = sig.IndexOf(Compiler.AmpersandSym); if (args.count() == sig.count() || (restOffset > -1 && args.count() >= restOffset)) { sigTag = Compiler.TagOf(sig); break; } } _tag = sigTag ?? varFexpr.Tag; } else _tag = null; }
public IfExpr(int line, Expr testExpr, Expr thenExpr, Expr elseExpr) { _line = line; _testExpr = testExpr; _thenExpr = thenExpr; _elseExpr = elseExpr; }
public DefExpr(Var var, Expr init, Expr meta, bool initProvided) { _var = var; _init = init; _meta = meta; _initProvided = initProvided; }
#pragma warning restore 414 #endregion #region C-tors public InstanceOfExpr(string source, IPersistentMap spanMap, Type t, Expr expr) { _source = source; _spanMap = spanMap; _t = t; _expr = expr; }
public InstanceMethodExpr(Expr target, string methodName, IPersistentVector args) { _target = target; _methodName = methodName; _args = args; _method = GetMatchingMethod(target, _args, _methodName); }
internal static Expression GenTypedArg(GenContext context, Type type, Expr arg) { if (Compiler.MaybePrimitiveType(arg) == type) return ((MaybePrimitiveExpr)arg).GenDlrUnboxed(context); else // Java has emitUnboxArg -- should we do something similar? return arg.GenDlr(context); }
public InvokeExpr(string source, int line, Symbol tag, Expr fexpr, IPersistentVector args) { _source = source; _line = line; _fexpr = fexpr; _args = args; _tag = tag ?? (fexpr is VarExpr ? ((VarExpr)fexpr).Tag : null); }
public void EmitAssign(RHC rhc, ObjExpr objx, CljILGen ilg, Expr val) { objx.EmitVar(ilg, _var); val.Emit(RHC.Expression, objx, ilg); ilg.Emit(OpCodes.Call, Compiler.Method_Var_set); if (rhc == RHC.Statement) ilg.Emit(OpCodes.Pop); }
public TryExpr(Expr tryExpr, IPersistentVector catchExprs, Expr finallyExpr, int retLocal, int finallyLocal) { _tryExpr = tryExpr; _catchExprs = catchExprs; _finallyExpr = finallyExpr; _retLocal = retLocal; _finallyLocal = finallyLocal; }
public KeywordInvokeExpr(string source, IPersistentMap spanMap, Symbol tag, KeywordExpr kw, Expr target) { _source = source; _spanMap = spanMap; _kw = kw; _target = target; _tag = tag; _siteIndex = Compiler.RegisterKeywordCallsite(kw.Kw); }
internal static Expression GenTypedArg(GenContext context, Type type, Expr arg) { if (Compiler.MaybePrimitiveType(arg) == type) return ((MaybePrimitiveExpr)arg).GenDlrUnboxed(context); else { Expression argExpr = arg.GenDlr(context); return GenMaybeUnboxedArg(type, argExpr); } }
public DefExpr(string source, int line, Var var, Expr init, Expr meta, bool initProvided, bool isDyanamic) { _source = source; _line = line; _var = var; _init = init; _meta = meta; _isDynamic = isDyanamic; _initProvided = initProvided; }
internal InstanceZeroArityCallExpr(string source, IPersistentMap spanMap, Symbol tag, Expr target, string memberName) { _source = source; _spanMap = spanMap; _memberName = memberName; _target = target; _tag = tag; _targetType = target.HasClrType ? target.ClrType : null; }
public InstanceMethodExpr(string source, IPersistentMap spanMap, Symbol tag, Expr target, string methodName, List<Type> typeArgs, List<HostArg> args) : base(source,spanMap,tag,methodName,typeArgs,args) { _target = target; if (target.HasClrType && target.ClrType == null) throw new ArgumentException(String.Format("Attempt to call instance method {0} on nil", methodName)); _method = Reflector.GetMatchingMethod(spanMap, target, _args, _methodName, _typeArgs); }
public LocalBinding(int index, Symbol sym, Symbol tag, Expr init) { if (Compiler.MaybePrimitiveType(init) != null && tag != null) throw new InvalidOperationException("Can't type hint a local with a primitive initializer"); _index = index; _sym = sym; _tag = tag; _init = init; _name = Compiler.Munge(sym.Name); }
internal InstanceZeroArityCallExpr(string source, IPersistentMap spanMap, Symbol tag, Expr target, string memberName) { _source = source; _spanMap = spanMap; _memberName = memberName; _target = target; _tag = tag; if ( RT.booleanCast(RT.WarnOnReflectionVar.deref())) RT.errPrintWriter().WriteLine("Reflection warning, {0}:{1}:{2} - reference to field/property {3} can't be resolved.", Compiler.SourcePathVar.deref(), Compiler.GetLineFromSpanMap(_spanMap), Compiler.GetColumnFromSpanMap(_spanMap), memberName); }
public DefExpr(string source, int line, int column, Var var, Expr init, Expr meta, bool initProvided, bool isDyanamic, bool shadowsCoreMapping) { _source = source; _line = line; _column = column; _var = var; _init = init; _meta = meta; _isDynamic = isDyanamic; _shadowsCoreMapping = shadowsCoreMapping; _initProvided = initProvided; }
public InstanceMethodExpr(string source, int line, Expr target, string methodName, IPersistentVector args) { _source = source; _line = line; _target = target; _methodName = methodName; _args = args; if (target.HasClrType && target.ClrType == null) throw new ArgumentException(String.Format("Attempt to call instance method {0} on nil", methodName)); _method = GetMatchingMethod(line, target, _args, _methodName); }
public InstanceFieldExpr(Expr target, string fieldName) { _target = target; _fieldName = fieldName; _targetType = target.HasClrType ? target.ClrType : null; _fieldInfo = _targetType != null ? _targetType.GetField(_fieldName, BindingFlags.Instance | BindingFlags.Public) : null; _propertyInfo = _targetType != null ? _targetType.GetProperty(_fieldName, BindingFlags.Instance | BindingFlags.Public) : null; if ( _fieldInfo == null && _propertyInfo == null && RT.booleanCast(RT.WARN_ON_REFLECTION.deref())) ((TextWriter)RT.ERR.deref()).WriteLine("Reflection warning {0}:{1} - reference to field/property {2} can't be resolved.", Compiler.SOURCE_PATH.deref(), /* line */ 0,_fieldName); }
internal InstanceZeroArityCallExpr(string source, IPersistentMap spanMap, Symbol tag, Expr target, string memberName) { _source = source; _spanMap = spanMap; _memberName = memberName; _target = target; _tag = tag; _targetType = target.HasClrType ? target.ClrType : null; if ( RT.booleanCast(RT.WARN_ON_REFLECTION.deref())) RT.errPrintWriter().WriteLine("Reflection warning, {0}:{1} - reference to field/property {2} can't be resolved.", Compiler.SOURCE_PATH.deref(), Compiler.GetLineFromSpanMap(_spanMap), memberName); }
public CaseExpr( IPersistentMap sourceSpan, LocalBindingExpr expr, int shift, int mask, int low, int high, Expr defaultExpr, Dictionary<int, Expr> tests, Dictionary<int, Expr> thens, bool allKeywords) { _sourceSpan = sourceSpan; _expr = expr; _shift = shift; _mask = mask; _low = low; _high = high; _defaultExpr = defaultExpr; _tests = tests; _thens = thens; _allKeywords = allKeywords; }
public LocalBinding(int index, Symbol sym, Symbol tag, Expr init, bool isThis, bool isArg, bool isByRef) { if (Compiler.MaybePrimitiveType(init) != null && tag != null) throw new InvalidOperationException("Can't type hint a local with a primitive initializer"); _index = index; _sym = sym; Tag = tag; Init = init; _name = Compiler.munge(sym.Name); _isThis = isThis; _isArg = isArg; _isByRef = isByRef; RecurMismatch = false; }
public InvokeExpr(string source, IPersistentMap spanMap, Symbol tag, Expr fexpr, IPersistentVector args) { _source = source; _spanMap = spanMap; _fexpr = fexpr; _args = args; if (fexpr is VarExpr) { Var fvar = ((VarExpr)fexpr).Var; Var pvar = (Var)RT.get(fvar.meta(), Compiler.PROTOCOL_KEY); if (pvar != null && Compiler.PROTOCOL_CALLSITES.isBound) { _isProtocol = true; _siteIndex = Compiler.RegisterProtocolCallsite(fvar); Object pon = RT.get(pvar.get(), _onKey); _protocolOn = HostExpr.MaybeType(pon, false); if (_protocolOn != null) { IPersistentMap mmap = (IPersistentMap)RT.get(pvar.get(), _methodMapKey); Keyword mmapVal = (Keyword)mmap.valAt(Keyword.intern(fvar.sym)); if (mmapVal == null) { throw new ArgumentException(String.Format("No method of interface: {0} found for function: {1} of protocol: {2} (The protocol method may have been defined before and removed.)", _protocolOn.FullName, fvar.Symbol, pvar.Symbol)); } String mname = Compiler.munge(mmapVal.Symbol.ToString()); List<MethodInfo> methods = Reflector.GetMethods(_protocolOn, mname, args.count() - 1, false); if (methods.Count != 1) throw new ArgumentException(String.Format("No single method: {0} of interface: {1} found for function: {2} of protocol: {3}", mname, _protocolOn.FullName, fvar.Symbol, pvar.Symbol)); _onMethod = methods[0]; } } //else if (pvar == null && Compiler.VAR_CALLSITES.isBound // && fvar.Namespace.Name.Name.StartsWith("clojure") // && !RT.booleanCast(RT.get(RT.meta(fvar), _dynamicKey))) //{ // // Java TODO: more specific criteria for binding these // _isDirect = true; // _siteIndex = Compiler.RegisterVarCallsite(fvar); //} } _tag = tag ?? (fexpr is VarExpr ? ((VarExpr)fexpr).Tag : null); }
public InvokeExpr(string source, IPersistentMap spanMap, Symbol tag, Expr fexpr, IPersistentVector args) { _source = source; _spanMap = spanMap; _fexpr = fexpr; _args = args; if (fexpr is VarExpr) { Var fvar = ((VarExpr)fexpr).Var; Var pvar = (Var)RT.get(fvar.meta(), Compiler.PROTOCOL_KEY); if (pvar != null && Compiler.PROTOCOL_CALLSITES.isBound) { _isProtocol = true; _siteIndex = Compiler.RegisterProtocolCallsite(fvar); Object pon = RT.get(pvar.get(), _onKey); _protocolOn = HostExpr.MaybeType(pon, false); if (_protocolOn != null) { IPersistentMap mmap = (IPersistentMap)RT.get(pvar.get(), _methodMapKey); Keyword mmapVal = (Keyword)mmap.valAt(Keyword.intern(fvar.sym)); if (mmapVal == null) { throw new ArgumentException(String.Format("No method of interface: {0} found for function: {1} of protocol: {2} (The protocol method may have been defined before and removed.)", _protocolOn.FullName, fvar.Symbol, pvar.Symbol)); } String mname = Compiler.munge(mmapVal.Symbol.ToString()); List<MethodBase> methods = Reflector.GetMethods(_protocolOn, mname, null, args.count() - 1, false); if (methods.Count != 1) throw new ArgumentException(String.Format("No single method: {0} of interface: {1} found for function: {2} of protocol: {3}", mname, _protocolOn.FullName, fvar.Symbol, pvar.Symbol)); _onMethod = (MethodInfo) methods[0]; } } } _tag = tag ?? (fexpr is VarExpr ? ((VarExpr)fexpr).Tag : null); }
public override Expression GenAssignDlr(GenContext context, Expr val) { Expression target = _target.GenDlr(context); Expression valExpr = val.GenDlr(context); if (_targetType != null) { Expression convTarget = Expression.Convert(target, _targetType); Expression access = _fieldInfo != null ? Expression.Field(convTarget, _fieldInfo) : Expression.Property(convTarget, _propertyInfo); return Expression.Assign(access, valExpr); } else { // TODO: Shouldn't this cause a reflection warning? Expression call = Expression.Call( target, Compiler.Method_Reflector_SetInstanceFieldOrProperty, Expression.Constant(_fieldName), valExpr); return call; } }
public InstanceFieldExpr(string source, IPersistentMap spanMap, Symbol tag, Expr target, string fieldName, FieldInfo finfo) : base(source, spanMap, tag, target, fieldName, finfo) { }
/// <summary> /// Parse-time lookup of instance method /// </summary> /// <param name="spanMap"></param> /// <param name="target"></param> /// <param name="args"></param> /// <param name="methodName"></param> /// <param name="typeArgs"></param> /// <returns></returns> public static MethodInfo GetMatchingMethod(IPersistentMap spanMap, Expr target, IList<HostArg> args, string methodName, IList<Type> typeArgs) { MethodBase method = null; bool hasMethods = false; if (target.HasClrType) { Type targetType = target.ClrType; IList<MethodBase> methods = GetMethods(targetType, methodName, typeArgs, args.Count, false); method = GetMatchingMethodAux(targetType, args, methods, methodName, false); hasMethods = methods.Count > 0; } MaybeReflectionWarn(spanMap, (target.HasClrType ? target.ClrType : null), false, hasMethods, method, methodName, args); return (MethodInfo)method; }
public abstract Expression GenAssign(RHC rhc, ObjExpr objx, GenContext context, Expr val);
public abstract object EvalAssign(Expr val);
public InstancePropertyExpr(string source, IPersistentMap spanMap, Symbol tag, Expr target, string fieldName, PropertyInfo pinfo) : base(source, spanMap, tag, target, fieldName, pinfo) { }
public InstanceFieldOrPropertyExpr(string source, IPersistentMap spanMap, Symbol tag, Expr target, string fieldName, TInfo tinfo) { _source = source; _spanMap = spanMap; _target = target; _fieldName = fieldName; _tinfo = tinfo; _tag = tag; _targetType = target.HasClrType ? target.ClrType : null; // Java version does not include check on _targetType // However, this seems consistent with the checks in the generation code. if ((_targetType == null || _tinfo == null) && RT.booleanCast(RT.WarnOnReflectionVar.deref())) { RT.errPrintWriter().WriteLine("Reflection warning, {0}:{1}:{2} - reference to field/property {3} can't be resolved.", Compiler.SourcePathVar.deref(), Compiler.GetLineFromSpanMap(_spanMap), Compiler.GetColumnFromSpanMap(_spanMap), _fieldName); } }
public abstract void EmitAssign(RHC rhc, ObjExpr objx, CljILGen ilg, Expr val);
public static Expr Parse(ParserContext pcon, ISeq form) { pcon = pcon.EvalOrExpr(); // TODO: DO we need the recur context here and below? Expr fexpr = Compiler.Analyze(pcon, form.first()); VarExpr varFexpr = fexpr as VarExpr; if (varFexpr != null && varFexpr.Var.Equals(Compiler.InstanceVar)) { if (RT.second(form) is Symbol) { Type t = HostExpr.MaybeType(RT.second(form), false); if (t != null) { return(new InstanceOfExpr((string)Compiler.SourceVar.deref(), (IPersistentMap)Compiler.SourceSpanVar.deref(), t, Compiler.Analyze(pcon, RT.third(form)))); } } } if (varFexpr != null && pcon.Rhc != RHC.Eval) { Var v = varFexpr.Var; object arglists = RT.get(RT.meta(v), Compiler.ArglistsKeyword); int arity = RT.count(form.next()); for (ISeq s = RT.seq(arglists); s != null; s = s.next()) { IPersistentVector sargs = (IPersistentVector)s.first(); if (sargs.count() == arity) { string primc = FnMethod.PrimInterface(sargs); if (primc != null) { return(Compiler.Analyze(pcon, RT.listStar(Symbol.intern(".invokePrim"), ((Symbol)form.first()).withMeta(RT.map(RT.TagKey, Symbol.intern(primc))), form.next()))); } break; } } } KeywordExpr kwFexpr = fexpr as KeywordExpr; if (kwFexpr != null && RT.count(form) == 2 && Compiler.KeywordCallsitesVar.isBound) { Expr target = Compiler.Analyze(pcon, RT.second(form)); return(new KeywordInvokeExpr((string)Compiler.SourceVar.deref(), (IPersistentMap)Compiler.SourceSpanVar.deref(), Compiler.TagOf(form), kwFexpr, target)); } IPersistentVector args = PersistentVector.EMPTY; for (ISeq s = RT.seq(form.next()); s != null; s = s.next()) { args = args.cons(Compiler.Analyze(pcon, s.first())); } //if (args.count() > Compiler.MAX_POSITIONAL_ARITY) // throw new ArgumentException(String.Format("No more than {0} args supported", Compiler.MAX_POSITIONAL_ARITY)); return(new InvokeExpr((string)Compiler.SourceVar.deref(), (IPersistentMap)Compiler.SourceSpanVar.deref(), //Compiler.GetSourceSpanMap(form), Compiler.TagOf(form), fexpr, args)); }
private Expression GenProtoFull(RHC rhc, ObjExpr objx, GenContext context, Expression fn) { Var v = ((VarExpr)_fexpr).Var; Expr e = (Expr)_args.nth(0); ParameterExpression targetParam = Expression.Parameter(typeof(Object), "target"); ParameterExpression targetTypeParam = Expression.Parameter(typeof(Type), "targetType"); ParameterExpression vpfnParam = Expression.Parameter(typeof(AFunction), "vpfn"); ParameterExpression thisParam = objx.ThisParam; Expression targetParamAssign = Expression.Assign(targetParam, Expression.Convert(e.GenCode(RHC.Expression, objx, context), targetParam.Type)); Expression targetTypeParamAssign = Expression.Assign( targetTypeParam, Expression.Call(null, Compiler.Method_Util_classOf, targetParam)); Expression cachedTypeField = Expression.Field(thisParam, objx.CachedTypeField(_siteIndex)); Expression setCachedClass = Expression.Assign( cachedTypeField, targetTypeParam); Expression vpfnParamAssign = Expression.Assign( vpfnParam, Expression.Convert(Expression.Call(objx.GenVar(context, v), Compiler.Method_Var_getRawRoot), typeof(AFunction))); if (_protocolOn == null) { return(Expression.Block( new ParameterExpression[] { targetParam, targetTypeParam, vpfnParam }, targetParamAssign, targetTypeParamAssign, Expression.IfThen( Expression.NotEqual(targetTypeParam, cachedTypeField), setCachedClass), vpfnParamAssign, GenerateArgsAndCall(rhc, objx, context, vpfnParam, targetParam))); } else { Expression[] args = new Expression[_args.count() - 1]; for (int i = 1; i < _args.count(); i++) { Expression bare = ((Expr)_args.nth(i)).GenCode(RHC.Expression, objx, context); args[i - 1] = Compiler.MaybeBox(bare); } return(Expression.Block( new ParameterExpression[] { targetParam, targetTypeParam, vpfnParam }, targetParamAssign, targetTypeParamAssign, Expression.Condition( Expression.And( Expression.NotEqual(targetTypeParam, cachedTypeField), Expression.TypeIs(targetParam, _protocolOn)), Compiler.MaybeBox(Expression.Call(Expression.Convert(targetParam, _protocolOn), _onMethod, args)), Expression.Block( Expression.IfThen( Expression.NotEqual(targetTypeParam, cachedTypeField), setCachedClass), vpfnParamAssign, GenerateArgsAndCall(rhc, objx, context, vpfnParam, targetParam))))); } }
public InvokeExpr(string source, IPersistentMap spanMap, Symbol tag, Expr fexpr, IPersistentVector args) { _source = source; _spanMap = spanMap; _fexpr = fexpr; _args = args; VarExpr varFexpr = fexpr as VarExpr; if (varFexpr != null) { Var fvar = varFexpr.Var; Var pvar = (Var)RT.get(fvar.meta(), Compiler.ProtocolKeyword); if (pvar != null && Compiler.ProtocolCallsitesVar.isBound) { _isProtocol = true; _siteIndex = Compiler.RegisterProtocolCallsite(fvar); Object pon = RT.get(pvar.get(), _onKey); _protocolOn = HostExpr.MaybeType(pon, false); if (_protocolOn != null) { IPersistentMap mmap = (IPersistentMap)RT.get(pvar.get(), _methodMapKey); Keyword mmapVal = (Keyword)mmap.valAt(Keyword.intern(fvar.sym)); if (mmapVal == null) { throw new ArgumentException(String.Format("No method of interface: {0} found for function: {1} of protocol: {2} (The protocol method may have been defined before and removed.)", _protocolOn.FullName, fvar.Symbol, pvar.Symbol)); } String mname = Compiler.munge(mmapVal.Symbol.ToString()); IList <MethodBase> methods = Reflector.GetMethods(_protocolOn, mname, null, args.count() - 1, false); if (methods.Count != 1) { throw new ArgumentException(String.Format("No single method: {0} of interface: {1} found for function: {2} of protocol: {3}", mname, _protocolOn.FullName, fvar.Symbol, pvar.Symbol)); } _onMethod = (MethodInfo)methods[0]; } } } //_tag = tag ?? (varFexpr != null ? varFexpr.Tag : null); if (tag != null) { _tag = tag; } else if (varFexpr != null) { object arglists = RT.get(RT.meta(varFexpr.Var), Compiler.ArglistsKeyword); object sigTag = null; for (ISeq s = RT.seq(arglists); s != null; s = s.next()) { APersistentVector sig = (APersistentVector)s.first(); int restOffset = sig.IndexOf(Compiler.AmpersandSym); if (args.count() == sig.count() || (restOffset > -1 && args.count() >= restOffset)) { sigTag = Compiler.TagOf(sig); break; } } _tag = sigTag ?? varFexpr.Tag; } else { _tag = null; } }
private void EmitComplexCall(ObjExpr objx, CljILGen ilg) { // This is made more complex than I'd like by light-compiling. // Without light-compile, we could just: // Emit the target expression // Emit the arguments (and build up the parameter list for the lambda) // Create the lambda, compile to a methodbuilder, and call it. // Light-compile forces us to // create a lambda at the beginning because we must // compile it to a delegate, to get the type // write code to grab the delegate from a cache // Then emit the target expression // emit the arguments (but note we need already to have built the parameter list) // Call the delegate // Combined, this becomes // Build the parameter list // Build the dynamic call and lambda (slightly different for light-compile vs full) // if light-compile // build the delegate // cache it // emit code to retrieve and cast it // emit the target expression // emit the args // emit the call (slightly different for light compile vs full) // // Build the parameter list List <ParameterExpression> paramExprs = new List <ParameterExpression>(_args.Count + 1); List <Type> paramTypes = new List <Type>(_args.Count + 1); Type targetType = GetTargetType(); if (!targetType.IsPrimitive) { targetType = typeof(object); } paramExprs.Add(Expression.Parameter(targetType)); paramTypes.Add(targetType); int i = 0; foreach (HostArg ha in _args) { i++; Expr e = ha.ArgExpr; Type argType = e.HasClrType && e.ClrType != null && e.ClrType.IsPrimitive ? e.ClrType : typeof(object); switch (ha.ParamType) { case HostArg.ParameterType.ByRef: { Type byRefType = argType.MakeByRefType(); paramExprs.Add(Expression.Parameter(byRefType, ha.LocalBinding.Name)); paramTypes.Add(byRefType); break; } case HostArg.ParameterType.Standard: if (argType.IsPrimitive && ha.ArgExpr is MaybePrimitiveExpr) { paramExprs.Add(Expression.Parameter(argType, ha.LocalBinding != null ? ha.LocalBinding.Name : "__temp_" + i)); paramTypes.Add(argType); } else { paramExprs.Add(Expression.Parameter(typeof(object), ha.LocalBinding != null ? ha.LocalBinding.Name : "__temp_" + i)); paramTypes.Add(typeof(object)); } break; default: throw Util.UnreachableCode(); } } // Build dynamic call and lambda Type returnType = HasClrType ? ClrType : typeof(object); InvokeMemberBinder binder = new ClojureInvokeMemberBinder(ClojureContext.Default, _methodName, paramExprs.Count, IsStaticCall); // This is what I want to do. //DynamicExpression dyn = Expression.Dynamic(binder, typeof(object), paramExprs); // Unfortunately, the Expression.Dynamic method does not respect byRef parameters. // The workaround appears to be to roll your delegate type and then use Expression.MakeDynamic, as below. List <Type> callsiteParamTypes = new List <Type>(paramTypes.Count + 1); callsiteParamTypes.Add(typeof(System.Runtime.CompilerServices.CallSite)); callsiteParamTypes.AddRange(paramTypes); Type dynType = Microsoft.Scripting.Generation.Snippets.Shared.DefineDelegate("__interop__", returnType, callsiteParamTypes.ToArray()); #if CLR2 // Not covariant. Sigh. List <Expression> paramsAsExprs = new List <Expression>(paramExprs.Count); paramsAsExprs.AddRange(paramExprs.ToArray()); DynamicExpression dyn = Expression.MakeDynamic(dynType, binder, paramsAsExprs); #else DynamicExpression dyn = Expression.MakeDynamic(dynType, binder, paramExprs); #endif LambdaExpression lambda; Type delType; MethodBuilder mbLambda; EmitDynamicCallPreamble(dyn, _spanMap, "__interop_" + _methodName + RT.nextID(), returnType, paramExprs, paramTypes.ToArray(), ilg, out lambda, out delType, out mbLambda); // Emit target + args EmitTargetExpression(objx, ilg); i = 0; foreach (HostArg ha in _args) { i++; Expr e = ha.ArgExpr; Type argType = e.HasClrType && e.ClrType != null && e.ClrType.IsPrimitive ? e.ClrType : typeof(object); switch (ha.ParamType) { case HostArg.ParameterType.ByRef: EmitByRefArg(ha, objx, ilg); break; case HostArg.ParameterType.Standard: if (argType.IsPrimitive && ha.ArgExpr is MaybePrimitiveExpr) { ((MaybePrimitiveExpr)ha.ArgExpr).EmitUnboxed(RHC.Expression, objx, ilg); } else { ha.ArgExpr.Emit(RHC.Expression, objx, ilg); } break; default: throw Util.UnreachableCode(); } } EmitDynamicCallPostlude(lambda, delType, mbLambda, ilg); }
private void EmitComplexCall(RHC rhc, ObjExpr objx, CljILGen ilg) { // See the notes on MethodExpr.EmitComplexCall on why this is so complicated List <ParameterExpression> paramExprs = new List <ParameterExpression>(_args.Count + 1); List <Type> paramTypes = new List <Type>(_args.Count + 1); paramExprs.Add(Expression.Parameter(typeof(Type))); paramTypes.Add(typeof(Type)); int i = 0; foreach (HostArg ha in _args) { i++; Expr e = ha.ArgExpr; Type argType = e.HasClrType && e.ClrType != null && e.ClrType.IsPrimitive ? e.ClrType : typeof(object); switch (ha.ParamType) { case HostArg.ParameterType.ByRef: { Type byRefType = argType.MakeByRefType(); paramExprs.Add(Expression.Parameter(byRefType, ha.LocalBinding.Name)); paramTypes.Add(byRefType); break; } case HostArg.ParameterType.Standard: if (argType.IsPrimitive && ha.ArgExpr is MaybePrimitiveExpr) { paramExprs.Add(Expression.Parameter(argType, ha.LocalBinding != null ? ha.LocalBinding.Name : "__temp_" + i)); paramTypes.Add(argType); } else { paramExprs.Add(Expression.Parameter(typeof(object), ha.LocalBinding != null ? ha.LocalBinding.Name : "__temp_" + i)); paramTypes.Add(typeof(object)); } break; default: throw Util.UnreachableCode(); } } // Build dynamic call and lambda Type returnType = HasClrType ? ClrType : typeof(object); CreateInstanceBinder binder = new ClojureCreateInstanceBinder(ClojureContext.Default, _args.Count); DynamicExpression dyn = Expression.Dynamic(binder, typeof(object), paramExprs); MethodExpr.EmitDynamicCallPreamble(dyn, _spanMap, "__interop_ctor_" + RT.nextID(), returnType, paramExprs, paramTypes.ToArray(), ilg, out LambdaExpression lambda, out Type delType, out MethodBuilder mbLambda); // Emit target + args EmitTargetExpression(objx, ilg); i = 0; foreach (HostArg ha in _args) { i++; Expr e = ha.ArgExpr; Type argType = e.HasClrType && e.ClrType != null && e.ClrType.IsPrimitive ? e.ClrType : typeof(object); switch (ha.ParamType) { case HostArg.ParameterType.ByRef: MethodExpr.EmitByRefArg(ha, objx, ilg); break; case HostArg.ParameterType.Standard: if (argType.IsPrimitive && ha.ArgExpr is MaybePrimitiveExpr expr) { expr.EmitUnboxed(RHC.Expression, objx, ilg); } else { ha.ArgExpr.Emit(RHC.Expression, objx, ilg); } break; default: throw Util.UnreachableCode(); } } MethodExpr.EmitDynamicCallPostlude(lambda, delType, mbLambda, ilg); }
public Expr Parse(ParserContext pcon, object form) { ISeq sform = (ISeq)form; // form is one of: // (. x fieldname-sym) // (. x 0-ary-method) // (. x propertyname-sym) // (. x methodname-sym args)+ // (. x (methodname-sym args?)) // (. x (generic-m if (RT.Length(sform) < 3) { throw new ParseException("Malformed member expression, expecting (. target member ... )"); } string source = (string)Compiler.SourceVar.deref(); IPersistentMap spanMap = (IPersistentMap)Compiler.SourceSpanVar.deref(); // Compiler.GetSourceSpanMap(form); Symbol tag = Compiler.TagOf(sform); // determine static or instance // static target must be symbol, either fully.qualified.Typename or Typename that has been imported Type t = HostExpr.MaybeType(RT.second(sform), false); // at this point, t will be non-null if static Expr instance = null; if (t == null) { instance = Compiler.Analyze(pcon.EvalOrExpr(), RT.second(sform)); } bool isZeroArityCall = RT.Length(sform) == 3 && RT.third(sform) is Symbol; if (isZeroArityCall) { PropertyInfo pinfo = null; FieldInfo finfo = null; // TODO: Figure out if we want to handle the -propname otherwise. bool isPropName = false; Symbol sym = (Symbol)RT.third(sform); if (sym.Name[0] == '-') { isPropName = true; sym = Symbol.intern(sym.Name.Substring(1)); } string fieldName = Compiler.munge(sym.Name); // The JVM version does not have to worry about Properties. It captures 0-arity methods under fields. // We have to put in special checks here for this. // Also, when reflection is required, we have to capture 0-arity methods under the calls that // are generated by StaticFieldExpr and InstanceFieldExpr. if (t != null) { if ((finfo = Reflector.GetField(t, fieldName, true)) != null) { return(new StaticFieldExpr(source, spanMap, tag, t, fieldName, finfo)); } if ((pinfo = Reflector.GetProperty(t, fieldName, true)) != null) { return(new StaticPropertyExpr(source, spanMap, tag, t, fieldName, pinfo)); } if (!isPropName && Reflector.GetArityZeroMethod(t, fieldName, true) != null) { return(new StaticMethodExpr(source, spanMap, tag, t, fieldName, null, new List <HostArg>())); } throw new MissingMemberException(t.Name, fieldName); } else if (instance != null && instance.HasClrType && instance.ClrType != null) { Type instanceType = instance.ClrType; if ((finfo = Reflector.GetField(instanceType, fieldName, false)) != null) { return(new InstanceFieldExpr(source, spanMap, tag, instance, fieldName, finfo)); } if ((pinfo = Reflector.GetProperty(instanceType, fieldName, false)) != null) { return(new InstancePropertyExpr(source, spanMap, tag, instance, fieldName, pinfo)); } if (!isPropName && Reflector.GetArityZeroMethod(instanceType, fieldName, false) != null) { return(new InstanceMethodExpr(source, spanMap, tag, instance, fieldName, null, new List <HostArg>())); } if (pcon.IsAssignContext) { return(new InstanceFieldExpr(source, spanMap, tag, instance, fieldName, null)); // same as InstancePropertyExpr when last arg is null } else { return(new InstanceZeroArityCallExpr(source, spanMap, tag, instance, fieldName)); } } else { // t is null, so we know this is not a static call // If instance is null, we are screwed anyway. // If instance is not null, then we don't have a type. // So we must be in an instance call to a property, field, or 0-arity method. // The code generated by InstanceFieldExpr/InstancePropertyExpr with a null FieldInfo/PropertyInfo // will generate code to do a runtime call to a Reflector method that will check all three. //return new InstanceFieldExpr(source, spanMap, tag, instance, fieldName, null); // same as InstancePropertyExpr when last arg is null //return new InstanceZeroArityCallExpr(source, spanMap, tag, instance, fieldName); if (pcon.IsAssignContext) { return(new InstanceFieldExpr(source, spanMap, tag, instance, fieldName, null)); // same as InstancePropertyExpr when last arg is null } else { return(new InstanceZeroArityCallExpr(source, spanMap, tag, instance, fieldName)); } } } //ISeq call = RT.third(form) is ISeq ? (ISeq)RT.third(form) : RT.next(RT.next(form)); ISeq call; List <Type> typeArgs = null; object fourth = RT.fourth(sform); if (fourth is ISeq && RT.first(fourth) is Symbol && ((Symbol)RT.first(fourth)).Equals(TypeArgsSym)) { // We have a type args supplied for a generic method call // (. thing methodname (type-args type1 ... ) args ...) typeArgs = ParseGenericMethodTypeArgs(RT.next(fourth)); call = RT.listStar(RT.third(sform), RT.next(RT.next(RT.next(RT.next(sform))))); } else { call = RT.third(sform) is ISeq ? (ISeq)RT.third(sform) : RT.next(RT.next(sform)); } if (!(RT.first(call) is Symbol)) { throw new ParseException("Malformed member exception"); } string methodName = Compiler.munge(((Symbol)RT.first(call)).Name); List <HostArg> args = ParseArgs(pcon, RT.next(call)); return(t != null ? (MethodExpr)(new StaticMethodExpr(source, spanMap, tag, t, methodName, typeArgs, args)) : (MethodExpr)(new InstanceMethodExpr(source, spanMap, tag, instance, methodName, typeArgs, args))); }