mirror of
https://github.com/denoland/rusty_v8.git
synced 2024-11-23 15:17:01 -05:00
Support ICU (#603)
Co-authored-by: Kunihiro Ishiguro <kunihiro@zebra.dev>
This commit is contained in:
parent
c22b0d3e38
commit
d60489c395
6 changed files with 107 additions and 1 deletions
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -22,3 +22,6 @@
|
|||
[submodule "third_party/zlib"]
|
||||
path = third_party/zlib
|
||||
url = https://chromium.googlesource.com/chromium/src/third_party/zlib.git
|
||||
[submodule "third_party/icu"]
|
||||
path = third_party/icu
|
||||
url = https://chromium.googlesource.com/chromium/deps/icu.git
|
||||
|
|
1
.gn
1
.gn
|
@ -28,7 +28,6 @@ default_args = {
|
|||
|
||||
# https://cs.chromium.org/chromium/src/docs/ccache_mac.md
|
||||
clang_use_chrome_plugins = false
|
||||
v8_enable_i18n_support = false
|
||||
v8_monolithic = false
|
||||
v8_use_external_startup_data = false
|
||||
v8_use_snapshot = true
|
||||
|
|
46
src/icu.rs
Normal file
46
src/icu.rs
Normal file
|
@ -0,0 +1,46 @@
|
|||
extern "C" {
|
||||
fn udata_setCommonData_68(this: *const u8, error_code: *mut i32);
|
||||
}
|
||||
|
||||
/// This function bypasses the normal ICU data loading process and allows you to force ICU's system
|
||||
/// data to come out of a user-specified area in memory.
|
||||
///
|
||||
/// ICU data must be at least 8-aligned, and should be 16-aligned. See
|
||||
/// https://unicode-org.github.io/icu/userguide/icudata
|
||||
///
|
||||
/// The format of this data is that of the icu common data file, as is generated by the pkgdata
|
||||
/// tool with mode=common or mode=dll. You can read in a whole common mode file and pass the
|
||||
/// address to the start of the data, or (with the appropriate link options) pass in the pointer to
|
||||
/// the data that has been loaded from a dll by the operating system, as shown in this code:
|
||||
///
|
||||
/// extern const char U_IMPORT U_ICUDATA_ENTRY_POINT [];
|
||||
/// // U_ICUDATA_ENTRY_POINT is same as entry point specified to pkgdata tool
|
||||
/// UErrorCode status = U_ZERO_ERROR;
|
||||
///
|
||||
/// udata_setCommonData(&U_ICUDATA_ENTRY_POINT, &status);
|
||||
///
|
||||
/// It is important that the declaration be as above. The entry point must not be declared as an
|
||||
/// extern void*.
|
||||
///
|
||||
/// Starting with ICU 4.4, it is possible to set several data packages, one per call to this
|
||||
/// function. udata_open() will look for data in the multiple data packages in the order in which
|
||||
/// they were set. The position of the linked-in or default-name ICU .data package in the search
|
||||
/// list depends on when the first data item is loaded that is not contained in the already
|
||||
/// explicitly set packages. If data was loaded implicitly before the first call to this function
|
||||
/// (for example, via opening a converter, constructing a UnicodeString from default-codepage data,
|
||||
/// using formatting or collation APIs, etc.), then the default data will be first in the list.
|
||||
///
|
||||
/// This function has no effect on application (non ICU) data. See udata_setAppData() for similar
|
||||
/// functionality for application data.
|
||||
// TODO(ry) Map error code to something useful.
|
||||
pub fn set_common_data(data: &'static [u8]) -> Result<(), i32> {
|
||||
let mut error_code = 0i32;
|
||||
unsafe {
|
||||
udata_setCommonData_68(data.as_ptr(), &mut error_code);
|
||||
}
|
||||
if error_code == 0 {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(error_code)
|
||||
}
|
||||
}
|
|
@ -45,6 +45,7 @@ mod external_references;
|
|||
mod fixed_array;
|
||||
mod function;
|
||||
mod handle;
|
||||
pub mod icu;
|
||||
mod isolate;
|
||||
mod isolate_create_params;
|
||||
mod module;
|
||||
|
|
|
@ -4715,3 +4715,59 @@ fn prepare_stack_trace_callback() {
|
|||
v8::Integer::new(scope, 42).into()
|
||||
}
|
||||
}
|
||||
|
||||
const ICU_DATA: &[u8; 10413584] =
|
||||
include_bytes!("../third_party/icu/common/icudtl.dat");
|
||||
|
||||
#[test]
|
||||
fn icu_date() {
|
||||
assert!(v8::icu::set_common_data(ICU_DATA).is_ok());
|
||||
|
||||
let _setup_guard = setup();
|
||||
let isolate = &mut v8::Isolate::new(Default::default());
|
||||
{
|
||||
let scope = &mut v8::HandleScope::new(isolate);
|
||||
let context = v8::Context::new(scope);
|
||||
let scope = &mut v8::ContextScope::new(scope, context);
|
||||
let source = r#"
|
||||
(new Date(Date.UTC(2020, 5, 26, 7, 0, 0))).toLocaleString("de-DE", {
|
||||
weekday: "long",
|
||||
year: "numeric",
|
||||
month: "long",
|
||||
day: "numeric",
|
||||
});
|
||||
"#;
|
||||
let value = eval(scope, source).unwrap();
|
||||
let date_de_val = v8::String::new(scope, "Freitag, 26. Juni 2020").unwrap();
|
||||
assert!(value.is_string());
|
||||
assert!(value.strict_equals(date_de_val.into()));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn icu_set_common_data_fail() {
|
||||
const BAD_DATA: &[u8; 3] = &[1, 2, 3];
|
||||
assert!(v8::icu::set_common_data(BAD_DATA).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn icu_format() {
|
||||
assert!(v8::icu::set_common_data(ICU_DATA).is_ok());
|
||||
|
||||
let _setup_guard = setup();
|
||||
let isolate = &mut v8::Isolate::new(Default::default());
|
||||
{
|
||||
let scope = &mut v8::HandleScope::new(isolate);
|
||||
let context = v8::Context::new(scope);
|
||||
let scope = &mut v8::ContextScope::new(scope, context);
|
||||
let source = r#"
|
||||
new Intl.NumberFormat("ja-JP", { style: "currency", currency: "JPY" }).format(
|
||||
1230000,
|
||||
);
|
||||
"#;
|
||||
let value = eval(scope, source).unwrap();
|
||||
let currency_jpy_val = v8::String::new(scope, "¥1,230,000").unwrap();
|
||||
assert!(value.is_string());
|
||||
assert!(value.strict_equals(currency_jpy_val.into()));
|
||||
}
|
||||
}
|
||||
|
|
1
third_party/icu
vendored
Submodule
1
third_party/icu
vendored
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit f4147b227f174e03f273053bb49fde33426d05bc
|
Loading…
Reference in a new issue