Пример #1
1
 public NewExpr(Type type, List<HostArg> args, IPersistentMap spanMap)
 {
     _args = args;
     _type = type;
     _spanMap = spanMap;
     _ctor = ComputeCtor();
 }
Пример #2
0
 public RecurExpr(string source, IPersistentMap spanMap, IPersistentVector loopLocals, IPersistentVector args)
 {
     _loopLocals = loopLocals;
     _args = args;
     _source = source;
     _spanMap = spanMap;
 }
Пример #3
0
 /// <summary>
 /// Construct a symbol from interned namespace name and symbol name,  with given metadata.
 /// </summary>
 /// <param name="meta">The metadata to attach.</param>
 /// <param name="ns_interned">The (interned) namespace name.</param>
 /// <param name="name_interned">The (interned) symbol name.</param>
 private Symbol(IPersistentMap meta, string ns_interned, string name_interned)
     : base(meta)
 {
     this._name = name_interned;
     this._ns = ns_interned;
     this._hash = ComputeHashCode();
 }
Пример #4
0
        public static IPersistentMap ExtractAttributes(IPersistentMap meta)
        {
            if (meta != null && EXTRACT_ATTRIBUTES.isBound)
                return (IPersistentMap)EXTRACT_ATTRIBUTES.invoke(meta);

            return PersistentArrayMap.EMPTY;
        }
Пример #5
0
 /// <summary>
 /// Initialize from given metatadata, plus first, restFn, rest.
 /// </summary>
 /// <param name="meta">The metadata to attach</param>
 /// <param name="first">The first of the sequence.</param>
 /// <param name="restFn">The function to generate the next value.</param>
 /// <param name="rest">The rest of the sequence..</param>
 FnSeq(IPersistentMap meta, object first, IFn restFn, ISeq rest)
     : base(meta)
 {
     _first = first;
     _restFn = restFn;
     _rest = rest;
 }
Пример #6
0
 public IfExpr( IPersistentMap sourceSpan, Expr testExpr, Expr thenExpr, Expr elseExpr)
 {
     _sourceSpan = sourceSpan;
     _testExpr = testExpr;
     _thenExpr = thenExpr;
     _elseExpr = elseExpr;
 }
Пример #7
0
 /// <summary>
 /// Create a copy with new metadata.
 /// </summary>
 /// <param name="meta">The new metadata.</param>
 /// <returns>A copy of the object with new metadata attached.</returns>
 public override IObj withMeta(IPersistentMap meta)
 {
     // Java doesn't make the identity test: return new Cons(meta, _first, _rest);
     return (meta == _meta)
         ? this
         : new Cons(meta, _first, _more);
 }
Пример #8
0
 internal static IFn CreateForMetaAlter(IPersistentMap meta)
 {
     AFnImpl fn = new AFnImpl();
     fn._fn0 = () => { return meta; };
     fn._fn1 = (object x) => { return meta; };
     return fn;
 }
Пример #9
0
 internal PersistentList(object first, IPersistentList rest, int count, IPersistentMap metadata)
     : base(metadata)
 {
     this.first = first;
     this.rest = rest;
     this.count = count;
 }
Пример #10
0
 private Keyword(string ns, string name, IPersistentMap metadata)
     : base(metadata)
 {
     this.ns = ns;
     this.name = name;
     this.hash = Utilities.CombineHash(name.GetHashCode(), Utilities.Hash(ns));
 }
Пример #11
0
        public static Expr Parse(ParserContext pcon, IPersistentMap form)
        {
            ParserContext pconToUse = pcon.EvEx();
            bool constant = true;

            IPersistentVector keyvals = PersistentVector.EMPTY;
            for (ISeq s = RT.seq(form); s != null; s = s.next())
            {
                IMapEntry e = (IMapEntry)s.first();
                Expr k = Compiler.Analyze(pconToUse, e.key());
                Expr v = Compiler.Analyze(pconToUse, e.val());
                keyvals = (IPersistentVector)keyvals.cons(k);
                keyvals = (IPersistentVector)keyvals.cons(v);
                if (!(k is LiteralExpr && v is LiteralExpr))
                    constant = false;
            }
            Expr ret = new MapExpr(keyvals);
            if (form is IObj && ((IObj)form).meta() != null)
                return Compiler.OptionallyGenerateMetaInit(pcon, form, ret);
            else if (constant)
            {
                IPersistentMap m = PersistentHashMap.EMPTY;
                for (int i = 0; i < keyvals.length(); i += 2)
                    m = m.assoc(((LiteralExpr)keyvals.nth(i)).Val, ((LiteralExpr)keyvals.nth(i + 1)).Val);
                return new ConstantExpr(m);
            }
            else
                return ret;
        }
Пример #12
0
        public static Expr Parse(ParserContext pcon, IPersistentMap form)
        {
            ParserContext pconToUse = pcon.EvEx();
            bool constant = true;

            IPersistentVector keyvals = PersistentVector.EMPTY;

            for (ISeq s = RT.seq(form); s != null; s = s.next())
            {
                IMapEntry e = (IMapEntry)s.first();
                Expr k = Compiler.Analyze(pconToUse, e.key());
                Expr v = Compiler.Analyze(pconToUse, e.val());
                keyvals = (IPersistentVector)keyvals.cons(k);
                keyvals = (IPersistentVector)keyvals.cons(v);
                if (!(k is LiteralExpr && v is LiteralExpr))
                    constant = false;
            }
            Expr ret = new MapExpr(keyvals);

            if (form is IObj && ((IObj)form).meta() != null)
                return Compiler.OptionallyGenerateMetaInit(pcon, form, ret);
            else if (constant)
            {
                // This 'optimzation' works, mostly, unless you have nested map values.
                // The nested map values do not participate in the constants map, so you end up with the code to create the keys.
                // Result: huge duplication of keyword creation.  3X increase in init time to the REPL.
                //IPersistentMap m = PersistentHashMap.EMPTY;
                //for (int i = 0; i < keyvals.length(); i += 2)
                //    m = m.assoc(((LiteralExpr)keyvals.nth(i)).Val, ((LiteralExpr)keyvals.nth(i + 1)).Val);
                //return new ConstantExpr(m);
                return ret;
            }
            else
                return ret;
        }
Пример #13
0
        public static IPersistentList Create(IList list, IPersistentMap metadata)
        {
            if (list == null || list.Count == 0)
                return EmptyList.Instance;

            return new ListObject(list, 0, metadata);
        }
Пример #14
0
 /// <summary>
 /// Construct a <see cref="StreamSeq">StreamSeq</see> from metadata and first/rest.
 /// </summary>
 /// <param name="meta">The metadata to attach</param>
 /// <param name="first">The first item.</param>
 /// <param name="rest">The rest of the sequence.</param>
 StreamSeq(IPersistentMap meta, Object first, ISeq rest)
     : base(meta)
 {
     _first = first;
     _rest = rest;
     _stream = null;
 }
Пример #15
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;
        }
Пример #16
0
 /// <summary>
 /// Initialize a struct from given data.
 /// </summary>
 /// <param name="meta">The metadata to attach.</param>
 /// <param name="def">The structure definition.</param>
 /// <param name="vals">Values for the fixed keys.</param>
 /// <param name="ext">Additional keys/values.</param>
 protected PersistentStructMap(IPersistentMap meta, Def def, Object[] vals, IPersistentMap ext)
     : base(meta)
 {
     _ext = ext;
     _def = def;
     _vals = vals;
 }
Пример #17
0
 /// <summary>
 /// Initialize a list with given metadata, first element and rest of list.
 /// </summary>
 /// <param name="meta">The metadata to attach.</param>
 /// <param name="first">The first element in the list.</param>
 /// <param name="rest">The rest of the list.</param>
 /// <param name="count">The number of elements in the list.</param>
 PersistentList(IPersistentMap meta, Object first, IPersistentList rest, int count)
     : base(meta)
 {
     this._first = first;
     this._rest = rest;
     this._count = count;
 }
Пример #18
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));
     }
 }
Пример #19
0
        public override IObject WithMetadata(IPersistentMap metadata)
        {
            if (this.Metadata == metadata)
                return this;

            return new Cons(this.first, this.rest, metadata);
        }
Пример #20
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;
        }
Пример #21
0
 /// <summary>
 /// Initialize a <see cref="PersistentVector">PersistentVector</see> from basic components.
 /// </summary>
 /// <param name="cnt"></param>
 /// <param name="shift"></param>
 /// <param name="root"></param>
 /// <param name="tail"></param>
 public PersistentVector(int cnt, int shift, Node root, object[] tail)
 {
     _meta = null;
     _cnt = cnt;
     _shift = shift;
     _root = root;
     _tail = tail;
 }
Пример #22
0
        private PersistentVector(IPersistentMap metadata, List<object[]> root, object[] tail)
            : base(metadata)
        {
            this.root = root;
            this.tail = tail;

            this.count = (tail == null ? 0 : tail.Length) + (root == null ? 0 : root.Count * NodeSize);
        }
Пример #23
0
 public ExceptionInfo(String s, IPersistentMap data, Exception innerException)
     : base(s, innerException)
 {
     if (data != null)
         this.data = data;
     else
         throw new ArgumentException("Additional data must be non-nil.", "data");
 }
Пример #24
0
 protected MethodExpr(string source, IPersistentMap spanMap, Symbol tag, string methodName, List<HostArg> args)
 {
     _source = source;
     _spanMap = spanMap;
     _methodName = methodName;
     _args = args;
     _tag = tag;
 }
Пример #25
0
 private EnumeratorSequence(IEnumerator enumerator, object first, ISequence rest, IPersistentMap metadata)
     : base(metadata)
 {
     this.enumerator = enumerator;
     this.first = first;
     this.rest = rest;
     this.restWasCalculated = true;
 }
Пример #26
0
 /// <summary>
 /// Construct a symbol from interned namespace name and symbol name.
 /// </summary>
 /// <param name="ns_interned">The (interned) namespace name.</param>
 /// <param name="name_interned">The (interned) symbol name.</param>
 private Symbol(string ns_interned, string name_interned)
     : base()
 {
     _meta = null;
     _name = name_interned;
     _ns = ns_interned;
     _hash = ComputeHashCode();
 }
Пример #27
0
 /// <summary>
 /// Initialize a <see cref="PersistentHashMap">PersistentHashMap</see> with a given count and root node.
 /// </summary>
 /// <param name="count">The count.</param>
 /// <param name="root">The root node.</param>
 /// <param name="hasNull"></param>
 /// <param name="nullValue"></param>
 PersistentHashMap(int count, INode root, bool hasNull, object nullValue)
 {
     _meta = null;
     _count = count;
     _root = root;
     _hasNull = hasNull;
     _nullValue = nullValue;
 }
Пример #28
0
 /// <summary>
 /// Initialize a <see cref="PersistentVector">PersistentVector</see> from given metadata and basic components.
 /// </summary>
 /// <param name="meta"></param>
 /// <param name="cnt"></param>
 /// <param name="shift"></param>
 /// <param name="root"></param>
 /// <param name="tail"></param>
 PersistentVector(IPersistentMap meta, int cnt, int shift, Node root, object[] tail)
 {
     _meta = meta;
     _cnt = cnt;
     _shift = shift;
     _root = root;
     _tail = tail;
 }
Пример #29
0
 ArraySeq(IPersistentMap meta, object array, int i)
     : base(meta)
 {
     _a = array;
     _i = i;
     _oa = (object[])(array is object[] ? array : null);
     _ilist = (IList)_a;
 }
Пример #30
0
 private Cycle(IPersistentMap meta, ISeq all, ISeq prev, ISeq current, ISeq next)
     :base(meta)
 {
     _all = all;
     _prev = prev;
     _current = current;
     _next = next;
 }
Пример #31
0
 /// <summary>
 /// Initialize a <see cref="PersistentHashSet">PersistentHashSet</see> to use given metadata and underlying map.
 /// </summary>
 /// <param name="meta">The metadata to attach.</param>
 /// <param name="impl">The implementating map.</param>
 PersistentHashSet(IPersistentMap meta, IPersistentMap impl)
     : base(meta, impl)
 {
 }
Пример #32
0
        /// <summary>
        /// Get the method for a dispatch value and cache it.
        /// </summary>
        /// <param name="dispatchVal">The disaptch value.</param>
        /// <returns>The mest method.</returns>
        private IFn FindAndCacheBestMethod(object dispatchVal)
        {
            _rw.EnterWriteLock();
            object         bestValue;
            IPersistentMap mt = _methodTable;
            IPersistentMap pt = _preferTable;
            object         ch = _cachedHierarchy;

            try
            {
                IMapEntry bestEntry = null;

                foreach (IMapEntry me in MethodTable)
                {
                    if (IsA(dispatchVal, me.key()))
                    {
                        if (bestEntry == null || Dominates(me.key(), bestEntry.key()))
                        {
                            bestEntry = me;
                        }
                        if (!Dominates(bestEntry.key(), me.key()))
                        {
                            throw new ArgumentException(String.Format("Multiple methods in multimethod {0} match dispatch value: {1} -> {2} and {3}, and neither is preferred",
                                                                      _name, dispatchVal, me.key(), bestEntry.key()));
                        }
                    }
                }
                if (bestEntry == null)
                {
                    bestValue = _methodTable.valAt(_defaultDispatchVal);
                    if (bestValue == null)
                    {
                        return(null);
                    }
                }
                else
                {
                    bestValue = bestEntry.val();
                }
            }
            finally
            {
                _rw.ExitWriteLock();
            }

            // ensure basis has stayed stable throughout, else redo
            _rw.EnterWriteLock();
            try
            {
                if (mt == _methodTable &&
                    pt == _preferTable &&
                    ch == _cachedHierarchy &&
                    _cachedHierarchy == _hierarchy.deref())
                {
                    // place in cache
                    _methodCache = _methodCache.assoc(dispatchVal, bestValue);
                    return((IFn)bestValue);
                }
                else
                {
                    ResetCache();
                    return(FindAndCacheBestMethod(dispatchVal));
                }
            }
            finally
            {
                _rw.ExitWriteLock();
            }
        }
Пример #33
0
 /// <summary>
 /// Initializes an <see cref="ASeq">ASeq</see> with given metadata.
 /// </summary>
 /// <param name="meta"></param>
 protected ASeq(IPersistentMap meta)
     : base(meta)
 {
 }
Пример #34
0
 /// <summary>
 /// Create a copy with new metadata.
 /// </summary>
 /// <param name="meta">The new metadata.</param>
 /// <returns>A copy of the object with new metadata attached.</returns>
 public IObj withMeta(IPersistentMap meta)
 {
     return(meta == _meta
         ? this
         : new PersistentTreeSet(meta, _impl));
 }
Пример #35
0
 public IObj withMeta(IPersistentMap meta)
 {
     // Java version does not do identity check
     return(new PersistentVector(meta, _cnt, _shift, _root, _tail));
 }
Пример #36
0
 protected AFunctionMeta(IPersistentMap meta)
 {
     _meta = meta;
 }
Пример #37
0
            public Expr Parse(ParserContext pcon, object form)
            {
                // (def x) or (def x initexpr) or (def x "docstring" initexpr)
                string docstring = null;

                if (RT.count(form) == 4 && (RT.third(form) is String))
                {
                    docstring = (String)RT.third(form);
                    form      = RT.list(RT.first(form), RT.second(form), RT.fourth(form));
                }

                if (RT.count(form) > 3)
                {
                    throw new ParseException("Too many arguments to def");
                }

                if (RT.count(form) < 2)
                {
                    throw new ParseException("Too few arguments to def");
                }

                Symbol sym = RT.second(form) as Symbol;

                if (sym == null)
                {
                    throw new ParseException("First argument to def must be a Symbol.");
                }

                //Console.WriteLine("Def {0}", sym.Name);

                Var v = Compiler.LookupVar(sym, true);

                if (v == null)
                {
                    throw new ParseException("Can't refer to qualified var that doesn't exist");
                }

                if (!v.Namespace.Equals(Compiler.CurrentNamespace))
                {
                    if (sym.Namespace == null)
                    {
                        v = Compiler.CurrentNamespace.intern(sym);
                    }

                    //throw new Exception(string.Format("Name conflict, can't def {0} because namespace: {1} refers to: {2}",
                    //            sym, Compiler.CurrentNamespace.Name, v));
                    else
                    {
                        throw new ParseException("Can't create defs outside of current namespace");
                    }
                }

                IPersistentMap mm        = sym.meta();
                bool           isDynamic = RT.booleanCast(RT.get(mm, Compiler.DynamicKeyword));

                if (isDynamic)
                {
                    v.setDynamic();
                }
                if (!isDynamic && sym.Name.StartsWith("*") && sym.Name.EndsWith("*") && sym.Name.Length > 1)
                {
                    RT.errPrintWriter().WriteLine("Warning: {0} not declared dynamic and thus is not dynamically rebindable, "
                                                  + "but its name suggests otherwise. Please either indicate ^:dynamic {0} or change the name. ({1}:{2}\n",
                                                  sym, Compiler.SourcePathVar.get(), Compiler.LineVar.get());
                }

                if (RT.booleanCast(RT.get(mm, Compiler.ArglistsKeyword)))
                {
                    IPersistentMap vm = v.meta();
                    //vm = (IPersistentMap)RT.assoc(vm, Compiler.STATIC_KEY, true);
                    // drop quote
                    vm = (IPersistentMap)RT.assoc(vm, Compiler.ArglistsKeyword, RT.second(mm.valAt(Compiler.ArglistsKeyword)));
                    v.setMeta(vm);
                }

                Object source_path = Compiler.SourcePathVar.get();

                source_path = source_path ?? "NO_SOURCE_FILE";
                mm          = (IPersistentMap)RT.assoc(mm, RT.LineKey, Compiler.LineVar.get())
                              .assoc(RT.ColumnKey, Compiler.ColumnVar.get())
                              .assoc(RT.FileKey, source_path);
                //.assoc(RT.SOURCE_SPAN_KEY,Compiler.SOURCE_SPAN.deref());
                if (docstring != null)
                {
                    mm = (IPersistentMap)RT.assoc(mm, RT.DocKey, docstring);
                }

                //  Following comment in JVM version
                //mm = mm.without(RT.DOC_KEY)
                //            .without(Keyword.intern(null, "arglists"))
                //            .without(RT.FILE_KEY)
                //            .without(RT.LINE_KEY)
                //            .without(RT.COLUMN_KEY)
                //            .without(Keyword.intern(null, "ns"))
                //            .without(Keyword.intern(null, "name"))
                //            .without(Keyword.intern(null, "added"))
                //            .without(Keyword.intern(null, "static"));

                mm = (IPersistentMap)Compiler.ElideMeta(mm);

                Expr meta         = mm == null || mm.count() == 0 ? null : Compiler.Analyze(pcon.EvalOrExpr(), mm);
                Expr init         = Compiler.Analyze(pcon.EvalOrExpr(), RT.third(form), v.Symbol.Name);
                bool initProvided = RT.count(form) == 3;

                return(new DefExpr(
                           (string)Compiler.SourceVar.deref(),
                           (int)Compiler.LineVar.deref(),
                           (int)Compiler.ColumnVar.deref(),
                           v, init, meta, initProvided, isDynamic));
            }
Пример #38
0
 public void SetLocals(IPersistentMap locals, IPersistentMap indexLocals)
 {
     Locals      = locals;
     IndexLocals = indexLocals;
 }
Пример #39
0
 /// <summary>
 /// Create a copy with new metadata.
 /// </summary>
 /// <param name="meta">The new metadata.</param>
 /// <returns>A copy of the object with new metadata attached.</returns>
 public override IObj withMeta(IPersistentMap meta)
 {
     return(meta == _meta
         ? this
         : new PersistentArrayMap(meta, _array));
 }
Пример #40
0
 public ArraySeq_sbyte(IPersistentMap meta, sbyte[] array, int index)
     : base(meta, array, index)
 {
 }
Пример #41
0
 public NumericArraySeq(IPersistentMap meta, T[] array, int index)
     : base(meta, array, index)
 {
 }
Пример #42
0
 public override IObj withMeta(IPersistentMap meta)
 {
     return(DuplicateWithMeta(meta));
 }
Пример #43
0
 public InstancePropertyExpr(string source, IPersistentMap spanMap, Symbol tag, Expr target, string propertyName, PropertyInfo pinfo)
     : base(source, spanMap, tag, target, propertyName, pinfo)
 {
 }
Пример #44
0
 public override IObj withMeta(IPersistentMap meta)
 {
     return((meta == _meta)
         ? this
         : new ChunkedSeq(meta, _vec, _node, _i, _offset));
 }
Пример #45
0
 public override IObj withMeta(IPersistentMap meta)
 {
     throw new NotImplementedException();
 }
Пример #46
0
 public InstanceFieldExpr(string source, IPersistentMap spanMap, Symbol tag, Expr target, string fieldName, FieldInfo finfo)
     : base(source, spanMap, tag, target, fieldName, finfo)
 {
 }
Пример #47
0
        static public void EmitDynamicCallPreamble(DynamicExpression dyn, IPersistentMap spanMap, string methodName, Type returnType, IList <ParameterExpression> paramExprs, Type[] paramTypes, CljILGen ilg, out LambdaExpression lambda, out Type delType, out MethodBuilder mbLambda)
        {
            Expression call = dyn;

            GenContext context = Compiler.CompilerContextVar.deref() as GenContext;

            DynInitHelper.SiteInfo siteInfo;
            if (context != null && context.DynInitHelper != null)
            {
                call = context.DynInitHelper.ReduceDyn(dyn, out siteInfo);
            }
            else
            {
                throw new InvalidOperationException("Don't know how to handle callsite in this case");
            }

            if (returnType == typeof(void))
            {
                call       = Expression.Block(call, Expression.Default(typeof(object)));
                returnType = typeof(object);
            }
            else if (returnType != call.Type)
            {
                call = Expression.Convert(call, returnType);
            }

            call = GenContext.AddDebugInfo(call, spanMap);


            delType  = Microsoft.Scripting.Generation.Snippets.Shared.DefineDelegate("__interop__", returnType, paramTypes);
            lambda   = Expression.Lambda(delType, call, paramExprs);
            mbLambda = null;

            if (context == null)
            {
                // light compile

                Delegate d   = lambda.Compile();
                int      key = RT.nextID();
                CacheDelegate(key, d);

                ilg.EmitInt(key);
                ilg.Emit(OpCodes.Call, Method_MethodExpr_GetDelegate);
                ilg.Emit(OpCodes.Castclass, delType);
            }
            else
            {
                mbLambda = context.TB.DefineMethod(methodName, MethodAttributes.Static | MethodAttributes.Public, CallingConventions.Standard, returnType, paramTypes);
                //lambda.CompileToMethod(mbLambda);
                // Now we get to do all this code create by hand.
                // the primary code is
                // (loc1 = fb).Target.Invoke(loc1,*args);
                // if return type if void, pop the value and push a null
                // if return type does not match the call site, add a conversion
                CljILGen ilg2 = new CljILGen(mbLambda.GetILGenerator());
                ilg2.EmitFieldGet(siteInfo.FieldBuilder);
                ilg2.Emit(OpCodes.Dup);
                LocalBuilder siteVar = ilg2.DeclareLocal(siteInfo.DelegateType);
                ilg2.Emit(OpCodes.Stloc, siteVar);
                ilg2.EmitFieldGet(siteInfo.SiteType.GetField("Target"));
                ilg2.Emit(OpCodes.Ldloc, siteVar);
                for (int i = 0; i < paramExprs.Count; i++)
                {
                    ilg2.EmitLoadArg(i);
                }

                ilg2.EmitCall(siteInfo.DelegateType.GetMethod("Invoke"));
                if (returnType == typeof(void))
                {
                    ilg2.Emit(OpCodes.Pop);
                    ilg2.EmitNull();
                }
                else if (returnType != call.Type)
                {
                    EmitConvertToType(ilg2, call.Type, returnType, false);
                }

                ilg2.Emit(OpCodes.Ret);


                /*
                 *             return Expression.Block(
                 * new[] { site },
                 * Expression.Call(
                 * Expression.Field(
                 *  Expression.Assign(site, access),
                 *  cs.GetType().GetField("Target")
                 * ),
                 * node.DelegateType.GetMethod("Invoke"),
                 * ClrExtensions.ArrayInsert(site, node.Arguments)
                 * )
                 */
            }
        }
Пример #48
0
 public AFunctionMeta()
 {
     _meta = null;
 }
Пример #49
0
        private static void EmitExposers(TypeBuilder proxyTB, Type superClass, IPersistentMap exposesFields)
        {
            for (ISeq s = RT.seq(exposesFields); s != null; s = s.next())
            {
                IMapEntry      me = (IMapEntry)s.first();
                Symbol         protectedFieldSym = (Symbol)me.key();
                IPersistentMap accessMap         = (IPersistentMap)me.val();

                string fieldName = protectedFieldSym.Name;
                Symbol getterSym = (Symbol)accessMap.valAt(_getKw, null);
                Symbol setterSym = (Symbol)accessMap.valAt(_setKW, null);

                FieldInfo fld = null;

                if (getterSym != null || setterSym != null)
                {
                    fld = superClass.GetField(fieldName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy | BindingFlags.Static | BindingFlags.Instance);
                }


                if (getterSym != null)
                {
                    MethodAttributes attribs = MethodAttributes.Public;
                    if (fld.IsStatic)
                    {
                        attribs |= MethodAttributes.Static;
                    }

                    MethodBuilder mb  = proxyTB.DefineMethod(getterSym.Name, attribs, fld.FieldType, Type.EmptyTypes);
                    CljILGen      gen = new CljILGen(mb.GetILGenerator());
                    //if (fld.IsStatic)
                    //    gen.Emit(OpCodes.Ldsfld, fld);
                    //else
                    //{
                    //    gen.Emit(OpCodes.Ldarg_0);
                    //    gen.Emit(OpCodes.Ldfld, fld);
                    //}
                    if (!fld.IsStatic)
                    {
                        gen.EmitLoadArg(0);
                    }
                    gen.EmitFieldGet(fld);

                    gen.Emit(OpCodes.Ret);
                }

                if (setterSym != null)
                {
                    MethodAttributes attribs = MethodAttributes.Public;
                    if (fld.IsStatic)
                    {
                        attribs |= MethodAttributes.Static;
                    }

                    MethodBuilder mb  = proxyTB.DefineMethod(setterSym.Name, attribs, typeof(void), new Type[] { fld.FieldType });
                    CljILGen      gen = new CljILGen(mb.GetILGenerator());
                    if (fld.IsStatic)
                    {
                        gen.Emit(OpCodes.Ldarg_0);
                        //gen.Emit(OpCodes.Stsfld, fld);
                    }
                    else
                    {
                        gen.Emit(OpCodes.Ldarg_0);
                        gen.Emit(OpCodes.Ldarg_1);
                        //gen.Emit(OpCodes.Stfld, fld);
                    }
                    gen.EmitFieldSet(fld);
                    gen.Emit(OpCodes.Ret);
                }
            }
        }
Пример #50
0
 /// <summary>
 /// Initialize a <see cref="PersistentTreeSet">PersistentTreeSet</see> using given metadata and underlying implementation map.
 /// </summary>
 /// <param name="meta">The metadata to attach</param>
 /// <param name="impl">A map to implement the set.</param>
 PersistentTreeSet(IPersistentMap meta, IPersistentMap impl)
     : base(impl)
 {
     _meta = meta;
 }
Пример #51
0
        static void DefineCtors(TypeBuilder proxyTB,
                                Type superClass,
                                string initName,
                                string postInitName,
                                ISeq ctors,
                                ISeq ctorTypes,
                                FieldBuilder initFB,
                                FieldBuilder postInitFB,
                                FieldBuilder stateFB,
                                string factoryName)
        {
            ISeq s1 = ctors;

            for (ISeq s = ctorTypes; s != null; s = s.next())
            {
                // TODO: Get rid of this mess by making sure the metadata on the keys of the constructors map gets copied to the constructor-types map.  Sigh.
                IPersistentMap ctorAttributes = GenInterface.ExtractAttributes(RT.meta(((IMapEntry)s1.first()).key()));
                s1 = s1.next();

                IMapEntry me = (IMapEntry)s.first();
                ISeq      thisParamTypesV = (ISeq)me.key();
                ISeq      baseParamTypesV = (ISeq)me.val();

                Type[] thisParamTypes = CreateTypeArray(thisParamTypesV);
                Type[] baseParamTypes = CreateTypeArray(baseParamTypesV);

                BindingFlags    flags     = BindingFlags.CreateInstance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance;
                ConstructorInfo superCtor = superClass.GetConstructor(flags, null, baseParamTypes, null);

                if (superCtor == null || superCtor.IsPrivate)
                {
                    throw new InvalidOperationException("Base class constructor missing or private");
                }

                ConstructorBuilder cb = proxyTB.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, thisParamTypes);
                GenInterface.SetCustomAttributes(cb, ctorAttributes);

                CljILGen gen = new CljILGen(cb.GetILGenerator());

                Label noInitLabel      = gen.DefineLabel();
                Label noPostInitLabel  = gen.DefineLabel();
                Label endPostInitLabel = gen.DefineLabel();
                Label endLabel         = gen.DefineLabel();

                LocalBuilder locSuperArgs = gen.DeclareLocal(typeof(object));
                LocalBuilder locInitVal   = gen.DeclareLocal(typeof(object));

                if (initFB != null)
                {
                    // init supplied
                    EmitGetVar(gen, initFB);
                    gen.Emit(OpCodes.Dup);
                    gen.Emit(OpCodes.Brfalse_S, noInitLabel);
                    gen.Emit(OpCodes.Castclass, typeof(IFn));

                    // box init args
                    for (int i = 0; i < thisParamTypes.Length; i++)
                    {
                        gen.EmitLoadArg(i + 1);                     // gen.Emit(OpCodes.Ldarg, i + 1);
                        if (thisParamTypes[i].IsValueType)
                        {
                            gen.Emit(OpCodes.Box, thisParamTypes[i]);
                        }
                    }

                    gen.EmitCall(Compiler.Methods_IFn_invoke[thisParamTypes.Length]);   // gen.Emit(OpCodes.Call, Compiler.Methods_IFn_invoke[thisParamTypes.Length]);

                    // Expecting:  [[super-ctor-args...] state]

                    // store the init return in a local
                    gen.Emit(OpCodes.Dup);
                    gen.Emit(OpCodes.Stloc, locInitVal);

                    // store the first element in a local
                    gen.EmitInt(0);                             // gen.Emit(OpCodes.Ldc_I4_0);
                    gen.EmitCall(Method_RT_nth);                // gen.Emit(OpCodes.Call, Method_RT_nth);
                    gen.Emit(OpCodes.Stloc, locSuperArgs);

                    // Stack this + super-ctor-args + call base-class ctor.
                    gen.EmitLoadArg(0);                         // gen.Emit(OpCodes.Ldarg_0);
                    for (int i = 0; i < baseParamTypes.Length; i++)
                    {
                        gen.Emit(OpCodes.Ldloc, locSuperArgs);
                        gen.EmitInt(i);                         // gen.Emit(OpCodes.Ldc_I4, i);
                        gen.EmitCall(Method_RT_nth);            // gen.Emit(OpCodes.Call, Method_RT_nth);
                        if (baseParamTypes[i].IsValueType)
                        {
                            gen.Emit(OpCodes.Unbox_Any, baseParamTypes[i]);
                        }
                        else
                        {
                            gen.Emit(OpCodes.Castclass, baseParamTypes[i]);
                        }
                    }

                    gen.Emit(OpCodes.Call, superCtor);

                    if (stateFB != null)
                    {
                        gen.EmitLoadArg(0);                     // gen.Emit(OpCodes.Ldarg_0);
                        gen.Emit(OpCodes.Ldloc, locInitVal);
                        gen.EmitInt(1);                         // gen.Emit(OpCodes.Ldc_I4_1);
                        gen.EmitCall(Method_RT_nth);            // gen.Emit(OpCodes.Call, Method_RT_nth);
                        gen.Emit(OpCodes.Castclass, typeof(object));
                        gen.EmitFieldSet(stateFB);              // gen.Emit(OpCodes.Stfld, stateFB);
                    }

                    gen.Emit(OpCodes.Br_S, endLabel);

                    // No init found
                    gen.MarkLabel(noInitLabel);

                    gen.Emit(OpCodes.Pop);
                    EmitUnsupported(gen, initName);

                    gen.MarkLabel(endLabel);
                }
                else  // no InitFB supplied.
                {
                    bool ok = thisParamTypes.Length == baseParamTypes.Length;
                    for (int i = 0; ok && i < thisParamTypes.Length; i++)
                    {
                        ok = baseParamTypes[i].IsAssignableFrom(thisParamTypes[i]);
                    }
                    if (!ok)
                    {
                        throw new InvalidOperationException(":init not specified, but ctor and super ctor args differ");
                    }
                    gen.EmitLoadArg(0);                                 // gen.Emit(OpCodes.Ldarg_0);
                    for (int i = 0; i < thisParamTypes.Length; i++)
                    {
                        gen.EmitLoadArg(i + 1);                         // gen.Emit(OpCodes.Ldarg, i + 1);
                        if (baseParamTypes[i] != thisParamTypes[i])
                        {
                            gen.Emit(OpCodes.Castclass, baseParamTypes[i]);
                        }
                    }
                    gen.Emit(OpCodes.Call, superCtor);
                }

                if (postInitFB != null)
                {
                    // post-init supplied
                    EmitGetVar(gen, postInitFB);
                    gen.Emit(OpCodes.Dup);
                    gen.Emit(OpCodes.Brfalse_S, noPostInitLabel);
                    gen.Emit(OpCodes.Castclass, typeof(IFn));

                    // box init args
                    gen.EmitLoadArg(0);                                 // gen.Emit(OpCodes.Ldarg_0);
                    for (int i = 0; i < thisParamTypes.Length; i++)
                    {
                        gen.EmitLoadArg(i + 1);                         // gen.Emit(OpCodes.Ldarg, i + 1);
                        if (thisParamTypes[i].IsValueType)
                        {
                            gen.Emit(OpCodes.Box, thisParamTypes[i]);
                        }
                        gen.Emit(OpCodes.Castclass, thisParamTypes[i]);
                    }
                    gen.EmitCall(Compiler.Methods_IFn_invoke[thisParamTypes.Length + 1]);   // gen.Emit(OpCodes.Call, Compiler.Methods_IFn_invoke[thisParamTypes.Length + 1]);
                    gen.Emit(OpCodes.Pop);
                    gen.Emit(OpCodes.Br_S, endPostInitLabel);

                    // no post-init found

                    gen.MarkLabel(noPostInitLabel);

                    gen.Emit(OpCodes.Pop);
                    EmitUnsupported(gen, postInitName + " not defined");

                    gen.MarkLabel(endPostInitLabel);
                }

                gen.Emit(OpCodes.Ret);


                if (!String.IsNullOrEmpty(factoryName))
                {
                    MethodBuilder factoryMB = proxyTB.DefineMethod(factoryName, MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, proxyTB, thisParamTypes);
                    CljILGen      genf      = new CljILGen(factoryMB.GetILGenerator());

                    LocalBuilder[] locals = new LocalBuilder[thisParamTypes.Length];
                    for (int i = 0; i < thisParamTypes.Length; i++)
                    {
                        locals[i] = genf.DeclareLocal(thisParamTypes[i]);
                        genf.EmitLoadArg(i);                    // genf.Emit(OpCodes.Ldarg, i);
                        genf.Emit(OpCodes.Stloc, locals[i]);
                    }


                    for (int i = 0; i < thisParamTypes.Length; i++)
                    {
                        genf.EmitLoadArg(i);                    // genf.Emit(OpCodes.Ldarg, i);
                    }
                    genf.EmitNew(cb);                           // genf.Emit(OpCodes.Newobj, cb);
                    genf.Emit(OpCodes.Ret);
                }
            }
        }
Пример #52
0
        public static Type GenerateClass(string className,
                                         Type superClass,
                                         ISeq interfaces, // of Types
                                         ISeq ctors,
                                         ISeq ctorTypes,
                                         ISeq methods,
                                         IPersistentMap exposesFields,
                                         IPersistentMap exposesMethods,
                                         string prefix,
                                         bool hasMain,
                                         string factoryName,
                                         string stateName,
                                         string initName,
                                         string postInitName,
                                         string implCname,
                                         string implNamespace,
                                         bool loadImplNamespace)
        {
            className = className.Replace('-', '_');

            string path = (string)Compiler.CompilePathVar.deref();

            if (path == null)
            {
                throw new InvalidOperationException("*compile-path* not set");
            }

            string extension = hasMain ? ".exe" : ".dll";


            GenContext context = GenContext.CreateWithExternalAssembly(Compiler.munge(path == "." ? className : path + "/" + className), extension, true);

            // define the class
            List <Type> interfaceTypes = new List <Type>();

            for (ISeq s = interfaces; s != null; s = s.next())
            {
                interfaceTypes.Add((Type)s.first());
            }


            TypeBuilder proxyTB = context.ModuleBuilder.DefineType(
                className,
                TypeAttributes.Class | TypeAttributes.Public,
                superClass,
                interfaceTypes.ToArray());

            List <MethodSignature> sigs = GetAllSignatures(superClass, interfaceTypes, methods);
            Dictionary <string, List <MethodSignature> > overloads = ComputeOverloads(sigs);

            HashSet <string> varNames = ComputeOverloadNames(overloads);

            foreach (MethodSignature sig in sigs)
            {
                varNames.Add(sig.Name);
            }

            if (!String.IsNullOrEmpty(initName))
            {
                varNames.Add(initName);
            }
            if (!String.IsNullOrEmpty(postInitName))
            {
                varNames.Add(postInitName);
            }
            if (hasMain)
            {
                varNames.Add(_mainName);
            }

            Dictionary <string, FieldBuilder> varMap = DefineStaticFields(proxyTB, varNames);

            FieldBuilder stateFB = String.IsNullOrEmpty(stateName) ? null : DefineStateField(proxyTB, stateName);

            DefineStaticCtor(proxyTB, prefix, varMap, loadImplNamespace, implNamespace, implCname);

            FieldBuilder initFB     = null;
            FieldBuilder postInitFB = null;
            FieldBuilder mainFB     = null;

            varMap.TryGetValue(initName, out initFB);
            varMap.TryGetValue(postInitName, out postInitFB);
            varMap.TryGetValue(_mainName, out mainFB);

            DefineCtors(proxyTB, superClass,
                        implNamespace + "." + prefix + initName,
                        implNamespace + "." + prefix + postInitName,
                        ctorTypes, initFB, postInitFB, stateFB, factoryName);

            EmitMethods(proxyTB, sigs, overloads, varMap, exposesMethods);
            EmitExposers(proxyTB, superClass, exposesFields);

            if (hasMain)
            {
                EmitMain(context, proxyTB, implNamespace + "." + prefix + _mainName, mainFB);
            }

            Type t = proxyTB.CreateType();

            context.SaveAssembly();

            return(t);
        }
Пример #53
0
 /// <summary>
 /// Initialize the sequence with given metatdata and array/index.
 /// </summary>
 /// <param name="meta">The metadata to attach.</param>
 /// <param name="array">The array being sequenced over.</param>
 /// <param name="i">The current index.</param>
 public Seq(IPersistentMap meta, object[] array, int i)
     : base(meta)
 {
     _array = array;
     _i     = i;
 }
Пример #54
0
        private static void EmitMethods(TypeBuilder proxyTB,
                                        List <MethodSignature> sigs,
                                        Dictionary <string, List <MethodSignature> > overloads,
                                        Dictionary <string, FieldBuilder> varMap,
                                        IPersistentMap exposesMethods)
        {
            foreach (MethodSignature sig in sigs)
            {
                FieldBuilder regularFB  = varMap[sig.Name];
                FieldBuilder overloadFB = null;
                if (overloads.ContainsKey(sig.Name))
                {
                    overloadFB = varMap[OverloadName(sig)];
                }

                switch (sig.Source)
                {
                case "super":
                    EmitForwardingMethod(proxyTB, false, regularFB, overloadFB, sig,
                                         delegate(CljILGen gen)
                    {
                        gen.EmitLoadArg(0);                                     // gen.Emit(OpCodes.Ldarg_0);
                        for (int i = 0; i < sig.ParamTypes.Length; i++)
                        {
                            gen.EmitLoadArg(i + 1);                             // gen.Emit(OpCodes.Ldarg, (i + 1));
                        }
                        gen.Emit(OpCodes.Call, sig.Method);                     // not gen.EmitCall(sig.Method) -- we need call versus callvirt
                    });
                    break;

                case "interface":
                    EmitForwardingMethod(proxyTB, false, regularFB, overloadFB, sig,
                                         delegate(CljILGen gen)
                    {
                        EmitUnsupported(gen, sig.Name);
                    });
                    break;

                default:
                    EmitForwardingMethod(proxyTB, sig.IsStatic, regularFB, overloadFB, sig,
                                         delegate(CljILGen gen)
                    {
                        EmitUnsupported(gen, sig.Name);
                    });
                    break;
                }
            }

            if (exposesMethods != null)
            {
                foreach (MethodSignature sig in sigs)
                {
                    if (sig.Source == "super")
                    {
                        Symbol name = Symbol.intern(sig.Name);
                        if (exposesMethods.containsKey(name))
                        {
                            CreateSuperCall(proxyTB, (Symbol)exposesMethods.valAt(name), sig.Method);
                        }
                    }
                }
            }
        }
Пример #55
0
 public ConcreteAReference(IPersistentMap meta) : base(meta)
 {
 }
Пример #56
0
        public static Expr Parse(ParserContext pcon, ISeq form, string name)
        {
            ISeq origForm = form;

            FnExpr fn = new FnExpr(Compiler.TagOf(form));

            fn.Src = form;

            Keyword   retKey          = Keyword.intern(null, "rettag"); // TODO: make static
            object    retTag          = RT.get(RT.meta(form), retKey);
            ObjMethod enclosingMethod = (ObjMethod)Compiler.MethodVar.deref();

            fn._hasEnclosingMethod = enclosingMethod != null;


            if (((IMeta)form.first()).meta() != null)
            {
                fn.OnceOnly = RT.booleanCast(RT.get(RT.meta(form.first()), KW_ONCE));
            }

            fn.ComputeNames(form, name);

            List <string> prims = new List <string>();

            //arglist might be preceded by symbol naming this fn
            Symbol nm = RT.second(form) as Symbol;

            if (nm != null)
            {
                fn.ThisName = nm.Name;
                form        = RT.cons(Compiler.FnSym, RT.next(RT.next(form)));
            }

            // Normalize body
            //now (fn [args] body...) or (fn ([args] body...) ([args2] body2...) ...)
            //turn former into latter
            if (RT.second(form) is IPersistentVector)
            {
                form = RT.list(Compiler.FnSym, RT.next(form));
            }

            fn.SpanMap = (IPersistentMap)Compiler.SourceSpanVar.deref();

            GenContext newContext = null;

            GenContext context = Compiler.CompilerContextVar.deref() as GenContext ?? Compiler.EvalContext;

            newContext = context.WithNewDynInitHelper(fn.InternalName + "__dynInitHelper_" + RT.nextID().ToString());
            Var.pushThreadBindings(RT.map(Compiler.CompilerContextVar, newContext));


            try
            {
                try
                {
                    Var.pushThreadBindings(RT.mapUniqueKeys(
                                               Compiler.ConstantsVar, PersistentVector.EMPTY,
                                               Compiler.ConstantIdsVar, new IdentityHashMap(),
                                               Compiler.KeywordsVar, PersistentHashMap.EMPTY,
                                               Compiler.VarsVar, PersistentHashMap.EMPTY,
                                               Compiler.KeywordCallsitesVar, PersistentVector.EMPTY,
                                               Compiler.ProtocolCallsitesVar, PersistentVector.EMPTY,
                                               Compiler.VarCallsitesVar, Compiler.EmptyVarCallSites(),
                                               Compiler.NoRecurVar, null));
                    SortedDictionary <int, FnMethod> methods = new SortedDictionary <int, FnMethod>();
                    FnMethod variadicMethod = null;
                    bool     usesThis       = false;

                    for (ISeq s = RT.next(form); s != null; s = RT.next(s))
                    {
                        FnMethod f = FnMethod.Parse(fn, (ISeq)RT.first(s), retTag);
                        if (f.UsesThis)
                        {
                            //Console.WriteLine("{0} uses this",fn.Name);
                            usesThis = true;
                        }
                        if (f.IsVariadic)
                        {
                            if (variadicMethod == null)
                            {
                                variadicMethod = f;
                            }
                            else
                            {
                                throw new ParseException("Can't have more than 1 variadic overload");
                            }
                        }
                        else if (!methods.ContainsKey(f.RequiredArity))
                        {
                            methods[f.RequiredArity] = f;
                        }
                        else
                        {
                            throw new ParseException("Can't have 2 overloads with the same arity.");
                        }
                        if (f.Prim != null)
                        {
                            prims.Add(f.Prim);
                        }
                    }

                    if (variadicMethod != null && methods.Count > 0 && methods.Keys.Max() >= variadicMethod.NumParams)
                    {
                        throw new ParseException("Can't have fixed arity methods with more params than the variadic method.");
                    }

                    fn.CanBeDirect = !fn._hasEnclosingMethod && fn.Closes.count() == 0 && !usesThis;

                    IPersistentCollection allMethods = null;
                    foreach (FnMethod method in methods.Values)
                    {
                        allMethods = RT.conj(allMethods, method);
                    }
                    if (variadicMethod != null)
                    {
                        allMethods = RT.conj(allMethods, variadicMethod);
                    }

                    if (fn.CanBeDirect)
                    {
                        for (ISeq s = RT.seq(allMethods); s != null; s = s.next())
                        {
                            FnMethod fm = s.first() as FnMethod;
                            if (fm.Locals != null)
                            {
                                for (ISeq sl = RT.seq(RT.keys(fm.Locals)); sl != null; sl = sl.next())
                                {
                                    LocalBinding lb = sl.first() as LocalBinding;
                                    if (lb.IsArg)
                                    {
                                        lb.Index -= 1;
                                    }
                                }
                            }
                        }
                    }

                    fn.Methods           = allMethods;
                    fn._variadicMethod   = variadicMethod;
                    fn.Keywords          = (IPersistentMap)Compiler.KeywordsVar.deref();
                    fn.Vars              = (IPersistentMap)Compiler.VarsVar.deref();
                    fn.Constants         = (PersistentVector)Compiler.ConstantsVar.deref();
                    fn.KeywordCallsites  = (IPersistentVector)Compiler.KeywordCallsitesVar.deref();
                    fn.ProtocolCallsites = (IPersistentVector)Compiler.ProtocolCallsitesVar.deref();
                    fn.VarCallsites      = (IPersistentSet)Compiler.VarCallsitesVar.deref();

                    fn.ConstantsID = RT.nextID();
                }
                finally
                {
                    Var.popThreadBindings();
                }


                IPersistentMap fmeta = RT.meta(origForm);
                if (fmeta != null)
                {
                    fmeta = fmeta.without(RT.LineKey).without(RT.ColumnKey).without(RT.SourceSpanKey).without(RT.FileKey).without(retKey);
                }
                fn._hasMeta = RT.count(fmeta) > 0;


                IPersistentVector primTypes = PersistentVector.EMPTY;
                foreach (string typename in prims)
                {
                    primTypes = primTypes.cons(Type.GetType(typename));
                }

                fn.Compile(
                    fn.IsVariadic ? typeof(RestFn) : typeof(AFunction),
                    null,
                    primTypes,
                    fn.OnceOnly,
                    newContext);

                if (fn.SupportsMeta)
                {
                    return(new MetaExpr(fn, MapExpr.Parse(pcon.EvalOrExpr(), fmeta)));
                }
                else
                {
                    return(fn);
                }
            }
            finally
            {
                if (newContext != null)
                {
                    Var.popThreadBindings();
                }
            }
        }
Пример #57
0
        protected void EmitValue(object value, CljILGen ilg)
        {
            bool partial = true;

            if (value == null)
            {
                ilg.Emit(OpCodes.Ldnull);
            }
            else if (value is String)
            {
                ilg.Emit(OpCodes.Ldstr, (String)value);
            }
            else if (value is Boolean)
            {
                ilg.EmitBoolean((Boolean)value);
                ilg.Emit(OpCodes.Box, typeof(bool));
            }
            else if (value is Int32)
            {
                ilg.EmitInt((int)value);
                ilg.Emit(OpCodes.Box, typeof(int));
            }
            else if (value is Int64)
            {
                ilg.EmitLong((long)value);
                ilg.Emit(OpCodes.Box, typeof(long));
            }
            else if (value is Double)
            {
                ilg.EmitDouble((double)value);
                ilg.Emit(OpCodes.Box, typeof(double));
            }
            else if (value is Char)
            {
                ilg.EmitChar((char)value);
                ilg.Emit(OpCodes.Box, typeof(char));
            }
            else if (value is Type)
            {
                Type t = (Type)value;
                if (t.IsValueType)
                {
                    ilg.EmitType(t);
                }
                else
                {
                    //ilg.EmitString(Compiler.DestubClassName(((Type)value).FullName));
                    ilg.EmitString(((Type)value).FullName);
                    ilg.EmitCall(Compiler.Method_RT_classForName);
                }
            }
            else if (value is Symbol)
            {
                Symbol sym = (Symbol)value;
                if (sym.Namespace == null)
                {
                    ilg.EmitNull();
                }
                else
                {
                    ilg.EmitString(sym.Namespace);
                }
                ilg.EmitString(sym.Name);
                ilg.EmitCall(Compiler.Method_Symbol_intern2);
            }
            else if (value is Keyword)
            {
                Keyword keyword = (Keyword)value;
                if (keyword.Namespace == null)
                {
                    ilg.EmitNull();
                }
                else
                {
                    ilg.EmitString(keyword.Namespace);
                }
                ilg.EmitString(keyword.Name);
                ilg.EmitCall(Compiler.Method_RT_keyword);
            }
            else if (value is Var)
            {
                Var var = (Var)value;
                ilg.EmitString(var.Namespace.Name.ToString());
                ilg.EmitString(var.Symbol.Name.ToString());
                ilg.EmitCall(Compiler.Method_RT_var2);
            }
            else if (value is IType)
            {
                IPersistentVector fields = (IPersistentVector)Reflector.InvokeStaticMethod(value.GetType(), "getBasis", Type.EmptyTypes);

                for (ISeq s = RT.seq(fields); s != null; s = s.next())
                {
                    Symbol field = (Symbol)s.first();
                    Type   k     = Compiler.TagType(Compiler.TagOf(field));
                    object val   = Reflector.GetInstanceFieldOrProperty(value, Compiler.munge(field.Name));
                    EmitValue(val, ilg);
                    if (k.IsPrimitive)
                    {
                        ilg.Emit(OpCodes.Castclass, k);
                    }
                }

                ConstructorInfo cinfo = value.GetType().GetConstructors()[0];
                ilg.EmitNew(cinfo);
            }
            else if (value is IRecord)
            {
                //MethodInfo[] minfos = value.GetType().GetMethods(BindingFlags.Static | BindingFlags.Public);
                EmitValue(PersistentArrayMap.create((IDictionary)value), ilg);

                MethodInfo createMI = value.GetType().GetMethod("create", BindingFlags.Static | BindingFlags.Public, null, CallingConventions.Standard, new Type[] { typeof(IPersistentMap) }, null);
                ilg.EmitCall(createMI);
            }
            else if (value is IPersistentMap)
            {
                IPersistentMap map     = (IPersistentMap)value;
                List <object>  entries = new List <object>(map.count() * 2);
                foreach (IMapEntry entry in map)
                {
                    entries.Add(entry.key());
                    entries.Add(entry.val());
                }
                EmitListAsObjectArray(entries, ilg);
                ilg.EmitCall(Compiler.Method_RT_map);
            }
            else if (value is IPersistentVector)
            {
                IPersistentVector args = (IPersistentVector)value;
                if (args.count() <= Tuple.MAX_SIZE)
                {
                    for (int i = 0; i < args.count(); i++)
                    {
                        EmitValue(args.nth(i), ilg);
                    }
                    ilg.Emit(OpCodes.Call, Compiler.Methods_CreateTuple[args.count()]);
                }
                else
                {
                    EmitListAsObjectArray(value, ilg);
                    ilg.EmitCall(Compiler.Method_RT_vector);
                }
            }
            else if (value is PersistentHashSet)
            {
                ISeq vs = RT.seq(value);
                if (vs == null)
                {
                    ilg.EmitFieldGet(Compiler.Method_PersistentHashSet_EMPTY);
                }
                else
                {
                    EmitListAsObjectArray(vs, ilg);
                    ilg.EmitCall(Compiler.Method_PersistentHashSet_create);
                }
            }
            else if (value is ISeq || value is IPersistentList)
            {
                EmitListAsObjectArray(value, ilg);
                ilg.EmitCall(Compiler.Method_PersistentList_create);
            }
            else if (value is Regex)
            {
                ilg.EmitString(((Regex)value).ToString());
                ilg.EmitNew(Compiler.Ctor_Regex_1);
            }
            else
            {
                string cs = null;
                try
                {
                    cs = RT.printString(value);
                }
                catch (Exception)
                {
                    throw new InvalidOperationException(String.Format("Can't embed object in code, maybe print-dup not defined: {0}", value));
                }
                if (cs.Length == 0)
                {
                    throw new InvalidOperationException(String.Format("Can't embed unreadable object in code: " + value));
                }
                if (cs.StartsWith("#<"))
                {
                    throw new InvalidOperationException(String.Format("Can't embed unreadable object in code: " + cs));
                }

                ilg.EmitString(cs);
                ilg.EmitCall(Compiler.Method_RT_readString);
                partial = false;
            }

            if (partial)
            {
                if (value is IObj && RT.count(((IObj)value).meta()) > 0)
                {
                    ilg.Emit(OpCodes.Castclass, typeof(IObj));
                    Object m = ((IObj)value).meta();
                    EmitValue(Compiler.ElideMeta(m), ilg);
                    ilg.Emit(OpCodes.Castclass, typeof(IPersistentMap));
                    ilg.Emit(OpCodes.Callvirt, Compiler.Method_IObj_withMeta);
                }
            }
        }
Пример #58
0
 /// <summary>
 /// Create an empty <see cref="PersistentArrayMap">PersistentArrayMap</see>.
 /// </summary>
 protected PersistentArrayMap()
 {
     _meta  = null;
     _array = new object[] { };
 }
Пример #59
0
 public ArraySeq_ushort(IPersistentMap meta, ushort[] array, int index)
     : base(meta, array, index)
 {
 }
Пример #60
0
            public Expr Parse(ParserContext pcon, object frm)
            {
                string         source  = (string)Compiler.SourceVar.deref();
                IPersistentMap spanMap = (IPersistentMap)Compiler.SourceSpanVar.deref();  // Compiler.GetSourceSpanMap(form);

                ISeq form = (ISeq)frm;

                IPersistentVector loopLocals = (IPersistentVector)Compiler.LoopLocalsVar.deref();

                if (pcon.Rhc != RHC.Return || loopLocals == null)
                {
                    throw new ParseException("Can only recur from tail position");
                }

                if (Compiler.NoRecurVar.deref() != null)
                {
                    throw new ParseException("Cannot recur across try");
                }

                IPersistentVector args = PersistentVector.EMPTY;

                for (ISeq s = RT.seq(form.next()); s != null; s = s.next())
                {
                    args = args.cons(Compiler.Analyze(pcon.SetRhc(RHC.Expression).SetAssign(false), s.first()));
                }
                if (args.count() != loopLocals.count())
                {
                    throw new ParseException(string.Format("Mismatched argument count to recur, expected: {0} args, got {1}",
                                                           loopLocals.count(), args.count()));
                }

                for (int i = 0; i < loopLocals.count(); i++)
                {
                    LocalBinding lb    = (LocalBinding)loopLocals.nth(i);
                    Type         primt = lb.PrimitiveType;
                    if (primt != null)
                    {
                        bool mismatch = false;
                        Type pt       = Compiler.MaybePrimitiveType((Expr)args.nth(i));
                        if (primt == typeof(long))
                        {
                            if (!(pt == typeof(long) || pt == typeof(int) || pt == typeof(short) || pt == typeof(uint) || pt == typeof(ushort) || pt == typeof(ulong) ||
                                  pt == typeof(char) || pt == typeof(byte) || pt == typeof(sbyte)))
                            {
                                mismatch = true;
                            }
                        }
                        else if (primt == typeof(double))
                        {
                            if (!(pt == typeof(double) || pt == typeof(float)))
                            {
                                mismatch = true;
                            }
                        }

                        if (mismatch)
                        {
                            lb.RecurMismatch = true;
                            if (RT.booleanCast(RT.WarnOnReflectionVar.deref()))
                            {
                                RT.errPrintWriter().WriteLine("{0}:{1} recur arg for primitive local: {2} is not matching primitive, had: {3}, needed {4}",
                                                              source, spanMap != null ? (int)spanMap.valAt(RT.StartLineKey, 0) : 0,
                                                              lb.Name, pt != null ? pt.Name : "Object", primt.Name);
                            }
                        }
                    }
                }


                return(new RecurExpr(source, spanMap, loopLocals, args));
            }