Improved emtests

This commit is contained in:
Syrus 2019-06-07 23:27:58 +02:00
parent df486b7beb
commit 2430958f22
10 changed files with 155 additions and 64 deletions

View File

@ -7,13 +7,13 @@ endif
# This will re-generate the Rust test files based on spectests/*.wast # This will re-generate the Rust test files based on spectests/*.wast
spectests: spectests:
WASMER_RUNTIME_GENERATE_SPECTESTS=1 cargo build -p wasmer-runtime-core WASMER_RUNTIME_GENERATE_SPECTESTS=1 cargo build -p wasmer-runtime-core -vv
emtests: emtests:
WASM_EMSCRIPTEN_GENERATE_EMTESTS=1 cargo build -p wasmer-emscripten WASM_EMSCRIPTEN_GENERATE_EMTESTS=1 cargo build -p wasmer-emscripten -vv
wasitests: wasitests:
WASM_WASI_GENERATE_WASITESTS=1 cargo build -p wasmer-wasi WASM_WASI_GENERATE_WASITESTS=1 cargo build -p wasmer-wasi -vv
# clean: # clean:
# rm -rf artifacts # rm -rf artifacts

View File

@ -7,6 +7,7 @@
use glob::glob; use glob::glob;
use std::collections::HashSet; use std::collections::HashSet;
use std::fs; use std::fs;
use std::str;
use std::path::Path; use std::path::Path;
use std::path::PathBuf; use std::path::PathBuf;
use std::process::Command; use std::process::Command;
@ -22,30 +23,9 @@ const EXTENSIONS: [&str; 2] = ["c", "cpp"];
const EXCLUDES: [&str; 0] = []; const EXCLUDES: [&str; 0] = [];
pub fn compile(file: &str, ignores: &HashSet<String>) -> Option<String> { pub fn compile(file: &str, ignores: &HashSet<String>) -> Option<String> {
let mut output_path = PathBuf::from(file);
output_path.set_extension("out");
// let output_str = output_path.to_str().unwrap();
// Compile to .out
// Command::new("cc")
// .arg(file)
// .arg("-o")
// .arg(output_str)
// .output()
// .expect("failed to execute process");
// Get the result of .out
// let output = Command::new(output_str)
// .arg(output_str)
// .output()
// .expect("failed to execute process");
// Remove executable
// fs::remove_file(output_str).unwrap();
let mut output_path = PathBuf::from(file); let mut output_path = PathBuf::from(file);
output_path.set_extension("js"); output_path.set_extension("js");
let output_str = output_path.to_str().unwrap(); let output_js = output_path.to_str().unwrap();
let wasm_file_metadata = { let wasm_file_metadata = {
let mut wasm_file_path = PathBuf::from(file); let mut wasm_file_path = PathBuf::from(file);
@ -55,34 +35,9 @@ pub fn compile(file: &str, ignores: &HashSet<String>) -> Option<String> {
let real_file = File::open(file).unwrap(); let real_file = File::open(file).unwrap();
let file_metadata = real_file.metadata().unwrap(); let file_metadata = real_file.metadata().unwrap();
if wasm_file_metadata.is_none()
|| file_metadata.modified().unwrap() >= wasm_file_metadata.unwrap().modified().unwrap()
{
// Compile to wasm
let _wasm_compilation = Command::new("emcc")
.arg(file)
.arg("-s")
.arg("WASM=1")
.arg("-o")
.arg(output_str)
.output()
.expect("failed to execute process");
// panic!("{:?}", wasm_compilation);
// if output.stderr {
// panic!("{}", output.stderr);
// }
// Remove js file
if Path::new(output_str).is_file() {
fs::remove_file(output_str).unwrap();
} else {
println!("Output JS not found: {}", output_str);
}
}
let mut output_path = PathBuf::from(file); let mut output_path = PathBuf::from(file);
output_path.set_extension("output");
let module_name = output_path let module_name = output_path
.file_stem() .file_stem()
.unwrap() .unwrap()
@ -90,11 +45,86 @@ pub fn compile(file: &str, ignores: &HashSet<String>) -> Option<String> {
.unwrap() .unwrap()
.to_owned(); .to_owned();
// let output_extension = if file.ends_with("c") || module_name.starts_with("test_") {
// let output_str = output_path.to_str().unwrap(); "out"
} else {
"txt"
};
output_path.set_extension(output_extension);
// Write the output to file if wasm_file_metadata.is_none()
// fs::write(output_str, output.stdout).expect("Unable to write file"); || file_metadata.modified().unwrap() >= wasm_file_metadata.unwrap().modified().unwrap()
{
eprintln!("Compiling {} to wasm...", file);
// Compile to wasm
let _wasm_compilation = Command::new("emcc")
.arg(file)
.arg("-s")
.arg("WASM=1")
.arg("-o")
.arg(output_js)
.output()
.expect("failed to execute process");
// panic!("{:?}", wasm_compilation);
if !_wasm_compilation.status.success() {
eprintln!("Can't compile {:?}", file);
eprintln!(" {}", str::from_utf8(&_wasm_compilation.stderr).expect("Can't get utf8 str").replace("\n", "\n "));
return None;
}
eprintln!("File {} compiled to wasm.", file);
// Remove js file
if Path::new(output_js).is_file() {
fs::remove_file(output_js).unwrap();
} else {
eprintln!("Output JS not found: {}", output_js);
}
let mut output_exec_path = PathBuf::from(file);
output_exec_path.set_extension("out_exec");
let output_exec = output_exec_path.to_str().unwrap();
eprintln!("Compiling native executable to get real .out output");
// Compile to .out
let cc_output = Command::new("cc")
.arg(file)
.arg("-o")
.arg(output_exec)
.output()
.expect("failed to execute process");
if !cc_output.status.success() {
eprintln!("Can't execute the file to get the output. Skipping");
return None;
}
eprintln!("Native file compiled {:?}", output_exec);
eprintln!("Trying to get automated output");
let mut dir = PathBuf::from(file);
dir.pop();
// Get the result of .out
let output = Command::new(output_exec)
.current_dir(dir)
.output()
.expect("failed to execute process");
// Remove executable
fs::remove_file(output_exec).unwrap();
if !cc_output.status.success() {
eprintln!("Can't execute the file to get the output. Skipping");
return None;
}
let output_str = output_path.to_str().unwrap();
// Write the output to file
fs::write(output_str, output.stdout).expect("Unable to write file");
}
let rs_module_name = module_name.to_lowercase(); let rs_module_name = module_name.to_lowercase();
let rust_test_filepath = format!( let rust_test_filepath = format!(
@ -102,12 +132,6 @@ pub fn compile(file: &str, ignores: &HashSet<String>) -> Option<String> {
rs_module_name.as_str() rs_module_name.as_str()
); );
let output_extension = if file.ends_with("c") || module_name.starts_with("test_") {
"out"
} else {
"txt"
};
let ignored = if ignores.contains(&module_name.to_lowercase()) { let ignored = if ignores.contains(&module_name.to_lowercase()) {
"\n#[ignore]" "\n#[ignore]"
} else { } else {

BIN
lib/emscripten/emtests/fnmatch.wasm vendored Normal file

Binary file not shown.

54
lib/emscripten/emtests/lseek.c vendored Normal file
View File

@ -0,0 +1,54 @@
// C program to read nth byte of a file and
// copy it to another file using lseek
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
void func(char arr[], int n)
{
// Open the file for READ only.
int f_write = open("lseek_start.txt", O_RDONLY);
// Open the file for WRITE and READ only.
int f_read = 1; // stdout
int count = 0;
while (read(f_write, arr, 1))
{
// to write the 1st byte of the input file in
// the output file
if (count < n)
{
// SEEK_CUR specifies that
// the offset provided is relative to the
// current file position
lseek (f_write, n, SEEK_CUR);
write (f_read, arr, 1);
count = n;
}
// After the nth byte (now taking the alternate
// nth byte)
else
{
count = (2*n);
lseek(f_write, count, SEEK_CUR);
write(f_read, arr, 1);
}
}
close(f_write);
close(f_read);
}
// Driver code
int main()
{
char arr[100];
int n;
n = 5;
// Calling for the function
func(arr, n);
return 0;
}

BIN
lib/emscripten/emtests/lseek.wasm vendored Normal file

Binary file not shown.

View File

@ -0,0 +1,2 @@
We encounter various problems like Maximum length palindrome in a string, number of palindromic substrings and many more interesting problems on palindromic substrings . Mostly of these palindromic substring problems have some DP O(n2) solution (n is length of the given string) or then we have a complex algorithm like Manachers algorithm which solves the Palindromic problems in linear time.
In this article, we will study an interesting Data Structure, which will solve all the above similar problems in much more simpler way. This data structure is invented by Mikhail Rubinchik.

View File

@ -340,8 +340,9 @@ pub fn ___syscall140(ctx: &mut Ctx, _which: i32, mut varargs: VarArgs) -> i32 {
*result_ptr = ret; *result_ptr = ret;
} }
debug!( debug!(
"=> fd: {}, offset: {}, result_ptr: {}, whence: {} = {}\nlast os error: {}", "=> fd: {}, ret: {}, offset: {}, result_ptr: {}, whence: {} = {}\nlast os error: {}",
fd, fd,
ret,
offset, offset,
result_ptr_value, result_ptr_value,
whence, whence,
@ -376,14 +377,14 @@ pub fn ___syscall145(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> i32
let iov_base = emscripten_memory_pointer!(ctx.memory(0), (*guest_iov_addr).iov_base) let iov_base = emscripten_memory_pointer!(ctx.memory(0), (*guest_iov_addr).iov_base)
as *mut c_void; as *mut c_void;
let iov_len = (*guest_iov_addr).iov_len as _; let iov_len = (*guest_iov_addr).iov_len as _;
// debug!("=> iov_addr: {:?}, {:?}", iov_base, iov_len); debug!("=> iov_addr: {:?}, {:?}", iov_base, iov_len);
let curr = read(fd, iov_base, iov_len); let curr = read(fd, iov_base, iov_len);
if curr < 0 { if curr < 0 {
return -1; return -1;
} }
ret += curr; ret += curr;
} }
// debug!(" => ret: {}", ret); debug!(" => ret: {}", ret);
ret as _ ret as _
} }
} }

View File

@ -0,0 +1,9 @@
#[test]
fn test_lseek() {
assert_emscripten_output!(
"../../emtests/lseek.wasm",
"lseek",
vec![],
"../../emtests/lseek.out"
);
}

View File

@ -11,6 +11,7 @@ mod fs_exports;
mod getvalue_setvalue; mod getvalue_setvalue;
mod legacy_exported_runtime_numbers; mod legacy_exported_runtime_numbers;
mod localtime; mod localtime;
mod lseek;
mod modularize_closure_pre; mod modularize_closure_pre;
mod printf; mod printf;
mod puts; mod puts;