Пример #1
0
 public IfExpr( IPersistentMap sourceSpan, Expr testExpr, Expr thenExpr, Expr elseExpr)
 {
     _sourceSpan = sourceSpan;
     _testExpr = testExpr;
     _thenExpr = thenExpr;
     _elseExpr = elseExpr;
 }
Пример #2
0
 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));
     }
 }
Пример #3
0
        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;
        }
Пример #4
0
 public IfExpr(int line, Expr testExpr, Expr thenExpr, Expr elseExpr)
 {
     _line = line;
     _testExpr = testExpr;
     _thenExpr = thenExpr;
     _elseExpr = elseExpr;
 }
Пример #5
0
 public DefExpr(Var var, Expr init, Expr meta, bool initProvided)
 {
     _var = var;
     _init = init;
     _meta = meta;
     _initProvided = initProvided;
 }
Пример #6
0
#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;
        }
Пример #7
0
        public InstanceMethodExpr(Expr target, string methodName, IPersistentVector args)
        {
            _target = target;
            _methodName = methodName;
            _args = args;

            _method = GetMatchingMethod(target, _args, _methodName);
        }
Пример #8
0
 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);
 }
Пример #9
0
 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);
 }
Пример #10
0
 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);
 }
Пример #11
0
 public TryExpr(Expr tryExpr, IPersistentVector catchExprs, Expr finallyExpr, int retLocal, int finallyLocal)
 {
     _tryExpr = tryExpr;
     _catchExprs = catchExprs;
     _finallyExpr = finallyExpr;
     _retLocal = retLocal;
     _finallyLocal = finallyLocal;
 }
Пример #12
0
 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);
 }
Пример #13
0
 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);
     }
 }
Пример #14
0
 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);
        }
Пример #17
0
        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); 
        }
Пример #19
0
 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;
 }
Пример #20
0
        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);
        }
Пример #21
0
        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);
        }
Пример #23
0
 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;
 }
Пример #24
0
        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;
        }
Пример #25
0
        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);
        }
Пример #26
0
        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);
        }
Пример #27
0
 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;
     }
 }
Пример #28
0
 public InstanceFieldExpr(string source, IPersistentMap spanMap, Symbol tag, Expr target, string fieldName, FieldInfo finfo)
     : base(source, spanMap, tag, target, fieldName, finfo)
 {
 }
Пример #29
0
        /// <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;
        }
Пример #30
0
 public abstract Expression GenAssign(RHC rhc, ObjExpr objx, GenContext context, Expr val);
Пример #31
0
 public abstract object EvalAssign(Expr val);
Пример #32
0
 public InstancePropertyExpr(string source, IPersistentMap spanMap, Symbol tag, Expr target, string fieldName, PropertyInfo pinfo)
     : base(source, spanMap, tag, target, fieldName, pinfo)
 {
 }
Пример #33
0
        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);
            }
        }
Пример #34
0
 public abstract void EmitAssign(RHC rhc, ObjExpr objx, CljILGen ilg, Expr val);
Пример #35
0
        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));
        }
Пример #36
0
        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)))));
            }
        }
Пример #37
0
        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;
            }
        }
Пример #38
0
        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);
        }
Пример #39
0
        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);
        }
Пример #40
0
            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)));
            }
Пример #41
0
 public abstract object EvalAssign(Expr val);