Merge pull request #710 from RazerM/master

Add more WebAssembly bindings
This commit is contained in:
Alex Crichton 2018-08-20 14:17:24 -07:00 committed by GitHub
commit 7486fa5104
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 337 additions and 15 deletions

View File

@ -21,4 +21,6 @@ doctest = false
wasm-bindgen = { path = "../..", version = "0.2.17" }
[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
futures = "0.1.20"
wasm-bindgen-test = { path = '../test', version = '=0.2.17' }
wasm-bindgen-futures = { path = '../futures', version = '=0.2.17' }

View File

@ -2848,19 +2848,163 @@ extern "C" {
pub fn delete(this: &WeakSet, value: &Object) -> bool;
}
// WebAssembly
#[wasm_bindgen]
extern "C" {
#[derive(Clone, Debug)]
pub type WebAssembly;
#[allow(non_snake_case)]
pub mod WebAssembly {
use super::*;
// WebAssembly
#[wasm_bindgen]
extern "C" {
/// `The WebAssembly.compile()` function compiles a `WebAssembly.Module`
/// from WebAssembly binary code. This function is useful if it is
/// necessary to a compile a module before it can be instantiated
/// (otherwise, the `WebAssembly.instantiate()` function should be used).
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/compile
#[wasm_bindgen(js_namespace = WebAssembly)]
pub fn compile(buffer_source: &JsValue) -> Promise;
/// The `WebAssembly.validate()` function validates a given typed
/// array of WebAssembly binary code, returning whether the bytes
/// form a valid wasm module (`true`) or not (`false`).
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/validate
#[wasm_bindgen(static_method_of = WebAssembly, catch)]
pub fn validate(bufferSource: &JsValue) -> Result<bool, JsValue>;
#[wasm_bindgen(js_namespace = WebAssembly, catch)]
pub fn validate(buffer_source: &JsValue) -> Result<bool, JsValue>;
}
// WebAssembly.CompileError
#[wasm_bindgen]
extern "C" {
/// The `WebAssembly.CompileError()` constructor creates a new
/// WebAssembly `CompileError` object, which indicates an error during
/// WebAssembly decoding or validation.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/CompileError
#[wasm_bindgen(extends = Error, js_namespace = WebAssembly)]
#[derive(Clone, Debug)]
pub type CompileError;
/// The `WebAssembly.CompileError()` constructor creates a new
/// WebAssembly `CompileError` object, which indicates an error during
/// WebAssembly decoding or validation.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/CompileError
#[wasm_bindgen(constructor, js_namespace = WebAssembly)]
pub fn new(message: &str) -> CompileError;
}
// WebAssembly.LinkError
#[wasm_bindgen]
extern "C" {
/// The `WebAssembly.LinkError()` constructor creates a new WebAssembly
/// LinkError object, which indicates an error during module
/// instantiation (besides traps from the start function).
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/LinkError
#[wasm_bindgen(extends = Error, js_namespace = WebAssembly)]
#[derive(Clone, Debug)]
pub type LinkError;
/// The `WebAssembly.LinkError()` constructor creates a new WebAssembly
/// LinkError object, which indicates an error during module
/// instantiation (besides traps from the start function).
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/LinkError
#[wasm_bindgen(constructor, js_namespace = WebAssembly)]
pub fn new(message: &str) -> LinkError;
}
// WebAssembly.RuntimeError
#[wasm_bindgen]
extern "C" {
/// The `WebAssembly.RuntimeError()` constructor creates a new WebAssembly
/// `RuntimeError` object — the type that is thrown whenever WebAssembly
/// specifies a trap.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/RuntimeError
#[wasm_bindgen(extends = Error, js_namespace = WebAssembly)]
#[derive(Clone, Debug)]
pub type RuntimeError;
/// The `WebAssembly.RuntimeError()` constructor creates a new WebAssembly
/// `RuntimeError` object — the type that is thrown whenever WebAssembly
/// specifies a trap.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/RuntimeError
#[wasm_bindgen(constructor, js_namespace = WebAssembly)]
pub fn new(message: &str) -> RuntimeError;
}
// WebAssembly.Module
#[wasm_bindgen]
extern "C" {
/// A `WebAssembly.Module` object contains stateless WebAssembly code
/// that has already been compiled by the browser and can be
/// efficiently shared with Workers, and instantiated multiple times.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Module
#[wasm_bindgen(js_namespace = WebAssembly, extends = Object)]
#[derive(Clone, Debug)]
pub type Module;
/// A `WebAssembly.Module` object contains stateless WebAssembly code
/// that has already been compiled by the browser and can be
/// efficiently shared with Workers, and instantiated multiple times.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Module
#[wasm_bindgen(constructor, js_namespace = WebAssembly, catch)]
pub fn new(buffer_source: &JsValue) -> Result<Module, JsValue>;
/// The `WebAssembly.customSections()` function returns a copy of the
/// contents of all custom sections in the given module with the given
/// string name.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Module/customSections
#[wasm_bindgen(static_method_of = Module, js_namespace = WebAssembly, js_name = customSections)]
pub fn custom_sections(module: &Module, sectionName: &str) -> Array;
/// The `WebAssembly.exports()` function returns an array containing
/// descriptions of all the declared exports of the given `Module`.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Module/exports
#[wasm_bindgen(static_method_of = Module, js_namespace = WebAssembly)]
pub fn exports(module: &Module) -> Array;
/// The `WebAssembly.imports()` function returns an array containing
/// descriptions of all the declared imports of the given `Module`.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Module/imports
#[wasm_bindgen(static_method_of = Module, js_namespace = WebAssembly)]
pub fn imports(module: &Module) -> Array;
}
// WebAssembly.Table
#[wasm_bindgen]
extern "C" {
/// The `WebAssembly.Table()` constructor creates a new `Table` object
/// of the given size and element type.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Table
#[wasm_bindgen(js_namespace = WebAssembly, extends = Object)]
#[derive(Clone, Debug)]
pub type Table;
/// The `WebAssembly.Table()` constructor creates a new `Table` object
/// of the given size and element type.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Table
#[wasm_bindgen(constructor, js_namespace = WebAssembly, catch)]
pub fn new(table_descriptor: &Object) -> Result<Table, JsValue>;
/// The `length` prototype property of the `WebAssembly.Table` object
/// returns the length of the table, i.e. the number of elements in the
/// table.
///
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Table/length
#[wasm_bindgen(method, getter, js_namespace = WebAssembly)]
pub fn length(this: &Table) -> u32;
}
}
// JSON

View File

@ -0,0 +1,28 @@
const { TextEncoder } = require("util");
const data =
"\u0000asm\u0001\u0000\u0000\u0000\u0001\b\u0002`\u0001\u007f\u0000`\u0000" +
"\u0000\u0002\u0019\u0001\u0007imports\rimported_func\u0000\u0000\u0003" +
"\u0002\u0001\u0001\u0007\u0011\u0001\rexported_func\u0000\u0001\n\b\u0001" +
"\u0006\u0000A*\u0010\u0000\u000b";
const encoder = new TextEncoder();
const wasmArray = encoder.encode(data);
function getWasmArray() {
return wasmArray;
}
function getTableObject() {
return { element: "anyfunc", initial: 1 }
}
function getInvalidTableObject() {
return { element: "anyfunc", initial: 1, maximum: 0 }
}
module.exports = {
getInvalidTableObject,
getTableObject,
getWasmArray,
};

View File

@ -1,9 +1,155 @@
use wasm_bindgen_test::*;
use futures::Future;
use js_sys::*;
use wasm_bindgen::{JsCast, prelude::*};
use wasm_bindgen_futures::JsFuture;
use wasm_bindgen_test::*;
#[wasm_bindgen(module = "tests/wasm/WebAssembly.js")]
extern {
#[wasm_bindgen(js_name = getWasmArray)]
fn get_wasm_array() -> Uint8Array;
#[wasm_bindgen(js_name = getTableObject)]
fn get_table_object() -> Object;
#[wasm_bindgen(js_name = getInvalidTableObject)]
fn get_invalid_table_object() -> Object;
}
fn get_invalid_wasm() -> JsValue {
ArrayBuffer::new(42).into()
}
fn get_bad_type_wasm() -> JsValue {
2.into()
}
fn get_valid_wasm() -> JsValue {
get_wasm_array().into()
}
#[wasm_bindgen_test]
fn validate() {
assert!(!WebAssembly::validate(&ArrayBuffer::new(42).into()).unwrap());
assert!(!WebAssembly::validate(&get_invalid_wasm()).unwrap());
assert!(WebAssembly::validate(&2.into()).is_err());
assert!(WebAssembly::validate(&get_bad_type_wasm()).is_err());
}
#[wasm_bindgen_test(async)]
fn compile_compile_error() -> impl Future<Item = (), Error = JsValue> {
let p = WebAssembly::compile(&get_invalid_wasm());
JsFuture::from(p)
.map(|_| unreachable!())
.or_else(|e| {
assert!(e.is_instance_of::<WebAssembly::CompileError>());
Ok(())
})
}
#[wasm_bindgen_test(async)]
fn compile_type_error() -> impl Future<Item = (), Error = JsValue> {
let p = WebAssembly::compile(&get_bad_type_wasm());
JsFuture::from(p)
.map(|_| unreachable!())
.or_else(|e| {
assert!(e.is_instance_of::<TypeError>());
Ok(())
})
}
#[wasm_bindgen_test(async)]
fn compile_valid() -> impl Future<Item = (), Error = JsValue> {
let p = WebAssembly::compile(&get_valid_wasm());
JsFuture::from(p)
.map(|module| {
assert!(module.is_instance_of::<WebAssembly::Module>());
})
.map_err(|_| unreachable!())
}
#[wasm_bindgen_test]
fn module_inheritance() {
let module = WebAssembly::Module::new(&get_valid_wasm()).unwrap();
assert!(module.is_instance_of::<WebAssembly::Module>());
assert!(module.is_instance_of::<Object>());
let _: &Object = module.as_ref();
}
#[wasm_bindgen_test]
fn module_error() {
let error = WebAssembly::Module::new(&get_invalid_wasm()).err().unwrap();
assert!(error.is_instance_of::<WebAssembly::CompileError>());
let error = WebAssembly::Module::new(&get_bad_type_wasm()).err().unwrap();
assert!(error.is_instance_of::<TypeError>());
}
#[wasm_bindgen_test]
fn module_custom_sections() {
let module = WebAssembly::Module::new(&get_valid_wasm()).unwrap();
let cust_sec = WebAssembly::Module::custom_sections(&module, "abcd");
assert_eq!(cust_sec.length(), 0);
}
#[wasm_bindgen_test]
fn module_exports() {
let module = WebAssembly::Module::new(&get_valid_wasm()).unwrap();
let exports = WebAssembly::Module::exports(&module);
assert_eq!(exports.length(), 1);
}
#[wasm_bindgen_test]
fn module_imports() {
let module = WebAssembly::Module::new(&get_valid_wasm()).unwrap();
let imports = WebAssembly::Module::imports(&module);
assert_eq!(imports.length(), 1);
}
#[wasm_bindgen_test]
fn table_inheritance() {
let table = WebAssembly::Table::new(&get_table_object().into()).unwrap();
assert!(table.is_instance_of::<WebAssembly::Table>());
assert!(table.is_instance_of::<Object>());
let _: &Object = table.as_ref();
}
#[wasm_bindgen_test]
fn table_error() {
let error = WebAssembly::Table::new(&get_invalid_table_object()).err().unwrap();
assert!(error.is_instance_of::<RangeError>());
}
#[wasm_bindgen_test]
fn table() {
let table = WebAssembly::Table::new(&get_table_object().into()).unwrap();
assert_eq!(table.length(), 1);
}
#[wasm_bindgen_test]
fn compile_error_inheritance() {
let error = WebAssembly::CompileError::new("");
assert!(error.is_instance_of::<WebAssembly::CompileError>());
assert!(error.is_instance_of::<Error>());
let _: &Error = error.as_ref();
}
#[wasm_bindgen_test]
fn link_error_inheritance() {
let error = WebAssembly::LinkError::new("");
assert!(error.is_instance_of::<WebAssembly::LinkError>());
assert!(error.is_instance_of::<Error>());
let _: &Error = error.as_ref();
}
#[wasm_bindgen_test]
fn runtime_error_inheritance() {
let error = WebAssembly::RuntimeError::new("");
assert!(error.is_instance_of::<WebAssembly::RuntimeError>());
assert!(error.is_instance_of::<Error>());
let _: &Error = error.as_ref();
}

View File

@ -1,8 +1,10 @@
#![cfg(target_arch = "wasm32")]
#![allow(non_snake_case)]
extern crate futures;
extern crate js_sys;
extern crate wasm_bindgen;
extern crate wasm_bindgen_futures;
extern crate wasm_bindgen_test;
pub mod global_fns;