Skip to content

Commit

Permalink
Fix handling of JS keyword when causing invalid code gen (#4329)
Browse files Browse the repository at this point in the history
  • Loading branch information
RunDevelopment authored Dec 8, 2024
1 parent c60e807 commit 5f288bd
Show file tree
Hide file tree
Showing 10 changed files with 536 additions and 52 deletions.
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,18 @@
* Optional parameters are now typed as `T | undefined | null` to reflect the actual JS behavior.
[#4188](https://github.com/rustwasm/wasm-bindgen/pull/4188)

### Fixed

- Fixed using [JavaScript keyword](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#keywords) as identifiers not being handled correctly.
[#4329](https://github.com/rustwasm/wasm-bindgen/pull/4329)

- Using JS keywords as `struct` and `enum` names will now error at compile time, instead of causing invalid JS code gen.
- Using JS keywords that are not valid to call or access properties on will now error at compile time, instead of causing invalid JS code gen if used as:
1. The first part of a `js_namespace` on imports.
2. The name of an imported type or constant if the type or constant does not have a `js_namespace` or `module` attribute.
3. The name of an imported function if the function is not a method and does not have a `js_namespace` or `module` attribute.
- Using JS keywords on imports in places other than the above will no longer cause the keywords to be escaped as `_{keyword}`.

--------------------------------------------------------------------------------

## [0.2.99](https://github.com/rustwasm/wasm-bindgen/compare/0.2.98...0.2.99)
Expand Down
21 changes: 21 additions & 0 deletions crates/cli/tests/reference/import.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { default as default1 } from 'tests/wasm/import_class.js';

let wasm;
export function __wbg_set_wasm(val) {
wasm = val;
Expand Down Expand Up @@ -65,6 +67,20 @@ export function __wbg_catchme_f7d87ea824a61e87() { return handleError(function (
catch_me();
}, arguments) };

export function __wbg_get_56ba567010fb9959(arg0) {
const ret = arg0.get();
return ret;
};

export function __wbg_myfunction_8c7b624429f78550() {
b.my_function();
};

export function __wbg_new_d21827b66c7fd25d(arg0) {
const ret = new default1(arg0);
return ret;
};

export function __wbg_nocatch_be850a8dddd9599d() {
no_catch();
};
Expand All @@ -73,6 +89,11 @@ export function __wbg_reload_84c12f152ad689f0() {
window.location.reload();
};

export function __wbg_static_accessor_CONST_9e9d5ae758197645() {
const ret = a.CONST;
return ret;
};

export function __wbg_write_c2ce0ce33a6087d5(arg0, arg1) {
window.document.write(getStringFromWasm0(arg0, arg1));
};
Expand Down
26 changes: 25 additions & 1 deletion crates/cli/tests/reference/import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,36 @@ extern "C" {
fn add(a: f64, b: f64) -> f64;
}

#[wasm_bindgen(js_namespace = ["a"])]
extern "C" {
// test that namespaces are overwritten and not inherited/concatenated
#[wasm_bindgen(js_namespace = ["b"])]
fn my_function();
#[wasm_bindgen(thread_local_v2)]
static CONST: f64;
}

#[wasm_bindgen(module = "tests/wasm/import_class.js")]
extern "C" {
#[wasm_bindgen(js_name = default)]
type RenamedTypes;
#[wasm_bindgen(constructor, js_class = default)]
fn new(arg: i32) -> RenamedTypes;
#[wasm_bindgen(method, js_class = default)]
fn get(this: &RenamedTypes) -> i32;
}

#[wasm_bindgen]
pub fn exported() -> Result<(), JsValue> {
bar_from_foo();
let _ = add(1.0, 2.0);
let _ = add(CONST.with(Clone::clone), 2.0);
reload();
write("");
no_catch();
my_function();

let f = RenamedTypes::new(1);
assert_eq!(f.get(), 2);

catch_me()
}
6 changes: 6 additions & 0 deletions crates/cli/tests/reference/keyword.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/* tslint:disable */
/* eslint-disable */
export function exported(): void;
export function _function(): void;
export function _var(): void;
export function weird_arguments(_new: number, _var: number, _switch: number, _default: number, _arguments: number): void;
91 changes: 91 additions & 0 deletions crates/cli/tests/reference/keyword.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
let wasm;
export function __wbg_set_wasm(val) {
wasm = val;
}


const lTextDecoder = typeof TextDecoder === 'undefined' ? (0, module.require)('util').TextDecoder : TextDecoder;

let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true });

cachedTextDecoder.decode();

let cachedUint8ArrayMemory0 = null;

function getUint8ArrayMemory0() {
if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {
cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);
}
return cachedUint8ArrayMemory0;
}

function getStringFromWasm0(ptr, len) {
ptr = ptr >>> 0;
return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));
}

export function exported() {
wasm.exported();
}

export function _function() {
wasm._function();
}

export function _var() {
wasm._var();
}

/**
* @param {number} _new
* @param {number} _var
* @param {number} _switch
* @param {number} _default
* @param {number} _arguments
*/
export function weird_arguments(_new, _var, _switch, _default, _arguments) {
wasm.weird_arguments(_new, _var, _switch, _default, _arguments);
}

export function __wbg_await_e0a0e75be8b6fef6() {
await();
};

export function __wbg_let_8d461e9e0592bd8c(arg0) {
arg0.let();
};

export function __wbg_new_4b026aaf1c1e4438() {
const ret = A.new();
return ret;
};

export function __wbg_new_d4bfd9add722b492() {
const ret = window.__TAURI__.menu.Menu.new();
return ret;
};

export function __wbg_new_e17dd7c5a1cd57d8() {
B.new();
};

export function __wbg_static_accessor_TRUE_c6b68bf8545d99a3() {
const ret = true;
return ret;
};

export function __wbindgen_init_externref_table() {
const table = wasm.__wbindgen_export_0;
const offset = table.grow(4);
table.set(0, undefined);
table.set(offset + 0, undefined);
table.set(offset + 1, null);
table.set(offset + 2, true);
table.set(offset + 3, false);
;
};

export function __wbindgen_throw(arg0, arg1) {
throw new Error(getStringFromWasm0(arg0, arg1));
};

57 changes: 57 additions & 0 deletions crates/cli/tests/reference/keyword.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
use wasm_bindgen::prelude::*;

// Imports with keywords

#[wasm_bindgen]
extern "C" {
#[wasm_bindgen]
pub type A;

#[wasm_bindgen(static_method_of = A, js_name = "new")]
pub fn static_new() -> A;
#[wasm_bindgen(js_namespace = ["B"], js_name = "new")]
pub fn namespace_new();

#[wasm_bindgen(method, js_name = "let")]
pub fn keyword_let(ptr: &A);

// await is not a reserved keyword in JS
pub fn r#await();

// true & false are reserved keywords in JS, but we allow them anyway
#[wasm_bindgen(thread_local_v2, js_name = "true")]
static TRUE: JsValue;
}

// https://github.com/rustwasm/wasm-bindgen/issues/4317
#[wasm_bindgen(js_namespace = ["window", "__TAURI__", "menu"])]
extern "C" {
#[wasm_bindgen]
pub type Menu;

#[wasm_bindgen(static_method_of = Menu)]
pub fn new() -> Menu;
}

// This function ensures the imported stuff isn't optimized out
#[wasm_bindgen]
pub fn exported() {
let a = A::static_new();
let _ = a.keyword_let();
let _ = namespace_new();
let _ = r#await();
std::hint::black_box(&TRUE);

let _ = Menu::new();
}

// Exports with keywords that we allow and are renamed automatically.

#[wasm_bindgen]
pub fn function() {}

#[wasm_bindgen(js_name = "var")]
pub fn sane_name() {}

#[wasm_bindgen]
pub fn weird_arguments(new: u32, var: u32, r#switch: u32, default: u32, arguments: u32) {}
20 changes: 20 additions & 0 deletions crates/cli/tests/reference/keyword.wat
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
(module $reference_test.wasm
(type (;0;) (func))
(type (;1;) (func (param i32 i32 i32 i32 i32)))
(import "./reference_test_bg.js" "__wbindgen_init_externref_table" (func (;0;) (type 0)))
(func $weird_arguments (;1;) (type 1) (param i32 i32 i32 i32 i32))
(func $exported (;2;) (type 0))
(func $_function (;3;) (type 0))
(func $_var (;4;) (type 0))
(table (;0;) 128 externref)
(memory (;0;) 17)
(export "memory" (memory 0))
(export "exported" (func $exported))
(export "_function" (func $_function))
(export "_var" (func $_var))
(export "weird_arguments" (func $weird_arguments))
(export "__wbindgen_export_0" (table 0))
(export "__wbindgen_start" (func 0))
(@custom "target_features" (after code) "\04+\0amultivalue+\0fmutable-globals+\0freference-types+\08sign-ext")
)

Loading

0 comments on commit 5f288bd

Please sign in to comment.