Merge pull request #273 from FreeMasen/validate-ptr

Validate ptr
This commit is contained in:
Nick Fitzgerald 2018-06-19 16:45:31 -07:00 committed by GitHub
commit 5eda5504e9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 78 additions and 1 deletions

View File

@ -2,6 +2,7 @@ use proc_macro2::{Ident, Span, TokenStream, TokenTree};
use quote::ToTokens;
use shared;
use syn;
use syn::AttrStyle;
#[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq))]
#[derive(Default)]

View File

@ -68,6 +68,9 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
/// passed should be `this.ptr`.
pub fn method(&mut self, method: bool) -> &mut Self {
if method {
self.prelude("if (this.ptr === 0) {
throw new Error('Attempt to use a moved value');
}");
self.rust_arguments.insert(0, "this.ptr".to_string());
}
self
@ -149,6 +152,9 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
} else {
self.prelude(&format!("\
const ptr{i} = {arg}.ptr;\n\
if (ptr{i} === 0) {{
throw new Error('Attempt to use a moved value');
}}
{arg}.ptr = 0;\n\
", i = i, arg = name));
self.rust_arguments.push(format!("ptr{}", i));
@ -361,4 +367,4 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
let ts = format!("{} {}({}): {};\n", prefix, self.js_name, ts_args, self.ret_ty);
(js, ts)
}
}
}

View File

@ -539,3 +539,4 @@ mod structural;
mod u64;
mod webidl;
mod comments;
mod validate_prt;

69
tests/all/validate_prt.rs Normal file
View File

@ -0,0 +1,69 @@
use super::project;
#[test]
fn works() {
project()
.file("src/lib.rs", r#"
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub struct Fruit {
name: String,
}
#[wasm_bindgen]
impl Fruit {
#[wasm_bindgen(method)]
pub fn name(&self) -> String {
self.name.clone()
}
#[wasm_bindgen(constructor)]
pub fn new(name: String) -> Self {
Fruit {
name,
}
}
}
#[wasm_bindgen]
pub fn eat(_fruit: Fruit) { }
"#)
.file("test.js", r#"
import * as wasm from './out';
const targetMessage = 'Attempt to use a moved value';
function assertEq(a, b) {
console.log(a, '?=', b);
if (a === b)
return;
throw new Error('not equal');
}
export function test() {
useMoved();
moveMoved();
}
export function useMoved() {
// create a new struct
let apple = new wasm.Fruit('apple');
// sanity check that this method works
let name = apple.name();
// consume the struct
wasm.eat(apple);
// try and use the moved apple again
try {
let movedName = apple.name();
} catch (e) {
assertEq(e.message, targetMessage);
}
}
export function moveMoved() {
let pear = new wasm.Fruit('pear');
let name = pear.name();
wasm.eat(pear);
try {
wasm.eat(pear);
} catch (e) {
assertEq(e.message, targetMessage);
}
}
"#)
.test();
}