Let's touch WebAssembly, which is getting better recently. I would like to create an environment where Java can be executed as a subject. Yes, it's a Java interpreter (Java VM) that runs in a browser, like a Java applet.
First of all, I would like to decline. Although it is a Java interpreter that interprets Java bytecode, it implements minimal bytecode. Also, since it implements only a few classes under java / lang, it is practically useless. Personally, I made it for studying the Java interpreter. I'm sorry for those who have expected.
We will proceed as follows.
I referred to "waba" as the C language source code of the Java interpreter. I learned a lot. Thank you very much.
wabasoft http://wabasoft.com/
I used "emscripten" for the WebAssembly compiler. https://emscripten.org/index.html
The following is the sequel. Running JavaVM with WebAssembly: Supplement
I installed it in the WSL environment of Windows 10. So I use Python2.7, but it was already installed.
> python --version
Python 2.7.15rc1
> git clone https://github.com/juj/emsdk.git
> cd emsdk
> ./emsdk install latest
> ./emsdk activate latest
You have now installed the WebAssembly compiler "emcc". When using it, you need to pass it through, so do the following:
> source ./emsdk_env.sh --build=Release
Create an appropriate folder and work.
Place a set of C language source files in the same folder.
I have posted it on the following GitHub.
https://github.com/poruruba/javaemu
> git clone https://github.com/poruruba/javaemu.git
> cd javaemu
Compile the Java source code. Java source code is divided into two types, and the placement method is changed. The first is Java source that is embedded in WebAssembly, and the other is Java source that is not embedded in WebAssembly. The latter is regular user-written Java source code. On the other hand, java / lang etc. are used by normal users, and the Java source of the system that does not change is the former. In addition, Java classes that have native functions that can be processed only in C language and that work with the interpreter are also the former.
It is assumed that the source code will be created under the java_src folder. Create a folder to put the compiled class files. Let's say pre_classes.
> mkdir pre_classes
The compilation is as follows.
>javac -encoding UTF8 -d pre_classes -sourcepath java_src java_src/base/framework/*.java java_src/java/lang/*.java java_src/test/*.java
The Java source files under base / framework and java / lang are the Java source of the system. java_src / test / *. java will be used for testing later, so please remove it after testing. Now you have a Java class file under the pre_classes folder.
I used the Oracle JDK on Windows. In the case of OpenJDK, I batted it with the class file on the execution environment, and I didn't know how to exclude it. .. ..
Now let's compile
> emcc *.c -s WASM=1 -o javaemu.js -s "EXTRA_EXPORTED_RUNTIME_METHODS=['ccall', 'UTF8ArrayToString', 'stringToUTF8Array']" --preload-file pre_classes
(Reference) Compile-time options https://emscripten.org/docs/tools_reference/emcc.html#emccdoc
-s WASM = 1 is a spell that indicates that a WASM file will be generated.
-o javaemu.js is for generating a file (javaemu.data) that combines WASM files (javaemu.wasm), utility Javascript (javaemu.js), and Java class files to be embedded in WebAssembly. The name javaemu is appropriate. Please use any name you like.
-s EXTRA_EXPORTED_RUNTIME_METHODS is the name of the function provided by javaemu.js that is allowed to be called from Javascript of the HTML page placed on the Web. ccall is required, but the other two are useful, so I set them.
--preload-file specifies the name of the folder where the files to be embedded in WebAssembly are located. The files under the specified folder name are grouped into a file called javaemu.data.
Of the completed files, the ones that will be placed on the Web are "javaemu.wasm", "javaemu.js", and "javaemu.data". javaemu.wasm is just a WebAssembly file compiled from C language.
Functions called from Javascript on web pages are defined in main.c.
main.c
int EMSCRIPTEN_KEEPALIVE setInoutBuffer(const unsigned char *buffer, long bufferSize );
int EMSCRIPTEN_KEEPALIVE setRomImage(unsigned char *romImage, long romSize );
int EMSCRIPTEN_KEEPALIVE callStaticMain(char *className, char *param );
Upload the html of the files dropped from GitHub to the web server. We have also prepared a page for checking the operation. Place the three files you just generated in the html folder as well.
> cp javaemu.wasm javaemu.js javaemu.data html/
Or
> cd html
> ln -s ../javaemu.wasm ../javaemu.js ../javaemu.data .
> cd ..
(Please put it in the root folder of HTML, otherwise javaemu.js will not read the wasm and data files well)
Thankfully, emscripten has a simple web server feature, so I'll use that. The port number is 8080.
emrun --serve_root html --no_browser --port 8080 .
Now, let's access it from a browser. As a browser, I tried running it on Chrome on Windows.
http://localhost:8080
For clarity, I'm pressing F12 to bring up the developer console.
Around Class Name, enter the embedded Java class name for testing. It is "test / TestFunc".
The original source code looks like the following.
TestFunc.java
package test;
import base.framework.System;
import base.framework.Convert;
import base.framework.Util;
public class TestFunc{
public static void main( String[] args ){
try
{
System.println("Hello test/TestFunc");
if( args.length >= 1 )
System.println("args[0]=" + args[0]);
String[] input = System.getInput(-1);
for( int i = 0 ; i < input.length ; i++ )
System.println("params[" + i + "]=" + input[i]);
System.setOutput(new String[]{ "World", "Good evening" });
}catch( Exception ex )
{
System.print( ex.toString() );
ex.printStackTrace();
}
}
}
Enter an appropriate character string in Input Arg and Input Params. Immediately press the "start was m" button.
Call the function implemented in C language with the following feeling. It takes a lot of work to load and run the WebAssembly file, but javaemu.js does it well.
start.js
this.output_return = Module.ccall('callStaticMain', // name of C function
"number", // return type
["string", "string"], // argument types
[this.class_name, this.input_arg]); // arguments
Then, while the messy debug characters were displayed in the console of the browser, I think that the following character string was displayed. The Java class file has been executed by the Java interpreter.
Hello test/TestFunc args[0]=ABCD params [] = Aiueo params [1] = Kakikukeko
Also, you should see the following on the page.
Output Return 0 Output Params ["World", "Good evening"]
Now let's create and run various Java sources.
I will create it under java_src. This time, we will create it under the test2 folder.
The compilation is as follows.
> mkdir classes
> javac -encoding UTF8 -d classes -sourcepath java_src -classpath pre_classes java_src/test2/*.java
I am creating a folder classes for storing class files. Since pre_classes is assumed to be embedded in the WebAssembly file, it is assumed that it is an existing class file and compiled.
Next, make the created class file a Jar file.
> jar cvf classes.jar -C classes .
The files under the classes folder are now grouped in the classes.jar file. Files other than the test2 class file have also been created, but they are harmless and can be ignored or excluded from the Jar file target.
Click the "Select File" button and specify the "classes.jar" created earlier. Below that, you'll see a list of the class files contained in the Jar file.
I used unzip.min.js of zlib.js to extract the Jar file, that is, the ZIP file.
zlib.js https://github.com/imaya/zlib.js
Now run it again from your browser.
Specify test2 / TestFunc included in the Jar file for Class Name, and click the "start was m" button to execute.
Did you see something like this on the console? It becomes test2 / TestFunc and you can see that the corresponding source is running.
Hello test2/TestFunc args[0]=ABCD [] = Aiueo [1] = Kakikukeko
The Java interpreter has been heavily customized from waba and is full of bugs, so I'll decline that much. .. ..
The explanation will be in the next article. First up to here.
The following is the sequel. Running JavaVM with WebAssembly: Supplement
that's all.
Recommended Posts