docs: 添加 Rustdoc 注释
This commit is contained in:
@@ -1,7 +1,11 @@
|
||||
#![doc = "OxideJS - Shared bytecode protocol and compiled module ABI"]
|
||||
|
||||
/// 编译产物与常量池 ABI([`CompiledModule`] / [`Constant`])。
|
||||
pub mod module;
|
||||
/// 操作码表与指令编解码([`OpCode`] / [`Instr`])。
|
||||
pub mod opcode;
|
||||
|
||||
/// 重导出 [`module`] 的编译产物与常量池类型。
|
||||
pub use module::{CompiledModule, Constant};
|
||||
/// 重导出 [`opcode`] 的操作码与指令类型。
|
||||
pub use opcode::{Instr, OpCode};
|
||||
|
||||
@@ -1,7 +1,16 @@
|
||||
//! 编译产物(compiled module)与常量池 ABI。
|
||||
//!
|
||||
//! [`CompiledModule`] 是编译器输出的字节码函数单元:指令序列、常量池、
|
||||
//! 寄存器布局元信息、子函数(嵌套函数)与 upvalue 捕获描述;随 VM 解释执行
|
||||
//! 或由其它模块克隆复制。`Display` 输出可读的反汇编文本,供调试用。
|
||||
|
||||
use std::fmt;
|
||||
|
||||
use crate::opcode::{self, OpCode};
|
||||
|
||||
/// 常量池条目:编译期折叠的不可变值。
|
||||
///
|
||||
/// 变体覆盖 ECMAScript 顶层字面量类型;`Display` 未实现,调试输出走 `Debug`。
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum Constant {
|
||||
Number(f64),
|
||||
@@ -12,6 +21,10 @@ pub enum Constant {
|
||||
Undefined,
|
||||
}
|
||||
|
||||
/// 闭包对上层作用域一个变量的捕获描述。
|
||||
///
|
||||
/// `enclosing_reg` 是外层函数中该变量的寄存器位;若外层变量本身就是 upvalue
|
||||
/// (多级闭包),`cell_idx` 指向链式捕获的 cell。
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct UpvalueCapture {
|
||||
pub name: String,
|
||||
@@ -19,6 +32,16 @@ pub struct UpvalueCapture {
|
||||
pub cell_idx: u8,
|
||||
}
|
||||
|
||||
/// 一个函数单元(或顶层脚本)的编译产物。
|
||||
///
|
||||
/// 字段说明:
|
||||
/// - `bytecode` / `constants` — 指令序列与常量池;
|
||||
/// - `n_registers` / `n_args` / `param_base` — 寄存器窗口布局;
|
||||
/// - `builtin_reg_map` — 内置对象到寄存器的预绑定;
|
||||
/// - `sub_modules` — 嵌套函数(闭包体)的编译产物;
|
||||
/// - `is_arrow` / `captured_this_const_idx` — 箭头函数词法 `this`;
|
||||
/// - `is_class_constructor` / `is_derived_constructor` / `needs_home_object` — 类相关;
|
||||
/// - `upvalue_captures` / `cells_needed` — 闭包捕获描述。
|
||||
pub struct CompiledModule {
|
||||
pub bytecode: Vec<opcode::Instr>,
|
||||
pub constants: Vec<Constant>,
|
||||
@@ -49,6 +72,7 @@ pub struct CompiledModule {
|
||||
}
|
||||
|
||||
impl CompiledModule {
|
||||
/// 构造空模块:空字节码、空常量池、零寄存器与全部标志默认关闭。
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
bytecode: Vec::new(),
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
//! 字节码操作码表与指令编解码。
|
||||
//!
|
||||
//! [`OpCode`] 由 `define_opcodes!` 宏从单张表生成;[`Instr`] 是 4 字节指令
|
||||
//! (opcode + rd + a + b,imm16/offset16 复用 a、b 两字节)。本模块提供
|
||||
//! 编译器发射(`encode*`)与 VM 解码(`opcode` / `rd` / `a` / `b` 等)全套函数。
|
||||
|
||||
use std::fmt;
|
||||
|
||||
/// Generate the `OpCode` enum plus its `TryFrom<u8>` and `Display` impls from a
|
||||
@@ -196,6 +202,7 @@ define_opcodes! {
|
||||
}
|
||||
|
||||
impl OpCode {
|
||||
/// 是否需要 IC 扩展字(inline cache 元数据跟随指令之后)。
|
||||
pub fn has_ic_ext_words(&self) -> bool {
|
||||
matches!(
|
||||
self,
|
||||
@@ -221,64 +228,77 @@ impl OpCode {
|
||||
/// - `b` — second source register, or imm16 high byte
|
||||
pub type Instr = u32;
|
||||
|
||||
/// 把操作码与三个操作数字节编码为一条 [`Instr`]。
|
||||
pub fn encode(op: OpCode, rd: u8, a: u8, b: u8) -> Instr {
|
||||
((b as Instr) << 24) | ((a as Instr) << 16) | ((rd as Instr) << 8) | (op as Instr)
|
||||
}
|
||||
|
||||
/// 解码指令的低 8 位操作码;未知字节返回 [`OpCode::NOP`]。
|
||||
pub fn opcode(instr: Instr) -> OpCode {
|
||||
OpCode::try_from((instr & 0xFF) as u8).unwrap_or(OpCode::NOP)
|
||||
}
|
||||
|
||||
/// 解码目标寄存器(bits 8-15)。
|
||||
pub fn rd(instr: Instr) -> u8 {
|
||||
((instr >> 8) & 0xFF) as u8
|
||||
}
|
||||
|
||||
/// 解码第一个操作数(bits 16-23)。
|
||||
pub fn a(instr: Instr) -> u8 {
|
||||
((instr >> 16) & 0xFF) as u8
|
||||
}
|
||||
|
||||
/// 解码第二个操作数(bits 24-31)。
|
||||
pub fn b(instr: Instr) -> u8 {
|
||||
((instr >> 24) & 0xFF) as u8
|
||||
}
|
||||
|
||||
/// 解码 16 位立即数(bits 16-31,由 a、b 两字节拼成)。
|
||||
pub fn imm16(instr: Instr) -> u16 {
|
||||
((instr >> 16) & 0xFFFF) as u16
|
||||
}
|
||||
|
||||
/// 解码 16 位有符号跳转偏移(bits 16-31)。
|
||||
pub fn offset16(instr: Instr) -> i16 {
|
||||
((instr >> 16) & 0xFFFF) as i16
|
||||
}
|
||||
|
||||
/// 发射无条件跳转指令(`JMP`,偏移以 16 位补码编码)。
|
||||
pub fn encode_jmp(offset: i16) -> Instr {
|
||||
let lo = (offset as u16 & 0xFF) as u8;
|
||||
let hi = ((offset as u16 >> 8) & 0xFF) as u8;
|
||||
encode(OpCode::JMP, 0, lo, hi)
|
||||
}
|
||||
|
||||
/// 发射 `JMP_IF_FALSE`:当 `rd` 寄存器为 falsy 时跳转。
|
||||
pub fn encode_jmp_if_false(rd: u8, offset: i16) -> Instr {
|
||||
let lo = (offset as u16 & 0xFF) as u8;
|
||||
let hi = ((offset as u16 >> 8) & 0xFF) as u8;
|
||||
encode(OpCode::JMP_IF_FALSE, rd, lo, hi)
|
||||
}
|
||||
|
||||
/// 发射 `JMP_IF_TRUE`:当 `rd` 寄存器为 truthy 时跳转。
|
||||
pub fn encode_jmp_if_true(rd: u8, offset: i16) -> Instr {
|
||||
let lo = (offset as u16 & 0xFF) as u8;
|
||||
let hi = ((offset as u16 >> 8) & 0xFF) as u8;
|
||||
encode(OpCode::JMP_IF_TRUE, rd, lo, hi)
|
||||
}
|
||||
|
||||
/// 发射 `JMP_IF_NULLISH`:当 `rd` 为 `null` / `undefined` 时跳转(`??` 短路)。
|
||||
pub fn encode_jmp_if_nullish(rd: u8, offset: i16) -> Instr {
|
||||
let lo = (offset as u16 & 0xFF) as u8;
|
||||
let hi = ((offset as u16 >> 8) & 0xFF) as u8;
|
||||
encode(OpCode::JMP_IF_NULLISH, rd, lo, hi)
|
||||
}
|
||||
|
||||
/// 发射 `TRY_BEGIN`:标记 try 块开始,偏移指向 catch 处理器。
|
||||
pub fn encode_try_begin(offset: i16) -> Instr {
|
||||
let lo = (offset as u16 & 0xFF) as u8;
|
||||
let hi = ((offset as u16 >> 8) & 0xFF) as u8;
|
||||
encode(OpCode::TRY_BEGIN, 0, lo, hi)
|
||||
}
|
||||
|
||||
/// 发射 `TRY_FINALLY_BEGIN`:标记 try/finally 块开始,偏移指向 finally 处理器。
|
||||
pub fn encode_try_finally_begin(offset: i16) -> Instr {
|
||||
let lo = (offset as u16 & 0xFF) as u8;
|
||||
let hi = ((offset as u16 >> 8) & 0xFF) as u8;
|
||||
|
||||
Reference in New Issue
Block a user