[codex] Initialize ICU data for code mode V8 (#17709)

Link ICU data into code mode, otherwise locale-dependent methods cause a
panic and a crash.
This commit is contained in:
pakrym-oai
2026-04-13 22:01:58 -07:00
committed by GitHub
Unverified
parent 3b24a9a532
commit ad37389c18
6 changed files with 101 additions and 7 deletions
+12 -7
View File
@@ -104,6 +104,8 @@ pub(crate) fn spawn_runtime(
request: ExecuteRequest,
event_tx: mpsc::UnboundedSender<RuntimeEvent>,
) -> Result<(std_mpsc::Sender<RuntimeCommand>, v8::IsolateHandle), String> {
initialize_v8()?;
let (command_tx, command_rx) = std_mpsc::channel();
let runtime_command_tx = command_tx.clone();
let (isolate_handle_tx, isolate_handle_rx) = std_mpsc::sync_channel(1);
@@ -164,15 +166,20 @@ pub(super) enum CompletionState {
},
}
fn initialize_v8() {
static PLATFORM: OnceLock<v8::SharedRef<v8::Platform>> = OnceLock::new();
fn initialize_v8() -> Result<(), String> {
static PLATFORM: OnceLock<Result<v8::SharedRef<v8::Platform>, String>> = OnceLock::new();
let _ = PLATFORM.get_or_init(|| {
match PLATFORM.get_or_init(|| {
v8::icu::set_common_data_77(deno_core_icudata::ICU_DATA)
.map_err(|error_code| format!("failed to initialize ICU data: {error_code}"))?;
let platform = v8::new_default_platform(0, false).make_shared();
v8::V8::initialize_platform(platform.clone());
v8::V8::initialize();
platform
});
Ok(platform)
}) {
Ok(_) => Ok(()),
Err(error_text) => Err(error_text.clone()),
}
}
fn run_runtime(
@@ -182,8 +189,6 @@ fn run_runtime(
isolate_handle_tx: std_mpsc::SyncSender<v8::IsolateHandle>,
runtime_command_tx: std_mpsc::Sender<RuntimeCommand>,
) {
initialize_v8();
let isolate = &mut v8::Isolate::new(v8::CreateParams::default());
let isolate_handle = isolate.thread_safe_handle();
if isolate_handle_tx.send(isolate_handle).is_err() {
+79
View File
@@ -561,6 +561,85 @@ mod tests {
);
}
#[tokio::test]
async fn date_locale_string_formats_with_icu_data() {
let service = CodeModeService::new();
let response = service
.execute(ExecuteRequest {
source: r#"
const value = new Date("2025-01-02T03:04:05Z")
.toLocaleString("fr-FR", {
weekday: "long",
month: "long",
day: "numeric",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
hour12: false,
timeZone: "UTC",
});
text(value);
"#
.to_string(),
yield_time_ms: None,
..execute_request("")
})
.await
.unwrap();
assert_eq!(
response,
RuntimeResponse::Result {
cell_id: "1".to_string(),
content_items: vec![FunctionCallOutputContentItem::InputText {
text: "jeudi 2 janvier \u{e0} 03:04:05".to_string(),
}],
stored_values: HashMap::new(),
error_text: None,
}
);
}
#[tokio::test]
async fn intl_date_time_format_formats_with_icu_data() {
let service = CodeModeService::new();
let response = service
.execute(ExecuteRequest {
source: r#"
const formatter = new Intl.DateTimeFormat("fr-FR", {
weekday: "long",
month: "long",
day: "numeric",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
hour12: false,
timeZone: "UTC",
});
text(formatter.format(new Date("2025-01-02T03:04:05Z")));
"#
.to_string(),
yield_time_ms: None,
..execute_request("")
})
.await
.unwrap();
assert_eq!(
response,
RuntimeResponse::Result {
cell_id: "1".to_string(),
content_items: vec![FunctionCallOutputContentItem::InputText {
text: "jeudi 2 janvier \u{e0} 03:04:05".to_string(),
}],
stored_values: HashMap::new(),
error_text: None,
}
);
}
#[tokio::test]
async fn output_helpers_return_undefined() {
let service = CodeModeService::new();