Skip to content

Commit a9c711f

Browse files
author
Ralph Küpper
committed
refactor(perry-runtime): split 20 large files into submodules
Pure code moves; perry-runtime lib + tests compile, 1078 unit tests pass, workspace compiles clean. Each oversized module split into topical siblings (re-exports preserve crate-internal APIs; no pub narrowed): - object/{native_module 8661, global_this 7788, field_get_set 6125, class_registry 6014, native_call_method 5512, native_module_dispatch 3471, object_ops 3273, mod 2672} - process 4913, intl 3209, symbol 2682, typedarray/mod 2660, child_process/mod 2545, fs/dir_glob_watch 2381, fs/mod 2045, node_stream_constructors 2177, regex 2158, closure/dispatch 2005, dgram 2050, dns 2039 All 20 removed from the size-gate allowlist.
1 parent b9f31bb commit a9c711f

134 files changed

Lines changed: 64562 additions & 61981 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
use super::*;
2+
3+
use std::collections::HashMap;
4+
use std::fs::File;
5+
use std::process::{Command, Stdio};
6+
use std::sync::{
7+
atomic::{AtomicU64, Ordering},
8+
Mutex,
9+
};
10+
11+
use sync_run::{
12+
cp_read_async_run_options, cp_read_spawn_sync_run_options, cp_read_sync_stdio_run_options,
13+
cp_run_to_completion, CpRun, CpRunError, CpRunOptions,
14+
};
15+
16+
use crate::closure::{
17+
js_closure_alloc, js_closure_get_capture_ptr, js_closure_set_capture_ptr, js_native_call_value,
18+
js_register_closure_arity, ClosureHeader,
19+
};
20+
use crate::object::{
21+
js_implicit_this_get, js_implicit_this_set, js_object_alloc_with_shape,
22+
js_object_get_field_by_name_f64, js_object_set_field, js_object_set_field_by_name,
23+
ObjectHeader,
24+
};
25+
use crate::string::{js_string_from_bytes, StringHeader};
26+
use crate::value::JSValue;
27+
28+
// Shape-id band kept clear of node_stream (0x7FFF_FE60+), fs streams
29+
// (0x7FFF_FE40), and weakref (0x7FFF_FE10+).
30+
pub(crate) const CP_SHAPE_ID: u32 = 0x7FFF_FD00;
31+
pub(crate) const CP_READABLE_SHAPE_ID: u32 = 0x7FFF_FD40;
32+
pub(crate) const CP_WRITABLE_SHAPE_ID: u32 = 0x7FFF_FD80;
33+
34+
// ----- object construction -----
35+
36+
pub(crate) type CpFn = unsafe extern "C" fn();
37+
#[allow(clippy::missing_transmute_annotations)]
38+
pub(crate) fn cp_cast0(f: extern "C" fn(*const ClosureHeader) -> f64) -> CpFn {
39+
unsafe { std::mem::transmute(f) }
40+
}
41+
#[allow(clippy::missing_transmute_annotations)]
42+
pub(crate) fn cp_cast1(f: extern "C" fn(*const ClosureHeader, f64) -> f64) -> CpFn {
43+
unsafe { std::mem::transmute(f) }
44+
}
45+
#[allow(clippy::missing_transmute_annotations)]
46+
pub(crate) fn cp_cast2(f: extern "C" fn(*const ClosureHeader, f64, f64) -> f64) -> CpFn {
47+
unsafe { std::mem::transmute(f) }
48+
}
49+
#[allow(clippy::missing_transmute_annotations)]
50+
pub(crate) fn cp_cast4(f: extern "C" fn(*const ClosureHeader, f64, f64, f64, f64) -> f64) -> CpFn {
51+
unsafe { std::mem::transmute(f) }
52+
}
53+
54+
pub(crate) fn cp_register_arities() {
55+
js_register_closure_arity(cp_method_on as *const u8, 2);
56+
js_register_closure_arity(cp_method_emit as *const u8, 2);
57+
js_register_closure_arity(cp_method_this0 as *const u8, 0);
58+
js_register_closure_arity(cp_method_this1 as *const u8, 1);
59+
js_register_closure_arity(cp_method_remove_listener as *const u8, 2);
60+
js_register_closure_arity(cp_method_remove_all_listeners as *const u8, 1);
61+
js_register_closure_arity(cp_method_kill as *const u8, 1);
62+
js_register_closure_arity(cp_method_dispose as *const u8, 0);
63+
crate::closure::js_register_closure_length(cp_method_dispose as *const u8, 0);
64+
js_register_closure_arity(cp_method_read as *const u8, 1);
65+
js_register_closure_arity(cp_method_pipe as *const u8, 1);
66+
js_register_closure_arity(cp_method_write2 as *const u8, 2);
67+
js_register_closure_arity(cp_method_stdin_end as *const u8, 1);
68+
// #3316: `send(message, sendHandle, options, callback)` — dispatch with 4
69+
// padded slots so the trailing callback is visible regardless of call-site
70+
// arity, and report `child.send.length === 4` like Node.
71+
js_register_closure_arity(cp_method_send as *const u8, 4);
72+
crate::closure::js_register_closure_length(cp_method_send as *const u8, 4);
73+
js_register_closure_arity(cp_method_disconnect as *const u8, 0);
74+
// The deferred send-callback thunk takes no JS args.
75+
js_register_closure_arity(cp_send_callback_thunk as *const u8, 0);
76+
}
77+
78+
/// Allocate a heap object whose method-name fields each hold a closure capturing
79+
/// the object itself in slot 0 (so method bodies recover `this`).
80+
pub(crate) fn cp_build_object(methods: &[(&str, CpFn)], shape_id: u32) -> *mut ObjectHeader {
81+
let mut packed: Vec<u8> = Vec::new();
82+
for (name, _) in methods {
83+
packed.extend_from_slice(name.as_bytes());
84+
packed.push(0);
85+
}
86+
let obj = js_object_alloc_with_shape(
87+
shape_id,
88+
methods.len() as u32,
89+
packed.as_ptr(),
90+
packed.len() as u32,
91+
);
92+
let this_bits = JSValue::pointer(obj as *const u8).bits();
93+
for (i, (_name, func)) in methods.iter().enumerate() {
94+
let closure = js_closure_alloc(*func as *const u8, 1);
95+
js_closure_set_capture_ptr(closure, 0, this_bits as i64);
96+
js_object_set_field(obj, i as u32, JSValue::pointer(closure as *const u8));
97+
}
98+
obj
99+
}
100+
101+
pub(crate) fn cp_install_dispose(cp: f64) {
102+
let Some(obj) = cp_object_ptr(cp) else {
103+
return;
104+
};
105+
106+
let closure = js_closure_alloc(cp_method_dispose as *const u8, 1);
107+
if closure.is_null() {
108+
return;
109+
}
110+
js_closure_set_capture_ptr(closure, 0, cp.to_bits() as i64);
111+
crate::object::set_bound_native_closure_name(closure, "");
112+
crate::object::set_builtin_closure_length(closure as usize, 0);
113+
let dispose_value = cp_box_ptr(closure as *const u8);
114+
115+
let hidden_attrs = crate::object::PropertyAttrs::new(true, false, true);
116+
for key in ["__perry_dispose__", "@@__perry_wk_dispose"] {
117+
cp_set_field(cp, key.as_bytes(), dispose_value);
118+
crate::object::set_builtin_property_attrs(obj as usize, key.to_string(), hidden_attrs);
119+
}
120+
121+
let dispose_sym = crate::symbol::well_known_symbol("dispose");
122+
if !dispose_sym.is_null() {
123+
let dispose_sym_value = cp_box_ptr(dispose_sym as *const u8);
124+
unsafe {
125+
crate::symbol::js_object_set_symbol_property(cp, dispose_sym_value, dispose_value);
126+
}
127+
}
128+
}
129+
130+
/// Build a stdout/stderr Readable-shaped EventEmitter.
131+
pub(crate) fn cp_build_readable() -> f64 {
132+
let methods: [(&str, CpFn); 13] = [
133+
("on", cp_cast2(cp_method_on)),
134+
("once", cp_cast2(cp_method_on)),
135+
("addListener", cp_cast2(cp_method_on)),
136+
("prependListener", cp_cast2(cp_method_on)),
137+
("off", cp_cast2(cp_method_remove_listener)),
138+
("removeListener", cp_cast2(cp_method_remove_listener)),
139+
("emit", cp_cast2(cp_method_emit)),
140+
("pause", cp_cast0(cp_method_this0)),
141+
("resume", cp_cast0(cp_method_this0)),
142+
("destroy", cp_cast0(cp_method_this0)),
143+
("setEncoding", cp_cast1(cp_method_this1)),
144+
("read", cp_cast1(cp_method_read)),
145+
("pipe", cp_cast1(cp_method_pipe)),
146+
];
147+
let obj = cp_build_object(&methods, CP_READABLE_SHAPE_ID + methods.len() as u32);
148+
let val = cp_box_ptr(obj as *const u8);
149+
cp_set_field(val, b"readable", TAG_TRUE_F64);
150+
cp_set_field(val, b"destroyed", TAG_FALSE_F64);
151+
val
152+
}
153+
154+
/// Build a stdin Writable-shaped EventEmitter.
155+
pub(crate) fn cp_build_writable() -> f64 {
156+
let methods: [(&str, CpFn); 11] = [
157+
("on", cp_cast2(cp_method_on)),
158+
("once", cp_cast2(cp_method_on)),
159+
("addListener", cp_cast2(cp_method_on)),
160+
("removeListener", cp_cast2(cp_method_remove_listener)),
161+
("off", cp_cast2(cp_method_remove_listener)),
162+
("emit", cp_cast2(cp_method_emit)),
163+
("write", cp_cast2(cp_method_write2)),
164+
("end", cp_cast1(cp_method_stdin_end)),
165+
("destroy", cp_cast0(cp_method_this0)),
166+
("cork", cp_cast0(cp_method_this0)),
167+
("uncork", cp_cast0(cp_method_this0)),
168+
];
169+
let obj = cp_build_object(&methods, CP_WRITABLE_SHAPE_ID + methods.len() as u32);
170+
let val = cp_box_ptr(obj as *const u8);
171+
cp_set_field(val, b"writable", TAG_TRUE_F64);
172+
cp_set_field(val, b"destroyed", TAG_FALSE_F64);
173+
val
174+
}

0 commit comments

Comments
 (0)