Last active
October 31, 2018 16:20
-
-
Save taowen/6ca3c5942c396298d0903bb686a3b373 to your computer and use it in GitHub Desktop.
This file contains 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
import org.graalvm.polyglot.*; | |
import java.lang.reflect.Array; | |
import java.lang.reflect.Field; | |
import java.util.Arrays; | |
public class Main { | |
public static void main(String[] args) throws Exception { | |
try (Context context = Context.create("js")) { | |
context.eval("js", "" + | |
"function *fib() {" + | |
"yield 1;" + | |
"yield 1;" + | |
"yield 2;" + | |
"yield 3;" + | |
"yield 5;" + | |
"}"); | |
Value returnNext = context.eval("js", "function(gen) { return gen.next(); }"); | |
Value fib = context.eval("js", "" + | |
"f = fib();"); | |
System.out.println(returnNext.execute(fib)); | |
printProgramCounter(fib); | |
System.out.println(returnNext.execute(fib)); | |
printProgramCounter(fib); | |
System.out.println(returnNext.execute(fib)); | |
printProgramCounter(fib); | |
System.out.println(returnNext.execute(fib)); | |
printProgramCounter(fib); | |
System.out.println(returnNext.execute(fib)); | |
printProgramCounter(fib); | |
// jump back to yield 1 | |
Object locals = get(fib, "receiver", "object2", "locals"); | |
Array.set(locals, 8, 1); | |
System.out.println(returnNext.execute(fib)); | |
System.out.println(returnNext.execute(fib)); | |
System.out.println(returnNext.execute(fib)); | |
} | |
} | |
private static void printProgramCounter(Value fib) throws Exception { | |
System.out.println(get(fib, "receiver", "object2", "locals", 8)); | |
} | |
private static Object get(Object obj, Object... paths) throws Exception { | |
if (paths.length == 0) { | |
return obj; | |
} | |
if (paths.length == 1) { | |
return getElementOrFieldValue(obj, paths[0]); | |
} | |
return get(getElementOrFieldValue(obj, paths[0]), Arrays.copyOfRange(paths, 1, paths.length)); | |
} | |
private static Object getElementOrFieldValue(Object obj, Object indexOrFieldName) throws Exception { | |
if (indexOrFieldName instanceof Integer) { | |
return Array.get(obj, (Integer) indexOrFieldName); | |
} | |
return getFieldValue(obj, (String) indexOrFieldName); | |
} | |
private static Object getFieldValue(Object obj, String fieldName) throws Exception { | |
Field field = getField(obj.getClass(), fieldName); | |
return field.get(obj); | |
} | |
private static Field getField(Class clazz, String fieldName) throws Exception { | |
Field field = clazz.getDeclaredField(fieldName); | |
field.setAccessible(true); | |
return field; | |
} | |
} |
Author
taowen
commented
Oct 31, 2018
•
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment