Skip to content

Instantly share code, notes, and snippets.

@lance
Created November 22, 2013 19:29
Show Gist options
  • Save lance/7605454 to your computer and use it in GitHub Desktop.
Save lance/7605454 to your computer and use it in GitHub Desktop.
package org.dynjs.runtime.linker.java;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodType;
import org.dynjs.runtime.ExecutionContext;
import org.dynjs.runtime.Types;
import org.projectodd.rephract.LinkLogger;
import org.projectodd.rephract.StrategicLink;
import org.projectodd.rephract.StrategyChain;
import org.projectodd.rephract.mop.ContextualLinkStrategy;
import com.headius.invokebinder.Binder;
public class JavaNullReplacingLinkStrategy extends ContextualLinkStrategy<ExecutionContext> {
private static MethodHandle RETURN_FILTER_HANDLE;
private static MethodHandle ARG_FILTER_HANDLE;
static {
try {
RETURN_FILTER_HANDLE = lookup().findStatic(JavaNullReplacingLinkStrategy.class, "filterReturn", MethodType.methodType(Object.class, Object.class));
ARG_FILTER_HANDLE = lookup().findStatic(JavaNullReplacingLinkStrategy.class, "filterArg", MethodType.methodType(Object.class, Object.class));
} catch (NoSuchMethodException | IllegalAccessException e) {
e.printStackTrace();
}
}
public JavaNullReplacingLinkStrategy(LinkLogger logger) {
super(ExecutionContext.class, logger);
}
@Override
public StrategicLink linkGetProperty(StrategyChain chain, Object receiver, String propName, Binder binder, Binder guardBinder) throws NoSuchMethodException,
IllegalAccessException {
StrategicLink link = super.linkGetProperty(chain, receiver, propName, binder, guardBinder);
if (link != null) {
MethodHandle target = link.getTarget();
return new StrategicLink(Binder.from(target.type()).filterReturn(RETURN_FILTER_HANDLE).invoke(target), link.getGuard());
}
return null;
}
@Override
public StrategicLink linkGetMethod(StrategyChain chain, Object receiver, String methodName, Binder binder, Binder guardBinder) throws NoSuchMethodException,
IllegalAccessException {
StrategicLink link = super.linkGetMethod(chain, receiver, methodName, binder, guardBinder);
if (link != null) {
MethodHandle target = link.getTarget();
return new StrategicLink(Binder.from(target.type()).filterReturn(RETURN_FILTER_HANDLE).invoke(target), link.getGuard());
}
return null;
}
@Override
public StrategicLink linkCall(StrategyChain chain, Object receiver, Object self, Object[] args, Binder binder, Binder guardBinder) throws NoSuchMethodException,
IllegalAccessException {
System.err.println("CALLING: " + receiver);
System.err.println("ON: " + self);
for (int i=0; i< args.length; ++i) {
System.err.println("WITH: " + args[i].getClass().getName());
}
StrategicLink link = super.linkCall(chain, receiver, self, args, binder, guardBinder);
if (link != null) {
MethodHandle target = link.getTarget();
System.err.println("Linked to target: " + target.type());
return new StrategicLink(Binder.from(target.type()).filterReturn(RETURN_FILTER_HANDLE).filter(0, ARG_FILTER_HANDLE).invoke(target), link.getGuard());
}
return null;
}
public static Object filterReturn(Object value) {
if (value == null) {
return Types.UNDEFINED;
}
return value;
}
public static Object filterArg(Object value) {
System.err.println("FILTERING ARG: " + value);
if (value .getClass() == Types.Null.class) {
return null;
}
return value;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment