mirror of
https://github.com/fluencelabs/asmble
synced 2025-04-24 22:32:19 +00:00
First Rust example for issue #9
This commit is contained in:
parent
0c4fb45d79
commit
ff7c88bf6c
3
.gitignore
vendored
3
.gitignore
vendored
@ -10,3 +10,6 @@
|
||||
/emscripten-runtime/out
|
||||
/annotations/build
|
||||
/annotations/out
|
||||
/examples/rust-simple/Cargo.lock
|
||||
/examples/rust-simple/build
|
||||
/examples/rust-simple/target
|
||||
|
63
build.gradle
63
build.gradle
@ -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'
|
||||
}
|
@ -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
|
||||
|
2
examples/rust-simple/.cargo/config
Normal file
2
examples/rust-simple/.cargo/config
Normal file
@ -0,0 +1,2 @@
|
||||
[build]
|
||||
target = "wasm32-unknown-unknown"
|
6
examples/rust-simple/Cargo.toml
Normal file
6
examples/rust-simple/Cargo.toml
Normal file
@ -0,0 +1,6 @@
|
||||
[package]
|
||||
name = "rust_simple"
|
||||
version = "0.1.0"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
24
examples/rust-simple/README.md
Normal file
24
examples/rust-simple/README.md
Normal 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;
|
||||
}
|
||||
```
|
4
examples/rust-simple/src/lib.rs
Normal file
4
examples/rust-simple/src/lib.rs
Normal file
@ -0,0 +1,4 @@
|
||||
#[no_mangle]
|
||||
pub extern "C" fn add_one(x: i32) -> i32 {
|
||||
x + 1
|
||||
}
|
@ -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));
|
||||
}
|
||||
}
|
@ -1,2 +1,5 @@
|
||||
rootProject.name = 'asmble'
|
||||
include 'annotations', 'compiler', 'emscripten-runtime'
|
||||
include 'annotations',
|
||||
'compiler',
|
||||
'emscripten-runtime',
|
||||
'examples:rust-simple'
|
Loading…
x
Reference in New Issue
Block a user