This commit is contained in:
Josh Matthews 2025-06-03 02:59:21 +01:00 committed by GitHub
commit ef3827a3ff
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 90 additions and 34 deletions

4
Cargo.lock generated
View file

@ -4692,7 +4692,7 @@ dependencies = [
[[package]]
name = "mozjs"
version = "0.14.1"
source = "git+https://github.com/servo/mozjs#728acdf3d4ce0604e9f75dd1d539dc6f291ccec7"
source = "git+https://github.com/jdm/mozjs?branch=137up#91a576a85a3f8902f5f2eaab6e1b9cd1d2d1bbca"
dependencies = [
"bindgen 0.71.1",
"cc",
@ -4704,7 +4704,7 @@ dependencies = [
[[package]]
name = "mozjs_sys"
version = "0.128.9-2"
source = "git+https://github.com/servo/mozjs#728acdf3d4ce0604e9f75dd1d539dc6f291ccec7"
source = "git+https://github.com/jdm/mozjs?branch=137up#91a576a85a3f8902f5f2eaab6e1b9cd1d2d1bbca"
dependencies = [
"bindgen 0.71.1",
"cc",

View file

@ -249,3 +249,8 @@ codegen-units = 1
# [patch."https://github.com/servo/rust-content-security-policy"]
# content-security-policy = { path = "../rust-content-security-policy/" }
# content-security-policy = { git = "https://github.com/timvdlippe/rust-content-security-policy/", branch = "fix-report-checks", features = ["serde"] }
[patch."https://github.com/servo/mozjs"]
#mozjs = { path = "../mozjs/mozjs" }
#mozjs_sys = { path = "../mozjs/mozjs-sys" }
mozjs = { git = "https://github.com/jdm/mozjs", branch = "137up" }
mozjs_sys = { git = "https://github.com/jdm/mozjs", branch = "137up" }

View file

@ -169,7 +169,6 @@ pub struct Preferences {
pub js_mem_gc_decommit_threshold_mb: i64,
pub js_mem_gc_dynamic_heap_growth_enabled: bool,
pub js_mem_gc_dynamic_mark_slice_enabled: bool,
pub js_mem_gc_empty_chunk_count_max: i64,
pub js_mem_gc_empty_chunk_count_min: i64,
pub js_mem_gc_high_frequency_heap_growth_max: i64,
pub js_mem_gc_high_frequency_heap_growth_min: i64,
@ -341,7 +340,6 @@ impl Preferences {
js_mem_gc_decommit_threshold_mb: 32,
js_mem_gc_dynamic_heap_growth_enabled: true,
js_mem_gc_dynamic_mark_slice_enabled: true,
js_mem_gc_empty_chunk_count_max: 30,
js_mem_gc_empty_chunk_count_min: 1,
js_mem_gc_high_frequency_heap_growth_max: 300,
js_mem_gc_high_frequency_heap_growth_min: 150,

View file

@ -113,9 +113,22 @@ unsafe extern "C" fn instance_class_has_proto_at_depth(
domclass.dom_class.interface_chain[depth as usize] as u32 == proto_id
}
/// <https://searchfox.org/mozilla-central/rev/c18faaae88b30182e487fa3341bc7d923e22f23a/xpcom/base/CycleCollectedJSRuntime.cpp#792>
unsafe extern "C" fn instance_class_is_error(clasp: *const js::jsapi::JSClass) -> bool {
if !is_dom_class(&*clasp) {
return false;
}
let domclass: *const DOMJSClass = clasp as *const _;
let domclass = &*domclass;
let root_interface = domclass.dom_class.interface_chain[0] as u32;
// TODO: support checking bare Exception prototype as well.
root_interface == PrototypeList::ID::DOMException as u32
}
#[allow(missing_docs)] // FIXME
pub(crate) const DOM_CALLBACKS: DOMCallbacks = DOMCallbacks {
instanceClassMatchesProto: Some(instance_class_has_proto_at_depth),
instanceClassIsError: Some(instance_class_is_error),
};
/// Eagerly define all relevant WebIDL interface constructors on the

View file

@ -15,11 +15,11 @@ use content_security_policy as csp;
use deny_public_fields::DenyPublicFields;
use dom_struct::dom_struct;
use fnv::FnvHasher;
use js::jsapi::JS_GetFunctionObject;
use js::jsapi::JS::CompileFunction;
use js::jsapi::{JS_GetFunctionObject, SupportUnscopables};
use js::jsval::JSVal;
use js::rust::wrappers::CompileFunction;
use js::rust::{
CompileOptionsWrapper, HandleObject, RootedObjectVectorWrapper, transform_u16_to_source_text,
CompileOptionsWrapper, HandleObject, transform_u16_to_source_text,
};
use libc::c_char;
use servo_url::ServoUrl;
@ -642,7 +642,8 @@ impl EventTarget {
};
// Step 3.9, subsection Scope steps 1-6
let scopechain = RootedObjectVectorWrapper::new(*cx);
//let scopechain = RootedObjectVectorWrapper::new(*cx);
let scopechain = js::rust::EnvironmentChain::new(*cx, SupportUnscopables::Yes);
if let Some(element) = element {
scopechain.append(document.reflector().get_jsobject().get());
@ -655,7 +656,7 @@ impl EventTarget {
rooted!(in(*cx) let mut handler = unsafe {
CompileFunction(
*cx,
scopechain.handle(),
scopechain.get(),
options.ptr,
name.as_ptr(),
args.len() as u32,

View file

@ -36,7 +36,7 @@ use ipc_channel::router::ROUTER;
use js::glue::{IsWrapper, UnwrapObjectDynamic};
use js::jsapi::{
Compile1, CurrentGlobalOrNull, GetNonCCWObjectGlobal, HandleObject, Heap,
InstantiateGlobalStencil, InstantiateOptions, JSContext, JSObject, JSScript, SetScriptPrivate,
InstantiateGlobalStencil, InstantiateOptions, JSContext, JSObject, JSScript, SetScriptPrivate, DelazificationOption,
};
use js::jsval::{PrivateValue, UndefinedValue};
use js::panic::maybe_resume_unwind;
@ -2826,6 +2826,7 @@ impl GlobalScope {
skipFilenameValidation: false,
hideScriptFromDebugger: false,
deferDebugMetadata: false,
eagerDelazificationStrategy_: DelazificationOption::OnDemandOnly,
};
let script = InstantiateGlobalStencil(
*cx,

View file

@ -24,12 +24,12 @@ use js::conversions::jsstr_to_string;
use js::glue::{
CollectServoSizes, CreateJobQueue, DeleteJobQueue, DispatchableRun, JobQueueTraps,
RUST_js_GetErrorMessage, SetBuildId, StreamConsumerConsumeChunk,
StreamConsumerNoteResponseURLs, StreamConsumerStreamEnd, StreamConsumerStreamError,
StreamConsumerNoteResponseURLs, StreamConsumerStreamEnd, StreamConsumerStreamError, JS_GetReservedSlot,
};
use js::jsapi::{
AsmJSOption, BuildIdCharVector, ContextOptionsRef, DisableIncrementalGC,
AsmJSOption, BuildIdCharVector, ContextOptionsRef,
Dispatchable as JSRunnable, Dispatchable_MaybeShuttingDown, GCDescription, GCOptions,
GCProgress, GCReason, GetPromiseUserInputEventHandlingState, HandleObject, HandleString, Heap,
GCProgress, GCReason, GetPromiseUserInputEventHandlingState, HandleObject, HandleString, Heap, MutableHandleObject, CompilationType, HandleValue,
InitConsumeStreamCallback, InitDispatchToEventLoop, JS_AddExtraGCRootsTracer,
JS_InitDestroyPrincipalsCallback, JS_InitReadPrincipalsCallback, JS_SetGCCallback,
JS_SetGCParameter, JS_SetGlobalJitCompilerOption, JS_SetOffthreadIonCompilationEnabled,
@ -37,9 +37,9 @@ use js::jsapi::{
JSGCStatus, JSJitCompilerOption, JSObject, JSSecurityCallbacks, JSTracer, JobQueue, MimeType,
PromiseRejectionHandlingState, PromiseUserInputEventHandlingState, RuntimeCode,
SetDOMCallbacks, SetGCSliceCallback, SetJobQueue, SetPreserveWrapperCallbacks,
SetProcessBuildIdOp, SetPromiseRejectionTrackerCallback, StreamConsumer as JSStreamConsumer,
SetProcessBuildIdOp, SetPromiseRejectionTrackerCallback, StreamConsumer as JSStreamConsumer, JS_NewObject, JSClass, JSCLASS_RESERVED_SLOTS_MASK, JSCLASS_RESERVED_SLOTS_SHIFT, JSClassOps, JS_SetReservedSlot,
};
use js::jsval::UndefinedValue;
use js::jsval::{ObjectValue, UndefinedValue};
use js::panic::wrap_panic;
pub(crate) use js::rust::ThreadSafeJSContext;
use js::rust::wrappers::{GetPromiseIsHandled, JS_GetPromiseResult};
@ -79,19 +79,20 @@ use crate::dom::promise::Promise;
use crate::dom::promiserejectionevent::PromiseRejectionEvent;
use crate::dom::response::Response;
use crate::microtask::{EnqueuedPromiseCallback, Microtask, MicrotaskQueue};
use crate::realms::{AlreadyInRealm, InRealm};
use crate::realms::{AlreadyInRealm, InRealm, enter_realm};
use crate::script_module::EnsureModuleHooksInitialized;
use crate::script_thread::trace_thread;
use crate::task_source::SendableTaskSource;
static JOB_QUEUE_TRAPS: JobQueueTraps = JobQueueTraps {
getIncumbentGlobal: Some(get_incumbent_global),
getHostDefinedData: Some(get_host_defined_data),
enqueuePromiseJob: Some(enqueue_promise_job),
empty: Some(empty),
};
static SECURITY_CALLBACKS: JSSecurityCallbacks = JSSecurityCallbacks {
contentSecurityPolicyAllows: Some(content_security_policy_allows),
codeForEvalGets: None, //TODO
subsumes: Some(principals::subsumes),
};
@ -216,19 +217,49 @@ impl From<ScriptThreadEventCategory> for ScriptHangAnnotation {
}
}
static HOST_DEFINED_DATA: JSClassOps = JSClassOps {
addProperty: None,
delProperty: None,
enumerate: None,
newEnumerate: None,
resolve: None,
mayResolve: None,
finalize: None,
call: None,
construct: None,
trace: None,
};
static HOST_DEFINED_DATA_CLASS: JSClass = JSClass {
name: c"HostDefinedData".as_ptr(),
flags: (HOST_DEFINED_DATA_SLOTS & JSCLASS_RESERVED_SLOTS_MASK) << JSCLASS_RESERVED_SLOTS_SHIFT,
cOps: &HOST_DEFINED_DATA,
spec: ptr::null(),
ext: ptr::null(),
oOps: ptr::null(),
};
const INCUMBENT_SETTING_SLOT: u32 = 0;
const HOST_DEFINED_DATA_SLOTS: u32 = 1;
#[allow(unsafe_code)]
unsafe extern "C" fn get_incumbent_global(_: *const c_void, _: *mut RawJSContext) -> *mut JSObject {
let mut result = ptr::null_mut();
unsafe extern "C" fn get_host_defined_data(_: *const c_void, cx: *mut RawJSContext, data: MutableHandleObject) -> bool {
wrap_panic(&mut || {
let incumbent_global = GlobalScope::incumbent();
let Some(incumbent_global) = GlobalScope::incumbent() else {
data.set(ptr::null_mut());
return;
};
assert!(incumbent_global.is_some());
let _realm = enter_realm(&*incumbent_global);
result = incumbent_global
.map(|g| g.reflector().get_jsobject().get())
.unwrap_or(ptr::null_mut())
rooted!(in(cx) let result = JS_NewObject(cx, &HOST_DEFINED_DATA_CLASS));
assert!(!result.is_null());
JS_SetReservedSlot(*result, INCUMBENT_SETTING_SLOT, &ObjectValue(*incumbent_global.reflector().get_jsobject()));
data.set(result.get());
});
result
true
}
#[allow(unsafe_code)]
@ -250,14 +281,16 @@ unsafe extern "C" fn enqueue_promise_job(
promise: HandleObject,
job: HandleObject,
_allocation_site: HandleObject,
incumbent_global: HandleObject,
host_defined_data: HandleObject,
) -> bool {
let cx = JSContext::from_ptr(cx);
let mut result = false;
wrap_panic(&mut || {
let microtask_queue = &*(extra as *const MicrotaskQueue);
let global = if !incumbent_global.is_null() {
GlobalScope::from_object(incumbent_global.get())
let global = if !host_defined_data.is_null() {
let mut incumbent_global = UndefinedValue();
JS_GetReservedSlot(host_defined_data.get(), INCUMBENT_SETTING_SLOT, &mut incumbent_global);
GlobalScope::from_object(incumbent_global.to_object())
} else {
let realm = AlreadyInRealm::assert_for_cx(cx);
GlobalScope::from_context(*cx, InRealm::already(&realm))
@ -367,6 +400,12 @@ unsafe extern "C" fn content_security_policy_allows(
cx: *mut RawJSContext,
runtime_code: RuntimeCode,
sample: HandleString,
_compilation_type: CompilationType,
_parameter_strings: u8, //FIXME in bindings generation
_body_string: HandleString,
_parameter_args: u8, //FIXME in bindings generation
_body_arg: HandleValue,
can_compile_strings: *mut bool,
) -> bool {
let mut allowed = false;
let cx = JSContext::from_ptr(cx);
@ -393,7 +432,8 @@ unsafe extern "C" fn content_security_policy_allows(
global.report_csp_violations(violations, None);
allowed = is_evaluation_allowed == CheckResult::Allowed;
});
allowed
*can_compile_strings = allowed;
true
}
#[allow(unsafe_code)]
@ -549,7 +589,7 @@ impl Runtime {
Some(empty_has_released_callback),
);
// Pre barriers aren't working correctly at the moment
DisableIncrementalGC(cx);
JS_SetGCParameter(cx, JSGCParamKey::JSGC_INCREMENTAL_GC_ENABLED, 0);
unsafe extern "C" fn dispatch_to_event_loop(
closure: *mut c_void,
@ -720,9 +760,6 @@ impl Runtime {
if let Some(val) = in_range(pref!(js_mem_gc_empty_chunk_count_min), 0, 10_000) {
JS_SetGCParameter(cx, JSGCParamKey::JSGC_MIN_EMPTY_CHUNK_COUNT, val as u32);
}
if let Some(val) = in_range(pref!(js_mem_gc_empty_chunk_count_max), 0, 10_000) {
JS_SetGCParameter(cx, JSGCParamKey::JSGC_MAX_EMPTY_CHUNK_COUNT, val as u32);
}
Runtime {
rt: runtime,

View file

@ -10685,7 +10685,7 @@
[]
],
"interfaces.js": [
"fbfc396b62c55415c0493b7528bd5e2b959452e6",
"29caf5f592034c3b68800ad398f29066335d9f06",
[]
],
"max-session-history-frame.html": [

View file

@ -19,6 +19,7 @@ function test_interfaces(interfaceNamesInGlobalScope) {
"Error",
"EvalError",
"FinalizationRegistry",
"Float16Array",
"Float32Array",
"Float64Array",
"Function",