@Override public Binder prepareBinder() { return Binder .from(type()) .filterReturn(CACHE.bindTo(this)); } }
@Override public Binder prepareBinder() { return Binder .from(type()) .filterReturn(CACHE.bindTo(this)); } }
/** * Use the given filter function to transform the return value at this * point in the binder. The filter will be inserted into the handle, and * return values will pass through it before continuing. * * The filter's argument must match the expected return value downstream * from this point in the binder, and the return value must match the * return value at this point in the binder. * * @param filter the function to use to transform the return value at this point * @return a new SmartBinder with the filter applied */ public SmartBinder filterReturn(MethodHandle filter) { return new SmartBinder(this, signature().changeReturn(filter.type().returnType()), binder.filterReturn(filter)); }
private static MethodHandle createAttrReaderHandle(InvokeSite site, IRubyObject self, RubyClass cls, VariableAccessor accessor) { MethodHandle nativeTarget; MethodHandle filter = cls.getClassRuntime().getNullToNilHandle(); MethodHandle getValue; if (accessor instanceof FieldVariableAccessor) { MethodHandle getter = ((FieldVariableAccessor)accessor).getGetter(); getValue = Binder.from(site.type()) .drop(0, 2) .filterReturn(filter) .cast(methodType(Object.class, self.getClass())) .invoke(getter); } else { getValue = Binder.from(site.type()) .drop(0, 2) .filterReturn(filter) .cast(methodType(Object.class, Object.class)) .prepend(accessor) .invokeVirtualQuiet(LOOKUP, "get"); } // NOTE: Must not cache the fully-bound handle in the method, since it's specific to this class return getValue; }
private static MethodHandle createAttrReaderHandle(InvokeSite site, IRubyObject self, RubyClass cls, VariableAccessor accessor) { MethodHandle nativeTarget; MethodHandle filter = cls.getClassRuntime().getNullToNilHandle(); MethodHandle getValue; if (accessor instanceof FieldVariableAccessor) { MethodHandle getter = ((FieldVariableAccessor)accessor).getGetter(); getValue = Binder.from(site.type()) .drop(0, 2) .filterReturn(filter) .cast(methodType(Object.class, self.getClass())) .invoke(getter); } else { getValue = Binder.from(site.type()) .drop(0, 2) .filterReturn(filter) .cast(methodType(Object.class, Object.class)) .prepend(accessor) .invokeVirtualQuiet(LOOKUP, "get"); } // NOTE: Must not cache the fully-bound handle in the method, since it's specific to this class return getValue; }
private static MethodHandle createAttrWriterHandle(InvokeSite site, IRubyObject self, RubyClass cls, VariableAccessor accessor) { MethodHandle nativeTarget; MethodHandle filter = Binder .from(IRubyObject.class, Object.class) .drop(0) .constant(cls.getRuntime().getNil()); MethodHandle setValue; if (accessor instanceof FieldVariableAccessor) { MethodHandle setter = ((FieldVariableAccessor)accessor).getSetter(); setValue = Binder.from(site.type()) .drop(0, 2) .filterReturn(filter) .cast(methodType(void.class, self.getClass(), Object.class)) .invoke(setter); } else { setValue = Binder.from(site.type()) .drop(0, 2) .filterReturn(filter) .cast(methodType(void.class, Object.class, Object.class)) .prepend(accessor) .invokeVirtualQuiet(LOOKUP, "set"); } return setValue; }
private static MethodHandle createAttrWriterHandle(InvokeSite site, IRubyObject self, RubyClass cls, VariableAccessor accessor) { MethodHandle nativeTarget; MethodHandle filter = Binder .from(IRubyObject.class, Object.class) .drop(0) .constant(cls.getRuntime().getNil()); MethodHandle setValue; if (accessor instanceof FieldVariableAccessor) { MethodHandle setter = ((FieldVariableAccessor)accessor).getSetter(); setValue = Binder.from(site.type()) .drop(0, 2) .filterReturn(filter) .cast(methodType(void.class, self.getClass(), Object.class)) .invoke(setter); } else { setValue = Binder.from(site.type()) .drop(0, 2) .filterReturn(filter) .cast(methodType(void.class, Object.class, Object.class)) .prepend(accessor) .invokeVirtualQuiet(LOOKUP, "set"); } return setValue; }
/** * Use the given filter function to transform the return value at this * point in the binder. The filter will be inserted into the handle, and * return values will pass through it before continuing. * * The filter's argument must match the expected return value downstream * from this point in the binder, and the return value must match the * return value at this point in the binder. * * @param filter the function to use to transform the return value at this point * @return a new SmartBinder with the filter applied */ public SmartBinder filterReturn(SmartHandle filter) { return new SmartBinder(this, signature().changeReturn(filter.signature().type().returnType()), binder.filterReturn(filter.handle())); }
.from(site.type()) .permute(2) .filterReturn(filter); .from(site.type()) .permute(2) .filterReturn(filter) .insert(1, accessor.getIndex()) .cast(Object.class, RubyBasicObject.class, int.class)
.from(site.type()) .permute(2, 3) .filterReturn(filter); .from(site.type()) .permute(2, 3) .filterReturn(filter) .insert(1, cls.getRealClass(), accessor.getIndex()) .cast(void.class, RubyBasicObject.class, RubyClass.class, int.class, Object.class)
.from(site.type()) .permute(2, 3) .filterReturn(filter); .from(site.type()) .permute(2, 3) .filterReturn(filter) .insert(1, cls.getRealClass(), accessor.getIndex()) .cast(void.class, RubyBasicObject.class, RubyClass.class, int.class, Object.class)
.from(site.type()) .permute(2) .filterReturn(filter); .from(site.type()) .permute(2) .filterReturn(filter) .insert(1, accessor.getIndex()) .cast(Object.class, RubyBasicObject.class, int.class)
.permute(2) .filter(0, receiverConverter) .filterReturn(filter) .cast(fieldHandle.type()) .invoke(fieldHandle); .permute(2, 3) .filter(0, receiverConverter) .filterReturn(constant(IRubyObject.class, self.getRuntime().getNil())) .cast(fieldHandle.type()) .invoke(fieldHandle);
.permute(2) .filter(0, receiverConverter) .filterReturn(filter) .cast(fieldHandle.type()) .invoke(fieldHandle); .permute(2, 3) .filter(0, receiverConverter) .filterReturn(constant(IRubyObject.class, self.getRuntime().getNil())) .cast(fieldHandle.type()) .invoke(fieldHandle);
if (nativeReturn != void.class) { exBinder = exBinder .filterReturn(Binder .from(newNativeReturn) .constant(nullValue(newNativeReturn))); .from(site.type()) .drop(0, isStatic ? 3 : 2) .filterReturn(returnFilter) .invoke(nativeTarget);
if (nativeReturn != void.class) { exBinder = exBinder .filterReturn(Binder .from(newNativeReturn) .constant(nullValue(newNativeReturn))); .from(site.type()) .drop(0, isStatic ? 3 : 2) .filterReturn(returnFilter) .invoke(nativeTarget);
if (nativeReturn != void.class) { exBinder = exBinder .filterReturn(Binder .from(newNativeReturn) .constant(nullValue(newNativeReturn))); .from(site.type()) .drop(0, isStatic ? 3 : 2) .filterReturn(returnFilter) .invoke(nativeTarget);
if (nativeReturn != void.class) { exBinder = exBinder .filterReturn(Binder .from(newNativeReturn) .constant(nullValue(newNativeReturn))); .from(site.type()) .drop(0, isStatic ? 3 : 2) .filterReturn(returnFilter) .invoke(nativeTarget);
.filterReturn(resultFilter) .invoke(nativeInvoker);
.filterReturn(resultFilter) .invoke(nativeInvoker);