Skip to content

Instantly share code, notes, and snippets.

@taowen
Last active October 31, 2018 16:20
Show Gist options
  • Save taowen/6ca3c5942c396298d0903bb686a3b373 to your computer and use it in GitHub Desktop.
Save taowen/6ca3c5942c396298d0903bb686a3b373 to your computer and use it in GitHub Desktop.
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;
}
}
@taowen
Copy link
Author

taowen commented Oct 31, 2018

{value: 1, done: false}
0
{value: 1, done: false}
1
{value: 2, done: false}
2
{value: 3, done: false}
3
{value: 5, done: false}
4
{value: 1, done: false}
{value: 2, done: false}
{value: 3, done: false}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment