Created
November 22, 2013 19:29
-
-
Save lance/7605454 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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