Initial skeleton for issue #9

This commit is contained in:
Chad Retz 2017-11-29 16:42:12 -06:00
parent 8b51e14c33
commit 4febf34e69
12 changed files with 302450 additions and 11 deletions

3
.gitignore vendored
View File

@ -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

View File

@ -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'
}

View File

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

View File

@ -0,0 +1,9 @@
[package]
name = "rust_regex"
version = "0.1.0"
[lib]
crate-type = ["cdylib"]
[dependencies]
regex = "0.2"

View File

@ -0,0 +1,3 @@
### Example: Rust Regex
TODO: The regex crate does not yet build with wasm32-unknown-unknown

View 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);
}
}

View File

@ -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;
}
}
}

View File

@ -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);
}
}

View File

@ -0,0 +1,10 @@
package asmble.examples.rustregex;
public interface RegexLib {
RegexPattern compile(String str);
interface RegexPattern {
int matchCount(String target);
}
}

View File

@ -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;
}
}
}

File diff suppressed because it is too large Load Diff

View File

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