mirror of
https://github.com/MercuryWorkshop/scramjet.git
synced 2025-05-13 06:20:02 -04:00
rewrite the rewriter
This commit is contained in:
parent
73c1c8a5c8
commit
6a5ecc4efc
6 changed files with 62 additions and 128 deletions
11
rewriter/Cargo.lock
generated
11
rewriter/Cargo.lock
generated
|
@ -67,6 +67,16 @@ dependencies = [
|
||||||
"static_assertions",
|
"static_assertions",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "console_error_panic_hook"
|
||||||
|
version = "0.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-utils"
|
name = "crossbeam-utils"
|
||||||
version = "0.8.20"
|
version = "0.8.20"
|
||||||
|
@ -449,6 +459,7 @@ dependencies = [
|
||||||
name = "rewriter"
|
name = "rewriter"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"console_error_panic_hook",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"oxc_allocator",
|
"oxc_allocator",
|
||||||
"oxc_ast",
|
"oxc_ast",
|
||||||
|
|
|
@ -7,6 +7,7 @@ edition = "2021"
|
||||||
crate-type = ["cdylib"]
|
crate-type = ["cdylib"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
console_error_panic_hook = "0.1.7"
|
||||||
js-sys = "0.3.69"
|
js-sys = "0.3.69"
|
||||||
oxc_allocator = "0.20.0"
|
oxc_allocator = "0.20.0"
|
||||||
oxc_ast = { version = "0.20.0", features = ["serialize"]}
|
oxc_ast = { version = "0.20.0", features = ["serialize"]}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
RUSTFLAGS='-C target-feature=+atomics,+bulk-memory,+simd128' cargo build --lib --target wasm32-unknown-unknown -Z build-std=panic_abort,std --release
|
RUSTFLAGS='-C target-feature=+atomics,+bulk-memory,+simd128' cargo build --lib --target wasm32-unknown-unknown -Z build-std=panic_abort,std --release
|
||||||
wasm-bindgen --weak-refs --target web --out-dir out/ target/wasm32-unknown-unknown/release/rewriter.wasm
|
wasm-bindgen --weak-refs --target web --out-dir out/ target/wasm32-unknown-unknown/release/rewriter.wasm
|
||||||
|
# wasm-bindgen --keep-debug --weak-refs --target web --out-dir out/ target/wasm32-unknown-unknown/release/rewriter.wasm
|
||||||
|
|
||||||
sed -i 's/import.meta.url/""/g' out/rewriter.js
|
sed -i 's/import.meta.url/""/g' out/rewriter.js
|
||||||
|
|
||||||
|
@ -8,6 +9,7 @@ cd ..
|
||||||
WASM=rewriter/out/rewriter_bg.wasm
|
WASM=rewriter/out/rewriter_bg.wasm
|
||||||
|
|
||||||
time wasm-opt -O4 --vacuum --dce --enable-threads --enable-bulk-memory --enable-simd "$WASM" -o rewriter/out/optimized.wasm
|
time wasm-opt -O4 --vacuum --dce --enable-threads --enable-bulk-memory --enable-simd "$WASM" -o rewriter/out/optimized.wasm
|
||||||
|
# cp "$WASM" rewriter/out/optimized.wasm
|
||||||
|
|
||||||
echo -n "self.WASM = '" > static/wasm.js
|
echo -n "self.WASM = '" > static/wasm.js
|
||||||
base64 -w0 < "rewriter/out/optimized.wasm" >> static/wasm.js
|
base64 -w0 < "rewriter/out/optimized.wasm" >> static/wasm.js
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
pub mod rewrite;
|
pub mod rewrite;
|
||||||
|
|
||||||
use std::str::{from_utf8, FromStr};
|
use std::{
|
||||||
|
panic,
|
||||||
|
str::{from_utf8, FromStr},
|
||||||
|
};
|
||||||
|
|
||||||
use js_sys::Uint8Array;
|
use js_sys::Uint8Array;
|
||||||
use rewrite::rewrite;
|
use rewrite::rewrite;
|
||||||
|
@ -13,6 +16,11 @@ extern "C" {
|
||||||
fn log(s: &str);
|
fn log(s: &str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
pub fn init() {
|
||||||
|
panic::set_hook(Box::new(console_error_panic_hook::hook));
|
||||||
|
}
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub fn rewrite_js(js: &str, url: &str) -> Vec<u8> {
|
pub fn rewrite_js(js: &str, url: &str) -> Vec<u8> {
|
||||||
rewrite(js, Url::from_str(url).unwrap())
|
rewrite(js, Url::from_str(url).unwrap())
|
||||||
|
|
|
@ -2,7 +2,7 @@ use oxc_allocator::Allocator;
|
||||||
use oxc_ast::{
|
use oxc_ast::{
|
||||||
ast::{
|
ast::{
|
||||||
AssignmentTarget, Class, Expression, Function, IdentifierReference, MemberExpression,
|
AssignmentTarget, Class, Expression, Function, IdentifierReference, MemberExpression,
|
||||||
TSImportType,
|
ObjectExpression, ObjectProperty, ObjectPropertyKind, TSImportType,
|
||||||
},
|
},
|
||||||
visit::walk,
|
visit::walk,
|
||||||
Visit,
|
Visit,
|
||||||
|
@ -37,47 +37,21 @@ struct Rewriter {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Visit<'a> for Rewriter {
|
impl<'a> Visit<'a> for Rewriter {
|
||||||
fn visit_assignment_expression(&mut self, expr: &oxc_ast::ast::AssignmentExpression<'a>) {
|
fn visit_identifier_reference(&mut self, it: &IdentifierReference<'a>) {
|
||||||
// if expr.left.is_simple_assignment_target() {
|
if UNSAFE_GLOBALS.contains(&it.name.to_string().as_str()) {
|
||||||
// let name = expr
|
|
||||||
// .left
|
|
||||||
// .as_simple_assignment_target()
|
|
||||||
// .unwrap()
|
|
||||||
// .get_identifier()
|
|
||||||
// .unwrap();
|
|
||||||
// if name == "location" {
|
|
||||||
// use oxc_ast::ast::Expression as E;
|
|
||||||
// let span = match &expr.right {
|
|
||||||
// E::Super(s) => s.span,
|
|
||||||
// E::ThisExpression(s) => s.span,
|
|
||||||
// E::Identifier(s) => s.span,
|
|
||||||
// E::NumericLiteral(s) => s.span,
|
|
||||||
// E::AssignmentExpression(s) => s.span,
|
|
||||||
//
|
|
||||||
// _ => todo!("{:?}", expr.right),
|
|
||||||
// };
|
|
||||||
// self.jschanges.push(JsChange::Assignment {
|
|
||||||
// name: name.to_string(),
|
|
||||||
// entirespan: expr.span,
|
|
||||||
// rhsspan: span,
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
match &expr.right {
|
|
||||||
Expression::Identifier(s) => {
|
|
||||||
if UNSAFE_GLOBALS.contains(&s.name.to_string().as_str()) {
|
|
||||||
self.jschanges.push(JsChange::GenericChange {
|
self.jschanges.push(JsChange::GenericChange {
|
||||||
span: s.span,
|
span: it.span,
|
||||||
text: format!("(globalThis.$s({}))", s.name),
|
text: format!("(globalThis.$s({}))", it.name),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
fn visit_this_expression(&mut self, it: &oxc_ast::ast::ThisExpression) {
|
||||||
walk::walk_assignment_expression(self, expr);
|
self.jschanges.push(JsChange::GenericChange {
|
||||||
}
|
span: it.span,
|
||||||
}
|
text: "(globalThis.$s(this))".to_string(),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_import_declaration(&mut self, it: &oxc_ast::ast::ImportDeclaration<'a>) {
|
fn visit_import_declaration(&mut self, it: &oxc_ast::ast::ImportDeclaration<'a>) {
|
||||||
let name = it.source.value.to_string();
|
let name = it.source.value.to_string();
|
||||||
let url = self.base.join(&name).unwrap();
|
let url = self.base.join(&name).unwrap();
|
||||||
|
@ -97,24 +71,29 @@ impl<'a> Visit<'a> for Rewriter {
|
||||||
});
|
});
|
||||||
walk::walk_import_expression(self, it);
|
walk::walk_import_expression(self, it);
|
||||||
}
|
}
|
||||||
fn visit_variable_declarator(&mut self, it: &oxc_ast::ast::VariableDeclarator<'a>) {
|
|
||||||
match &it.init {
|
fn visit_object_expression(&mut self, it: &oxc_ast::ast::ObjectExpression<'a>) {
|
||||||
Some(Expression::Identifier(s)) => {
|
for prop in &it.properties {
|
||||||
|
match prop {
|
||||||
|
ObjectPropertyKind::ObjectProperty(p) => match &p.value {
|
||||||
|
Expression::Identifier(s) => {
|
||||||
if UNSAFE_GLOBALS.contains(&s.name.to_string().as_str()) {
|
if UNSAFE_GLOBALS.contains(&s.name.to_string().as_str()) {
|
||||||
|
if p.shorthand {
|
||||||
self.jschanges.push(JsChange::GenericChange {
|
self.jschanges.push(JsChange::GenericChange {
|
||||||
span: s.span,
|
span: s.span,
|
||||||
text: format!("(globalThis.$s({}))", s.name),
|
text: format!("{}: (globalThis.$s({}))", s.name, s.name),
|
||||||
});
|
});
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
|
||||||
walk::walk_variable_declarator(self, it);
|
|
||||||
}
|
}
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_member_expression(&mut self, it: &MemberExpression<'a>) {
|
walk::walk_object_expression(self, it);
|
||||||
self.trace_member(it);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,60 +109,6 @@ const UNSAFE_GLOBALS: [&str; 8] = [
|
||||||
"document",
|
"document",
|
||||||
];
|
];
|
||||||
|
|
||||||
impl Rewriter {
|
|
||||||
fn trace_member<'a>(&mut self, it: &MemberExpression<'a>) {
|
|
||||||
match &it {
|
|
||||||
MemberExpression::StaticMemberExpression(s) => match &s.object {
|
|
||||||
Expression::Identifier(obj) => {
|
|
||||||
if UNSAFE_GLOBALS.contains(&obj.name.to_string().as_str()) {
|
|
||||||
self.jschanges.push(JsChange::GenericChange {
|
|
||||||
span: obj.span,
|
|
||||||
text: format!("(globalThis.$s({}))", obj.name),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Expression::ThisExpression(obj) => {
|
|
||||||
self.jschanges.push(JsChange::GenericChange {
|
|
||||||
span: obj.span,
|
|
||||||
text: "(globalThis.$s(this))".to_string(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
if it.object().is_member_expression() {
|
|
||||||
self.trace_member(it.object().as_member_expression().unwrap());
|
|
||||||
} else {
|
|
||||||
walk::walk_member_expression(self, it);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
MemberExpression::ComputedMemberExpression(s) => match &s.object {
|
|
||||||
Expression::Identifier(obj) => {
|
|
||||||
if UNSAFE_GLOBALS.contains(&obj.name.to_string().as_str()) {
|
|
||||||
self.jschanges.push(JsChange::GenericChange {
|
|
||||||
span: obj.span,
|
|
||||||
text: format!("(globalThis.$s({}))", obj.name),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Expression::ThisExpression(obj) => {
|
|
||||||
self.jschanges.push(JsChange::GenericChange {
|
|
||||||
span: obj.span,
|
|
||||||
text: "(globalThis.$s(this))".to_string(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
if it.object().is_member_expression() {
|
|
||||||
self.trace_member(it.object().as_member_expression().unwrap());
|
|
||||||
} else {
|
|
||||||
walk::walk_member_expression(self, it);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn rewrite(js: &str, url: Url) -> Vec<u8> {
|
pub fn rewrite(js: &str, url: Url) -> Vec<u8> {
|
||||||
let allocator = Allocator::default();
|
let allocator = Allocator::default();
|
||||||
let source_type = SourceType::default();
|
let source_type = SourceType::default();
|
||||||
|
@ -259,24 +184,6 @@ pub fn rewrite(js: &str, url: Url) -> Vec<u8> {
|
||||||
|
|
||||||
// offset = (offset as i64 + (text.len() as i64 - len as i64)) as usize;
|
// offset = (offset as i64 + (text.len() as i64 - len as i64)) as usize;
|
||||||
}
|
}
|
||||||
// JsChange::Assignment {
|
|
||||||
// name,
|
|
||||||
// entirespan,
|
|
||||||
// rhsspan,
|
|
||||||
// } => {
|
|
||||||
// let len = (entirespan.end - entirespan.start) as usize;
|
|
||||||
// let start = entirespan.start as usize + offset;
|
|
||||||
// let end = entirespan.end as usize + offset;
|
|
||||||
//
|
|
||||||
// let text = format!(
|
|
||||||
// "$set({}, {})",
|
|
||||||
// name,
|
|
||||||
// &js[rhsspan.start as usize..rhsspan.end as usize]
|
|
||||||
// );
|
|
||||||
// rewritten.replace_range(start..end, &text);
|
|
||||||
//
|
|
||||||
// offset += text.len() - len;
|
|
||||||
// }
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { decodeUrl } from "./url";
|
||||||
|
|
||||||
// i am a cat. i like to be petted. i like to be fed. i like to be
|
// i am a cat. i like to be petted. i like to be fed. i like to be
|
||||||
import {
|
import {
|
||||||
|
init,
|
||||||
initSync,
|
initSync,
|
||||||
rewrite_js,
|
rewrite_js,
|
||||||
rewrite_js_from_arraybuffer,
|
rewrite_js_from_arraybuffer,
|
||||||
|
@ -14,6 +15,10 @@ initSync(
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
init();
|
||||||
|
|
||||||
|
Error.stackTraceLimit = 50
|
||||||
|
|
||||||
global.rws = rewriteJs;
|
global.rws = rewriteJs;
|
||||||
export function rewriteJs(js: string | ArrayBuffer, origin?: URL) {
|
export function rewriteJs(js: string | ArrayBuffer, origin?: URL) {
|
||||||
if ("window" in globalThis) origin ??= new URL(decodeUrl(location.href));
|
if ("window" in globalThis) origin ??= new URL(decodeUrl(location.href));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue