Skip to content

Commit

Permalink
Make the HostHooks shareable (#4141)
Browse files Browse the repository at this point in the history
  • Loading branch information
hansl authored Jan 23, 2025
1 parent 8aecf1b commit de552ec
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 46 deletions.
80 changes: 45 additions & 35 deletions core/engine/src/builtins/date/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ impl BuiltInConstructor for Date {
// b. Return ToDateString(now).
return Ok(JsValue::from(to_date_string_t(
now as f64,
context.host_hooks(),
context.host_hooks().as_ref(),
)));
}

Expand All @@ -222,7 +222,7 @@ impl BuiltInConstructor for Date {
// 3. If numberOfArgs = 0, then
[] => {
// a. Let dv be the time value (UTC) identifying the current time.
Self::utc_now(context.host_hooks())
Self::utc_now(context.host_hooks().as_ref())
}
// 4. Else if numberOfArgs = 1, then
// a. Let value be values[0].
Expand All @@ -243,7 +243,7 @@ impl BuiltInConstructor for Date {
if let Some(v) = v.as_string() {
// 1. Assert: The next step never returns an abrupt completion because v is a String.
// 2. Let tv be the result of parsing v as a date, in exactly the same manner as for the parse method (21.4.3.2).
let tv = parse_date(v, context.host_hooks());
let tv = parse_date(v, context.host_hooks().as_ref());
if let Some(tv) = tv {
tv as f64
} else {
Expand Down Expand Up @@ -296,7 +296,7 @@ impl BuiltInConstructor for Date {
let final_date = make_date(make_day(yr, m, dt), make_time(h, min, s, milli));

// k. Let dv be TimeClip(UTC(finalDate)).
Self(time_clip(utc_t(final_date, context.host_hooks())))
Self(time_clip(utc_t(final_date, context.host_hooks().as_ref())))
}
};

Expand Down Expand Up @@ -343,7 +343,8 @@ impl Date {
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse
pub(crate) fn parse(_: &JsValue, args: &[JsValue], context: &mut Context) -> JsResult<JsValue> {
let date = args.get_or_undefined(0).to_string(context)?;
Ok(parse_date(&date, context.host_hooks()).map_or(JsValue::from(f64::NAN), JsValue::from))
Ok(parse_date(&date, context.host_hooks().as_ref())
.map_or(JsValue::from(f64::NAN), JsValue::from))
}

/// `Date.UTC()`
Expand Down Expand Up @@ -430,7 +431,7 @@ impl Date {
// 5. Return DateFromTime(LocalTime(t)).
Ok(JsValue::from(date_from_time(local_time(
t,
context.host_hooks(),
context.host_hooks().as_ref(),
))))
} else {
// 5. Return DateFromTime(t).
Expand Down Expand Up @@ -467,7 +468,10 @@ impl Date {

if LOCAL {
// 5. Return WeekDay(LocalTime(t)).
Ok(JsValue::from(week_day(local_time(t, context.host_hooks()))))
Ok(JsValue::from(week_day(local_time(
t,
context.host_hooks().as_ref(),
))))
} else {
// 5. Return WeekDay(t).
Ok(JsValue::from(week_day(t)))
Expand Down Expand Up @@ -506,7 +510,7 @@ impl Date {

// 5. Return YearFromTime(LocalTime(t)) - 1900𝔽.
Ok(JsValue::from(
year_from_time(local_time(t, context.host_hooks())) - 1900,
year_from_time(local_time(t, context.host_hooks().as_ref())) - 1900,
))
}

Expand Down Expand Up @@ -540,7 +544,7 @@ impl Date {
// 5. Return YearFromTime(LocalTime(t)).
Ok(JsValue::from(year_from_time(local_time(
t,
context.host_hooks(),
context.host_hooks().as_ref(),
))))
} else {
// 5. Return YearFromTime(t).
Expand Down Expand Up @@ -578,7 +582,7 @@ impl Date {
// 5. Return HourFromTime(LocalTime(t)).
Ok(JsValue::from(hour_from_time(local_time(
t,
context.host_hooks(),
context.host_hooks().as_ref(),
))))
} else {
// 5. Return HourFromTime(t).
Expand Down Expand Up @@ -616,7 +620,7 @@ impl Date {
// 5. Return msFromTime(LocalTime(t)).
Ok(JsValue::from(ms_from_time(local_time(
t,
context.host_hooks(),
context.host_hooks().as_ref(),
))))
} else {
// 5. Return msFromTime(t).
Expand Down Expand Up @@ -654,7 +658,7 @@ impl Date {
// 5. Return MinFromTime(LocalTime(t)).
Ok(JsValue::from(min_from_time(local_time(
t,
context.host_hooks(),
context.host_hooks().as_ref(),
))))
} else {
// 5. Return MinFromTime(t).
Expand Down Expand Up @@ -693,7 +697,7 @@ impl Date {
// 5. Return MonthFromTime(LocalTime(t)).
Ok(JsValue::from(month_from_time(local_time(
t,
context.host_hooks(),
context.host_hooks().as_ref(),
))))
} else {
// 5. Return MonthFromTime(t).
Expand Down Expand Up @@ -731,7 +735,7 @@ impl Date {
// 5. Return SecFromTime(LocalTime(t)).
Ok(JsValue::from(sec_from_time(local_time(
t,
context.host_hooks(),
context.host_hooks().as_ref(),
))))
} else {
// 5. Return SecFromTime(t).
Expand Down Expand Up @@ -797,7 +801,7 @@ impl Date {

// 5. Return (t - LocalTime(t)) / msPerMinute.
Ok(JsValue::from(
(t - local_time(t, context.host_hooks())) / MS_PER_MINUTE,
(t - local_time(t, context.host_hooks().as_ref())) / MS_PER_MINUTE,
))
}

Expand Down Expand Up @@ -840,7 +844,7 @@ impl Date {

if LOCAL {
// 6. Set t to LocalTime(t).
t = local_time(t, context.host_hooks());
t = local_time(t, context.host_hooks().as_ref());
}

// 7. Let newDate be MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), dt), TimeWithinDay(t)).
Expand All @@ -851,7 +855,7 @@ impl Date {

let u = if LOCAL {
// 8. Let u be TimeClip(UTC(newDate)).
time_clip(utc_t(new_date, context.host_hooks()))
time_clip(utc_t(new_date, context.host_hooks().as_ref()))
} else {
// 8. Let v be TimeClip(newDate).
time_clip(new_date)
Expand Down Expand Up @@ -903,7 +907,7 @@ impl Date {
if t.is_nan() {
0.0
} else {
local_time(t, context.host_hooks())
local_time(t, context.host_hooks().as_ref())
}
} else {
// 4. If t is NaN, set t to +0𝔽.
Expand Down Expand Up @@ -936,7 +940,7 @@ impl Date {

let u = if LOCAL {
// 9. Let u be TimeClip(UTC(newDate)).
time_clip(utc_t(new_date, context.host_hooks()))
time_clip(utc_t(new_date, context.host_hooks().as_ref()))
} else {
// 9. Let u be TimeClip(newDate).
time_clip(new_date)
Expand Down Expand Up @@ -1004,7 +1008,7 @@ impl Date {

if LOCAL {
// 9. Set t to LocalTime(t).
t = local_time(t, context.host_hooks());
t = local_time(t, context.host_hooks().as_ref());
}

// 10. If min is not present, let m be MinFromTime(t).
Expand All @@ -1021,7 +1025,7 @@ impl Date {

let u = if LOCAL {
// 14. Let u be TimeClip(UTC(date)).
time_clip(utc_t(date, context.host_hooks()))
time_clip(utc_t(date, context.host_hooks().as_ref()))
} else {
// 14. Let u be TimeClip(date).
time_clip(date)
Expand Down Expand Up @@ -1077,7 +1081,7 @@ impl Date {

if LOCAL {
// 6. Set t to LocalTime(t).
t = local_time(t, context.host_hooks());
t = local_time(t, context.host_hooks().as_ref());
}

// 7. Let time be MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms).
Expand All @@ -1090,7 +1094,10 @@ impl Date {

let u = if LOCAL {
// 8. Let u be TimeClip(UTC(MakeDate(Day(t), time))).
time_clip(utc_t(make_date(day(t), time), context.host_hooks()))
time_clip(utc_t(
make_date(day(t), time),
context.host_hooks().as_ref(),
))
} else {
// 8. Let u be TimeClip(MakeDate(Day(t), time)).
time_clip(make_date(day(t), time))
Expand Down Expand Up @@ -1152,7 +1159,7 @@ impl Date {

if LOCAL {
// 8. Set t to LocalTime(t).
t = local_time(t, context.host_hooks());
t = local_time(t, context.host_hooks().as_ref());
}

// 9. If sec is not present, let s be SecFromTime(t).
Expand All @@ -1166,7 +1173,7 @@ impl Date {

let u = if LOCAL {
// 12. Let u be TimeClip(UTC(date)).
time_clip(utc_t(date, context.host_hooks()))
time_clip(utc_t(date, context.host_hooks().as_ref()))
} else {
// 12. Let u be TimeClip(date).
time_clip(date)
Expand Down Expand Up @@ -1226,7 +1233,7 @@ impl Date {

// 7. Set t to LocalTime(t).
if LOCAL {
t = local_time(t, context.host_hooks());
t = local_time(t, context.host_hooks().as_ref());
}

// 8. If date is not present, let dt be DateFromTime(t).
Expand All @@ -1240,7 +1247,7 @@ impl Date {

let u = if LOCAL {
// 10. Let u be TimeClip(UTC(newDate)).
time_clip(utc_t(new_date, context.host_hooks()))
time_clip(utc_t(new_date, context.host_hooks().as_ref()))
} else {
// 10. Let u be TimeClip(newDate).
time_clip(new_date)
Expand Down Expand Up @@ -1299,7 +1306,7 @@ impl Date {

// 7. Set t to LocalTime(t).
if LOCAL {
t = local_time(t, context.host_hooks());
t = local_time(t, context.host_hooks().as_ref());
}

// 8. If ms is not present, let milli be msFromTime(t).
Expand All @@ -1313,7 +1320,7 @@ impl Date {

let u = if LOCAL {
// 10. Let u be TimeClip(UTC(date)).
time_clip(utc_t(date, context.host_hooks()))
time_clip(utc_t(date, context.host_hooks().as_ref()))
} else {
// 10. Let u be TimeClip(date).
time_clip(date)
Expand Down Expand Up @@ -1373,7 +1380,7 @@ impl Date {
let t = if t.is_nan() {
0.0
} else {
local_time(t, context.host_hooks())
local_time(t, context.host_hooks().as_ref())
};

// 6. Let yyyy be MakeFullYear(y).
Expand All @@ -1386,7 +1393,7 @@ impl Date {
let date = make_date(d, time_within_day(t));

// 9. Let u be TimeClip(UTC(date)).
let u = time_clip(utc_t(date, context.host_hooks()));
let u = time_clip(utc_t(date, context.host_hooks().as_ref()));

let mut date_mut = this
.as_object()
Expand Down Expand Up @@ -1475,7 +1482,7 @@ impl Date {
};

// 5. Let t be LocalTime(tv).
let t = local_time(tv, context.host_hooks());
let t = local_time(tv, context.host_hooks().as_ref());

// 6. Return DateString(t).
Ok(JsValue::from(date_string(t)))
Expand Down Expand Up @@ -1668,7 +1675,10 @@ impl Date {
.0;

// 4. Return ToDateString(tv).
Ok(JsValue::from(to_date_string_t(tv, context.host_hooks())))
Ok(JsValue::from(to_date_string_t(
tv,
context.host_hooks().as_ref(),
)))
}

/// [`Date.prototype.toTimeString()`][spec].
Expand Down Expand Up @@ -1701,12 +1711,12 @@ impl Date {
}

// 5. Let t be LocalTime(tv).
let t = local_time(tv, context.host_hooks());
let t = local_time(tv, context.host_hooks().as_ref());

// 6. Return the string-concatenation of TimeString(t) and TimeZoneString(tv).
Ok(JsValue::from(js_string!(
&time_string(t),
&time_zone_string(t, context.host_hooks())
&time_zone_string(t, context.host_hooks().as_ref())
)))
}

Expand Down
3 changes: 2 additions & 1 deletion core/engine/src/context/hooks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use time::{OffsetDateTime, UtcOffset};
/// need to be redefined:
///
/// ```
/// use std::rc::Rc;
/// use boa_engine::{
/// context::{Context, ContextBuilder, HostHooks},
/// realm::Realm,
Expand All @@ -42,7 +43,7 @@ use time::{OffsetDateTime, UtcOffset};
/// }
/// }
///
/// let context = &mut ContextBuilder::new().host_hooks(&Hooks).build().unwrap();
/// let context = &mut ContextBuilder::new().host_hooks(Rc::new(Hooks)).build().unwrap();
/// let result = context.eval(Source::from_bytes(r#"eval("let a = 5")"#));
/// assert_eq!(
/// result.unwrap_err().to_string(),
Expand Down
16 changes: 8 additions & 8 deletions core/engine/src/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ pub struct Context {
#[cfg(feature = "intl")]
intl_provider: icu::IntlProvider,

host_hooks: &'static dyn HostHooks,
host_hooks: Rc<dyn HostHooks>,

job_executor: Rc<dyn JobExecutor>,

Expand Down Expand Up @@ -530,7 +530,7 @@ impl Context {

/// Create a new Realm with the default global bindings.
pub fn create_realm(&mut self) -> JsResult<Realm> {
let realm = Realm::create(self.host_hooks, &self.root_shape)?;
let realm = Realm::create(self.host_hooks.as_ref(), &self.root_shape)?;

let old_realm = self.enter_realm(realm);

Expand All @@ -549,8 +549,8 @@ impl Context {
/// Gets the host hooks.
#[inline]
#[must_use]
pub fn host_hooks(&self) -> &'static dyn HostHooks {
self.host_hooks
pub fn host_hooks(&self) -> Rc<dyn HostHooks> {
self.host_hooks.clone()
}

/// Gets the job executor.
Expand Down Expand Up @@ -887,7 +887,7 @@ impl Context {
#[derive(Default)]
pub struct ContextBuilder {
interner: Option<Interner>,
host_hooks: Option<&'static dyn HostHooks>,
host_hooks: Option<Rc<dyn HostHooks>>,
job_executor: Option<Rc<dyn JobExecutor>>,
module_loader: Option<Rc<dyn ModuleLoader>>,
can_block: bool,
Expand Down Expand Up @@ -1021,7 +1021,7 @@ impl ContextBuilder {
///
/// [`Host Hooks`]: https://tc39.es/ecma262/#sec-host-hooks-summary
#[must_use]
pub fn host_hooks<H: HostHooks + 'static>(mut self, host_hooks: &'static H) -> Self {
pub fn host_hooks<H: HostHooks + 'static>(mut self, host_hooks: Rc<H>) -> Self {
self.host_hooks = Some(host_hooks);
self
}
Expand Down Expand Up @@ -1088,8 +1088,8 @@ impl ContextBuilder {

let root_shape = RootShape::default();

let host_hooks = self.host_hooks.unwrap_or(&DefaultHooks);
let realm = Realm::create(host_hooks, &root_shape)?;
let host_hooks = self.host_hooks.unwrap_or(Rc::new(DefaultHooks));
let realm = Realm::create(host_hooks.as_ref(), &root_shape)?;
let vm = Vm::new(realm);

let module_loader: Rc<dyn ModuleLoader> = if let Some(loader) = self.module_loader {
Expand Down
Loading

0 comments on commit de552ec

Please sign in to comment.