mirror of
https://github.com/fluencelabs/asmble
synced 2025-04-24 22:32:19 +00:00
Initial skeleton for issue #9
This commit is contained in:
parent
8b51e14c33
commit
4febf34e69
3
.gitignore
vendored
3
.gitignore
vendored
@ -16,3 +16,6 @@
|
||||
/examples/rust-string/Cargo.lock
|
||||
/examples/rust-string/build
|
||||
/examples/rust-string/target
|
||||
/examples/rust-regex/Cargo.lock
|
||||
/examples/rust-regex/build
|
||||
/examples/rust-regex/target
|
||||
|
32
build.gradle
32
build.gradle
@ -70,30 +70,30 @@ project(':examples') {
|
||||
}
|
||||
}
|
||||
|
||||
ext.wasmFileName = { ->
|
||||
ext.rustWasmFileName = { ->
|
||||
def buildType = rustBuildRelease ? 'release' : 'debug'
|
||||
def wasmFiles = fileTree(dir: "target/wasm32-unknown-unknown/$buildType", includes: ['*.wasm']).files
|
||||
if (wasmFiles.size() != 1) throw new GradleException('Expected single WASM file, got ' + wasmFiles.size())
|
||||
return wasmFiles.iterator().next()
|
||||
}
|
||||
|
||||
task wasmFile() {
|
||||
task rustWasmFile() {
|
||||
dependsOn rustToWasm
|
||||
doFirst {
|
||||
println 'File: ' + wasmFileName()
|
||||
println 'File: ' + rustWasmFileName()
|
||||
}
|
||||
}
|
||||
|
||||
task showWast(type: JavaExec) {
|
||||
task showRustWast(type: JavaExec) {
|
||||
dependsOn rustToWasm
|
||||
classpath configurations.compileClasspath
|
||||
main = 'asmble.cli.MainKt'
|
||||
doFirst {
|
||||
args 'translate', wasmFileName()
|
||||
args 'translate', rustWasmFileName()
|
||||
}
|
||||
}
|
||||
|
||||
task compileWasm(type: JavaExec) {
|
||||
task compileRustWasm(type: JavaExec) {
|
||||
dependsOn rustToWasm
|
||||
classpath configurations.compileClasspath
|
||||
main = 'asmble.cli.MainKt'
|
||||
@ -101,12 +101,24 @@ project(':examples') {
|
||||
// args 'help', 'compile'
|
||||
def outFile = 'build/wasm-classes/' + wasmCompiledClassName.replace('.', '/') + '.class'
|
||||
file(outFile).parentFile.mkdirs()
|
||||
args 'compile', wasmFileName(), wasmCompiledClassName, '-out', outFile
|
||||
args 'compile', rustWasmFileName(), wasmCompiledClassName, '-out', outFile
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
project(':examples:rust-regex') {
|
||||
apply plugin: 'application'
|
||||
ext.wasmCompiledClassName = 'asmble.generated.RustRegex'
|
||||
dependencies {
|
||||
compile files('build/wasm-classes')
|
||||
}
|
||||
compileJava {
|
||||
dependsOn compileRustWasm
|
||||
}
|
||||
mainClassName = 'asmble.examples.rustregex.Main'
|
||||
}
|
||||
|
||||
project(':examples:rust-simple') {
|
||||
apply plugin: 'application'
|
||||
ext.wasmCompiledClassName = 'asmble.generated.RustSimple'
|
||||
@ -114,9 +126,8 @@ project(':examples:rust-simple') {
|
||||
compile files('build/wasm-classes')
|
||||
}
|
||||
compileJava {
|
||||
dependsOn compileWasm
|
||||
dependsOn compileRustWasm
|
||||
}
|
||||
|
||||
mainClassName = 'asmble.examples.rustsimple.Main'
|
||||
}
|
||||
|
||||
@ -127,8 +138,7 @@ project(':examples:rust-string') {
|
||||
compile files('build/wasm-classes')
|
||||
}
|
||||
compileJava {
|
||||
dependsOn compileWasm
|
||||
dependsOn compileRustWasm
|
||||
}
|
||||
|
||||
mainClassName = 'asmble.examples.ruststring.Main'
|
||||
}
|
2
examples/rust-regex/.cargo/config
Normal file
2
examples/rust-regex/.cargo/config
Normal file
@ -0,0 +1,2 @@
|
||||
[build]
|
||||
target = "wasm32-unknown-unknown"
|
9
examples/rust-regex/Cargo.toml
Normal file
9
examples/rust-regex/Cargo.toml
Normal file
@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "rust_regex"
|
||||
version = "0.1.0"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
regex = "0.2"
|
3
examples/rust-regex/README.md
Normal file
3
examples/rust-regex/README.md
Normal file
@ -0,0 +1,3 @@
|
||||
### Example: Rust Regex
|
||||
|
||||
TODO: The regex crate does not yet build with wasm32-unknown-unknown
|
37
examples/rust-regex/src/lib.rs
Normal file
37
examples/rust-regex/src/lib.rs
Normal file
@ -0,0 +1,37 @@
|
||||
#![feature(allocator_api)]
|
||||
|
||||
extern crate regex;
|
||||
|
||||
use regex::Regex;
|
||||
use std::heap::{Alloc, Heap, Layout};
|
||||
use std::mem;
|
||||
use std::str;
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn compile_pattern(str_ptr: *mut u8, len: usize) -> *const Regex {
|
||||
unsafe {
|
||||
let bytes = Vec::<u8>::from_raw_parts(str_ptr, len, len);
|
||||
let s = str::from_utf8(&bytes).unwrap();
|
||||
let r = Regex::new(s).unwrap();
|
||||
let raw_r = &r as *const Regex;
|
||||
mem::forget(s);
|
||||
mem::forget(r);
|
||||
raw_r
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn alloc(size: usize) -> *mut u8 {
|
||||
unsafe {
|
||||
let layout = Layout::from_size_align(size, mem::align_of::<u8>()).unwrap();
|
||||
Heap.alloc(layout).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn dealloc(ptr: *mut u8, size: usize) {
|
||||
unsafe {
|
||||
let layout = Layout::from_size_align(size, mem::align_of::<u8>()).unwrap();
|
||||
Heap.dealloc(ptr, layout);
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package asmble.examples.rustregex;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class JavaLib implements RegexLib {
|
||||
@Override
|
||||
public JavaPattern compile(String str) {
|
||||
return new JavaPattern(str);
|
||||
}
|
||||
|
||||
public static class JavaPattern implements RegexPattern {
|
||||
|
||||
final Pattern pattern;
|
||||
|
||||
JavaPattern(String pattern) {
|
||||
this(Pattern.compile(pattern));
|
||||
}
|
||||
|
||||
JavaPattern(Pattern pattern) {
|
||||
this.pattern = pattern;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int matchCount(String target) {
|
||||
Matcher matcher = pattern.matcher(target);
|
||||
int count = 0;
|
||||
while (matcher.find()) {
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package asmble.examples.rustregex;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
public 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) throws Exception {
|
||||
String twainText = loadTwainText();
|
||||
System.out.println("Appearances of 'Twain': " + new JavaLib().compile("Twain").matchCount(twainText));
|
||||
}
|
||||
|
||||
public static String loadTwainText() throws IOException {
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
try (InputStream is = Main.class.getResourceAsStream("/twain-for-regex.txt")) {
|
||||
byte[] buffer = new byte[0xFFFF];
|
||||
while (true) {
|
||||
int lastLen = is.read(buffer);
|
||||
if (lastLen < 0) {
|
||||
break;
|
||||
}
|
||||
os.write(buffer, 0, lastLen);
|
||||
}
|
||||
}
|
||||
return new String(os.toByteArray(), StandardCharsets.ISO_8859_1);
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package asmble.examples.rustregex;
|
||||
|
||||
public interface RegexLib {
|
||||
|
||||
RegexPattern compile(String str);
|
||||
|
||||
interface RegexPattern {
|
||||
int matchCount(String target);
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package asmble.examples.rustregex;
|
||||
|
||||
public class RustLib implements RegexLib {
|
||||
|
||||
@Override
|
||||
public RustPattern compile(String str) {
|
||||
// TODO
|
||||
return null;
|
||||
}
|
||||
|
||||
public class RustPattern implements RegexPattern {
|
||||
|
||||
@Override
|
||||
public int matchCount(String target) {
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
302278
examples/rust-regex/src/main/resources/twain-for-regex.txt
Normal file
302278
examples/rust-regex/src/main/resources/twain-for-regex.txt
Normal file
File diff suppressed because it is too large
Load Diff
@ -2,5 +2,6 @@ rootProject.name = 'asmble'
|
||||
include 'annotations',
|
||||
'compiler',
|
||||
'emscripten-runtime',
|
||||
'examples:rust-regex',
|
||||
'examples:rust-simple',
|
||||
'examples:rust-string'
|
Loading…
x
Reference in New Issue
Block a user