/*** * Current host interop uses reflection, which requires pre-existing classes * Work around this by: * Generate a stub class that has the same interfaces and fields as the class we are generating. * Use it as a type hint for this, and bind the simple name of the class to this stub (in resolve etc) * Unmunge the name (using a magic prefix) on any code gen for classes */ // TODO: Preparse method heads to pick up signatures, implement those methods as abstract or as NotImpelmented so that Reflection can pick up calls during compilation and avoide a callsite. static Type CompileStub(GenContext context, Type super, NewInstanceExpr ret, Type[] interfaces, Object frm) { //GenContext context = Compiler.CompilerContextVar.get() as GenContext ?? GenContext.CreateWithExternalAssembly("stub" + RT.nextID().ToString(), ".dll", false); //GenContext context = Compiler.IsCompiling ? Compiler.CompilerContextVar.get() as GenContext : GenContext.CreateWithExternalAssembly("stub" + RT.nextID().ToString(), ".dll", false); //context = GenContext.CreateWithExternalAssembly("stub" + RT.nextID().ToString(), ".dll", false); TypeBuilder tb = context.ModuleBuilder.DefineType(Compiler.CompileStubPrefix + "." + ret.InternalName + RT.nextID(), TypeAttributes.Public | TypeAttributes.Abstract, super, interfaces); tb.DefineDefaultConstructor(MethodAttributes.Public); // instance fields for closed-overs for (ISeq s = RT.keys(ret.Closes); s != null; s = s.next()) { LocalBinding lb = (LocalBinding)s.first(); FieldAttributes access = FieldAttributes.Public; // TODO: FIgure out Volatile if (!ret.IsVolatile(lb)) { access |= FieldAttributes.InitOnly; } if (lb.PrimitiveType != null) { tb.DefineField(lb.Name, lb.PrimitiveType, access); } else { tb.DefineField(lb.Name, typeof(Object), access); } } // ctor that takes closed-overs and does nothing if (ret.CtorTypes().Length > 0) { ConstructorBuilder cb = tb.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, ret.CtorTypes()); CljILGen ilg = new CljILGen(cb.GetILGenerator()); ilg.EmitLoadArg(0); ilg.Emit(OpCodes.Call, super.GetConstructor(Type.EmptyTypes)); ilg.Emit(OpCodes.Ret); if (ret._altCtorDrops > 0) { Type[] ctorTypes = ret.CtorTypes(); int newLen = ctorTypes.Length - ret._altCtorDrops; if (newLen > 0) { Type[] altCtorTypes = new Type[newLen]; for (int i = 0; i < altCtorTypes.Length; i++) { altCtorTypes[i] = ctorTypes[i]; } ConstructorBuilder cb2 = tb.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, altCtorTypes); CljILGen ilg2 = new CljILGen(cb2.GetILGenerator()); ilg2.EmitLoadArg(0); for (int i = 0; i < newLen; i++) { ilg2.EmitLoadArg(i + 1); } for (int i = 0; i < ret._altCtorDrops; i++) { ilg2.EmitNull(); } ilg2.Emit(OpCodes.Call, cb); ilg2.Emit(OpCodes.Ret); } } } Type t = tb.CreateType(); //Compiler.RegisterDuplicateType(t); return(t); }
protected override void EmitStatics(TypeBuilder tb) { if (IsDefType) { // getBasis() { MethodBuilder mbg = tb.DefineMethod("getBasis", MethodAttributes.Public | MethodAttributes.Static, typeof(IPersistentVector), Type.EmptyTypes); CljILGen ilg = new CljILGen(mbg.GetILGenerator()); EmitValue(_hintedFields, ilg); ilg.Emit(OpCodes.Ret); } if (Fields.count() > _hintedFields.count()) { // create(IPersistentMap) MethodBuilder mbc = tb.DefineMethod("create", MethodAttributes.Public | MethodAttributes.Static, tb, new Type[] { typeof(IPersistentMap) }); CljILGen gen = new CljILGen(mbc.GetILGenerator()); LocalBuilder kwLocal = gen.DeclareLocal(typeof(Keyword)); List <LocalBuilder> locals = new List <LocalBuilder>(); for (ISeq s = RT.seq(_hintedFields); s != null; s = s.next()) { string bName = ((Symbol)s.first()).Name; Type t = Compiler.TagType(Compiler.TagOf(s.first())); // local_kw = Keyword.intern(bname) // local_i = arg_0.valAt(kw,null) gen.EmitLoadArg(0); gen.EmitString(bName); gen.EmitCall(Compiler.Method_Keyword_intern_string); gen.Emit(OpCodes.Dup); gen.Emit(OpCodes.Stloc, kwLocal.LocalIndex); gen.EmitNull(); gen.EmitCall(Compiler.Method_IPersistentMap_valAt2); LocalBuilder lb = gen.DeclareLocal(t); locals.Add(lb); if (t.IsPrimitive) { gen.EmitUnbox(t); } gen.Emit(OpCodes.Stloc, lb.LocalIndex); // arg_0 = arg_0.without(local_kw); gen.EmitLoadArg(0); gen.Emit(OpCodes.Ldloc, kwLocal.LocalIndex); gen.EmitCall(Compiler.Method_IPersistentMap_without); gen.EmitStoreArg(0); } foreach (LocalBuilder lb in locals) { gen.Emit(OpCodes.Ldloc, lb.LocalIndex); } gen.EmitNull(); gen.EmitLoadArg(0); gen.EmitCall(Compiler.Method_RT_seqOrElse); gen.EmitNew(_ctorInfo); gen.Emit(OpCodes.Ret); } } }
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); bool tailPosition = Compiler.InTailCall(pcon.Rhc); // 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>(), tailPosition)); } 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>(), tailPosition)); } 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, tailPosition)) : (MethodExpr)(new InstanceMethodExpr(source, spanMap, tag, instance, methodName, typeArgs, args, tailPosition))); }
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); #if CLR2 // Not covariant. Sigh. List <Expression> paramsAsExprs = new List <Expression>(paramExprs.Count); paramsAsExprs.AddRange(paramExprs.ToArray()); DynamicExpression dyn = Expression.Dynamic(binder, typeof(object), paramsAsExprs); #else DynamicExpression dyn = Expression.Dynamic(binder, typeof(object), paramExprs); #endif LambdaExpression lambda; Type delType; MethodBuilder mbLambda; MethodExpr.EmitDynamicCallPreamble(dyn, _spanMap, "__interop_ctor_" + 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: MethodExpr.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(); } } MethodExpr.EmitDynamicCallPostlude(lambda, delType, mbLambda, ilg); }
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)); }
public static IPersistentVector MSig(string name, Type[] paramTypes, Type retType) { return(RT.vector(name, RT.seq(paramTypes), retType)); }
internal bool IsVolatile(LocalBinding lb) { return(RT.booleanCast(RT.contains(Fields, lb.Symbol)) && RT.booleanCast(RT.get(lb.Symbol.meta(), Keyword.intern("volatile-mutable")))); }
public static Expr Parse(ParserContext pcon, ISeq form, string name) { ISeq origForm = form; FnExpr fn = new FnExpr(Compiler.TagOf(form)); fn._src = form; 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 if (RT.second(form) is Symbol) { Symbol nm = (Symbol)RT.second(form); fn._thisName = nm.Name; fn._isStatic = false; // RT.booleanCast(RT.get(nm.meta(), Compiler.STATIC_KEY)); 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; for (ISeq s = RT.next(form); s != null; s = RT.next(s)) { FnMethod f = FnMethod.Parse(fn, (ISeq)RT.first(s), fn._isStatic); 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."); } if (fn._isStatic && fn.Closes.count() > 0) { throw new ParseException("static fns can't be closures"); } IPersistentCollection allMethods = null; foreach (FnMethod method in methods.Values) { allMethods = RT.conj(allMethods, method); } if (variadicMethod != null) { allMethods = RT.conj(allMethods, variadicMethod); } 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); } 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(); } } }
/// <summary> /// Gets the number of items in the collection. /// </summary> /// <returns>The number of items in the collection.</returns> public override int count() { return(_vals.Length + RT.count(_ext)); }
/// <summary> /// Gets the number of items in the collection. /// </summary> /// <returns>The number of items in the collection.</returns> public override int count() { return(1 + RT.count(_more)); }
public object alter(IFn fn, ISeq args) { set(fn.applyTo(RT.cons(deref(), args))); return(this); }
public void setMacro() { //alterMeta(_assoc, RT.list(_macroKey, RT.T)); alterMeta(_assoc, RT.list(_macroKey, true)); }
public override object invoke(object m, object k) { return(RT.dissoc(m, k)); }
public override object invoke(object m, object k, object v) { return(RT.assoc(m, k, v)); }
public Type Compile(Type superType, Type stubType, IPersistentVector interfaces, bool onetimeUse, GenContext context) { if (CompiledType != null) { return(CompiledType); } string publicTypeName = IsDefType /* || (CanBeDirect && Compiler.IsCompiling) */ ? InternalName : InternalName + "__" + RT.nextID(); TypeBuilder = context.AssemblyGen.DefinePublicType(publicTypeName, superType, true); context = context.WithNewDynInitHelper().WithTypeBuilder(TypeBuilder); Var.pushThreadBindings(RT.map(Compiler.CompilerContextVar, context)); try { if (interfaces != null) { for (int i = 0; i < interfaces.count(); i++) { TypeBuilder.AddInterfaceImplementation((Type)interfaces.nth(i)); } } ObjExpr.MarkAsSerializable(TypeBuilder); GenInterface.SetCustomAttributes(TypeBuilder, ClassMeta); try { if (IsDefType) { Compiler.RegisterDuplicateType(TypeBuilder); Var.pushThreadBindings(RT.map( Compiler.CompileStubOrigClassVar, stubType, Compiler.CompilingDefTypeVar, true )); //, //Compiler.COMPILE_STUB_CLASS, _baseType)); } EmitConstantFieldDefs(TypeBuilder); EmitKeywordCallsiteDefs(TypeBuilder); DefineStaticConstructor(TypeBuilder); if (SupportsMeta) { MetaField = TypeBuilder.DefineField("__meta", typeof(IPersistentMap), FieldAttributes.Public | FieldAttributes.InitOnly); } // If this IsDefType, then it has already emitted the closed-over fields on the base class. if (!IsDefType) { EmitClosedOverFields(TypeBuilder); } EmitProtocolCallsites(TypeBuilder); CtorInfo = EmitConstructor(TypeBuilder, superType); if (AltCtorDrops > 0) { EmitFieldOnlyConstructors(TypeBuilder, superType); } if (SupportsMeta) { EmitNonMetaConstructor(TypeBuilder, superType); EmitMetaFunctions(TypeBuilder); } EmitStatics(TypeBuilder); EmitMethods(TypeBuilder); CompiledType = TypeBuilder.CreateType(); if (context.DynInitHelper != null) { context.DynInitHelper.FinalizeType(); } CtorInfo = GetConstructorWithArgCount(CompiledType, CtorTypes().Length); return(CompiledType); } finally { if (IsDefType) { Var.popThreadBindings(); } } } finally { Var.popThreadBindings(); } }
public Expr Parse(ParserContext pcon, object frm) { ISeq form = (ISeq)frm; if (RT.Length(form) != 3) { throw new ParseException("Malformed assignment, expecting (set! target val)"); } Expr target = Compiler.Analyze(new ParserContext(RHC.Expression, true), RT.second(form)); AssignableExpr ae = target as AssignableExpr; if (ae == null) { throw new ParseException("Invalid assignment target"); } return(new AssignExpr(ae, Compiler.Analyze(pcon.SetRhc(RHC.Expression), RT.third(form)))); }
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); } } }
internal void AddMethod(FnMethod method) { _methods = RT.conj(_methods, method); }
private void EmitComplexCall(ObjExpr objx, CljILGen ilg) { // TOD: We have gotten rid of light-compile. Simplify this. // 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) { typeof(System.Runtime.CompilerServices.CallSite) }; callsiteParamTypes.AddRange(paramTypes); Type dynType = Microsoft.Scripting.Generation.Snippets.Shared.DefineDelegate("__interop__", returnType, callsiteParamTypes.ToArray()); DynamicExpression dyn = Expression.MakeDynamic(dynType, binder, paramExprs); EmitDynamicCallPreamble(dyn, _spanMap, "__interop_" + _methodName + 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: EmitByRefArg(ha, objx, ilg); break; case HostArg.ParameterType.Standard: if (argType.IsPrimitive && ha.ArgExpr is MaybePrimitiveExpr mpe) { mpe.EmitUnboxed(RHC.Expression, objx, ilg); } else { ha.ArgExpr.Emit(RHC.Expression, objx, ilg); } break; default: throw Util.UnreachableCode(); } } EmitDynamicCallPostlude(lambda, delType, mbLambda, ilg); }
public static NewInstanceMethod Parse(ObjExpr objx, ISeq form, Symbol thisTag, Dictionary <IPersistentVector, List <MethodInfo> > overrideables, Dictionary <IPersistentVector, List <MethodInfo> > explicits) { // (methodname [this-name args*] body...) // this-name might be nil NewInstanceMethod method = new NewInstanceMethod(objx, (ObjMethod)Compiler.MethodVar.deref()); Symbol dotName = (Symbol)RT.first(form); Symbol name; string methodName; int idx = dotName.Name.LastIndexOf("."); if (idx >= 0) { // we have an explicit interface implementation string dotNameStr = dotName.Name; string interfaceName = dotNameStr.Substring(0, idx); method._explicitInterface = RT.classForName(interfaceName); if (method._explicitInterface == null) { throw new ParseException(String.Format("Unable to find interface {0} for explicit method implemntation: {1}", interfaceName, dotNameStr)); } methodName = dotNameStr.Substring(idx + 1); name = (Symbol)Symbol.intern(null, Compiler.munge(dotName.Name)).withMeta(RT.meta(dotName)); } else { name = (Symbol)Symbol.intern(null, Compiler.munge(dotName.Name)).withMeta(RT.meta(dotName)); methodName = name.Name; } IPersistentVector parms = (IPersistentVector)RT.second(form); if (parms.count() == 0 || !(parms.nth(0) is Symbol)) { throw new ParseException("Must supply at least one argument for 'this' in: " + dotName); } Symbol thisName = (Symbol)parms.nth(0); parms = RT.subvec(parms, 1, parms.count()); ISeq body = RT.next(RT.next(form)); try { method.SpanMap = (IPersistentMap)Compiler.SourceSpanVar.deref(); // register as the current method and set up a new env frame // PathNode pnade = new PathNode(PATHTYPE.PATH, (PathNode) CLEAR_PATH.get()); Var.pushThreadBindings( RT.mapUniqueKeys( Compiler.MethodVar, method, Compiler.LocalEnvVar, Compiler.LocalEnvVar.deref(), Compiler.LoopLocalsVar, null, Compiler.NextLocalNumVar, 0 // CLEAR_PATH, pnode, // CLEAR_ROOT, pnode, // CLEAR_SITES, PersistentHashMap.EMPTY )); // register 'this' as local 0 //method._thisBinding = Compiler.RegisterLocalThis(((thisName == null) ? dummyThis : thisName), thisTag, null); Compiler.RegisterLocalThis(((thisName == null) ? dummyThis : thisName), thisTag, null); IPersistentVector argLocals = PersistentVector.EMPTY; method._retType = Compiler.TagType(Compiler.TagOf(name)); method._argTypes = new Type[parms.count()]; bool hinted = Compiler.TagOf(name) != null; Type[] pTypes = new Type[parms.count()]; Symbol[] pSyms = new Symbol[parms.count()]; bool[] pRefs = new bool[parms.count()]; for (int i = 0; i < parms.count(); i++) { // Param should be symbol or (by-ref symbol) Symbol p; bool isByRef = false; object pobj = parms.nth(i); if (pobj is Symbol) { p = (Symbol)pobj; } else if (pobj is ISeq) { ISeq pseq = (ISeq)pobj; object first = RT.first(pseq); object second = RT.second(pseq); if (!(first is Symbol && ((Symbol)first).Equals(HostExpr.ByRefSym))) { throw new ParseException("First element in parameter pair must be by-ref"); } if (!(second is Symbol)) { throw new ParseException("Params must be Symbols"); } isByRef = true; p = (Symbol)second; hinted = true; } else { throw new ParseException("Params must be Symbols or of the form (by-ref Symbol)"); } object tag = Compiler.TagOf(p); if (tag != null) { hinted = true; } if (p.Namespace != null) { p = Symbol.intern(p.Name); } Type pType = Compiler.TagType(tag); if (isByRef) { pType = pType.MakeByRefType(); } pTypes[i] = pType; pSyms[i] = p; pRefs[i] = isByRef; } Dictionary <IPersistentVector, List <MethodInfo> > matches = method.IsExplicit ? FindMethodsWithNameAndArity(method._explicitInterface, methodName, parms.count(), overrideables, explicits) : FindMethodsWithNameAndArity(methodName, parms.count(), overrideables); IPersistentVector mk = MSig(methodName, pTypes, method._retType); List <MethodInfo> ms = null; if (matches.Count > 0) { // multiple matches if (matches.Count > 1) { // must be hinted and match one method if (!hinted) { throw new ParseException("Must hint overloaded method: " + name.Name); } if (!matches.TryGetValue(mk, out ms)) { throw new ParseException("Can't find matching overloaded method: " + name.Name); } method._minfos = ms; } else // one match { // if hinted, validate match, if (hinted) { if (!matches.TryGetValue(mk, out ms)) { throw new ParseException("Can't find matching method: " + name.Name + ", leave off hints for auto match."); } method._minfos = ms; //if (m.ReturnType != method._retType) // throw new ArgumentException(String.Format("Mismatched return type: {0}, expected {1}, had: {2}", // name.Name, m.ReturnType.Name, method._retType.Name)); } else // adopt found method sig { using (var e = matches.GetEnumerator()) { e.MoveNext(); mk = e.Current.Key; ms = e.Current.Value; } MethodInfo m = ms[0]; method._retType = m.ReturnType; pTypes = Compiler.GetTypes(m.GetParameters()); method._minfos = ms; } } } else { throw new ParseException("Can't define method not in interfaces: " + name.Name); } if (method.IsExplicit) { method._explicitMethodInfo = ms[0]; } // validate unique name + arity among additional methods for (int i = 0; i < parms.count(); i++) { LocalBinding lb = Compiler.RegisterLocal(pSyms[i], null, new MethodParamExpr(pTypes[i]), true, pRefs[i]); argLocals = argLocals.assocN(i, lb); method._argTypes[i] = pTypes[i]; } Compiler.LoopLocalsVar.set(argLocals); method._name = name.Name; method._methodMeta = GenInterface.ExtractAttributes(RT.meta(name)); method._parms = parms; method._argLocals = argLocals; method._body = (new BodyExpr.Parser()).Parse(new ParserContext(RHC.Return), body); return(method); } finally { Var.popThreadBindings(); } }
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) { GenContext context = Compiler.CompilerContextVar.deref() as GenContext; DynInitHelper.SiteInfo siteInfo; Expression call; 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.SiteType); 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); } var invokeMethod = siteInfo.DelegateType.GetMethod("Invoke"); ilg2.EmitCall(invokeMethod); if (returnType == typeof(void)) { ilg2.Emit(OpCodes.Pop); ilg2.EmitNull(); } else if (returnType != invokeMethod.ReturnType) { EmitConvertToType(ilg2, invokeMethod.ReturnType, 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) * ) */ } }
public static Type GetTypeFromName(string name) { ClrTypeSpec spec = Parse(name); if (spec == null) { return(null); } return(spec.Resolve( assyName => Assembly.Load(assyName), //(assy, typeName) => assy == null ? RT.classForName(typeName) : assy.GetType(typeName)); <--- this goes into an infinite loop on a non-existent typename (assy, typeName) => assy == null ? (name.Equals(typeName) ? null : RT.classForName(typeName)) : assy.GetType(typeName))); }
/// <summary> /// Returns a String that represents the current object. /// </summary> /// <returns>A String that represents the current object.</returns> public override string ToString() { return(RT.printString(this)); }
internal static void EmitUnboxArg(CljILGen ilg, Type paramType) { if (paramType.IsPrimitive) { MethodInfo m = null; if (paramType == typeof(bool)) { m = HostExpr.Method_RT_booleanCast; } else if (paramType == typeof(char)) { m = HostExpr.Method_RT_charCast; } else if (paramType == typeof(IntPtr)) { m = HostExpr.Method_RT_intPtrCast; } else if (paramType == typeof(UIntPtr)) { m = HostExpr.Method_RT_uintPtrCast; } else { var typeCode = Type.GetTypeCode(paramType); if (RT.booleanCast(RT.UncheckedMathVar.deref())) { switch (typeCode) { case TypeCode.SByte: m = HostExpr.Method_RT_uncheckedSbyteCast; break; case TypeCode.Byte: m = HostExpr.Method_RT_uncheckedByteCast; break; case TypeCode.Int16: m = HostExpr.Method_RT_uncheckedShortCast; break; case TypeCode.UInt16: m = HostExpr.Method_RT_uncheckedUshortCast; break; case TypeCode.Int32: m = HostExpr.Method_RT_uncheckedIntCast; break; case TypeCode.UInt32: m = HostExpr.Method_RT_uncheckedUintCast; break; case TypeCode.Int64: m = HostExpr.Method_RT_uncheckedLongCast; break; case TypeCode.UInt64: m = HostExpr.Method_RT_uncheckedUlongCast; break; case TypeCode.Single: m = HostExpr.Method_RT_uncheckedFloatCast; break; case TypeCode.Double: m = HostExpr.Method_RT_uncheckedDoubleCast; break; case TypeCode.Char: m = HostExpr.Method_RT_uncheckedCharCast; break; case TypeCode.Decimal: m = HostExpr.Method_RT_uncheckedDecimalCast; break; default: throw new ArgumentOutOfRangeException("paramType", paramType, string.Format("Don't know how to handle typeCode {0} for paramType", typeCode)); } } else { switch (typeCode) { case TypeCode.SByte: m = HostExpr.Method_RT_sbyteCast; break; case TypeCode.Byte: m = HostExpr.Method_RT_byteCast; break; case TypeCode.Int16: m = HostExpr.Method_RT_shortCast; break; case TypeCode.UInt16: m = HostExpr.Method_RT_ushortCast; break; case TypeCode.Int32: m = HostExpr.Method_RT_intCast; break; case TypeCode.UInt32: m = HostExpr.Method_RT_uintCast; break; case TypeCode.Int64: m = HostExpr.Method_RT_longCast; break; case TypeCode.UInt64: m = HostExpr.Method_RT_ulongCast; break; case TypeCode.Single: m = HostExpr.Method_RT_floatCast; break; case TypeCode.Double: m = HostExpr.Method_RT_doubleCast; break; case TypeCode.Char: m = HostExpr.Method_RT_charCast; break; case TypeCode.Decimal: m = HostExpr.Method_RT_decimalCast; break; default: throw new ArgumentOutOfRangeException("paramType", paramType, string.Format("Don't know how to handle typeCode {0} for paramType", typeCode)); } } } ilg.Emit(OpCodes.Castclass, typeof(Object)); ilg.Emit(OpCodes.Call, m); } else { // TODO: Properly handle value types here. Really, we need to know the incoming type. if (paramType.IsValueType) { ilg.Emit(OpCodes.Unbox_Any, paramType); } else { ilg.Emit(OpCodes.Castclass, paramType); } } }
public Expr Parse(object form) { return(new MonitorEnterExpr(Compiler.GenerateAST(RT.second(form)))); }
internal static ObjExpr Build( IPersistentVector interfaceSyms, IPersistentVector fieldSyms, Symbol thisSym, string tagName, Symbol className, Symbol typeTag, ISeq methodForms, Object frm) { NewInstanceExpr ret = new NewInstanceExpr(null); ret._src = frm; ret._name = className.ToString(); ret._classMeta = GenInterface.ExtractAttributes(RT.meta(className)); ret.InternalName = ret._name; // ret.Name.Replace('.', '/'); // Java: ret.objtype = Type.getObjectType(ret.internalName); if (thisSym != null) { ret._thisName = thisSym.Name; } if (fieldSyms != null) { IPersistentMap fmap = PersistentHashMap.EMPTY; object[] closesvec = new object[2 * fieldSyms.count()]; for (int i = 0; i < fieldSyms.count(); i++) { Symbol sym = (Symbol)fieldSyms.nth(i); LocalBinding lb = new LocalBinding(-1, sym, null, new MethodParamExpr(Compiler.TagType(Compiler.TagOf(sym))), false, false, false); fmap = fmap.assoc(sym, lb); closesvec[i * 2] = lb; closesvec[i * 2 + 1] = lb; } // Java TODO: inject __meta et al into closes - when? // use array map to preserve ctor order ret.Closes = new PersistentArrayMap(closesvec); ret.Fields = fmap; for (int i = fieldSyms.count() - 1; i >= 0 && (((Symbol)fieldSyms.nth(i)).Name.Equals("__meta") || ((Symbol)fieldSyms.nth(i)).Name.Equals("__extmap")); --i) { ret._altCtorDrops++; } } // Java TODO: set up volatiles //ret._volatiles = PersistentHashSet.create(RT.seq(RT.get(ret._optionsMap, volatileKey))); IPersistentVector interfaces = PersistentVector.EMPTY; for (ISeq s = RT.seq(interfaceSyms); s != null; s = s.next()) { Type t = (Type)Compiler.Resolve((Symbol)s.first()); if (!t.IsInterface) { throw new ParseException("only interfaces are supported, had: " + t.Name); } interfaces = interfaces.cons(t); } Type superClass = typeof(Object); Dictionary <IPersistentVector, List <MethodInfo> > overrideables; GatherMethods(superClass, RT.seq(interfaces), out overrideables); ret._methodMap = overrideables; GenContext context = Compiler.IsCompiling ? Compiler.CompilerContextVar.get() as GenContext : (ret.IsDefType ? GenContext.CreateWithExternalAssembly("deftype" + RT.nextID().ToString(), ".dll", true) : (Compiler.CompilerContextVar.get() as GenContext ?? Compiler.EvalContext)); GenContext genC = context.WithNewDynInitHelper(ret.InternalName + "__dynInitHelper_" + RT.nextID().ToString()); Type stub = CompileStub(genC, superClass, ret, SeqToTypeArray(interfaces), frm); Symbol thisTag = Symbol.intern(null, stub.FullName); //Symbol stubTag = Symbol.intern(null,stub.FullName); //Symbol thisTag = Symbol.intern(null, tagName); try { Var.pushThreadBindings( RT.map( 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, Compiler.CompilerContextVar, genC )); if (ret.IsDefType) { Var.pushThreadBindings( RT.map( Compiler.MethodVar, null, Compiler.LocalEnvVar, ret.Fields, Compiler.CompileStubSymVar, Symbol.intern(null, tagName), Compiler.CompileStubClassVar, stub )); ret._hintedFields = RT.subvec(fieldSyms, 0, fieldSyms.count() - ret._altCtorDrops); } // now (methodname [args] body)* ret.SpanMap = (IPersistentMap)Compiler.SourceSpanVar.deref(); IPersistentCollection methods = null; for (ISeq s = methodForms; s != null; s = RT.next(s)) { NewInstanceMethod m = NewInstanceMethod.Parse(ret, (ISeq)RT.first(s), thisTag, overrideables); methods = RT.conj(methods, m); } ret._methods = methods; ret.Keywords = (IPersistentMap)Compiler.KeywordsVar.deref(); ret.Vars = (IPersistentMap)Compiler.VarsVar.deref(); ret.Constants = (PersistentVector)Compiler.ConstantsVar.deref(); ret._constantsID = RT.nextID(); ret.KeywordCallsites = (IPersistentVector)Compiler.KeywordCallsitesVar.deref(); ret.ProtocolCallsites = (IPersistentVector)Compiler.ProtocolCallsitesVar.deref(); ret.VarCallsites = (IPersistentSet)Compiler.VarCallsitesVar.deref(); } finally { if (ret.IsDefType) { Var.popThreadBindings(); } Var.popThreadBindings(); } // TOD: Really, the first stub here should be 'superclass' but can't handle hostexprs nested in method bodies -- reify method compilation takes place before this sucker is compiled, so can't replace the call. // Might be able to flag stub classes and not try to convert, leading to a dynsite. //if (RT.CompileDLR) ret.Compile(stub, stub, interfaces, false, genC); //else // ret.CompileNoDlr(stub, stub, interfaces, false, genC); Compiler.RegisterDuplicateType(ret.CompiledType); return(ret); }
public static void StartREPL() { replSocket = (UdpClient)RT.var("arcadia.repl", "start-server").invoke(11211); EditorApplication.update += Repl.Update; }
public static IPersistentVector MSig(MethodInfo m) { return(RT.vector(m.Name, RT.seq(Compiler.GetTypes(m.GetParameters())), m.ReturnType)); }
public static void StopREPL() { RT.var("arcadia.repl", "stop-server").invoke(replSocket); replSocket = null; EditorApplication.update -= Repl.Update; }
String DB_OAUTH2_AUTHORISE(RT response_type, String client_id, String redirect_uri) // nah options { var root = "https://www.dropbox.com/1/oauth2/authorize?response_type={0}&client_id={1}&redirect_uri={2}"; return string.Format(root, response_type == RT.Code ? "code" : "token", client_id, redirect_uri); }
static string GenerateName() { return("__InternalDynamicExpressionInits_" + RT.nextID()); }