void EmitProto(RHC rhc, ObjExpr objx, CljILGen ilg) { Label onLabel = ilg.DefineLabel(); Label callLabel = ilg.DefineLabel(); Label endLabel = ilg.DefineLabel(); Var v = ((VarExpr)_fexpr).Var; Expr e = (Expr)_args.nth(0); e.Emit(RHC.Expression, objx, ilg); // target ilg.Emit(OpCodes.Dup); // target, target LocalBuilder targetTemp = ilg.DeclareLocal(typeof(Object)); GenContext.SetLocalName(targetTemp, "target"); ilg.Emit(OpCodes.Stloc, targetTemp); // target ilg.Emit(OpCodes.Call, Compiler.Method_Util_classOf); // class ilg.EmitLoadArg(0); // class, this ilg.EmitFieldGet(objx.CachedTypeField(_siteIndex)); // class, cached-class ilg.Emit(OpCodes.Beq, callLabel); // if (_protocolOn != null) { ilg.Emit(OpCodes.Ldloc, targetTemp); // target ilg.Emit(OpCodes.Isinst, _protocolOn); // null or target ilg.Emit(OpCodes.Ldnull); // (null or target), null ilg.Emit(OpCodes.Cgt_Un); // (0 or 1) ilg.Emit(OpCodes.Brtrue, onLabel); } ilg.Emit(OpCodes.Ldloc, targetTemp); // target ilg.Emit(OpCodes.Call, Compiler.Method_Util_classOf); // class LocalBuilder typeTemp = ilg.DeclareLocal(typeof(Type)); GenContext.SetLocalName(typeTemp, "type"); ilg.Emit(OpCodes.Stloc, typeTemp); // (typeType <= class) ilg.EmitLoadArg(0); // this ilg.Emit(OpCodes.Ldloc, typeTemp); // this, class ilg.EmitFieldSet(objx.CachedTypeField(_siteIndex)); // ilg.MarkLabel(callLabel); objx.EmitVar(ilg, v); // var ilg.Emit(OpCodes.Call, Compiler.Method_Var_getRawRoot); // proto-fn ilg.Emit(OpCodes.Castclass, typeof(AFunction)); ilg.Emit(OpCodes.Ldloc, targetTemp); // proto-fn, target EmitArgsAndCall(1, rhc, objx, ilg); ilg.Emit(OpCodes.Br, endLabel); ilg.MarkLabel(onLabel); ilg.Emit(OpCodes.Ldloc, targetTemp); // target if (_protocolOn != null) { ilg.Emit(OpCodes.Castclass, _protocolOn); MethodExpr.EmitTypedArgs(objx, ilg, _onMethod.GetParameters(), RT.subvec(_args, 1, _args.count())); //if (rhc == RHC.Return) //{ // ObjMethod2 method = (ObjMethod)Compiler.MethodVar.deref(); // method.EmitClearLocals(context); //} ilg.Emit(OpCodes.Callvirt, _onMethod); HostExpr.EmitBoxReturn(objx, ilg, _onMethod.ReturnType); } ilg.MarkLabel(endLabel); }
private Expression GenProtoFull(RHC rhc, ObjExpr objx, GenContext context, Expression fn) { Var v = ((VarExpr)_fexpr).Var; Expr e = (Expr)_args.nth(0); ParameterExpression targetParam = Expression.Parameter(typeof(Object), "target"); ParameterExpression targetTypeParam = Expression.Parameter(typeof(Type), "targetType"); ParameterExpression vpfnParam = Expression.Parameter(typeof(AFunction), "vpfn"); ParameterExpression thisParam = objx.ThisParam; Expression targetParamAssign = Expression.Assign(targetParam, e.GenCode(RHC.Expression, objx, context)); Expression targetTypeParamAssign = Expression.Assign( targetTypeParam, Expression.Call(null, Compiler.Method_Util_classOf, targetParam)); Expression cachedTypeField = Expression.Field(thisParam, objx.CachedTypeField(_siteIndex)); Expression setCachedClass = Expression.Assign( cachedTypeField, targetTypeParam); Expression vpfnParamAssign = Expression.Assign( vpfnParam, Expression.Convert(Expression.Call(objx.GenVar(context, v), Compiler.Method_Var_getRawRoot), typeof(AFunction))); if (_protocolOn == null) { return Expression.Block( new ParameterExpression[] { targetParam, targetTypeParam, vpfnParam }, targetParamAssign, targetTypeParamAssign, setCachedClass, vpfnParamAssign, GenerateArgsAndCall(rhc, objx, context, vpfnParam, targetParam)); } else { Expression[] args = new Expression[_args.count()-1]; for (int i = 1; i < _args.count(); i++) { Expression bare = ((Expr)_args.nth(i)).GenCode(RHC.Expression, objx, context); args[i - 1] = Compiler.MaybeBox(bare); } return Expression.Block( new ParameterExpression[] { targetParam, targetTypeParam, vpfnParam }, targetParamAssign, targetTypeParamAssign, Expression.Condition( Expression.Or( Expression.Equal(targetTypeParam, cachedTypeField), Expression.Not(Expression.TypeIs(targetParam, _protocolOn))), Expression.Block( setCachedClass, vpfnParamAssign, GenerateArgsAndCall(rhc, objx, context, vpfnParam, targetParam)), Compiler.MaybeBox(Expression.Call(Expression.Convert(targetParam, _protocolOn), _onMethod, args)))); } }
void EmitProto(RHC rhc, ObjExpr objx, CljILGen ilg) { Label onLabel = ilg.DefineLabel(); Label callLabel = ilg.DefineLabel(); Label endLabel = ilg.DefineLabel(); Var v = ((VarExpr)_fexpr).Var; Expr e = (Expr)_args.nth(0); e.Emit(RHC.Expression, objx, ilg); // target ilg.Emit(OpCodes.Dup); // target, target LocalBuilder targetTemp = ilg.DeclareLocal(typeof(Object)); GenContext.SetLocalName(targetTemp, "target"); ilg.Emit(OpCodes.Stloc,targetTemp); // target ilg.Emit(OpCodes.Call,Compiler.Method_Util_classOf); // class ilg.EmitLoadArg(0); // class, this ilg.EmitFieldGet(objx.CachedTypeField(_siteIndex)); // class, cached-class ilg.Emit(OpCodes.Beq, callLabel); // if (_protocolOn != null) { ilg.Emit(OpCodes.Ldloc,targetTemp); // target ilg.Emit(OpCodes.Isinst, _protocolOn); // null or target ilg.Emit(OpCodes.Ldnull); // (null or target), null ilg.Emit(OpCodes.Cgt_Un); // (0 or 1) ilg.Emit(OpCodes.Brtrue, onLabel); } ilg.Emit(OpCodes.Ldloc,targetTemp); // target ilg.Emit(OpCodes.Call,Compiler.Method_Util_classOf); // class LocalBuilder typeTemp = ilg.DeclareLocal(typeof(Type)); GenContext.SetLocalName(typeTemp, "type"); ilg.Emit(OpCodes.Stloc,typeTemp); // (typeType <= class) ilg.EmitLoadArg(0); // this ilg.Emit(OpCodes.Ldloc,typeTemp); // this, class ilg.EmitFieldSet(objx.CachedTypeField(_siteIndex)); // ilg.MarkLabel(callLabel); objx.EmitVar(ilg,v); // var ilg.Emit(OpCodes.Call,Compiler.Method_Var_getRawRoot); // proto-fn ilg.Emit(OpCodes.Castclass, typeof(AFunction)); ilg.Emit(OpCodes.Ldloc,targetTemp); // proto-fn, target EmitArgsAndCall(1,rhc,objx,ilg); ilg.Emit(OpCodes.Br,endLabel); ilg.MarkLabel(onLabel); ilg.Emit(OpCodes.Ldloc,targetTemp); // target if ( _protocolOn != null ) { ilg.Emit(OpCodes.Castclass, _protocolOn); MethodExpr.EmitTypedArgs(objx, ilg, _onMethod.GetParameters(), RT.subvec(_args, 1, _args.count())); //if (rhc == RHC.Return) //{ // ObjMethod2 method = (ObjMethod)Compiler.MethodVar.deref(); // method.EmitClearLocals(context); //} ilg.Emit(OpCodes.Callvirt, _onMethod); HostExpr.EmitBoxReturn(objx, ilg, _onMethod.ReturnType); } ilg.MarkLabel(endLabel); }
private Expression GenProtoFull(RHC rhc, ObjExpr objx, GenContext context, Expression fn) { Var v = ((VarExpr)_fexpr).Var; Expr e = (Expr)_args.nth(0); ParameterExpression targetParam = Expression.Parameter(typeof(Object), "target"); ParameterExpression targetTypeParam = Expression.Parameter(typeof(Type), "targetType"); ParameterExpression vpfnParam = Expression.Parameter(typeof(AFunction), "vpfn"); ParameterExpression thisParam = objx.ThisParam; Expression targetParamAssign = Expression.Assign(targetParam, Expression.Convert(e.GenCode(RHC.Expression, objx, context), targetParam.Type)); Expression targetTypeParamAssign = Expression.Assign( targetTypeParam, Expression.Call(null, Compiler.Method_Util_classOf, targetParam)); Expression cachedTypeField = Expression.Field(thisParam, objx.CachedTypeField(_siteIndex)); Expression setCachedClass = Expression.Assign( cachedTypeField, targetTypeParam); Expression vpfnParamAssign = Expression.Assign( vpfnParam, Expression.Convert(Expression.Call(objx.GenVar(context, v), Compiler.Method_Var_getRawRoot), typeof(AFunction))); if (_protocolOn == null) { return(Expression.Block( new ParameterExpression[] { targetParam, targetTypeParam, vpfnParam }, targetParamAssign, targetTypeParamAssign, Expression.IfThen( Expression.NotEqual(targetTypeParam, cachedTypeField), setCachedClass), vpfnParamAssign, GenerateArgsAndCall(rhc, objx, context, vpfnParam, targetParam))); } else { Expression[] args = new Expression[_args.count() - 1]; for (int i = 1; i < _args.count(); i++) { Expression bare = ((Expr)_args.nth(i)).GenCode(RHC.Expression, objx, context); args[i - 1] = Compiler.MaybeBox(bare); } return(Expression.Block( new ParameterExpression[] { targetParam, targetTypeParam, vpfnParam }, targetParamAssign, targetTypeParamAssign, Expression.Condition( Expression.And( Expression.NotEqual(targetTypeParam, cachedTypeField), Expression.TypeIs(targetParam, _protocolOn)), Compiler.MaybeBox(Expression.Call(Expression.Convert(targetParam, _protocolOn), _onMethod, args)), Expression.Block( Expression.IfThen( Expression.NotEqual(targetTypeParam, cachedTypeField), setCachedClass), vpfnParamAssign, GenerateArgsAndCall(rhc, objx, context, vpfnParam, targetParam))))); } }