Kengo's blog

Technical articles about original projects, JVM, Static Analysis and TypeScript.

How dynjs runs javascript

※ブログ記事と言うよりはメモのようなものなので、日本語は省略します。


I'm trying to read dynjs. At 1st, let's try to know how it executes given javascript.

READY TO READ

build it and create an IDE project

There is a wiki page to introduce how to build. Please read and try it.
I created an Eclipse project by executing mvn eclipse:eclipse -DdownloadSources.

creating script

The dynjs gets script from files to execute. So we have to create a script file.

$ echo 'print("Hello, world!");' > sample.js

TRACE IT!

loading script from a file

OK, let's execute Main.java from IDE. We can give arguments to dynjs, so I give just "sample.js".
Main.java has a main method. It build an argument object with args4j. At last, Main class calls executeFile method.

final DynJSConfig cfg = new DynJSConfig();
new DynJS(cfg).eval(context, new FileInputStream(filename));

This eval(DynThreadContext, InputStream) method calls parseSourceCode(DynThreadContext, InputStream) method to create a List<Statement> with parser created by antlr3. This list is used to execute a compiler.

private void execute(DynThreadContext context, List result) {
Script script = compiler.compile(result.toArray(new Statement[]{}));
script.setGlobalScope(context.getScope());
script.execute(context);
}

dynjs/src/main/java/org/dynjs/runtime/DynJS.java at 150f102bec3709e3af5e7a49934feb075f9cd008 from dynjs/dynjs - GitHub
compiling a List<Statement>

Compiler gets List<Statement> from DynJS class, and use it to compile.

Compiler creates a class and its instance dynamically, and call its execute(DynThreadContext) method. I dumped defined class to a binary file and checked it by javap, and I found this method is very simple.

public void execute(org.dynjs.runtime.DynThreadContext);
  Code:
   0:	ldc	#14; //String Hello, world!
   2:	dup
   3:	getstatic	#20; //Field java/lang/System.out:Ljava/io/PrintStream;
   6:	swap
   7:	invokevirtual	#26; //Method java/io/PrintStream.println:(Ljava/lang/Object;)V
   10:	return
}

My sample.js doesn't need context, so it doesn't use opcode like aload etc. I'll try to check around parser, method calls and the duck typing.