mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-27 20:21:12 +08:00
feat: 补齐动态函数构造器族与原型对象
This commit is contained in:
@@ -19,7 +19,9 @@ impl Vm {
|
||||
/// 原样透传。
|
||||
///
|
||||
/// # 步骤
|
||||
/// 1. wrap 源码 `function anonymous(p...) { body }`,parse + compile。
|
||||
/// 1. wrap 源码 `{prefix} anonymous(p...) { body }`(prefix 按生成器 /
|
||||
/// 异步标志取 `function` / `function*` / `async function` /
|
||||
/// `async function*`),parse + compile。
|
||||
/// 2. 取 `sub_modules[0]`(匿名函数模块),把其子树 flat_id 重编号到平表末尾
|
||||
/// 并重写子树内每条 `CREATE_CLOSURE` 的 imm16。
|
||||
/// 3. 同步扩容当前代际的常量缓存,建函数对象并设置 name/length。
|
||||
@@ -33,12 +35,23 @@ impl Vm {
|
||||
///
|
||||
/// # 副作用
|
||||
/// - 扩展当前代际平表(`tables[current_gen]`)与常量缓存。
|
||||
pub fn create_dynamic_function(&mut self, params: &[String], body: &str) -> Result<JsValue, String> {
|
||||
pub fn create_dynamic_function(
|
||||
&mut self, params: &[String], body: &str, is_generator: bool, is_async: bool,
|
||||
) -> Result<JsValue, String> {
|
||||
// wrap 源码:body 两端换行防止以行注释结尾吞掉右花括号;形参串后补
|
||||
// 换行,使形参以 HTML 注释(`<!--`/`-->`)结尾时注释在行末终止、
|
||||
// 右括号不被吞(规范按形参串与体串各自独立解析,此处以换行等价)。
|
||||
// 函数形态按生成器 / 异步标志分流,编译标志(is_generator / is_async)
|
||||
// 由 emit 层从 AST 读回,函数对象原型与 prototype 属性面随之自动分流。
|
||||
let prefix = if is_async {
|
||||
if is_generator { "async function*" } else { "async function" }
|
||||
} else if is_generator {
|
||||
"function*"
|
||||
} else {
|
||||
"function"
|
||||
};
|
||||
let params_str = params.join(", ");
|
||||
let source = format!("function anonymous({params_str}\n) {{\n{body}\n}}");
|
||||
let source = format!("{prefix} anonymous({params_str}\n) {{\n{body}\n}}");
|
||||
|
||||
let allocator = oxide_parser::Allocator::default();
|
||||
let program = oxide_parser::parse(&allocator, &source)
|
||||
|
||||
@@ -179,6 +179,21 @@ impl oxide_runtime_api::VmHost for Vm {
|
||||
// 按严格处理(受限访问器对其抛错)。
|
||||
self.callee_module(obj).map(|m| m.is_strict).unwrap_or(true)
|
||||
}
|
||||
fn function_is_restricted(&self, obj: &JsObject) -> bool {
|
||||
// 严格函数对象,或 [[Prototype]] 为三个动态函数原型之一(生成器 /
|
||||
// 异步 / 异步生成器函数):caller/arguments 访问一律受限。
|
||||
if self.function_is_strict(obj) {
|
||||
return true;
|
||||
}
|
||||
let proto = obj.proto();
|
||||
if !proto.is_object() {
|
||||
return false;
|
||||
}
|
||||
let p = proto.as_js_object_ptr();
|
||||
p == self.generator_function_proto.as_ptr() as *mut JsObject
|
||||
|| p == self.async_function_proto.as_ptr() as *mut JsObject
|
||||
|| p == self.async_generator_function_proto.as_ptr() as *mut JsObject
|
||||
}
|
||||
fn promote_if_needed_for_write_ptr(&mut self, target_ptr: *mut JsObject, value: JsValue) -> JsValue {
|
||||
self.promote_if_needed_for_write_ptr(target_ptr, value)
|
||||
}
|
||||
@@ -201,8 +216,10 @@ impl oxide_runtime_api::VmHost for Vm {
|
||||
.and_then(|cells| cells.get(cell_idx as usize).copied())
|
||||
.filter(|p| !p.is_null())
|
||||
}
|
||||
fn create_dynamic_function(&mut self, params: &[String], body: &str) -> Result<JsValue, String> {
|
||||
self.create_dynamic_function(params, body)
|
||||
fn create_dynamic_function(
|
||||
&mut self, params: &[String], body: &str, is_generator: bool, is_async: bool,
|
||||
) -> Result<JsValue, String> {
|
||||
self.create_dynamic_function(params, body, is_generator, is_async)
|
||||
}
|
||||
fn create_dynamic_script(&mut self, code: &str) -> Result<JsValue, String> {
|
||||
self.create_dynamic_script(code)
|
||||
|
||||
Reference in New Issue
Block a user