First Rust example for issue #9

This commit is contained in:
Chad Retz 2017-11-28 17:00:38 -06:00
parent 0c4fb45d79
commit ff7c88bf6c
9 changed files with 121 additions and 2 deletions

3
.gitignore vendored
View File

@ -10,3 +10,6 @@
/emscripten-runtime/out
/annotations/build
/annotations/out
/examples/rust-simple/Cargo.lock
/examples/rust-simple/build
/examples/rust-simple/target

View File

@ -7,9 +7,13 @@ buildscript {
repositories {
mavenCentral()
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'me.champeau.gradle:jmh-gradle-plugin:0.4.4'
}
}
@ -49,3 +53,62 @@ project(':compiler') {
testCompile "org.ow2.asm:asm-debug-all:$asm_version"
}
}
project(':examples') {
subprojects {
dependencies {
compileOnly project(':compiler')
}
task rustToWasm(type: Exec) {
commandLine 'cargo', 'build', '--release'
}
ext.wasmFileName = { ->
def wasmFiles = fileTree(dir: 'target/wasm32-unknown-unknown/release', includes: ['*.wasm']).files
if (wasmFiles.size() != 1) throw new GradleException('Expected single WASM file, got ' + wasmFiles.size())
return wasmFiles.iterator().next()
}
task wasmFile() {
dependsOn rustToWasm
doFirst {
println 'File: ' + wasmFileName()
}
}
task showWast(type: JavaExec) {
dependsOn rustToWasm
classpath configurations.compileClasspath
main = 'asmble.cli.MainKt'
doFirst {
args 'translate', wasmFileName()
}
}
task compileWasm(type: JavaExec) {
dependsOn rustToWasm
classpath configurations.compileClasspath
main = 'asmble.cli.MainKt'
doFirst {
// args 'help', 'compile'
def outFile = 'build/wasm-classes/' + wasmCompiledClassName.replace('.', '/') + '.class'
file(outFile).parentFile.mkdirs()
args 'compile', wasmFileName(), wasmCompiledClassName, '-out', outFile
}
}
}
}
project(':examples:rust-simple') {
apply plugin: 'application'
ext.wasmCompiledClassName = 'asmble.generated.RustSimple'
dependencies {
compile files('build/wasm-classes')
}
compileJava {
dependsOn compileWasm
}
mainClassName = 'asmble.examples.rustsimple.Main'
}

View File

@ -79,7 +79,7 @@ open class Linker {
params = params.map(ModuleClass::ref),
ret = mod.ref
)
// The stack here on our is for building params to constructor...
// The stack here on out is for building params to constructor...
// The constructor we'll use is:
// * Mem-class based constructor if it's an import

View File

@ -0,0 +1,2 @@
[build]
target = "wasm32-unknown-unknown"

View File

@ -0,0 +1,6 @@
[package]
name = "rust_simple"
version = "0.1.0"
[lib]
crate-type = ["cdylib"]

View File

@ -0,0 +1,24 @@
### Example: Rust Simple
This shows a simple example of compiling Rust to WASM and then to the JVM.
The [root build script](../../build.gradle) actually has the build commands to build it. But basically it runs
`cargo build --release` on this directory which compiles `add_one` from [lib.rs](src/lib.rs) into
`target/wasm32-unknown-unknown/release/rust_simple.wasm`. Then the build script takes that wasm file and compiles it
to `asmble.generated.RustSimple` in `build/wasm-classes`. The class is used by
[Main.java](src/main/java/asmble/examples/rustsimple/Main.java). It is instantiated with a set of memory and then
`add_one` is invoked with `25` to return `26`.
To run it yourself, run the following from the root `asmble` dir (assuming you have built the Gradle wrapper described
in the root README's "Building and Testing" section):
./gradlew --no-daemon :examples:rust-simple:run
Yes, this does include Rust's std lib, but it's not that big of a deal. The actual method executed for `add_one` looks
like this decompiled:
```java
private int $func0(final int n) {
return n + 1;
}
```

View File

@ -0,0 +1,4 @@
#[no_mangle]
pub extern "C" fn add_one(x: i32) -> i32 {
x + 1
}

View File

@ -0,0 +1,14 @@
package asmble.examples.rustsimple;
import asmble.generated.RustSimple;
class Main {
// 20 pages is good for now
private static final int PAGE_SIZE = 65536;
private static final int MAX_MEMORY = 20 * PAGE_SIZE;
public static void main(String[] args) {
RustSimple simple = new RustSimple(MAX_MEMORY);
System.out.println("25 + 1 = " + simple.add_one(25));
}
}

View File

@ -1,2 +1,5 @@
rootProject.name = 'asmble'
include 'annotations', 'compiler', 'emscripten-runtime'
include 'annotations',
'compiler',
'emscripten-runtime',
'examples:rust-simple'