Mid rewrite
This commit is contained in:
+22
-5
@@ -1,3 +1,14 @@
|
||||
//! QuickJS bytecode represents the program as a hierarchy. Each function has a set of child functions
|
||||
//! that reference captured variables in their parent
|
||||
//!
|
||||
//! This module:
|
||||
//! - flattens the hierarchy
|
||||
//! - assigns an integer idx to each function
|
||||
//! - converts child ownership to a reference by-idx
|
||||
//! - extracts closure captures into a separate vec
|
||||
//!
|
||||
//! Also adds a synthetic entry point function that calls the top level fn generated by QuickJS
|
||||
|
||||
use crate::libqjs::parse::{
|
||||
Atom, AtomRef, ClosureVar, Function, ImmOperand, Instr, JsValue, QuickJSBinary, opcodes::OpCode,
|
||||
};
|
||||
@@ -6,11 +17,16 @@ use crate::libqjs::parse::{
|
||||
pub struct FlatFn {
|
||||
pub name: AtomRef,
|
||||
pub arg_count: usize,
|
||||
pub var_count: usize,
|
||||
pub local_count: usize,
|
||||
pub cpool: Vec<JsValue>,
|
||||
pub code: Vec<Instr>,
|
||||
}
|
||||
|
||||
/// Flattens the binary
|
||||
///
|
||||
/// Returns:
|
||||
/// - flat_fns[i] = the i'th flattened function
|
||||
/// - captures[i] = the i'th fn's captures from its parent
|
||||
pub fn flatten(bin: QuickJSBinary) -> (Vec<FlatFn>, Vec<Vec<ClosureVar>>, Vec<Atom>) {
|
||||
let mut fns = vec![];
|
||||
let mut captures = vec![];
|
||||
@@ -27,18 +43,19 @@ fn walk(func: Function, flat_fns: &mut Vec<FlatFn>, captures: &mut Vec<Vec<Closu
|
||||
flat_fns.push(FlatFn {
|
||||
name: func.name,
|
||||
arg_count: func.arg_count,
|
||||
var_count: func.var_count,
|
||||
local_count: func.var_count,
|
||||
cpool: vec![],
|
||||
code: func.byte_code,
|
||||
});
|
||||
|
||||
captures.push(func.closure_vars);
|
||||
|
||||
// Every direct child ownership is replaced by a by-idx reference
|
||||
let cpool = func
|
||||
.cpool
|
||||
.into_iter()
|
||||
.map(|c| match c {
|
||||
JsValue::Function(child) => JsValue::FnById(walk(child, flat_fns, captures)),
|
||||
JsValue::Function(child) => JsValue::FnByIdx(walk(child, flat_fns, captures)),
|
||||
other => other,
|
||||
})
|
||||
.collect();
|
||||
@@ -82,8 +99,8 @@ fn add_entry_point(fns: &mut Vec<FlatFn>, captures: &mut Vec<Vec<ClosureVar>>) {
|
||||
fns.push(FlatFn {
|
||||
name: AtomRef::Predefined(0),
|
||||
arg_count: 0,
|
||||
var_count: 1,
|
||||
cpool: vec![JsValue::FnById(0)],
|
||||
local_count: 1,
|
||||
cpool: vec![JsValue::FnByIdx(0)], // First fn is the top level <eval>
|
||||
code,
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user