From fbb192e4b31610948e082e6036910b1b17d92ca7 Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Sun, 5 Feb 2023 18:18:10 +0100 Subject: [PATCH 01/16] fix clippy lints --- examples/eval.rs | 4 ++-- libquickjs-sys/build.rs | 2 +- libquickjs-sys/src/lib.rs | 1 + src/bindings/compile.rs | 13 +++---------- src/bindings/convert.rs | 5 ++--- src/bindings/mod.rs | 16 +++++++--------- src/bindings/value.rs | 5 ++--- src/callback.rs | 4 ++-- src/console.rs | 6 +++--- src/lib.rs | 14 +++++--------- src/tests.rs | 28 +++++++++++++--------------- src/value/bigint.rs | 4 ++-- src/value/mod.rs | 9 +++------ 13 files changed, 46 insertions(+), 65 deletions(-) diff --git a/examples/eval.rs b/examples/eval.rs index 03e2647..932febb 100644 --- a/examples/eval.rs +++ b/examples/eval.rs @@ -4,7 +4,7 @@ pub fn main() { let context = Context::new().unwrap(); let value = context.eval("1 + 2").unwrap(); - println!("js: 1 + 2 = {:?}", value); + println!("js: 1 + 2 = {value:?}"); context .add_callback("myCallback", |a: i32, b: i32| a + b * b) @@ -18,5 +18,5 @@ pub fn main() { "#, ) .unwrap(); - println!("js: callback = {:?}", value); + println!("js: callback = {value:?}"); } diff --git a/libquickjs-sys/build.rs b/libquickjs-sys/build.rs index ce14550..5836beb 100644 --- a/libquickjs-sys/build.rs +++ b/libquickjs-sys/build.rs @@ -126,7 +126,7 @@ fn apply_patches(code_dir: &PathBuf) { let patch = patch.expect("Could not open patch"); eprintln!("Applying {:?}...", patch.file_name()); let status = std::process::Command::new("patch") - .current_dir(&code_dir) + .current_dir(code_dir) .arg("-i") .arg(patch.path()) .spawn() diff --git a/libquickjs-sys/src/lib.rs b/libquickjs-sys/src/lib.rs index 7bbc074..914a1ed 100644 --- a/libquickjs-sys/src/lib.rs +++ b/libquickjs-sys/src/lib.rs @@ -6,6 +6,7 @@ #![allow(non_upper_case_globals)] #![allow(non_camel_case_types)] #![allow(non_snake_case)] +#![allow(clippy::missing_safety_doc)] include!(concat!(env!("OUT_DIR"), "/bindings.rs")); diff --git a/src/bindings/compile.rs b/src/bindings/compile.rs index e6ce020..cca4ed4 100644 --- a/src/bindings/compile.rs +++ b/src/bindings/compile.rs @@ -47,7 +47,7 @@ pub fn run_compiled_function<'a>( context.ensure_no_excpetion().map_err(|e| { if let ExecutionError::Internal(msg) = e { - ExecutionError::Internal(format!("Could not evaluate compiled function: {}", msg)) + ExecutionError::Internal(format!("Could not evaluate compiled function: {msg}")) } else { e } @@ -122,7 +122,6 @@ pub mod tests { "test_func.es", ); let func = func_res - .ok() .expect("func compile failed") .try_into_compiled_function() .unwrap(); @@ -132,7 +131,6 @@ pub mod tests { let func2_res = from_bytecode(&ctx, &bytecode); let func2 = func2_res - .ok() .expect("could not read bytecode") .try_into_compiled_function() .unwrap(); @@ -157,7 +155,6 @@ pub mod tests { "test_func.es", ); let func = func_res - .ok() .expect("func compile failed") .try_into_compiled_function() .unwrap(); @@ -166,7 +163,6 @@ pub mod tests { assert!(!bytecode.is_empty()); let func2_res = from_bytecode(&ctx, &bytecode); let func2 = func2_res - .ok() .expect("could not read bytecode") .try_into_compiled_function() .unwrap(); @@ -191,7 +187,7 @@ pub mod tests { "{the changes of me compil1ng a're slim to 0-0}", "test_func_fail.es", ); - func_res.err().expect("func compiled unexpectedly"); + func_res.expect_err("func compiled unexpectedly"); } #[test] @@ -200,7 +196,6 @@ pub mod tests { let func_res = compile(&ctx, "let abcdef = 1;", "test_func_runfail.es"); let func = func_res - .ok() .expect("func compile failed") .try_into_compiled_function() .unwrap(); @@ -232,9 +227,7 @@ pub mod tests { assert_eq!(1, func2.as_value().get_ref_count()); - let _run_res2 = run_compiled_function(&func2) - .err() - .expect("run 2 succeeded unexpectedly"); + let _run_res2 = run_compiled_function(&func2).expect_err("run 2 succeeded unexpectedly"); assert_eq!(1, func2.as_value().get_ref_count()); } diff --git a/src/bindings/convert.rs b/src/bindings/convert.rs index 9304a8f..a0621ce 100644 --- a/src/bindings/convert.rs +++ b/src/bindings/convert.rs @@ -227,7 +227,7 @@ pub(super) fn serialize_value( let s = DroppableValue::new(s, |&mut s| unsafe { q::JS_FreeValue(context, s); }); - if (*s).tag != TAG_STRING { + if s.tag != TAG_STRING { return Err(ValueError::Internal( "Could not construct String object needed to create BigInt object".into(), )); @@ -503,8 +503,7 @@ pub(super) fn deserialize_value( } } x => Err(ValueError::Internal(format!( - "Unhandled JS_TAG value: {}", - x + "Unhandled JS_TAG value: {x}" ))), } } diff --git a/src/bindings/mod.rs b/src/bindings/mod.rs index 86eab4f..2582302 100644 --- a/src/bindings/mod.rs +++ b/src/bindings/mod.rs @@ -269,13 +269,11 @@ impl<'a> OwnedObjectRef<'a> { if raw.tag == TAG_EXCEPTION { Err(ExecutionError::Internal(format!( - "Exception while getting property '{}'", - name + "Exception while getting property '{name}'" ))) } else if raw.tag == TAG_UNDEFINED { Err(ExecutionError::Internal(format!( - "Property '{}' not found", - name + "Property '{name}' not found" ))) } else { Ok(OwnedValueRef::new(self.value.context, raw)) @@ -681,10 +679,10 @@ impl ContextWrapper { } /// Add a global JS function that is backed by a Rust function or closure. - pub fn create_callback<'a, F>( - &'a self, + pub fn create_callback( + &self, callback: impl Callback + 'static, - ) -> Result, ExecutionError> { + ) -> Result { let argcount = callback.argument_count() as i32; let context = self.context; @@ -724,8 +722,8 @@ impl ContextWrapper { Ok(f) } - pub fn add_callback<'a, F>( - &'a self, + pub fn add_callback( + &self, name: &str, callback: impl Callback + 'static, ) -> Result<(), ExecutionError> { diff --git a/src/bindings/value.rs b/src/bindings/value.rs index 6eff3ca..b60707f 100644 --- a/src/bindings/value.rs +++ b/src/bindings/value.rs @@ -432,8 +432,7 @@ impl<'a> OwnedJsObject<'a> { if tag.is_exception() { Err(ExecutionError::Internal(format!( - "Exception while getting property '{}'", - name + "Exception while getting property '{name}'" ))) } else if tag.is_undefined() { Ok(None) @@ -444,7 +443,7 @@ impl<'a> OwnedJsObject<'a> { pub fn property_require(&self, name: &str) -> Result, ExecutionError> { self.property(name)? - .ok_or_else(|| ExecutionError::Internal(format!("Property '{}' not found", name))) + .ok_or_else(|| ExecutionError::Internal(format!("Property '{name}' not found"))) } /// Determine if the object is a promise by checking the presence of diff --git a/src/callback.rs b/src/callback.rs index cd9f9a4..0c2edeb 100644 --- a/src/callback.rs +++ b/src/callback.rs @@ -104,7 +104,7 @@ where } fn call(&self, args: Vec) -> Result, ValueError> { - if args.len() != 0 { + if !args.is_empty() { return Ok(Err(format!( "Invalid argument count: Expected 0, got {}", args.len(), @@ -124,7 +124,7 @@ impl_callback![ 5: (A1, A2, A3, A4, A5,), ]; -/// A wrapper around Vec, used for vararg callbacks. +/// A wrapper around [`Vec`], used for vararg callbacks. /// /// To create a callback with a variable number of arguments, a callback closure /// must take a single `Arguments` argument. diff --git a/src/console.rs b/src/console.rs index 99d70a4..bd3b8ad 100644 --- a/src/console.rs +++ b/src/console.rs @@ -28,7 +28,7 @@ impl std::fmt::Display for Level { Warn => "warn", Error => "error", }; - write!(f, "{}", v) + write!(f, "{v}") } } @@ -91,7 +91,7 @@ mod log { .map(print_value) .collect::>() .join(", "); - format!("[{}]", parts) + format!("[{parts}]") } JsValue::Object(map) => { let parts = map @@ -99,7 +99,7 @@ mod log { .map(|(key, value)| format!("{}: {}", key, print_value(value))) .collect::>() .join(", "); - format!("{{{}}}", parts) + format!("{{{parts}}}") } #[cfg(feature = "chrono")] JsValue::Date(v) => v.to_string(), diff --git a/src/lib.rs b/src/lib.rs index 9c5bb82..7497162 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -32,7 +32,7 @@ //! "#).unwrap(); //! ``` -#![allow(dead_code)] +#![allow(dead_code, clippy::missing_safety_doc)] #![deny(missing_docs)] mod bindings; @@ -52,6 +52,7 @@ pub use self::{ /// Error on Javascript execution. #[derive(PartialEq, Debug)] +#[non_exhaustive] pub enum ExecutionError { /// Code to be executed contained zero-bytes. InputWithZeroBytes, @@ -63,8 +64,6 @@ pub enum ExecutionError { Exception(JsValue), /// JS Runtime exceeded the memory limit. OutOfMemory, - #[doc(hidden)] - __NonExhaustive, } impl fmt::Display for ExecutionError { @@ -73,10 +72,9 @@ impl fmt::Display for ExecutionError { match self { InputWithZeroBytes => write!(f, "Invalid script input: code contains zero byte (\\0)"), Conversion(e) => e.fmt(f), - Internal(e) => write!(f, "Internal error: {}", e), - Exception(e) => write!(f, "{:?}", e), + Internal(e) => write!(f, "Internal error: {e}"), + Exception(e) => write!(f, "{e:?}"), OutOfMemory => write!(f, "Out of memory: runtime memory limit exceeded"), - __NonExhaustive => unreachable!(), } } } @@ -91,6 +89,7 @@ impl From for ExecutionError { /// Error on context creation. #[derive(Debug)] +#[non_exhaustive] pub enum ContextError { /// Runtime could not be created. RuntimeCreationFailed, @@ -98,8 +97,6 @@ pub enum ContextError { ContextCreationFailed, /// Execution error while building. Execution(ExecutionError), - #[doc(hidden)] - __NonExhaustive, } impl fmt::Display for ContextError { @@ -109,7 +106,6 @@ impl fmt::Display for ContextError { RuntimeCreationFailed => write!(f, "Could not create runtime"), ContextCreationFailed => write!(f, "Could not create context"), Execution(e) => e.fmt(f), - __NonExhaustive => unreachable!(), } } } diff --git a/src/tests.rs b/src/tests.rs index b35900b..a5a247e 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -74,9 +74,7 @@ fn test_eval_pass() { for (index, (code, res)) in obj_cases.into_iter().enumerate() { let full_code = format!( - "var v{index} = {code}; v{index}", - index = index, - code = code + "var v{index} = {code}; v{index}" ); assert_eq!(c.eval(&full_code), res,); } @@ -283,7 +281,7 @@ fn test_callback() { c.add_callback("cb1", |flag: bool| !flag).unwrap(); assert_eq!(c.eval("cb1(true)").unwrap(), JsValue::Bool(false),); - c.add_callback("concat2", |a: String, b: String| format!("{}{}", a, b)) + c.add_callback("concat2", |a: String, b: String| format!("{a}{b}")) .unwrap(); assert_eq!( c.eval(r#"concat2("abc", "def")"#).unwrap(), @@ -486,7 +484,7 @@ fn chrono_serialize() { let now_millis = now.timestamp_millis(); let timestamp = c - .call_function("dateToTimestamp", vec![JsValue::Date(now.clone())]) + .call_function("dateToTimestamp", vec![JsValue::Date(now)]) .unwrap(); assert_eq!(timestamp, JsValue::Float(now_millis as f64)); @@ -512,8 +510,8 @@ fn chrono_roundtrip() { c.eval(" function identity(x) { return x; } ").unwrap(); let d = chrono::Utc::now(); - let td = JsValue::Date(d.clone()); - let td2 = c.call_function("identity", vec![td.clone()]).unwrap(); + let td = JsValue::Date(d); + let td2 = c.call_function("identity", vec![td]).unwrap(); let d2 = if let JsValue::Date(x) = td2 { x } else { @@ -647,7 +645,7 @@ fn test_global_setter() { fn test_date_iso(#[case] input: &str, #[case] expect: i64) { let ctx = Context::new().unwrap(); let res = ctx - .eval(&format!(r#"new Date("{}").getTime()"#, input)) + .eval(&format!(r#"new Date("{input}").getTime()"#)) .unwrap(); let n: f64 = res.try_into().unwrap(); @@ -668,7 +666,7 @@ fn test_date_iso(#[case] input: &str, #[case] expect: i64) { fn test_date_gmt(#[case] input: &str, #[case] expect: i64) { let ctx = Context::new().unwrap(); let res = ctx - .eval(&format!(r#"new Date("{}").getTime()"#, input)) + .eval(&format!(r#"new Date("{input}").getTime()"#)) .unwrap(); let n: f64 = res.try_into().unwrap(); @@ -722,7 +720,7 @@ fn test_date_gmt(#[case] input: &str, #[case] expect: i64) { fn test_date_tz(#[case] input: &str, #[case] expect: i64) { let ctx = Context::new().unwrap(); let res = ctx - .eval(&format!(r#"new Date("{}").getTime()"#, input)) + .eval(&format!(r#"new Date("{input}").getTime()"#)) .unwrap(); let n: f64 = res.try_into().unwrap(); @@ -746,7 +744,7 @@ fn test_date_tz(#[case] input: &str, #[case] expect: i64) { fn test_date_special(#[case] input: &str, #[case] expect: i64) { let ctx = Context::new().unwrap(); let res = ctx - .eval(&format!(r#"new Date("{}").getTime()"#, input)) + .eval(&format!(r#"new Date("{input}").getTime()"#)) .unwrap(); let n: f64 = res.try_into().unwrap(); @@ -772,11 +770,11 @@ fn test_date_special(#[case] input: &str, #[case] expect: i64) { fn test_date_invalid(#[case] input: &str) { let ctx = Context::new().unwrap(); let res = ctx - .eval(&format!(r#"new Date("{}").getTime()"#, input)) + .eval(&format!(r#"new Date("{input}").getTime()"#)) .unwrap(); let n: f64 = res.try_into().unwrap(); - assert!(n.is_nan(), "got: {}", n); + assert!(n.is_nan(), "got: {n}"); } #[test] @@ -856,14 +854,14 @@ fn test_date_ut() { for case in test_cases_ut { let ctx = Context::new().unwrap(); let res = ctx - .eval(&format!(r#"new Date("{}").getTime()"#, case)) + .eval(&format!(r#"new Date("{case}").getTime()"#)) .unwrap(); let n: f64 = res.try_into().unwrap(); if n == 946713600000.0 { passed += 1; } else { - println!("FAIL: `{}` - {}", case, n); + println!("FAIL: `{case}` - {n}"); failed += 1; } } diff --git a/src/value/bigint.rs b/src/value/bigint.rs index df2d475..af912e3 100644 --- a/src/value/bigint.rs +++ b/src/value/bigint.rs @@ -46,8 +46,8 @@ impl BigInt { impl std::fmt::Display for BigInt { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { match self.inner { - BigIntOrI64::Int(i) => write!(f, "{}", i), - BigIntOrI64::BigInt(ref i) => write!(f, "{}", i), + BigIntOrI64::Int(i) => write!(f, "{i}"), + BigIntOrI64::BigInt(ref i) => write!(f, "{i}"), } } } diff --git a/src/value/mod.rs b/src/value/mod.rs index 4f2e71d..27fe3f0 100644 --- a/src/value/mod.rs +++ b/src/value/mod.rs @@ -259,6 +259,7 @@ where /// Error during value conversion. #[derive(PartialEq, Eq, Debug)] +#[non_exhaustive] pub enum ValueError { /// Invalid non-utf8 string. InvalidString(std::str::Utf8Error), @@ -268,8 +269,6 @@ pub enum ValueError { Internal(String), /// Received an unexpected type that could not be converted. UnexpectedType, - #[doc(hidden)] - __NonExhaustive, } // TODO: remove this once either the Never type get's stabilized or the compiler @@ -286,13 +285,11 @@ impl fmt::Display for ValueError { match self { InvalidString(e) => write!( f, - "Value conversion failed - invalid non-utf8 string: {}", - e + "Value conversion failed - invalid non-utf8 string: {e}" ), StringWithZeroBytes(_) => write!(f, "String contains \\0 bytes",), - Internal(e) => write!(f, "Value conversion failed - internal error: {}", e), + Internal(e) => write!(f, "Value conversion failed - internal error: {e}"), UnexpectedType => write!(f, "Could not convert - received unexpected type"), - __NonExhaustive => unreachable!(), } } } From 972114fae8f1f237aaa8aefb0202ced8ec431822 Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Sun, 5 Feb 2023 18:25:07 +0100 Subject: [PATCH 02/16] upgrade rust edition --- Cargo.toml | 2 +- libquickjs-sys/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 812552d..69c530d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [package] -edition = "2018" +edition = "2021" name = "quick-js" description = "QuickJS Javascript engine wrapper" version = "0.4.2-alpha.0" diff --git a/libquickjs-sys/Cargo.toml b/libquickjs-sys/Cargo.toml index 1c98857..626c6bb 100644 --- a/libquickjs-sys/Cargo.toml +++ b/libquickjs-sys/Cargo.toml @@ -1,5 +1,5 @@ [package] -edition = "2018" +edition = "2021" name = "libquickjs-sys" description = "QuickJS Javascript Engine FFI bindings" version = "0.9.0" From 9f69e8f5b4026f5415acbcee8a3894f5f8af3222 Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Sun, 5 Feb 2023 18:34:00 +0100 Subject: [PATCH 03/16] format code --- src/bindings/convert.rs | 4 +--- src/tests.rs | 4 +--- src/value/mod.rs | 5 +---- 3 files changed, 3 insertions(+), 10 deletions(-) diff --git a/src/bindings/convert.rs b/src/bindings/convert.rs index a0621ce..b22aa29 100644 --- a/src/bindings/convert.rs +++ b/src/bindings/convert.rs @@ -502,8 +502,6 @@ pub(super) fn deserialize_value( })) } } - x => Err(ValueError::Internal(format!( - "Unhandled JS_TAG value: {x}" - ))), + x => Err(ValueError::Internal(format!("Unhandled JS_TAG value: {x}"))), } } diff --git a/src/tests.rs b/src/tests.rs index a5a247e..389ddd4 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -73,9 +73,7 @@ fn test_eval_pass() { ]; for (index, (code, res)) in obj_cases.into_iter().enumerate() { - let full_code = format!( - "var v{index} = {code}; v{index}" - ); + let full_code = format!("var v{index} = {code}; v{index}"); assert_eq!(c.eval(&full_code), res,); } diff --git a/src/value/mod.rs b/src/value/mod.rs index 27fe3f0..ba980ea 100644 --- a/src/value/mod.rs +++ b/src/value/mod.rs @@ -283,10 +283,7 @@ impl fmt::Display for ValueError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { use ValueError::*; match self { - InvalidString(e) => write!( - f, - "Value conversion failed - invalid non-utf8 string: {e}" - ), + InvalidString(e) => write!(f, "Value conversion failed - invalid non-utf8 string: {e}"), StringWithZeroBytes(_) => write!(f, "String contains \\0 bytes",), Internal(e) => write!(f, "Value conversion failed - internal error: {e}"), UnexpectedType => write!(f, "Could not convert - received unexpected type"), From 95c79348b2382eb3ed1d6d616c3dad6877e655ae Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Sun, 5 Feb 2023 20:29:03 +0100 Subject: [PATCH 04/16] recreate bindings with latest bindgen --- libquickjs-sys/embed/bindings.rs | 599 +++++++++++++++---------------- libquickjs-sys/src/lib.rs | 2 +- src/bindings/compile.rs | 2 +- src/bindings/convert.rs | 2 +- 4 files changed, 285 insertions(+), 320 deletions(-) diff --git a/libquickjs-sys/embed/bindings.rs b/libquickjs-sys/embed/bindings.rs index ffe6e5e..198dee4 100644 --- a/libquickjs-sys/embed/bindings.rs +++ b/libquickjs-sys/embed/bindings.rs @@ -1,4 +1,4 @@ -/* automatically generated by rust-bindgen 0.55.1 */ +/* automatically generated by rust-bindgen 0.63.0 */ pub const _STDIO_H: u32 = 1; pub const _FEATURES_H: u32 = 1; @@ -17,6 +17,10 @@ pub const __USE_POSIX199506: u32 = 1; pub const __USE_XOPEN2K: u32 = 1; pub const __USE_XOPEN2K8: u32 = 1; pub const _ATFILE_SOURCE: u32 = 1; +pub const __WORDSIZE: u32 = 64; +pub const __WORDSIZE_TIME64_COMPAT32: u32 = 1; +pub const __SYSCALL_WORDSIZE: u32 = 64; +pub const __TIMESIZE: u32 = 64; pub const __USE_MISC: u32 = 1; pub const __USE_ATFILE: u32 = 1; pub const __USE_FORTIFY_LEVEL: u32 = 0; @@ -24,27 +28,26 @@ pub const __GLIBC_USE_DEPRECATED_GETS: u32 = 0; pub const __GLIBC_USE_DEPRECATED_SCANF: u32 = 0; pub const _STDC_PREDEF_H: u32 = 1; pub const __STDC_IEC_559__: u32 = 1; +pub const __STDC_IEC_60559_BFP__: u32 = 201404; pub const __STDC_IEC_559_COMPLEX__: u32 = 1; +pub const __STDC_IEC_60559_COMPLEX__: u32 = 201404; pub const __STDC_ISO_10646__: u32 = 201706; pub const __GNU_LIBRARY__: u32 = 6; pub const __GLIBC__: u32 = 2; -pub const __GLIBC_MINOR__: u32 = 32; +pub const __GLIBC_MINOR__: u32 = 36; pub const _SYS_CDEFS_H: u32 = 1; pub const __glibc_c99_flexarr_available: u32 = 1; -pub const __WORDSIZE: u32 = 64; -pub const __WORDSIZE_TIME64_COMPAT32: u32 = 1; -pub const __SYSCALL_WORDSIZE: u32 = 64; pub const __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI: u32 = 0; pub const __HAVE_GENERIC_SELECTION: u32 = 1; pub const __GLIBC_USE_LIB_EXT2: u32 = 0; pub const __GLIBC_USE_IEC_60559_BFP_EXT: u32 = 0; pub const __GLIBC_USE_IEC_60559_BFP_EXT_C2X: u32 = 0; +pub const __GLIBC_USE_IEC_60559_EXT: u32 = 0; pub const __GLIBC_USE_IEC_60559_FUNCS_EXT: u32 = 0; pub const __GLIBC_USE_IEC_60559_FUNCS_EXT_C2X: u32 = 0; pub const __GLIBC_USE_IEC_60559_TYPES_EXT: u32 = 0; pub const __GNUC_VA_LIST: u32 = 1; pub const _BITS_TYPES_H: u32 = 1; -pub const __TIMESIZE: u32 = 64; pub const _BITS_TYPESIZES_H: u32 = 1; pub const __OFF_T_MATCHES_OFF64_T: u32 = 1; pub const __INO_T_MATCHES_INO64_T: u32 = 1; @@ -70,7 +73,7 @@ pub const EOF: i32 = -1; pub const SEEK_SET: u32 = 0; pub const SEEK_CUR: u32 = 1; pub const SEEK_END: u32 = 2; -pub const P_tmpdir: &'static [u8; 5usize] = b"/tmp\0"; +pub const P_tmpdir: &[u8; 5usize] = b"/tmp\0"; pub const _BITS_STDIO_LIM_H: u32 = 1; pub const L_tmpnam: u32 = 20; pub const TMP_MAX: u32 = 238328; @@ -191,7 +194,6 @@ pub const JS_DEF_PROP_DOUBLE: u32 = 6; pub const JS_DEF_PROP_UNDEFINED: u32 = 7; pub const JS_DEF_OBJECT: u32 = 8; pub const JS_DEF_ALIAS: u32 = 9; -pub type size_t = ::std::os::raw::c_ulong; pub type va_list = __builtin_va_list; pub type __gnuc_va_list = __builtin_va_list; pub type __u_char = ::std::os::raw::c_uchar; @@ -235,6 +237,8 @@ pub struct __fsid_t { } #[test] fn bindgen_test_layout___fsid_t() { + const UNINIT: ::std::mem::MaybeUninit<__fsid_t> = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); assert_eq!( ::std::mem::size_of::<__fsid_t>(), 8usize, @@ -246,7 +250,7 @@ fn bindgen_test_layout___fsid_t() { concat!("Alignment of ", stringify!(__fsid_t)) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<__fsid_t>())).__val as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).__val) as usize - ptr as usize }, 0usize, concat!( "Offset of field: ", @@ -295,10 +299,12 @@ pub struct __mbstate_t { pub union __mbstate_t__bindgen_ty_1 { pub __wch: ::std::os::raw::c_uint, pub __wchb: [::std::os::raw::c_char; 4usize], - _bindgen_union_align: u32, } #[test] fn bindgen_test_layout___mbstate_t__bindgen_ty_1() { + const UNINIT: ::std::mem::MaybeUninit<__mbstate_t__bindgen_ty_1> = + ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); assert_eq!( ::std::mem::size_of::<__mbstate_t__bindgen_ty_1>(), 4usize, @@ -310,7 +316,7 @@ fn bindgen_test_layout___mbstate_t__bindgen_ty_1() { concat!("Alignment of ", stringify!(__mbstate_t__bindgen_ty_1)) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<__mbstate_t__bindgen_ty_1>())).__wch as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).__wch) as usize - ptr as usize }, 0usize, concat!( "Offset of field: ", @@ -320,9 +326,7 @@ fn bindgen_test_layout___mbstate_t__bindgen_ty_1() { ) ); assert_eq!( - unsafe { - &(*(::std::ptr::null::<__mbstate_t__bindgen_ty_1>())).__wchb as *const _ as usize - }, + unsafe { ::std::ptr::addr_of!((*ptr).__wchb) as usize - ptr as usize }, 0usize, concat!( "Offset of field: ", @@ -334,6 +338,8 @@ fn bindgen_test_layout___mbstate_t__bindgen_ty_1() { } #[test] fn bindgen_test_layout___mbstate_t() { + const UNINIT: ::std::mem::MaybeUninit<__mbstate_t> = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); assert_eq!( ::std::mem::size_of::<__mbstate_t>(), 8usize, @@ -345,7 +351,7 @@ fn bindgen_test_layout___mbstate_t() { concat!("Alignment of ", stringify!(__mbstate_t)) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<__mbstate_t>())).__count as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).__count) as usize - ptr as usize }, 0usize, concat!( "Offset of field: ", @@ -355,7 +361,7 @@ fn bindgen_test_layout___mbstate_t() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<__mbstate_t>())).__value as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).__value) as usize - ptr as usize }, 4usize, concat!( "Offset of field: ", @@ -373,6 +379,8 @@ pub struct _G_fpos_t { } #[test] fn bindgen_test_layout__G_fpos_t() { + const UNINIT: ::std::mem::MaybeUninit<_G_fpos_t> = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); assert_eq!( ::std::mem::size_of::<_G_fpos_t>(), 16usize, @@ -384,7 +392,7 @@ fn bindgen_test_layout__G_fpos_t() { concat!("Alignment of ", stringify!(_G_fpos_t)) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<_G_fpos_t>())).__pos as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).__pos) as usize - ptr as usize }, 0usize, concat!( "Offset of field: ", @@ -394,7 +402,7 @@ fn bindgen_test_layout__G_fpos_t() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<_G_fpos_t>())).__state as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).__state) as usize - ptr as usize }, 8usize, concat!( "Offset of field: ", @@ -413,6 +421,8 @@ pub struct _G_fpos64_t { } #[test] fn bindgen_test_layout__G_fpos64_t() { + const UNINIT: ::std::mem::MaybeUninit<_G_fpos64_t> = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); assert_eq!( ::std::mem::size_of::<_G_fpos64_t>(), 16usize, @@ -424,7 +434,7 @@ fn bindgen_test_layout__G_fpos64_t() { concat!("Alignment of ", stringify!(_G_fpos64_t)) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<_G_fpos64_t>())).__pos as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).__pos) as usize - ptr as usize }, 0usize, concat!( "Offset of field: ", @@ -434,7 +444,7 @@ fn bindgen_test_layout__G_fpos64_t() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<_G_fpos64_t>())).__state as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).__state) as usize - ptr as usize }, 8usize, concat!( "Offset of field: ", @@ -492,12 +502,14 @@ pub struct _IO_FILE { pub _wide_data: *mut _IO_wide_data, pub _freeres_list: *mut _IO_FILE, pub _freeres_buf: *mut ::std::os::raw::c_void, - pub __pad5: size_t, + pub __pad5: usize, pub _mode: ::std::os::raw::c_int, pub _unused2: [::std::os::raw::c_char; 20usize], } #[test] fn bindgen_test_layout__IO_FILE() { + const UNINIT: ::std::mem::MaybeUninit<_IO_FILE> = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); assert_eq!( ::std::mem::size_of::<_IO_FILE>(), 216usize, @@ -509,7 +521,7 @@ fn bindgen_test_layout__IO_FILE() { concat!("Alignment of ", stringify!(_IO_FILE)) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<_IO_FILE>()))._flags as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr)._flags) as usize - ptr as usize }, 0usize, concat!( "Offset of field: ", @@ -519,7 +531,7 @@ fn bindgen_test_layout__IO_FILE() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<_IO_FILE>()))._IO_read_ptr as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr)._IO_read_ptr) as usize - ptr as usize }, 8usize, concat!( "Offset of field: ", @@ -529,7 +541,7 @@ fn bindgen_test_layout__IO_FILE() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<_IO_FILE>()))._IO_read_end as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr)._IO_read_end) as usize - ptr as usize }, 16usize, concat!( "Offset of field: ", @@ -539,7 +551,7 @@ fn bindgen_test_layout__IO_FILE() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<_IO_FILE>()))._IO_read_base as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr)._IO_read_base) as usize - ptr as usize }, 24usize, concat!( "Offset of field: ", @@ -549,7 +561,7 @@ fn bindgen_test_layout__IO_FILE() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<_IO_FILE>()))._IO_write_base as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr)._IO_write_base) as usize - ptr as usize }, 32usize, concat!( "Offset of field: ", @@ -559,7 +571,7 @@ fn bindgen_test_layout__IO_FILE() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<_IO_FILE>()))._IO_write_ptr as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr)._IO_write_ptr) as usize - ptr as usize }, 40usize, concat!( "Offset of field: ", @@ -569,7 +581,7 @@ fn bindgen_test_layout__IO_FILE() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<_IO_FILE>()))._IO_write_end as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr)._IO_write_end) as usize - ptr as usize }, 48usize, concat!( "Offset of field: ", @@ -579,7 +591,7 @@ fn bindgen_test_layout__IO_FILE() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<_IO_FILE>()))._IO_buf_base as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr)._IO_buf_base) as usize - ptr as usize }, 56usize, concat!( "Offset of field: ", @@ -589,7 +601,7 @@ fn bindgen_test_layout__IO_FILE() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<_IO_FILE>()))._IO_buf_end as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr)._IO_buf_end) as usize - ptr as usize }, 64usize, concat!( "Offset of field: ", @@ -599,7 +611,7 @@ fn bindgen_test_layout__IO_FILE() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<_IO_FILE>()))._IO_save_base as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr)._IO_save_base) as usize - ptr as usize }, 72usize, concat!( "Offset of field: ", @@ -609,7 +621,7 @@ fn bindgen_test_layout__IO_FILE() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<_IO_FILE>()))._IO_backup_base as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr)._IO_backup_base) as usize - ptr as usize }, 80usize, concat!( "Offset of field: ", @@ -619,7 +631,7 @@ fn bindgen_test_layout__IO_FILE() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<_IO_FILE>()))._IO_save_end as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr)._IO_save_end) as usize - ptr as usize }, 88usize, concat!( "Offset of field: ", @@ -629,7 +641,7 @@ fn bindgen_test_layout__IO_FILE() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<_IO_FILE>()))._markers as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr)._markers) as usize - ptr as usize }, 96usize, concat!( "Offset of field: ", @@ -639,7 +651,7 @@ fn bindgen_test_layout__IO_FILE() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<_IO_FILE>()))._chain as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr)._chain) as usize - ptr as usize }, 104usize, concat!( "Offset of field: ", @@ -649,7 +661,7 @@ fn bindgen_test_layout__IO_FILE() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<_IO_FILE>()))._fileno as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr)._fileno) as usize - ptr as usize }, 112usize, concat!( "Offset of field: ", @@ -659,7 +671,7 @@ fn bindgen_test_layout__IO_FILE() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<_IO_FILE>()))._flags2 as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr)._flags2) as usize - ptr as usize }, 116usize, concat!( "Offset of field: ", @@ -669,7 +681,7 @@ fn bindgen_test_layout__IO_FILE() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<_IO_FILE>()))._old_offset as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr)._old_offset) as usize - ptr as usize }, 120usize, concat!( "Offset of field: ", @@ -679,7 +691,7 @@ fn bindgen_test_layout__IO_FILE() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<_IO_FILE>()))._cur_column as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr)._cur_column) as usize - ptr as usize }, 128usize, concat!( "Offset of field: ", @@ -689,7 +701,7 @@ fn bindgen_test_layout__IO_FILE() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<_IO_FILE>()))._vtable_offset as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr)._vtable_offset) as usize - ptr as usize }, 130usize, concat!( "Offset of field: ", @@ -699,7 +711,7 @@ fn bindgen_test_layout__IO_FILE() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<_IO_FILE>()))._shortbuf as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr)._shortbuf) as usize - ptr as usize }, 131usize, concat!( "Offset of field: ", @@ -709,7 +721,7 @@ fn bindgen_test_layout__IO_FILE() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<_IO_FILE>()))._lock as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr)._lock) as usize - ptr as usize }, 136usize, concat!( "Offset of field: ", @@ -719,7 +731,7 @@ fn bindgen_test_layout__IO_FILE() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<_IO_FILE>()))._offset as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr)._offset) as usize - ptr as usize }, 144usize, concat!( "Offset of field: ", @@ -729,7 +741,7 @@ fn bindgen_test_layout__IO_FILE() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<_IO_FILE>()))._codecvt as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr)._codecvt) as usize - ptr as usize }, 152usize, concat!( "Offset of field: ", @@ -739,7 +751,7 @@ fn bindgen_test_layout__IO_FILE() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<_IO_FILE>()))._wide_data as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr)._wide_data) as usize - ptr as usize }, 160usize, concat!( "Offset of field: ", @@ -749,7 +761,7 @@ fn bindgen_test_layout__IO_FILE() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<_IO_FILE>()))._freeres_list as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr)._freeres_list) as usize - ptr as usize }, 168usize, concat!( "Offset of field: ", @@ -759,7 +771,7 @@ fn bindgen_test_layout__IO_FILE() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<_IO_FILE>()))._freeres_buf as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr)._freeres_buf) as usize - ptr as usize }, 176usize, concat!( "Offset of field: ", @@ -769,7 +781,7 @@ fn bindgen_test_layout__IO_FILE() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<_IO_FILE>())).__pad5 as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).__pad5) as usize - ptr as usize }, 184usize, concat!( "Offset of field: ", @@ -779,7 +791,7 @@ fn bindgen_test_layout__IO_FILE() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<_IO_FILE>()))._mode as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr)._mode) as usize - ptr as usize }, 192usize, concat!( "Offset of field: ", @@ -789,7 +801,7 @@ fn bindgen_test_layout__IO_FILE() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<_IO_FILE>()))._unused2 as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr)._unused2) as usize - ptr as usize }, 196usize, concat!( "Offset of field: ", @@ -800,7 +812,6 @@ fn bindgen_test_layout__IO_FILE() { ); } pub type off_t = __off_t; -pub type ssize_t = __ssize_t; pub type fpos_t = __fpos_t; extern "C" { pub static mut stdin: *mut FILE; @@ -828,11 +839,14 @@ extern "C" { __new: *const ::std::os::raw::c_char, ) -> ::std::os::raw::c_int; } +extern "C" { + pub fn fclose(__stream: *mut FILE) -> ::std::os::raw::c_int; +} extern "C" { pub fn tmpfile() -> *mut FILE; } extern "C" { - pub fn tmpnam(__s: *mut ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; + pub fn tmpnam(arg1: *mut ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; } extern "C" { pub fn tmpnam_r(__s: *mut ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; @@ -843,9 +857,6 @@ extern "C" { __pfx: *const ::std::os::raw::c_char, ) -> *mut ::std::os::raw::c_char; } -extern "C" { - pub fn fclose(__stream: *mut FILE) -> ::std::os::raw::c_int; -} extern "C" { pub fn fflush(__stream: *mut FILE) -> ::std::os::raw::c_int; } @@ -872,14 +883,14 @@ extern "C" { extern "C" { pub fn fmemopen( __s: *mut ::std::os::raw::c_void, - __len: size_t, + __len: usize, __modes: *const ::std::os::raw::c_char, ) -> *mut FILE; } extern "C" { pub fn open_memstream( __bufloc: *mut *mut ::std::os::raw::c_char, - __sizeloc: *mut size_t, + __sizeloc: *mut usize, ) -> *mut FILE; } extern "C" { @@ -890,11 +901,11 @@ extern "C" { __stream: *mut FILE, __buf: *mut ::std::os::raw::c_char, __modes: ::std::os::raw::c_int, - __n: size_t, + __n: usize, ) -> ::std::os::raw::c_int; } extern "C" { - pub fn setbuffer(__stream: *mut FILE, __buf: *mut ::std::os::raw::c_char, __size: size_t); + pub fn setbuffer(__stream: *mut FILE, __buf: *mut ::std::os::raw::c_char, __size: usize); } extern "C" { pub fn setlinebuf(__stream: *mut FILE); @@ -1103,7 +1114,7 @@ extern "C" { extern "C" { pub fn __getdelim( __lineptr: *mut *mut ::std::os::raw::c_char, - __n: *mut size_t, + __n: *mut usize, __delimiter: ::std::os::raw::c_int, __stream: *mut FILE, ) -> __ssize_t; @@ -1111,7 +1122,7 @@ extern "C" { extern "C" { pub fn getdelim( __lineptr: *mut *mut ::std::os::raw::c_char, - __n: *mut size_t, + __n: *mut usize, __delimiter: ::std::os::raw::c_int, __stream: *mut FILE, ) -> __ssize_t; @@ -1119,7 +1130,7 @@ extern "C" { extern "C" { pub fn getline( __lineptr: *mut *mut ::std::os::raw::c_char, - __n: *mut size_t, + __n: *mut usize, __stream: *mut FILE, ) -> __ssize_t; } @@ -1151,18 +1162,18 @@ extern "C" { extern "C" { pub fn fread_unlocked( __ptr: *mut ::std::os::raw::c_void, - __size: size_t, - __n: size_t, + __size: usize, + __n: usize, __stream: *mut FILE, - ) -> size_t; + ) -> usize; } extern "C" { pub fn fwrite_unlocked( __ptr: *const ::std::os::raw::c_void, - __size: size_t, - __n: size_t, + __size: usize, + __n: usize, __stream: *mut FILE, - ) -> size_t; + ) -> usize; } extern "C" { pub fn fseek( @@ -1220,15 +1231,15 @@ extern "C" { extern "C" { pub fn fileno_unlocked(__stream: *mut FILE) -> ::std::os::raw::c_int; } +extern "C" { + pub fn pclose(__stream: *mut FILE) -> ::std::os::raw::c_int; +} extern "C" { pub fn popen( __command: *const ::std::os::raw::c_char, __modes: *const ::std::os::raw::c_char, ) -> *mut FILE; } -extern "C" { - pub fn pclose(__stream: *mut FILE) -> ::std::os::raw::c_int; -} extern "C" { pub fn ctermid(__s: *mut ::std::os::raw::c_char) -> *mut ::std::os::raw::c_char; } @@ -1287,23 +1298,23 @@ pub struct JSClass { } pub type JSClassID = u32; pub type JSAtom = u32; -pub const JS_TAG_FIRST: ::std::os::raw::c_int = -11; -pub const JS_TAG_BIG_DECIMAL: ::std::os::raw::c_int = -11; -pub const JS_TAG_BIG_INT: ::std::os::raw::c_int = -10; -pub const JS_TAG_BIG_FLOAT: ::std::os::raw::c_int = -9; -pub const JS_TAG_SYMBOL: ::std::os::raw::c_int = -8; -pub const JS_TAG_STRING: ::std::os::raw::c_int = -7; -pub const JS_TAG_MODULE: ::std::os::raw::c_int = -3; -pub const JS_TAG_FUNCTION_BYTECODE: ::std::os::raw::c_int = -2; -pub const JS_TAG_OBJECT: ::std::os::raw::c_int = -1; -pub const JS_TAG_INT: ::std::os::raw::c_int = 0; -pub const JS_TAG_BOOL: ::std::os::raw::c_int = 1; -pub const JS_TAG_NULL: ::std::os::raw::c_int = 2; -pub const JS_TAG_UNDEFINED: ::std::os::raw::c_int = 3; -pub const JS_TAG_UNINITIALIZED: ::std::os::raw::c_int = 4; -pub const JS_TAG_CATCH_OFFSET: ::std::os::raw::c_int = 5; -pub const JS_TAG_EXCEPTION: ::std::os::raw::c_int = 6; -pub const JS_TAG_FLOAT64: ::std::os::raw::c_int = 7; +pub const JS_TAG_FIRST: _bindgen_ty_1 = -11; +pub const JS_TAG_BIG_DECIMAL: _bindgen_ty_1 = -11; +pub const JS_TAG_BIG_INT: _bindgen_ty_1 = -10; +pub const JS_TAG_BIG_FLOAT: _bindgen_ty_1 = -9; +pub const JS_TAG_SYMBOL: _bindgen_ty_1 = -8; +pub const JS_TAG_STRING: _bindgen_ty_1 = -7; +pub const JS_TAG_MODULE: _bindgen_ty_1 = -3; +pub const JS_TAG_FUNCTION_BYTECODE: _bindgen_ty_1 = -2; +pub const JS_TAG_OBJECT: _bindgen_ty_1 = -1; +pub const JS_TAG_INT: _bindgen_ty_1 = 0; +pub const JS_TAG_BOOL: _bindgen_ty_1 = 1; +pub const JS_TAG_NULL: _bindgen_ty_1 = 2; +pub const JS_TAG_UNDEFINED: _bindgen_ty_1 = 3; +pub const JS_TAG_UNINITIALIZED: _bindgen_ty_1 = 4; +pub const JS_TAG_CATCH_OFFSET: _bindgen_ty_1 = 5; +pub const JS_TAG_EXCEPTION: _bindgen_ty_1 = 6; +pub const JS_TAG_FLOAT64: _bindgen_ty_1 = 7; pub type _bindgen_ty_1 = ::std::os::raw::c_int; #[repr(C)] #[derive(Debug, Copy, Clone)] @@ -1312,6 +1323,8 @@ pub struct JSRefCountHeader { } #[test] fn bindgen_test_layout_JSRefCountHeader() { + const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); assert_eq!( ::std::mem::size_of::(), 4usize, @@ -1323,7 +1336,7 @@ fn bindgen_test_layout_JSRefCountHeader() { concat!("Alignment of ", stringify!(JSRefCountHeader)) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).ref_count as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).ref_count) as usize - ptr as usize }, 0usize, concat!( "Offset of field: ", @@ -1339,10 +1352,11 @@ pub union JSValueUnion { pub int32: i32, pub float64: f64, pub ptr: *mut ::std::os::raw::c_void, - _bindgen_union_align: u64, } #[test] fn bindgen_test_layout_JSValueUnion() { + const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); assert_eq!( ::std::mem::size_of::(), 8usize, @@ -1354,7 +1368,7 @@ fn bindgen_test_layout_JSValueUnion() { concat!("Alignment of ", stringify!(JSValueUnion)) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).int32 as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).int32) as usize - ptr as usize }, 0usize, concat!( "Offset of field: ", @@ -1364,7 +1378,7 @@ fn bindgen_test_layout_JSValueUnion() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).float64 as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).float64) as usize - ptr as usize }, 0usize, concat!( "Offset of field: ", @@ -1374,7 +1388,7 @@ fn bindgen_test_layout_JSValueUnion() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).ptr as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).ptr) as usize - ptr as usize }, 0usize, concat!( "Offset of field: ", @@ -1392,6 +1406,8 @@ pub struct JSValue { } #[test] fn bindgen_test_layout_JSValue() { + const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); assert_eq!( ::std::mem::size_of::(), 16usize, @@ -1403,7 +1419,7 @@ fn bindgen_test_layout_JSValue() { concat!("Alignment of ", stringify!(JSValue)) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).u as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).u) as usize - ptr as usize }, 0usize, concat!( "Offset of field: ", @@ -1413,7 +1429,7 @@ fn bindgen_test_layout_JSValue() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).tag as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).tag) as usize - ptr as usize }, 8usize, concat!( "Offset of field: ", @@ -1453,13 +1469,15 @@ pub type JSCFunctionData = ::std::option::Option< #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct JSMallocState { - pub malloc_count: size_t, - pub malloc_size: size_t, - pub malloc_limit: size_t, + pub malloc_count: usize, + pub malloc_size: usize, + pub malloc_limit: usize, pub opaque: *mut ::std::os::raw::c_void, } #[test] fn bindgen_test_layout_JSMallocState() { + const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); assert_eq!( ::std::mem::size_of::(), 32usize, @@ -1471,7 +1489,7 @@ fn bindgen_test_layout_JSMallocState() { concat!("Alignment of ", stringify!(JSMallocState)) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).malloc_count as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).malloc_count) as usize - ptr as usize }, 0usize, concat!( "Offset of field: ", @@ -1481,7 +1499,7 @@ fn bindgen_test_layout_JSMallocState() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).malloc_size as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).malloc_size) as usize - ptr as usize }, 8usize, concat!( "Offset of field: ", @@ -1491,7 +1509,7 @@ fn bindgen_test_layout_JSMallocState() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).malloc_limit as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).malloc_limit) as usize - ptr as usize }, 16usize, concat!( "Offset of field: ", @@ -1501,7 +1519,7 @@ fn bindgen_test_layout_JSMallocState() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).opaque as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).opaque) as usize - ptr as usize }, 24usize, concat!( "Offset of field: ", @@ -1515,7 +1533,7 @@ fn bindgen_test_layout_JSMallocState() { #[derive(Debug, Copy, Clone)] pub struct JSMallocFunctions { pub js_malloc: ::std::option::Option< - unsafe extern "C" fn(s: *mut JSMallocState, size: size_t) -> *mut ::std::os::raw::c_void, + unsafe extern "C" fn(s: *mut JSMallocState, size: usize) -> *mut ::std::os::raw::c_void, >, pub js_free: ::std::option::Option< unsafe extern "C" fn(s: *mut JSMallocState, ptr: *mut ::std::os::raw::c_void), @@ -1524,14 +1542,16 @@ pub struct JSMallocFunctions { unsafe extern "C" fn( s: *mut JSMallocState, ptr: *mut ::std::os::raw::c_void, - size: size_t, + size: usize, ) -> *mut ::std::os::raw::c_void, >, pub js_malloc_usable_size: - ::std::option::Option size_t>, + ::std::option::Option usize>, } #[test] fn bindgen_test_layout_JSMallocFunctions() { + const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); assert_eq!( ::std::mem::size_of::(), 32usize, @@ -1543,7 +1563,7 @@ fn bindgen_test_layout_JSMallocFunctions() { concat!("Alignment of ", stringify!(JSMallocFunctions)) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).js_malloc as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).js_malloc) as usize - ptr as usize }, 0usize, concat!( "Offset of field: ", @@ -1553,7 +1573,7 @@ fn bindgen_test_layout_JSMallocFunctions() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).js_free as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).js_free) as usize - ptr as usize }, 8usize, concat!( "Offset of field: ", @@ -1563,7 +1583,7 @@ fn bindgen_test_layout_JSMallocFunctions() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).js_realloc as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).js_realloc) as usize - ptr as usize }, 16usize, concat!( "Offset of field: ", @@ -1573,9 +1593,7 @@ fn bindgen_test_layout_JSMallocFunctions() { ) ); assert_eq!( - unsafe { - &(*(::std::ptr::null::())).js_malloc_usable_size as *const _ as usize - }, + unsafe { ::std::ptr::addr_of!((*ptr).js_malloc_usable_size) as usize - ptr as usize }, 24usize, concat!( "Offset of field: ", @@ -1597,13 +1615,13 @@ extern "C" { pub fn JS_SetRuntimeInfo(rt: *mut JSRuntime, info: *const ::std::os::raw::c_char); } extern "C" { - pub fn JS_SetMemoryLimit(rt: *mut JSRuntime, limit: size_t); + pub fn JS_SetMemoryLimit(rt: *mut JSRuntime, limit: usize); } extern "C" { - pub fn JS_SetGCThreshold(rt: *mut JSRuntime, gc_threshold: size_t); + pub fn JS_SetGCThreshold(rt: *mut JSRuntime, gc_threshold: usize); } extern "C" { - pub fn JS_SetMaxStackSize(rt: *mut JSRuntime, stack_size: size_t); + pub fn JS_SetMaxStackSize(rt: *mut JSRuntime, stack_size: usize); } extern "C" { pub fn JS_UpdateStackTop(rt: *mut JSRuntime); @@ -1718,7 +1736,7 @@ extern "C" { ) -> JSValue; } extern "C" { - pub fn js_malloc_rt(rt: *mut JSRuntime, size: size_t) -> *mut ::std::os::raw::c_void; + pub fn js_malloc_rt(rt: *mut JSRuntime, size: usize) -> *mut ::std::os::raw::c_void; } extern "C" { pub fn js_free_rt(rt: *mut JSRuntime, ptr: *mut ::std::os::raw::c_void); @@ -1727,20 +1745,20 @@ extern "C" { pub fn js_realloc_rt( rt: *mut JSRuntime, ptr: *mut ::std::os::raw::c_void, - size: size_t, + size: usize, ) -> *mut ::std::os::raw::c_void; } extern "C" { pub fn js_malloc_usable_size_rt( rt: *mut JSRuntime, ptr: *const ::std::os::raw::c_void, - ) -> size_t; + ) -> usize; } extern "C" { - pub fn js_mallocz_rt(rt: *mut JSRuntime, size: size_t) -> *mut ::std::os::raw::c_void; + pub fn js_mallocz_rt(rt: *mut JSRuntime, size: usize) -> *mut ::std::os::raw::c_void; } extern "C" { - pub fn js_malloc(ctx: *mut JSContext, size: size_t) -> *mut ::std::os::raw::c_void; + pub fn js_malloc(ctx: *mut JSContext, size: usize) -> *mut ::std::os::raw::c_void; } extern "C" { pub fn js_free(ctx: *mut JSContext, ptr: *mut ::std::os::raw::c_void); @@ -1749,23 +1767,22 @@ extern "C" { pub fn js_realloc( ctx: *mut JSContext, ptr: *mut ::std::os::raw::c_void, - size: size_t, + size: usize, ) -> *mut ::std::os::raw::c_void; } extern "C" { - pub fn js_malloc_usable_size(ctx: *mut JSContext, ptr: *const ::std::os::raw::c_void) - -> size_t; + pub fn js_malloc_usable_size(ctx: *mut JSContext, ptr: *const ::std::os::raw::c_void) -> usize; } extern "C" { pub fn js_realloc2( ctx: *mut JSContext, ptr: *mut ::std::os::raw::c_void, - size: size_t, - pslack: *mut size_t, + size: usize, + pslack: *mut usize, ) -> *mut ::std::os::raw::c_void; } extern "C" { - pub fn js_mallocz(ctx: *mut JSContext, size: size_t) -> *mut ::std::os::raw::c_void; + pub fn js_mallocz(ctx: *mut JSContext, size: usize) -> *mut ::std::os::raw::c_void; } extern "C" { pub fn js_strdup( @@ -1777,7 +1794,7 @@ extern "C" { pub fn js_strndup( ctx: *mut JSContext, s: *const ::std::os::raw::c_char, - n: size_t, + n: usize, ) -> *mut ::std::os::raw::c_char; } #[repr(C)] @@ -1812,6 +1829,8 @@ pub struct JSMemoryUsage { } #[test] fn bindgen_test_layout_JSMemoryUsage() { + const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); assert_eq!( ::std::mem::size_of::(), 208usize, @@ -1823,7 +1842,7 @@ fn bindgen_test_layout_JSMemoryUsage() { concat!("Alignment of ", stringify!(JSMemoryUsage)) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).malloc_size as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).malloc_size) as usize - ptr as usize }, 0usize, concat!( "Offset of field: ", @@ -1833,7 +1852,7 @@ fn bindgen_test_layout_JSMemoryUsage() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).malloc_limit as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).malloc_limit) as usize - ptr as usize }, 8usize, concat!( "Offset of field: ", @@ -1843,7 +1862,7 @@ fn bindgen_test_layout_JSMemoryUsage() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).memory_used_size as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).memory_used_size) as usize - ptr as usize }, 16usize, concat!( "Offset of field: ", @@ -1853,7 +1872,7 @@ fn bindgen_test_layout_JSMemoryUsage() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).malloc_count as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).malloc_count) as usize - ptr as usize }, 24usize, concat!( "Offset of field: ", @@ -1863,7 +1882,7 @@ fn bindgen_test_layout_JSMemoryUsage() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).memory_used_count as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).memory_used_count) as usize - ptr as usize }, 32usize, concat!( "Offset of field: ", @@ -1873,7 +1892,7 @@ fn bindgen_test_layout_JSMemoryUsage() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).atom_count as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).atom_count) as usize - ptr as usize }, 40usize, concat!( "Offset of field: ", @@ -1883,7 +1902,7 @@ fn bindgen_test_layout_JSMemoryUsage() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).atom_size as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).atom_size) as usize - ptr as usize }, 48usize, concat!( "Offset of field: ", @@ -1893,7 +1912,7 @@ fn bindgen_test_layout_JSMemoryUsage() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).str_count as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).str_count) as usize - ptr as usize }, 56usize, concat!( "Offset of field: ", @@ -1903,7 +1922,7 @@ fn bindgen_test_layout_JSMemoryUsage() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).str_size as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).str_size) as usize - ptr as usize }, 64usize, concat!( "Offset of field: ", @@ -1913,7 +1932,7 @@ fn bindgen_test_layout_JSMemoryUsage() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).obj_count as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).obj_count) as usize - ptr as usize }, 72usize, concat!( "Offset of field: ", @@ -1923,7 +1942,7 @@ fn bindgen_test_layout_JSMemoryUsage() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).obj_size as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).obj_size) as usize - ptr as usize }, 80usize, concat!( "Offset of field: ", @@ -1933,7 +1952,7 @@ fn bindgen_test_layout_JSMemoryUsage() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).prop_count as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).prop_count) as usize - ptr as usize }, 88usize, concat!( "Offset of field: ", @@ -1943,7 +1962,7 @@ fn bindgen_test_layout_JSMemoryUsage() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).prop_size as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).prop_size) as usize - ptr as usize }, 96usize, concat!( "Offset of field: ", @@ -1953,7 +1972,7 @@ fn bindgen_test_layout_JSMemoryUsage() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).shape_count as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).shape_count) as usize - ptr as usize }, 104usize, concat!( "Offset of field: ", @@ -1963,7 +1982,7 @@ fn bindgen_test_layout_JSMemoryUsage() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).shape_size as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).shape_size) as usize - ptr as usize }, 112usize, concat!( "Offset of field: ", @@ -1973,7 +1992,7 @@ fn bindgen_test_layout_JSMemoryUsage() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).js_func_count as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).js_func_count) as usize - ptr as usize }, 120usize, concat!( "Offset of field: ", @@ -1983,7 +2002,7 @@ fn bindgen_test_layout_JSMemoryUsage() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).js_func_size as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).js_func_size) as usize - ptr as usize }, 128usize, concat!( "Offset of field: ", @@ -1993,7 +2012,7 @@ fn bindgen_test_layout_JSMemoryUsage() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).js_func_code_size as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).js_func_code_size) as usize - ptr as usize }, 136usize, concat!( "Offset of field: ", @@ -2003,9 +2022,7 @@ fn bindgen_test_layout_JSMemoryUsage() { ) ); assert_eq!( - unsafe { - &(*(::std::ptr::null::())).js_func_pc2line_count as *const _ as usize - }, + unsafe { ::std::ptr::addr_of!((*ptr).js_func_pc2line_count) as usize - ptr as usize }, 144usize, concat!( "Offset of field: ", @@ -2015,9 +2032,7 @@ fn bindgen_test_layout_JSMemoryUsage() { ) ); assert_eq!( - unsafe { - &(*(::std::ptr::null::())).js_func_pc2line_size as *const _ as usize - }, + unsafe { ::std::ptr::addr_of!((*ptr).js_func_pc2line_size) as usize - ptr as usize }, 152usize, concat!( "Offset of field: ", @@ -2027,7 +2042,7 @@ fn bindgen_test_layout_JSMemoryUsage() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).c_func_count as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).c_func_count) as usize - ptr as usize }, 160usize, concat!( "Offset of field: ", @@ -2037,7 +2052,7 @@ fn bindgen_test_layout_JSMemoryUsage() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).array_count as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).array_count) as usize - ptr as usize }, 168usize, concat!( "Offset of field: ", @@ -2047,7 +2062,7 @@ fn bindgen_test_layout_JSMemoryUsage() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).fast_array_count as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).fast_array_count) as usize - ptr as usize }, 176usize, concat!( "Offset of field: ", @@ -2057,9 +2072,7 @@ fn bindgen_test_layout_JSMemoryUsage() { ) ); assert_eq!( - unsafe { - &(*(::std::ptr::null::())).fast_array_elements as *const _ as usize - }, + unsafe { ::std::ptr::addr_of!((*ptr).fast_array_elements) as usize - ptr as usize }, 184usize, concat!( "Offset of field: ", @@ -2069,9 +2082,7 @@ fn bindgen_test_layout_JSMemoryUsage() { ) ); assert_eq!( - unsafe { - &(*(::std::ptr::null::())).binary_object_count as *const _ as usize - }, + unsafe { ::std::ptr::addr_of!((*ptr).binary_object_count) as usize - ptr as usize }, 192usize, concat!( "Offset of field: ", @@ -2081,9 +2092,7 @@ fn bindgen_test_layout_JSMemoryUsage() { ) ); assert_eq!( - unsafe { - &(*(::std::ptr::null::())).binary_object_size as *const _ as usize - }, + unsafe { ::std::ptr::addr_of!((*ptr).binary_object_size) as usize - ptr as usize }, 200usize, concat!( "Offset of field: ", @@ -2103,7 +2112,7 @@ extern "C" { pub fn JS_NewAtomLen( ctx: *mut JSContext, str_: *const ::std::os::raw::c_char, - len: size_t, + len: usize, ) -> JSAtom; } extern "C" { @@ -2141,6 +2150,8 @@ pub struct JSPropertyEnum { } #[test] fn bindgen_test_layout_JSPropertyEnum() { + const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); assert_eq!( ::std::mem::size_of::(), 8usize, @@ -2152,7 +2163,7 @@ fn bindgen_test_layout_JSPropertyEnum() { concat!("Alignment of ", stringify!(JSPropertyEnum)) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).is_enumerable as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).is_enumerable) as usize - ptr as usize }, 0usize, concat!( "Offset of field: ", @@ -2162,7 +2173,7 @@ fn bindgen_test_layout_JSPropertyEnum() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).atom as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).atom) as usize - ptr as usize }, 4usize, concat!( "Offset of field: ", @@ -2182,6 +2193,8 @@ pub struct JSPropertyDescriptor { } #[test] fn bindgen_test_layout_JSPropertyDescriptor() { + const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); assert_eq!( ::std::mem::size_of::(), 56usize, @@ -2193,7 +2206,7 @@ fn bindgen_test_layout_JSPropertyDescriptor() { concat!("Alignment of ", stringify!(JSPropertyDescriptor)) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).flags as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).flags) as usize - ptr as usize }, 0usize, concat!( "Offset of field: ", @@ -2203,7 +2216,7 @@ fn bindgen_test_layout_JSPropertyDescriptor() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).value as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).value) as usize - ptr as usize }, 8usize, concat!( "Offset of field: ", @@ -2213,7 +2226,7 @@ fn bindgen_test_layout_JSPropertyDescriptor() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).getter as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).getter) as usize - ptr as usize }, 24usize, concat!( "Offset of field: ", @@ -2223,7 +2236,7 @@ fn bindgen_test_layout_JSPropertyDescriptor() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).setter as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).setter) as usize - ptr as usize }, 40usize, concat!( "Offset of field: ", @@ -2298,6 +2311,8 @@ pub struct JSClassExoticMethods { } #[test] fn bindgen_test_layout_JSClassExoticMethods() { + const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); assert_eq!( ::std::mem::size_of::(), 56usize, @@ -2309,9 +2324,7 @@ fn bindgen_test_layout_JSClassExoticMethods() { concat!("Alignment of ", stringify!(JSClassExoticMethods)) ); assert_eq!( - unsafe { - &(*(::std::ptr::null::())).get_own_property as *const _ as usize - }, + unsafe { ::std::ptr::addr_of!((*ptr).get_own_property) as usize - ptr as usize }, 0usize, concat!( "Offset of field: ", @@ -2321,10 +2334,7 @@ fn bindgen_test_layout_JSClassExoticMethods() { ) ); assert_eq!( - unsafe { - &(*(::std::ptr::null::())).get_own_property_names as *const _ - as usize - }, + unsafe { ::std::ptr::addr_of!((*ptr).get_own_property_names) as usize - ptr as usize }, 8usize, concat!( "Offset of field: ", @@ -2334,9 +2344,7 @@ fn bindgen_test_layout_JSClassExoticMethods() { ) ); assert_eq!( - unsafe { - &(*(::std::ptr::null::())).delete_property as *const _ as usize - }, + unsafe { ::std::ptr::addr_of!((*ptr).delete_property) as usize - ptr as usize }, 16usize, concat!( "Offset of field: ", @@ -2346,10 +2354,7 @@ fn bindgen_test_layout_JSClassExoticMethods() { ) ); assert_eq!( - unsafe { - &(*(::std::ptr::null::())).define_own_property as *const _ - as usize - }, + unsafe { ::std::ptr::addr_of!((*ptr).define_own_property) as usize - ptr as usize }, 24usize, concat!( "Offset of field: ", @@ -2359,9 +2364,7 @@ fn bindgen_test_layout_JSClassExoticMethods() { ) ); assert_eq!( - unsafe { - &(*(::std::ptr::null::())).has_property as *const _ as usize - }, + unsafe { ::std::ptr::addr_of!((*ptr).has_property) as usize - ptr as usize }, 32usize, concat!( "Offset of field: ", @@ -2371,9 +2374,7 @@ fn bindgen_test_layout_JSClassExoticMethods() { ) ); assert_eq!( - unsafe { - &(*(::std::ptr::null::())).get_property as *const _ as usize - }, + unsafe { ::std::ptr::addr_of!((*ptr).get_property) as usize - ptr as usize }, 40usize, concat!( "Offset of field: ", @@ -2383,9 +2384,7 @@ fn bindgen_test_layout_JSClassExoticMethods() { ) ); assert_eq!( - unsafe { - &(*(::std::ptr::null::())).set_property as *const _ as usize - }, + unsafe { ::std::ptr::addr_of!((*ptr).set_property) as usize - ptr as usize }, 48usize, concat!( "Offset of field: ", @@ -2421,6 +2420,8 @@ pub struct JSClassDef { } #[test] fn bindgen_test_layout_JSClassDef() { + const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); assert_eq!( ::std::mem::size_of::(), 40usize, @@ -2432,7 +2433,7 @@ fn bindgen_test_layout_JSClassDef() { concat!("Alignment of ", stringify!(JSClassDef)) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).class_name as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).class_name) as usize - ptr as usize }, 0usize, concat!( "Offset of field: ", @@ -2442,7 +2443,7 @@ fn bindgen_test_layout_JSClassDef() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).finalizer as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).finalizer) as usize - ptr as usize }, 8usize, concat!( "Offset of field: ", @@ -2452,7 +2453,7 @@ fn bindgen_test_layout_JSClassDef() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).gc_mark as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).gc_mark) as usize - ptr as usize }, 16usize, concat!( "Offset of field: ", @@ -2462,7 +2463,7 @@ fn bindgen_test_layout_JSClassDef() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).call as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).call) as usize - ptr as usize }, 24usize, concat!( "Offset of field: ", @@ -2472,7 +2473,7 @@ fn bindgen_test_layout_JSClassDef() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).exotic as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).exotic) as usize - ptr as usize }, 32usize, concat!( "Offset of field: ", @@ -2594,7 +2595,7 @@ extern "C" { pub fn JS_NewStringLen( ctx: *mut JSContext, str1: *const ::std::os::raw::c_char, - len1: size_t, + len1: usize, ) -> JSValue; } extern "C" { @@ -2612,7 +2613,7 @@ extern "C" { extern "C" { pub fn JS_ToCStringLen2( ctx: *mut JSContext, - plen: *mut size_t, + plen: *mut usize, val1: JSValue, cesu8: ::std::os::raw::c_int, ) -> *const ::std::os::raw::c_char; @@ -2793,14 +2794,14 @@ extern "C" { extern "C" { pub fn JS_DetectModule( input: *const ::std::os::raw::c_char, - input_len: size_t, + input_len: usize, ) -> ::std::os::raw::c_int; } extern "C" { pub fn JS_Eval( ctx: *mut JSContext, input: *const ::std::os::raw::c_char, - input_len: size_t, + input_len: usize, filename: *const ::std::os::raw::c_char, eval_flags: ::std::os::raw::c_int, ) -> JSValue; @@ -2810,7 +2811,7 @@ extern "C" { ctx: *mut JSContext, this_obj: JSValue, input: *const ::std::os::raw::c_char, - input_len: size_t, + input_len: usize, filename: *const ::std::os::raw::c_char, eval_flags: ::std::os::raw::c_int, ) -> JSValue; @@ -2890,7 +2891,7 @@ extern "C" { pub fn JS_ParseJSON( ctx: *mut JSContext, buf: *const ::std::os::raw::c_char, - buf_len: size_t, + buf_len: usize, filename: *const ::std::os::raw::c_char, ) -> JSValue; } @@ -2898,7 +2899,7 @@ extern "C" { pub fn JS_ParseJSON2( ctx: *mut JSContext, buf: *const ::std::os::raw::c_char, - buf_len: size_t, + buf_len: usize, filename: *const ::std::os::raw::c_char, flags: ::std::os::raw::c_int, ) -> JSValue; @@ -2922,28 +2923,28 @@ extern "C" { pub fn JS_NewArrayBuffer( ctx: *mut JSContext, buf: *mut u8, - len: size_t, + len: usize, free_func: JSFreeArrayBufferDataFunc, opaque: *mut ::std::os::raw::c_void, is_shared: ::std::os::raw::c_int, ) -> JSValue; } extern "C" { - pub fn JS_NewArrayBufferCopy(ctx: *mut JSContext, buf: *const u8, len: size_t) -> JSValue; + pub fn JS_NewArrayBufferCopy(ctx: *mut JSContext, buf: *const u8, len: usize) -> JSValue; } extern "C" { pub fn JS_DetachArrayBuffer(ctx: *mut JSContext, obj: JSValue); } extern "C" { - pub fn JS_GetArrayBuffer(ctx: *mut JSContext, psize: *mut size_t, obj: JSValue) -> *mut u8; + pub fn JS_GetArrayBuffer(ctx: *mut JSContext, psize: *mut usize, obj: JSValue) -> *mut u8; } extern "C" { pub fn JS_GetTypedArrayBuffer( ctx: *mut JSContext, obj: JSValue, - pbyte_offset: *mut size_t, - pbyte_length: *mut size_t, - pbytes_per_element: *mut size_t, + pbyte_offset: *mut usize, + pbyte_length: *mut usize, + pbytes_per_element: *mut usize, ) -> JSValue; } #[repr(C)] @@ -2952,7 +2953,7 @@ pub struct JSSharedArrayBufferFunctions { pub sab_alloc: ::std::option::Option< unsafe extern "C" fn( opaque: *mut ::std::os::raw::c_void, - size: size_t, + size: usize, ) -> *mut ::std::os::raw::c_void, >, pub sab_free: ::std::option::Option< @@ -2965,6 +2966,9 @@ pub struct JSSharedArrayBufferFunctions { } #[test] fn bindgen_test_layout_JSSharedArrayBufferFunctions() { + const UNINIT: ::std::mem::MaybeUninit = + ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); assert_eq!( ::std::mem::size_of::(), 32usize, @@ -2976,9 +2980,7 @@ fn bindgen_test_layout_JSSharedArrayBufferFunctions() { concat!("Alignment of ", stringify!(JSSharedArrayBufferFunctions)) ); assert_eq!( - unsafe { - &(*(::std::ptr::null::())).sab_alloc as *const _ as usize - }, + unsafe { ::std::ptr::addr_of!((*ptr).sab_alloc) as usize - ptr as usize }, 0usize, concat!( "Offset of field: ", @@ -2988,9 +2990,7 @@ fn bindgen_test_layout_JSSharedArrayBufferFunctions() { ) ); assert_eq!( - unsafe { - &(*(::std::ptr::null::())).sab_free as *const _ as usize - }, + unsafe { ::std::ptr::addr_of!((*ptr).sab_free) as usize - ptr as usize }, 8usize, concat!( "Offset of field: ", @@ -3000,9 +3000,7 @@ fn bindgen_test_layout_JSSharedArrayBufferFunctions() { ) ); assert_eq!( - unsafe { - &(*(::std::ptr::null::())).sab_dup as *const _ as usize - }, + unsafe { ::std::ptr::addr_of!((*ptr).sab_dup) as usize - ptr as usize }, 16usize, concat!( "Offset of field: ", @@ -3012,9 +3010,7 @@ fn bindgen_test_layout_JSSharedArrayBufferFunctions() { ) ); assert_eq!( - unsafe { - &(*(::std::ptr::null::())).sab_opaque as *const _ as usize - }, + unsafe { ::std::ptr::addr_of!((*ptr).sab_opaque) as usize - ptr as usize }, 24usize, concat!( "Offset of field: ", @@ -3129,7 +3125,7 @@ extern "C" { extern "C" { pub fn JS_WriteObject( ctx: *mut JSContext, - psize: *mut size_t, + psize: *mut usize, obj: JSValue, flags: ::std::os::raw::c_int, ) -> *mut u8; @@ -3137,18 +3133,18 @@ extern "C" { extern "C" { pub fn JS_WriteObject2( ctx: *mut JSContext, - psize: *mut size_t, + psize: *mut usize, obj: JSValue, flags: ::std::os::raw::c_int, psab_tab: *mut *mut *mut u8, - psab_tab_len: *mut size_t, + psab_tab_len: *mut usize, ) -> *mut u8; } extern "C" { pub fn JS_ReadObject( ctx: *mut JSContext, buf: *const u8, - buf_len: size_t, + buf_len: usize, flags: ::std::os::raw::c_int, ) -> JSValue; } @@ -3242,10 +3238,11 @@ pub union JSCFunctionType { magic: ::std::os::raw::c_int, ) -> JSValue, >, - _bindgen_union_align: u64, } #[test] fn bindgen_test_layout_JSCFunctionType() { + const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); assert_eq!( ::std::mem::size_of::(), 8usize, @@ -3257,7 +3254,7 @@ fn bindgen_test_layout_JSCFunctionType() { concat!("Alignment of ", stringify!(JSCFunctionType)) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).generic as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).generic) as usize - ptr as usize }, 0usize, concat!( "Offset of field: ", @@ -3267,7 +3264,7 @@ fn bindgen_test_layout_JSCFunctionType() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).generic_magic as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).generic_magic) as usize - ptr as usize }, 0usize, concat!( "Offset of field: ", @@ -3277,7 +3274,7 @@ fn bindgen_test_layout_JSCFunctionType() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).constructor as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).constructor) as usize - ptr as usize }, 0usize, concat!( "Offset of field: ", @@ -3287,9 +3284,7 @@ fn bindgen_test_layout_JSCFunctionType() { ) ); assert_eq!( - unsafe { - &(*(::std::ptr::null::())).constructor_magic as *const _ as usize - }, + unsafe { ::std::ptr::addr_of!((*ptr).constructor_magic) as usize - ptr as usize }, 0usize, concat!( "Offset of field: ", @@ -3299,9 +3294,7 @@ fn bindgen_test_layout_JSCFunctionType() { ) ); assert_eq!( - unsafe { - &(*(::std::ptr::null::())).constructor_or_func as *const _ as usize - }, + unsafe { ::std::ptr::addr_of!((*ptr).constructor_or_func) as usize - ptr as usize }, 0usize, concat!( "Offset of field: ", @@ -3311,7 +3304,7 @@ fn bindgen_test_layout_JSCFunctionType() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).f_f as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).f_f) as usize - ptr as usize }, 0usize, concat!( "Offset of field: ", @@ -3321,7 +3314,7 @@ fn bindgen_test_layout_JSCFunctionType() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).f_f_f as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).f_f_f) as usize - ptr as usize }, 0usize, concat!( "Offset of field: ", @@ -3331,7 +3324,7 @@ fn bindgen_test_layout_JSCFunctionType() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).getter as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).getter) as usize - ptr as usize }, 0usize, concat!( "Offset of field: ", @@ -3341,7 +3334,7 @@ fn bindgen_test_layout_JSCFunctionType() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).setter as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).setter) as usize - ptr as usize }, 0usize, concat!( "Offset of field: ", @@ -3351,7 +3344,7 @@ fn bindgen_test_layout_JSCFunctionType() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).getter_magic as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).getter_magic) as usize - ptr as usize }, 0usize, concat!( "Offset of field: ", @@ -3361,7 +3354,7 @@ fn bindgen_test_layout_JSCFunctionType() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).setter_magic as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).setter_magic) as usize - ptr as usize }, 0usize, concat!( "Offset of field: ", @@ -3371,7 +3364,7 @@ fn bindgen_test_layout_JSCFunctionType() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).iterator_next as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).iterator_next) as usize - ptr as usize }, 0usize, concat!( "Offset of field: ", @@ -3424,7 +3417,6 @@ pub union JSCFunctionListEntry__bindgen_ty_1 { pub i32_: i32, pub i64_: i64, pub f64_: f64, - _bindgen_union_align: [u64; 2usize], } #[repr(C)] #[derive(Copy, Clone)] @@ -3435,6 +3427,9 @@ pub struct JSCFunctionListEntry__bindgen_ty_1__bindgen_ty_1 { } #[test] fn bindgen_test_layout_JSCFunctionListEntry__bindgen_ty_1__bindgen_ty_1() { + const UNINIT: ::std::mem::MaybeUninit = + ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); assert_eq!( ::std::mem::size_of::(), 16usize, @@ -3452,10 +3447,7 @@ fn bindgen_test_layout_JSCFunctionListEntry__bindgen_ty_1__bindgen_ty_1() { ) ); assert_eq!( - unsafe { - &(*(::std::ptr::null::())).length - as *const _ as usize - }, + unsafe { ::std::ptr::addr_of!((*ptr).length) as usize - ptr as usize }, 0usize, concat!( "Offset of field: ", @@ -3465,10 +3457,7 @@ fn bindgen_test_layout_JSCFunctionListEntry__bindgen_ty_1__bindgen_ty_1() { ) ); assert_eq!( - unsafe { - &(*(::std::ptr::null::())).cproto - as *const _ as usize - }, + unsafe { ::std::ptr::addr_of!((*ptr).cproto) as usize - ptr as usize }, 1usize, concat!( "Offset of field: ", @@ -3478,10 +3467,7 @@ fn bindgen_test_layout_JSCFunctionListEntry__bindgen_ty_1__bindgen_ty_1() { ) ); assert_eq!( - unsafe { - &(*(::std::ptr::null::())).cfunc - as *const _ as usize - }, + unsafe { ::std::ptr::addr_of!((*ptr).cfunc) as usize - ptr as usize }, 8usize, concat!( "Offset of field: ", @@ -3499,6 +3485,9 @@ pub struct JSCFunctionListEntry__bindgen_ty_1__bindgen_ty_2 { } #[test] fn bindgen_test_layout_JSCFunctionListEntry__bindgen_ty_1__bindgen_ty_2() { + const UNINIT: ::std::mem::MaybeUninit = + ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); assert_eq!( ::std::mem::size_of::(), 16usize, @@ -3516,10 +3505,7 @@ fn bindgen_test_layout_JSCFunctionListEntry__bindgen_ty_1__bindgen_ty_2() { ) ); assert_eq!( - unsafe { - &(*(::std::ptr::null::())).get - as *const _ as usize - }, + unsafe { ::std::ptr::addr_of!((*ptr).get) as usize - ptr as usize }, 0usize, concat!( "Offset of field: ", @@ -3529,10 +3515,7 @@ fn bindgen_test_layout_JSCFunctionListEntry__bindgen_ty_1__bindgen_ty_2() { ) ); assert_eq!( - unsafe { - &(*(::std::ptr::null::())).set - as *const _ as usize - }, + unsafe { ::std::ptr::addr_of!((*ptr).set) as usize - ptr as usize }, 8usize, concat!( "Offset of field: ", @@ -3550,6 +3533,9 @@ pub struct JSCFunctionListEntry__bindgen_ty_1__bindgen_ty_3 { } #[test] fn bindgen_test_layout_JSCFunctionListEntry__bindgen_ty_1__bindgen_ty_3() { + const UNINIT: ::std::mem::MaybeUninit = + ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); assert_eq!( ::std::mem::size_of::(), 16usize, @@ -3567,10 +3553,7 @@ fn bindgen_test_layout_JSCFunctionListEntry__bindgen_ty_1__bindgen_ty_3() { ) ); assert_eq!( - unsafe { - &(*(::std::ptr::null::())).name - as *const _ as usize - }, + unsafe { ::std::ptr::addr_of!((*ptr).name) as usize - ptr as usize }, 0usize, concat!( "Offset of field: ", @@ -3580,10 +3563,7 @@ fn bindgen_test_layout_JSCFunctionListEntry__bindgen_ty_1__bindgen_ty_3() { ) ); assert_eq!( - unsafe { - &(*(::std::ptr::null::())).base - as *const _ as usize - }, + unsafe { ::std::ptr::addr_of!((*ptr).base) as usize - ptr as usize }, 8usize, concat!( "Offset of field: ", @@ -3601,6 +3581,9 @@ pub struct JSCFunctionListEntry__bindgen_ty_1__bindgen_ty_4 { } #[test] fn bindgen_test_layout_JSCFunctionListEntry__bindgen_ty_1__bindgen_ty_4() { + const UNINIT: ::std::mem::MaybeUninit = + ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); assert_eq!( ::std::mem::size_of::(), 16usize, @@ -3618,10 +3601,7 @@ fn bindgen_test_layout_JSCFunctionListEntry__bindgen_ty_1__bindgen_ty_4() { ) ); assert_eq!( - unsafe { - &(*(::std::ptr::null::())).tab - as *const _ as usize - }, + unsafe { ::std::ptr::addr_of!((*ptr).tab) as usize - ptr as usize }, 0usize, concat!( "Offset of field: ", @@ -3631,10 +3611,7 @@ fn bindgen_test_layout_JSCFunctionListEntry__bindgen_ty_1__bindgen_ty_4() { ) ); assert_eq!( - unsafe { - &(*(::std::ptr::null::())).len - as *const _ as usize - }, + unsafe { ::std::ptr::addr_of!((*ptr).len) as usize - ptr as usize }, 8usize, concat!( "Offset of field: ", @@ -3646,6 +3623,9 @@ fn bindgen_test_layout_JSCFunctionListEntry__bindgen_ty_1__bindgen_ty_4() { } #[test] fn bindgen_test_layout_JSCFunctionListEntry__bindgen_ty_1() { + const UNINIT: ::std::mem::MaybeUninit = + ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); assert_eq!( ::std::mem::size_of::(), 16usize, @@ -3660,9 +3640,7 @@ fn bindgen_test_layout_JSCFunctionListEntry__bindgen_ty_1() { ) ); assert_eq!( - unsafe { - &(*(::std::ptr::null::())).func as *const _ as usize - }, + unsafe { ::std::ptr::addr_of!((*ptr).func) as usize - ptr as usize }, 0usize, concat!( "Offset of field: ", @@ -3672,10 +3650,7 @@ fn bindgen_test_layout_JSCFunctionListEntry__bindgen_ty_1() { ) ); assert_eq!( - unsafe { - &(*(::std::ptr::null::())).getset as *const _ - as usize - }, + unsafe { ::std::ptr::addr_of!((*ptr).getset) as usize - ptr as usize }, 0usize, concat!( "Offset of field: ", @@ -3685,10 +3660,7 @@ fn bindgen_test_layout_JSCFunctionListEntry__bindgen_ty_1() { ) ); assert_eq!( - unsafe { - &(*(::std::ptr::null::())).alias as *const _ - as usize - }, + unsafe { ::std::ptr::addr_of!((*ptr).alias) as usize - ptr as usize }, 0usize, concat!( "Offset of field: ", @@ -3698,10 +3670,7 @@ fn bindgen_test_layout_JSCFunctionListEntry__bindgen_ty_1() { ) ); assert_eq!( - unsafe { - &(*(::std::ptr::null::())).prop_list as *const _ - as usize - }, + unsafe { ::std::ptr::addr_of!((*ptr).prop_list) as usize - ptr as usize }, 0usize, concat!( "Offset of field: ", @@ -3711,9 +3680,7 @@ fn bindgen_test_layout_JSCFunctionListEntry__bindgen_ty_1() { ) ); assert_eq!( - unsafe { - &(*(::std::ptr::null::())).str_ as *const _ as usize - }, + unsafe { ::std::ptr::addr_of!((*ptr).str_) as usize - ptr as usize }, 0usize, concat!( "Offset of field: ", @@ -3723,9 +3690,7 @@ fn bindgen_test_layout_JSCFunctionListEntry__bindgen_ty_1() { ) ); assert_eq!( - unsafe { - &(*(::std::ptr::null::())).i32_ as *const _ as usize - }, + unsafe { ::std::ptr::addr_of!((*ptr).i32_) as usize - ptr as usize }, 0usize, concat!( "Offset of field: ", @@ -3735,9 +3700,7 @@ fn bindgen_test_layout_JSCFunctionListEntry__bindgen_ty_1() { ) ); assert_eq!( - unsafe { - &(*(::std::ptr::null::())).i64_ as *const _ as usize - }, + unsafe { ::std::ptr::addr_of!((*ptr).i64_) as usize - ptr as usize }, 0usize, concat!( "Offset of field: ", @@ -3747,9 +3710,7 @@ fn bindgen_test_layout_JSCFunctionListEntry__bindgen_ty_1() { ) ); assert_eq!( - unsafe { - &(*(::std::ptr::null::())).f64_ as *const _ as usize - }, + unsafe { ::std::ptr::addr_of!((*ptr).f64_) as usize - ptr as usize }, 0usize, concat!( "Offset of field: ", @@ -3761,6 +3722,8 @@ fn bindgen_test_layout_JSCFunctionListEntry__bindgen_ty_1() { } #[test] fn bindgen_test_layout_JSCFunctionListEntry() { + const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); assert_eq!( ::std::mem::size_of::(), 32usize, @@ -3772,7 +3735,7 @@ fn bindgen_test_layout_JSCFunctionListEntry() { concat!("Alignment of ", stringify!(JSCFunctionListEntry)) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).name as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).name) as usize - ptr as usize }, 0usize, concat!( "Offset of field: ", @@ -3782,7 +3745,7 @@ fn bindgen_test_layout_JSCFunctionListEntry() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).prop_flags as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).prop_flags) as usize - ptr as usize }, 8usize, concat!( "Offset of field: ", @@ -3792,7 +3755,7 @@ fn bindgen_test_layout_JSCFunctionListEntry() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).def_type as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).def_type) as usize - ptr as usize }, 9usize, concat!( "Offset of field: ", @@ -3802,7 +3765,7 @@ fn bindgen_test_layout_JSCFunctionListEntry() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).magic as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).magic) as usize - ptr as usize }, 10usize, concat!( "Offset of field: ", @@ -3812,7 +3775,7 @@ fn bindgen_test_layout_JSCFunctionListEntry() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::())).u as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).u) as usize - ptr as usize }, 16usize, concat!( "Offset of field: ", @@ -3882,6 +3845,8 @@ pub struct __va_list_tag { } #[test] fn bindgen_test_layout___va_list_tag() { + const UNINIT: ::std::mem::MaybeUninit<__va_list_tag> = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); assert_eq!( ::std::mem::size_of::<__va_list_tag>(), 24usize, @@ -3893,7 +3858,7 @@ fn bindgen_test_layout___va_list_tag() { concat!("Alignment of ", stringify!(__va_list_tag)) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<__va_list_tag>())).gp_offset as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).gp_offset) as usize - ptr as usize }, 0usize, concat!( "Offset of field: ", @@ -3903,7 +3868,7 @@ fn bindgen_test_layout___va_list_tag() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<__va_list_tag>())).fp_offset as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).fp_offset) as usize - ptr as usize }, 4usize, concat!( "Offset of field: ", @@ -3913,7 +3878,7 @@ fn bindgen_test_layout___va_list_tag() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<__va_list_tag>())).overflow_arg_area as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).overflow_arg_area) as usize - ptr as usize }, 8usize, concat!( "Offset of field: ", @@ -3923,7 +3888,7 @@ fn bindgen_test_layout___va_list_tag() { ) ); assert_eq!( - unsafe { &(*(::std::ptr::null::<__va_list_tag>())).reg_save_area as *const _ as usize }, + unsafe { ::std::ptr::addr_of!((*ptr).reg_save_area) as usize - ptr as usize }, 16usize, concat!( "Offset of field: ", diff --git a/libquickjs-sys/src/lib.rs b/libquickjs-sys/src/lib.rs index 914a1ed..8cde5fc 100644 --- a/libquickjs-sys/src/lib.rs +++ b/libquickjs-sys/src/lib.rs @@ -34,7 +34,7 @@ mod tests { let value = JS_Eval( ctx, code.as_ptr(), - (code_str.len() - 1) as u64, + code_str.len() - 1, script.as_ptr(), JS_EVAL_TYPE_GLOBAL as i32, ); diff --git a/src/bindings/compile.rs b/src/bindings/compile.rs index cca4ed4..38d476d 100644 --- a/src/bindings/compile.rs +++ b/src/bindings/compile.rs @@ -66,7 +66,7 @@ pub fn to_bytecode(context: &ContextWrapper, compiled_func: &JsCompiledFunction) *compiled_func.as_value().as_inner(), q::JS_WRITE_OBJ_BYTECODE as i32, ); - let slice = std::slice::from_raw_parts(raw, len as usize); + let slice = std::slice::from_raw_parts(raw, len); let data = slice.to_vec(); q::js_free(context.context, raw as *mut c_void); data diff --git a/src/bindings/convert.rs b/src/bindings/convert.rs index b22aa29..7f7efc6 100644 --- a/src/bindings/convert.rs +++ b/src/bindings/convert.rs @@ -221,7 +221,7 @@ pub(super) fn serialize_value( q::JS_NewStringLen( context, bigint_string.as_ptr() as *const c_char, - bigint_string.len() as q::size_t, + bigint_string.len(), ) }; let s = DroppableValue::new(s, |&mut s| unsafe { From ddfaae50c20196507adf18c3456230dc92a4ab14 Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Sun, 5 Feb 2023 20:31:40 +0100 Subject: [PATCH 05/16] update dependencies --- Cargo.toml | 5 ++--- libquickjs-sys/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 69c530d..915272c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,16 +21,15 @@ bigint = ["num-bigint", "num-traits", "libquickjs-sys/patched"] [dependencies] libquickjs-sys = { version = ">= 0.9.0, < 0.10.0", path = "./libquickjs-sys" } chrono = { version = "0.4.7", optional = true } -num-bigint = { version = "0.2.2", optional = true } +num-bigint = { version = "0.4.0", optional = true } num-traits = { version = "0.2.0", optional = true } log = { version = "0.4.8", optional = true } once_cell = "1.2.0" [dev-dependencies] -rstest = "0.15.0" +rstest = "0.16.0" [workspace] members = [ "libquickjs-sys", ] - diff --git a/libquickjs-sys/Cargo.toml b/libquickjs-sys/Cargo.toml index 626c6bb..71f44bb 100644 --- a/libquickjs-sys/Cargo.toml +++ b/libquickjs-sys/Cargo.toml @@ -21,6 +21,6 @@ default = ["bundled"] system = ["bindgen"] [build-dependencies] -bindgen = { version = "0.57.0", optional = true } +bindgen = { version = "0.63.0", optional = true } cc = { version = "1.0.66", optional = true } copy_dir = { version = "0.1.2", optional = true } From df3ec1d417a8e903345d320d91d507779d0efefe Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Sun, 5 Feb 2023 21:28:09 +0100 Subject: [PATCH 06/16] added quickjs patch for dateparser --- Cargo.toml | 5 +- justfile | 3 +- libquickjs-sys/Cargo.toml | 5 +- libquickjs-sys/build.rs | 49 +- libquickjs-sys/embed/patches/dateparser.patch | 971 ++++++++++++++++++ libquickjs-sys/embed/quickjs/quickjs.c | 439 ++------ src/tests.rs | 587 +++++------ 7 files changed, 1377 insertions(+), 682 deletions(-) create mode 100644 libquickjs-sys/embed/patches/dateparser.patch diff --git a/Cargo.toml b/Cargo.toml index 915272c..b3d233d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,8 +15,9 @@ features = [ "chrono", "bigint", "log" ] [features] default = ["chrono"] -patched = ["libquickjs-sys/patched"] -bigint = ["num-bigint", "num-traits", "libquickjs-sys/patched"] +patch_bigint = ["libquickjs-sys/patch_bigint"] +patch_dateparser = ["libquickjs-sys/patch_dateparser"] +bigint = ["num-bigint", "num-traits", "libquickjs-sys/patch_bigint"] [dependencies] libquickjs-sys = { version = ">= 0.9.0, < 0.10.0", path = "./libquickjs-sys" } diff --git a/justfile b/justfile index 7901278..5bcf226 100644 --- a/justfile +++ b/justfile @@ -55,5 +55,4 @@ valgrind: echo "Checking for memory leaks..." cargo clean cargo build --tests --all-features - find target/debug/deps -maxdepth 1 -type f -executable | xargs valgrind --leak-check=full --error-exitcode=1 --gen-suppressions=yes --show-error-list=yes - + find target/debug/deps -maxdepth 1 -type f -executable -not -name "*.so" | xargs valgrind --leak-check=full --error-exitcode=1 --gen-suppressions=yes --show-error-list=yes diff --git a/libquickjs-sys/Cargo.toml b/libquickjs-sys/Cargo.toml index 71f44bb..9e69eb5 100644 --- a/libquickjs-sys/Cargo.toml +++ b/libquickjs-sys/Cargo.toml @@ -15,9 +15,10 @@ build = "build.rs" [features] bundled = ["cc", "copy_dir"] -patched = ["bundled"] -default = ["bundled"] +patch_bigint = ["bundled"] +patch_dateparser = ["bundled"] +default = ["bundled"] system = ["bindgen"] [build-dependencies] diff --git a/libquickjs-sys/build.rs b/libquickjs-sys/build.rs index 5836beb..cacd4d5 100644 --- a/libquickjs-sys/build.rs +++ b/libquickjs-sys/build.rs @@ -55,8 +55,11 @@ fn main() { copy_dir::copy_dir(embed_path.join("quickjs"), &code_dir) .expect("Could not copy quickjs directory"); - #[cfg(feature = "patched")] - apply_patches(&code_dir); + #[cfg(feature = "patch_bigint")] + apply_patch(&code_dir, "js-tobigint64-overflow.patch"); + + #[cfg(feature = "patch_dateparser")] + apply_patch(&code_dir, "dateparser.patch"); std::fs::copy( embed_path.join("static-functions.c"), @@ -115,27 +118,25 @@ fn main() { .expect("Could not copy bindings.rs"); } -#[cfg(feature = "patched")] -fn apply_patches(code_dir: &PathBuf) { - use std::fs; +#[cfg(any(feature = "patch_bigint", feature = "patch_dateparser"))] +fn apply_patch(code_dir: &PathBuf, name: &str) { + eprintln!("Applying {name}"); + let patch_path = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()) + .join("embed") + .join("patches") + .join(name); + assert!(patch_path.exists(), "Could not open patch {name}"); - eprintln!("Applying patches..."); - let embed_path = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()).join("embed"); - let patches_path = embed_path.join("patches"); - for patch in fs::read_dir(patches_path).expect("Could not open patches directory") { - let patch = patch.expect("Could not open patch"); - eprintln!("Applying {:?}...", patch.file_name()); - let status = std::process::Command::new("patch") - .current_dir(code_dir) - .arg("-i") - .arg(patch.path()) - .spawn() - .expect("Could not apply patches") - .wait() - .expect("Could not apply patches"); - assert!( - status.success(), - "Patch command returned non-zero exit code" - ); - } + let status = std::process::Command::new("patch") + .current_dir(code_dir) + .arg("-i") + .arg(&patch_path) + .spawn() + .expect("Could not apply patches") + .wait() + .expect("Could not apply patches"); + assert!( + status.success(), + "Patch command returned non-zero exit code" + ); } diff --git a/libquickjs-sys/embed/patches/dateparser.patch b/libquickjs-sys/embed/patches/dateparser.patch new file mode 100644 index 0000000..28addea --- /dev/null +++ b/libquickjs-sys/embed/patches/dateparser.patch @@ -0,0 +1,971 @@ +diff --git a/libquickjs-sys/embed/quickjs/quickjs.c b/libquickjs-sys/embed/quickjs/quickjs.c +index 48aeffc..a3325b3 100644 +--- a/libquickjs-sys/embed/quickjs/quickjs.c ++++ b/libquickjs-sys/embed/quickjs/quickjs.c +@@ -1435,6 +1435,10 @@ static inline int is_digit(int c) { + return c >= '0' && c <= '9'; + } + ++static inline int is_space_like(char c) { ++ return c == ' ' || c == ',' || c == ':' || c == '-'; ++} ++ + typedef struct JSClassShortDef { + JSAtom class_name; + JSClassFinalizer *finalizer; +@@ -47929,6 +47933,23 @@ static int const month_days[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 + static char const month_names[] = "JanFebMarAprMayJunJulAugSepOctNovDec"; + static char const day_names[] = "SunMonTueWedThuFriSat"; + ++static const struct KnownZone { ++ char tzName[4]; ++ int tzOffset; ++} known_zones[] = { ++ { "UTC", 0 }, ++ { "UT", 0 }, ++ { "GMT", 0 }, ++ { "EST", -300 }, ++ { "EDT", -240 }, ++ { "CST", -360 }, ++ { "CDT", -300 }, ++ { "MST", -420 }, ++ { "MDT", -360 }, ++ { "PST", -480 }, ++ { "PDT", -420 } ++}; ++ + static __exception int get_date_fields(JSContext *ctx, JSValueConst obj, + double fields[9], int is_local, int force) + { +@@ -48294,14 +48315,46 @@ static JSValue js_Date_UTC(JSContext *ctx, JSValueConst this_val, + return JS_NewFloat64(ctx, set_date_fields(fields, 0)); + } + +-static void string_skip_spaces(JSString *sp, int *pp) { +- while (*pp < sp->len && string_get(sp, *pp) == ' ') ++static void string_skip_spaces_and_comments(JSString *sp, int *pp) { ++ int nesting = 0; ++ while (*pp < sp->len) { ++ char ch = string_get(sp, *pp); ++ int nxt = *pp + 1; ++ ++ // interpret - before a number as a sign rather than a comment char ++ if (ch == '-' && nxt < sp->len && is_digit(string_get(sp, nxt))) { ++ break; ++ } ++ if (!is_space_like(ch)) { ++ if (ch == '(') { ++ nesting++; ++ } else if (ch == ')' && nesting > 0) { ++ nesting--; ++ } else if (nesting == 0) { ++ break; ++ } ++ } ++ + *pp += 1; ++ } + } + +-static void string_skip_non_spaces(JSString *sp, int *pp) { +- while (*pp < sp->len && string_get(sp, *pp) != ' ') +- *pp += 1; ++static BOOL char_eq_ignorecase(char c1, char c2) { ++ if (c1 == c2) return TRUE; ++ ++ if (c1 >= 'A' && c1 <= 'Z' && c2 == c1 + 32) return TRUE; ++ if (c1 >= 'a' && c1 <= 'z' && c2 == c1 - 32) return TRUE; ++ return FALSE; ++} ++ ++static BOOL string_eq_ignorecase(JSString *s1, int p, const char *s2, int len) { ++ if (s1->len - p < len) return FALSE; ++ ++ for (int i=0; i= sp->len) ++ // Check contents of first words if not number ++ int64_t month = -1; ++ int word_start = p; ++ char c = string_get(sp, p); ++ ++ while (!is_digit(c)) { ++ if (c == ' ' || c == '(') { ++ if (p - word_start >= 3) { ++ month = find_abbrev(sp, word_start, month_names, 12); ++ } ++ string_skip_spaces_and_comments(sp, &p); // and comments ++ word_start = p; ++ } else { ++ p++; ++ } ++ ++ c = string_get(sp, p); ++ } ++ ++ // Missing delimiter between month and day (like "January29")? ++ if (month == -1 && word_start != p) { ++ month = find_abbrev(sp, word_start, month_names, 12); ++ } ++ ++ string_skip_spaces_and_comments(sp, &p); // and comments ++ if (sp->len <= p) + goto done; +- c = string_get(sp, p); +- if (c >= '0' && c <= '9') { +- /* day of month first */ +- if (string_get_digits(sp, &p, &fields[2])) ++ ++ // '09-Nov-99 23:12:40 GMT' ++ int64_t day = 0; ++ if (string_get_digits(sp, &p, &day)) ++ goto done; ++ ++ int64_t year = 0; ++ if (day > 31) { ++ if (string_get(sp, p) != '/') + goto done; +- if (string_get_month(sp, &p, &fields[1])) ++ // looks like a YYYY/MM/DD date ++ p++; ++ if (sp->len <= p) + goto done; +- } else { +- /* month first */ +- if (string_get_month(sp, &p, &fields[1])) ++ ++ year = day; ++ if (string_get_digits(sp, &p, &month)) + goto done; +- string_skip_spaces(sp, &p); +- if (string_get_digits(sp, &p, &fields[2])) ++ month--; ++ ++ if (string_get(sp, p) != '/') + goto done; +- } +- /* year */ +- string_skip_spaces(sp, &p); +- if (string_get_signed_digits(sp, &p, &fields[0])) +- goto done; ++ p++; ++ if (sp->len <= p) ++ goto done; ++ ++ if (string_get_digits(sp, &p, &day)) ++ goto done; ++ } else if (string_get(sp, p) == '/' && month == -1) { ++ p++; ++ // This looks like a MM/DD/YYYY date, not an RFC date. ++ month = day - 1; // 0-based ++ if (string_get_digits(sp, &p, &day)) ++ goto done; ++ ++ if (string_get(sp, p) != '/') ++ goto done; ++ p++; ++ if (sp->len <= p) ++ goto done; ++ } else { ++ if (string_get(sp, p) == '-') { ++ p++; ++ } ++ string_skip_spaces_and_comments(sp, &p); // and comments ++ ++ if (string_get(sp, p) == ',') { ++ p++; ++ } + +- /* hour, min, seconds */ +- string_skip_spaces(sp, &p); +- for(i = 0; i < 3; i++) { +- if (i == 1 || i == 2) { +- if (p >= sp->len) ++ if (month == -1) { ++ month = find_abbrev(sp, p, month_names, 12); ++ if (month == -1) ++ goto done; ++ ++ while (p < sp->len && string_get(sp, p) != '-' && string_get(sp, p) != ' ') { ++ p++; ++ } ++ if (sp->len <= p) + goto done; +- if (string_get(sp, p) != ':') ++ ++ // '-99 23:12:40 GMT' ++ if (string_get(sp, p) != '-' && string_get(sp, p) != '/' && string_get(sp, p) != ' ') { + goto done; ++ } + p++; + } +- if (string_get_digits(sp, &p, &fields[3 + i])) ++ ++ if (month < 0 || month > 11) { + goto done; ++ } + } +- // XXX: parse optional milliseconds? + +- /* parse the time zone offset if present: [+-]HHmm */ +- is_local = FALSE; +- tz = 0; +- for (tz = 0; p < sp->len; p++) { +- sgn = string_get(sp, p); +- if (sgn == '+' || sgn == '-') { ++ if (year <= 0) { ++ if (string_get_digits(sp, &p, &year)) ++ goto done; ++ if (year <= 0) { ++ goto done; ++ } ++ } ++ ++ // Don't fail if the time is missing. ++ int64_t hour = 0; ++ int64_t minute = 0; ++ int64_t second = 0; ++ ++ if (sp->len > p) { ++ // ' 23:12:40 GMT' ++ if (string_get(sp, p) == ':') { ++ // There was no year; the number was the hour. ++ year = -1; ++ } else if (is_space_like(string_get(sp, p))) { + p++; +- if (string_get_fixed_width_digits(sp, &p, 2, &hh)) ++ string_skip_spaces_and_comments(sp, &p); // and comments ++ } else { ++ goto done; ++ } ++ ++ // Read a number? If not, this might be a timezone name. ++ if (!string_get_digits(sp, &p, &hour)) { ++ if (hour < 0 || hour > 23) { + goto done; +- if (string_get_fixed_width_digits(sp, &p, 2, &mm)) ++ } ++ ++ if (sp->len <= p) + goto done; +- tz = hh * 60 + mm; +- if (sgn == '-') +- tz = -tz; +- break; ++ ++ // ':12:40 GMT' ++ if (string_get(sp, p) != ':') { ++ goto done; ++ } ++ p++; ++ ++ if (string_get_digits(sp, &p, &minute)) ++ goto done; ++ ++ if (minute < 0 || minute > 59) { ++ goto done; ++ } ++ ++ // ':40 GMT' ++ // seconds are optional in rfc822 + rfc2822 ++ if (string_get(sp, p) == ':') { ++ p++; ++ ++ if (string_get_digits(sp, &p, &second)) ++ goto done; ++ ++ if (second < 0 || second > 59) { ++ goto done; ++ } ++ ++ // disallow trailing colon seconds ++ if (string_get(sp, p) == ':') { ++ goto done; ++ } ++ } else if (string_get(sp, p) != ' ') { ++ goto done; ++ } ++ ++ string_skip_spaces_and_comments(sp, &p); // and comments ++ ++ if (string_eq_ignorecase(sp, p, "AM", 2)) { ++ if (hour > 12) { ++ goto done; ++ } ++ if (hour == 12) { ++ hour = 0; ++ } ++ p += 2; ++ string_skip_spaces_and_comments(sp, &p); // and comments ++ } else if (string_eq_ignorecase(sp, p, "PM", 2)) { ++ if (hour > 12) { ++ goto done; ++ } ++ if (hour != 12) { ++ hour += 12; ++ } ++ p += 2; ++ string_skip_spaces_and_comments(sp, &p); // and comments ++ } ++ } ++ } ++ ++ // Don't fail if the time zone is missing. ++ // Some websites omit the time zone ++ if (sp->len > p) { ++ if (string_get(sp, p) == '+' || string_get(sp, p) == '-') { ++ int64_t o; ++ if (string_get_digits(sp, &p, &o)) ++ goto done; ++ ++ if (o < -9959 || o > 9959) { ++ goto done; ++ } ++ ++ int sgn = (o < 0) ? -1 : 1; ++ o = abs((int32_t) o); ++ ++ if (string_get(sp, p) != ':') { ++ tz = ((o / 100) * 60 + (o % 100)) * sgn; ++ } else { ++ p++; ++ int64_t o2; ++ if (string_get_digits(sp, &p, &o2)) ++ goto done; ++ tz = (o * 60 + o2) * sgn; ++ } ++ is_local = FALSE; ++ } else { ++ for (int i = 0; i < sizeof(known_zones) / sizeof(struct KnownZone); i++) { ++ if (string_eq_ignorecase(sp, p, known_zones[i].tzName, strlen(known_zones[i].tzName))) { ++ tz = known_zones[i].tzOffset; ++ p += strlen(known_zones[i].tzName); ++ is_local = FALSE; ++ break; ++ } ++ } ++ } ++ } ++ ++ string_skip_spaces_and_comments(sp, &p); ++ ++ if (sp->len > p && year == -1) { ++ if (string_get_digits(sp, &p, &year)) ++ goto done; ++ } ++ ++ string_skip_spaces_and_comments(sp, &p); ++ ++ // Trailing garbage ++ if (sp->len > p) { ++ goto done; ++ } ++ ++ // Y2K: Handle 2 digit years. ++ if (year >= 0 && year < 100) { ++ if (year < 50) { ++ year += 2000; ++ } else { ++ year += 1900; + } + } ++ ++ fields[0] = year; ++ fields[1] = month; ++ fields[2] = day; ++ fields[3] = hour; ++ fields[4] = minute; ++ fields[5] = second; + } ++ + for(i = 0; i < 7; i++) + fields1[i] = fields[i]; +- d = set_date_fields(fields1, is_local) - tz * 60000; ++ d = set_date_fields(fields1, is_local) - (tz * 60000); + rv = JS_NewFloat64(ctx, d); + + done: +-- +2.39.1 + + +From f52e54d69ca1b62c9c855f360881ca8e4886ed1a Mon Sep 17 00:00:00 2001 +From: ThetaDev +Date: Sat, 13 Aug 2022 01:39:24 +0200 +Subject: [PATCH 2/5] 2 small fixes + +--- + libquickjs-sys/embed/quickjs/quickjs.c | 20 ++++++++++++-------- + 1 file changed, 12 insertions(+), 8 deletions(-) + +diff --git a/libquickjs-sys/embed/quickjs/quickjs.c b/libquickjs-sys/embed/quickjs/quickjs.c +index a3325b3..8ff9f4e 100644 +--- a/libquickjs-sys/embed/quickjs/quickjs.c ++++ b/libquickjs-sys/embed/quickjs/quickjs.c +@@ -48322,7 +48322,7 @@ static void string_skip_spaces_and_comments(JSString *sp, int *pp) { + int nxt = *pp + 1; + + // interpret - before a number as a sign rather than a comment char +- if (ch == '-' && nxt < sp->len && is_digit(string_get(sp, nxt))) { ++ if (ch == '-' && nesting == 0 && nxt < sp->len && is_digit(string_get(sp, nxt))) { + break; + } + if (!is_space_like(ch)) { +@@ -48496,6 +48496,8 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, + + sp = JS_VALUE_GET_STRING(s); + p = 0; ++ string_skip_spaces_and_comments(sp, &p); ++ + if (p < sp->len && (((c = string_get(sp, p)) >= '0' && c <= '9') || c == '+' || c == '-')) { + /* ISO format */ + /* year field can be negative */ +@@ -48579,7 +48581,7 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, + if (p - word_start >= 3) { + month = find_abbrev(sp, word_start, month_names, 12); + } +- string_skip_spaces_and_comments(sp, &p); // and comments ++ string_skip_spaces_and_comments(sp, &p); + word_start = p; + } else { + p++; +@@ -48593,7 +48595,7 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, + month = find_abbrev(sp, word_start, month_names, 12); + } + +- string_skip_spaces_and_comments(sp, &p); // and comments ++ string_skip_spaces_and_comments(sp, &p); + if (sp->len <= p) + goto done; + +@@ -48640,7 +48642,7 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, + if (string_get(sp, p) == '-') { + p++; + } +- string_skip_spaces_and_comments(sp, &p); // and comments ++ string_skip_spaces_and_comments(sp, &p); + + if (string_get(sp, p) == ',') { + p++; +@@ -48669,6 +48671,8 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, + } + } + ++ string_skip_spaces_and_comments(sp, &p); ++ + if (year <= 0) { + if (string_get_digits(sp, &p, &year)) + goto done; +@@ -48689,7 +48693,7 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, + year = -1; + } else if (is_space_like(string_get(sp, p))) { + p++; +- string_skip_spaces_and_comments(sp, &p); // and comments ++ string_skip_spaces_and_comments(sp, &p); + } else { + goto done; + } +@@ -48736,7 +48740,7 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, + goto done; + } + +- string_skip_spaces_and_comments(sp, &p); // and comments ++ string_skip_spaces_and_comments(sp, &p); + + if (string_eq_ignorecase(sp, p, "AM", 2)) { + if (hour > 12) { +@@ -48746,7 +48750,7 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, + hour = 0; + } + p += 2; +- string_skip_spaces_and_comments(sp, &p); // and comments ++ string_skip_spaces_and_comments(sp, &p); + } else if (string_eq_ignorecase(sp, p, "PM", 2)) { + if (hour > 12) { + goto done; +@@ -48755,7 +48759,7 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, + hour += 12; + } + p += 2; +- string_skip_spaces_and_comments(sp, &p); // and comments ++ string_skip_spaces_and_comments(sp, &p); + } + } + } +-- +2.39.1 + + +From ad17c000b6664c6f9ef2ecedbcaade19fc41c1eb Mon Sep 17 00:00:00 2001 +From: ThetaDev +Date: Sat, 13 Aug 2022 10:11:06 +0200 +Subject: [PATCH 3/5] fix y2k issue + +--- + libquickjs-sys/embed/quickjs/quickjs.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/libquickjs-sys/embed/quickjs/quickjs.c b/libquickjs-sys/embed/quickjs/quickjs.c +index 8ff9f4e..e7c71b0 100644 +--- a/libquickjs-sys/embed/quickjs/quickjs.c ++++ b/libquickjs-sys/embed/quickjs/quickjs.c +@@ -48604,7 +48604,7 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, + if (string_get_digits(sp, &p, &day)) + goto done; + +- int64_t year = 0; ++ int64_t year = -1; + if (day > 31) { + if (string_get(sp, p) != '/') + goto done; +@@ -48673,10 +48673,10 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, + + string_skip_spaces_and_comments(sp, &p); + +- if (year <= 0) { ++ if (year < 0) { + if (string_get_digits(sp, &p, &year)) + goto done; +- if (year <= 0) { ++ if (year < 0) { + goto done; + } + } +-- +2.39.1 + + +From 333283c377422f62a5e72605814c34b74f0f875d Mon Sep 17 00:00:00 2001 +From: ThetaDev +Date: Sat, 13 Aug 2022 15:02:04 +0200 +Subject: [PATCH 4/5] fix more date formats, now passes all tests + +--- + libquickjs-sys/embed/quickjs/quickjs.c | 84 +++++++++++++++++--------- + 1 file changed, 56 insertions(+), 28 deletions(-) + +diff --git a/libquickjs-sys/embed/quickjs/quickjs.c b/libquickjs-sys/embed/quickjs/quickjs.c +index e7c71b0..91b34c7 100644 +--- a/libquickjs-sys/embed/quickjs/quickjs.c ++++ b/libquickjs-sys/embed/quickjs/quickjs.c +@@ -1436,7 +1436,7 @@ static inline int is_digit(int c) { + } + + static inline int is_space_like(char c) { +- return c == ' ' || c == ',' || c == ':' || c == '-'; ++ return c == ' ' || c == ',' || c == ':' || c == '-' || c == '/'; + } + + typedef struct JSClassShortDef { +@@ -48339,12 +48339,10 @@ static void string_skip_spaces_and_comments(JSString *sp, int *pp) { + } + } + +-static BOOL char_eq_ignorecase(char c1, char c2) { +- if (c1 == c2) return TRUE; +- +- if (c1 >= 'A' && c1 <= 'Z' && c2 == c1 + 32) return TRUE; +- if (c1 >= 'a' && c1 <= 'z' && c2 == c1 - 32) return TRUE; +- return FALSE; ++static inline BOOL char_eq_ignorecase(char c1, char c2) { ++ if ((c1 >= 'A' && c1 <= 'Z') || (c1 >= 'a' && c1 <= 'z')) ++ return (c1 | 0x20) == (c2 | 0x20); ++ return c1 == c2; + } + + static BOOL string_eq_ignorecase(JSString *s1, int p, const char *s2, int len) { +@@ -48498,7 +48496,16 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, + p = 0; + string_skip_spaces_and_comments(sp, &p); + +- if (p < sp->len && (((c = string_get(sp, p)) >= '0' && c <= '9') || c == '+' || c == '-')) { ++ int end_of_digits = p; ++ if (string_get(sp, end_of_digits) == '+' || string_get(sp, end_of_digits) == '-') { ++ p++; ++ } ++ while (end_of_digits < sp->len && is_digit(string_get(sp, end_of_digits))) { ++ end_of_digits++; ++ } ++ ++ if ((end_of_digits - p) > 0 && ++ (string_get(sp, end_of_digits) == '-' || string_get(sp, end_of_digits) == 'T')) { + /* ISO format */ + /* year field can be negative */ + if (string_get_signed_digits(sp, &p, &fields[0])) +@@ -48523,8 +48530,13 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, + c = '.'; + break; + } +- if (string_get(sp, p) != c) +- break; ++ if (string_get(sp, p) != c) { ++ // 2000T08:00Z ++ if (i < 3 && string_get(sp, p) == 'T') { ++ i = 3; ++ } ++ else break; ++ } + p++; + if (i == 6) { + if (string_get_milliseconds(sp, &p, &fields[i])) +@@ -48633,7 +48645,7 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, + if (string_get_digits(sp, &p, &day)) + goto done; + +- if (string_get(sp, p) != '/') ++ if (!is_space_like(string_get(sp, p))) + goto done; + p++; + if (sp->len <= p) +@@ -48644,25 +48656,17 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, + } + string_skip_spaces_and_comments(sp, &p); + +- if (string_get(sp, p) == ',') { +- p++; +- } +- ++ // Jan,2000,08:00:00 UT + if (month == -1) { + month = find_abbrev(sp, p, month_names, 12); + if (month == -1) + goto done; + +- while (p < sp->len && string_get(sp, p) != '-' && string_get(sp, p) != ' ') { ++ while (p < sp->len && !is_space_like(string_get(sp, p))) { + p++; + } + if (sp->len <= p) + goto done; +- +- // '-99 23:12:40 GMT' +- if (string_get(sp, p) != '-' && string_get(sp, p) != '/' && string_get(sp, p) != ' ') { +- goto done; +- } + p++; + } + +@@ -48674,10 +48678,11 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, + string_skip_spaces_and_comments(sp, &p); + + if (year < 0) { +- if (string_get_digits(sp, &p, &year)) +- goto done; +- if (year < 0) { +- goto done; ++ // Year following, e.g. 01 Jan 2000 08:00:00 UT ++ // Time following, e.g. Jan 01 08:00:00 UT 2000 ++ if (sp->len <= p + 2 || string_get(sp, p + 2) != ':') { ++ if (string_get_digits(sp, &p, &year)) ++ goto done; + } + } + +@@ -48694,8 +48699,6 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, + } else if (is_space_like(string_get(sp, p))) { + p++; + string_skip_spaces_and_comments(sp, &p); +- } else { +- goto done; + } + + // Read a number? If not, this might be a timezone name. +@@ -48769,7 +48772,7 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, + if (sp->len > p) { + if (string_get(sp, p) == '+' || string_get(sp, p) == '-') { + int64_t o; +- if (string_get_digits(sp, &p, &o)) ++ if (string_get_signed_digits(sp, &p, &o)) + goto done; + + if (o < -9959 || o > 9959) { +@@ -48795,6 +48798,31 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, + tz = known_zones[i].tzOffset; + p += strlen(known_zones[i].tzName); + is_local = FALSE; ++ ++ // TZ offset (GMT+0) ++ if (string_get(sp, p) == '+' || string_get(sp, p) == '-') { ++ int64_t o; ++ if (string_get_signed_digits(sp, &p, &o)) ++ goto done; ++ ++ if (o < -9959 || o > 9959) { ++ goto done; ++ } ++ ++ int sgn = (o < 0) ? -1 : 1; ++ o = abs((int32_t) o); ++ ++ if (string_get(sp, p) != ':') { ++ tz += ((o / 100) * 60 + (o % 100)) * sgn; ++ } else { ++ p++; ++ int64_t o2; ++ if (string_get_digits(sp, &p, &o2)) ++ goto done; ++ tz += (o * 60 + o2) * sgn; ++ } ++ } ++ + break; + } + } +-- +2.39.1 + + +From 749be29936abc5c9d1d1dedf863a70d7bafaa795 Mon Sep 17 00:00:00 2001 +From: ThetaDev +Date: Sat, 13 Aug 2022 18:07:09 +0200 +Subject: [PATCH 5/5] added date validation + +--- + libquickjs-sys/embed/quickjs/quickjs.c | 105 ++++++++++++------------- + 1 file changed, 50 insertions(+), 55 deletions(-) + +diff --git a/libquickjs-sys/embed/quickjs/quickjs.c b/libquickjs-sys/embed/quickjs/quickjs.c +index 91b34c7..68f0120 100644 +--- a/libquickjs-sys/embed/quickjs/quickjs.c ++++ b/libquickjs-sys/embed/quickjs/quickjs.c +@@ -48440,6 +48440,34 @@ static int string_get_milliseconds(JSString *sp, int *pp, int64_t *pval) { + return 0; + } + ++static int string_get_num_timezone(JSString *sp, int *pp, int64_t *pval) ++{ ++ int p = *pp; ++ ++ int64_t o; ++ if (string_get_signed_digits(sp, &p, &o)) ++ return -1; ++ ++ if (o < -9959 || o > 9959) { ++ return -1; ++ } ++ ++ int sgn = (o < 0) ? -1 : 1; ++ o = abs((int32_t) o); ++ ++ if (string_get(sp, p) != ':') { ++ *pval = ((o / 100) * 60 + (o % 100)) * sgn; ++ } else { ++ p++; ++ int64_t o2; ++ if (string_get_digits(sp, &p, &o2)) ++ return -1; ++ *pval = (o * 60 + o2) * sgn; ++ } ++ ++ *pp = p; ++ return 0; ++} + + static int find_abbrev(JSString *sp, int p, const char *list, int count) { + int n, i; +@@ -48515,18 +48543,18 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, + if (p >= sp->len) + break; + switch(i) { +- case 1: +- case 2: ++ case 1: // Year ++ case 2: // Month + c = '-'; + break; +- case 3: ++ case 3: // Day + c = 'T'; + break; +- case 4: +- case 5: ++ case 4: // Hour ++ case 5: // Minute + c = ':'; + break; +- case 6: ++ case 6: // Second + c = '.'; + break; + } +@@ -48546,6 +48574,9 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, + goto done; + } + } ++ // Hour only is invalid ++ if (i == 4) goto done; ++ + /* no time: UTC by default */ + is_local = (i > 3); + fields[1] -= 1; +@@ -48669,10 +48700,6 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, + goto done; + p++; + } +- +- if (month < 0 || month > 11) { +- goto done; +- } + } + + string_skip_spaces_and_comments(sp, &p); +@@ -48718,10 +48745,6 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, + + if (string_get_digits(sp, &p, &minute)) + goto done; +- +- if (minute < 0 || minute > 59) { +- goto done; +- } + + // ':40 GMT' + // seconds are optional in rfc822 + rfc2822 +@@ -48730,10 +48753,6 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, + + if (string_get_digits(sp, &p, &second)) + goto done; +- +- if (second < 0 || second > 59) { +- goto done; +- } + + // disallow trailing colon seconds + if (string_get(sp, p) == ':') { +@@ -48771,26 +48790,8 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, + // Some websites omit the time zone + if (sp->len > p) { + if (string_get(sp, p) == '+' || string_get(sp, p) == '-') { +- int64_t o; +- if (string_get_signed_digits(sp, &p, &o)) +- goto done; +- +- if (o < -9959 || o > 9959) { ++ if (string_get_num_timezone(sp, &p, &tz)) + goto done; +- } +- +- int sgn = (o < 0) ? -1 : 1; +- o = abs((int32_t) o); +- +- if (string_get(sp, p) != ':') { +- tz = ((o / 100) * 60 + (o % 100)) * sgn; +- } else { +- p++; +- int64_t o2; +- if (string_get_digits(sp, &p, &o2)) +- goto done; +- tz = (o * 60 + o2) * sgn; +- } + is_local = FALSE; + } else { + for (int i = 0; i < sizeof(known_zones) / sizeof(struct KnownZone); i++) { +@@ -48802,27 +48803,11 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, + // TZ offset (GMT+0) + if (string_get(sp, p) == '+' || string_get(sp, p) == '-') { + int64_t o; +- if (string_get_signed_digits(sp, &p, &o)) ++ if (string_get_num_timezone(sp, &p, &o)) + goto done; + +- if (o < -9959 || o > 9959) { +- goto done; +- } +- +- int sgn = (o < 0) ? -1 : 1; +- o = abs((int32_t) o); +- +- if (string_get(sp, p) != ':') { +- tz += ((o / 100) * 60 + (o % 100)) * sgn; +- } else { +- p++; +- int64_t o2; +- if (string_get_digits(sp, &p, &o2)) +- goto done; +- tz += (o * 60 + o2) * sgn; +- } ++ tz += o; + } +- + break; + } + } +@@ -48860,6 +48845,16 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, + fields[5] = second; + } + ++ // Validate fields ++ if (fields[1] < 0 || fields[1] > 11 || ++ fields[2] < 1 || fields[2] > 31 || ++ fields[3] < 0 || fields[3] > 24 || ++ fields[4] < 0 || fields[4] > 59 || ++ fields[5] < 0 || fields[5] > 59 || ++ fields[6] < 0 || fields[6] > 999 || ++ fields[3] * 3600 * 1000 + fields[4] * 60000 + fields[5] * 1000 + fields[6] > 24 * 3600 * 1000 ++ ) goto done; ++ + for(i = 0; i < 7; i++) + fields1[i] = fields[i]; + d = set_date_fields(fields1, is_local) - (tz * 60000); +-- +2.39.1 + diff --git a/libquickjs-sys/embed/quickjs/quickjs.c b/libquickjs-sys/embed/quickjs/quickjs.c index 68f0120..48aeffc 100644 --- a/libquickjs-sys/embed/quickjs/quickjs.c +++ b/libquickjs-sys/embed/quickjs/quickjs.c @@ -1435,10 +1435,6 @@ static inline int is_digit(int c) { return c >= '0' && c <= '9'; } -static inline int is_space_like(char c) { - return c == ' ' || c == ',' || c == ':' || c == '-' || c == '/'; -} - typedef struct JSClassShortDef { JSAtom class_name; JSClassFinalizer *finalizer; @@ -47933,23 +47929,6 @@ static int const month_days[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 static char const month_names[] = "JanFebMarAprMayJunJulAugSepOctNovDec"; static char const day_names[] = "SunMonTueWedThuFriSat"; -static const struct KnownZone { - char tzName[4]; - int tzOffset; -} known_zones[] = { - { "UTC", 0 }, - { "UT", 0 }, - { "GMT", 0 }, - { "EST", -300 }, - { "EDT", -240 }, - { "CST", -360 }, - { "CDT", -300 }, - { "MST", -420 }, - { "MDT", -360 }, - { "PST", -480 }, - { "PDT", -420 } -}; - static __exception int get_date_fields(JSContext *ctx, JSValueConst obj, double fields[9], int is_local, int force) { @@ -48315,44 +48294,14 @@ static JSValue js_Date_UTC(JSContext *ctx, JSValueConst this_val, return JS_NewFloat64(ctx, set_date_fields(fields, 0)); } -static void string_skip_spaces_and_comments(JSString *sp, int *pp) { - int nesting = 0; - while (*pp < sp->len) { - char ch = string_get(sp, *pp); - int nxt = *pp + 1; - - // interpret - before a number as a sign rather than a comment char - if (ch == '-' && nesting == 0 && nxt < sp->len && is_digit(string_get(sp, nxt))) { - break; - } - if (!is_space_like(ch)) { - if (ch == '(') { - nesting++; - } else if (ch == ')' && nesting > 0) { - nesting--; - } else if (nesting == 0) { - break; - } - } - +static void string_skip_spaces(JSString *sp, int *pp) { + while (*pp < sp->len && string_get(sp, *pp) == ' ') *pp += 1; - } } -static inline BOOL char_eq_ignorecase(char c1, char c2) { - if ((c1 >= 'A' && c1 <= 'Z') || (c1 >= 'a' && c1 <= 'z')) - return (c1 | 0x20) == (c2 | 0x20); - return c1 == c2; -} - -static BOOL string_eq_ignorecase(JSString *s1, int p, const char *s2, int len) { - if (s1->len - p < len) return FALSE; - - for (int i=0; ilen && string_get(sp, *pp) != ' ') + *pp += 1; } /* parse a numeric field with an optional sign if accept_sign is TRUE */ @@ -48440,34 +48389,6 @@ static int string_get_milliseconds(JSString *sp, int *pp, int64_t *pval) { return 0; } -static int string_get_num_timezone(JSString *sp, int *pp, int64_t *pval) -{ - int p = *pp; - - int64_t o; - if (string_get_signed_digits(sp, &p, &o)) - return -1; - - if (o < -9959 || o > 9959) { - return -1; - } - - int sgn = (o < 0) ? -1 : 1; - o = abs((int32_t) o); - - if (string_get(sp, p) != ':') { - *pval = ((o / 100) * 60 + (o % 100)) * sgn; - } else { - p++; - int64_t o2; - if (string_get_digits(sp, &p, &o2)) - return -1; - *pval = (o * 60 + o2) * sgn; - } - - *pp = p; - return 0; -} static int find_abbrev(JSString *sp, int p, const char *list, int count) { int n, i; @@ -48485,30 +48406,27 @@ static int find_abbrev(JSString *sp, int p, const char *list, int count) { return -1; } +static int string_get_month(JSString *sp, int *pp, int64_t *pval) { + int n; + + string_skip_spaces(sp, pp); + n = find_abbrev(sp, *pp, month_names, 12); + if (n < 0) + return -1; + + *pval = n; + *pp += 3; + return 0; +} + static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { - // This parses a date in the form: - // Tuesday, 09-Nov-99 23:12:40 GMT - // or - // Sat, 01-Jan-2000 08:00:00 GMT - // or - // Sat, 01 Jan 2000 08:00:00 GMT - // or - // 01 Jan 99 22:00 +0100 (exceptions in rfc822/rfc2822) - // ### non RFC formats, added for Javascript: - // [Wednesday] January 09 1999 23:12:40 GMT - // [Wednesday] January 09 23:12:40 GMT 1999 - // - // We ignore the weekday. - // - // Date parser adapted from KJS' implementation - // Source: https://invent.kde.org/frameworks/kjs/-/blob/fd9252ec4b270ebb4a299129099bce97f00dac0e/src/kjs/date_object.cpp#L1153 - + // parse(s) JSValue s, rv; int64_t fields[] = { 0, 1, 1, 0, 0, 0, 0 }; double fields1[7]; - int64_t tz = 0, hh, mm; + int64_t tz, hh, mm; double d; int p, i, c, sgn, l; JSString *sp; @@ -48522,18 +48440,7 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, sp = JS_VALUE_GET_STRING(s); p = 0; - string_skip_spaces_and_comments(sp, &p); - - int end_of_digits = p; - if (string_get(sp, end_of_digits) == '+' || string_get(sp, end_of_digits) == '-') { - p++; - } - while (end_of_digits < sp->len && is_digit(string_get(sp, end_of_digits))) { - end_of_digits++; - } - - if ((end_of_digits - p) > 0 && - (string_get(sp, end_of_digits) == '-' || string_get(sp, end_of_digits) == 'T')) { + if (p < sp->len && (((c = string_get(sp, p)) >= '0' && c <= '9') || c == '+' || c == '-')) { /* ISO format */ /* year field can be negative */ if (string_get_signed_digits(sp, &p, &fields[0])) @@ -48543,28 +48450,23 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, if (p >= sp->len) break; switch(i) { - case 1: // Year - case 2: // Month + case 1: + case 2: c = '-'; break; - case 3: // Day + case 3: c = 'T'; break; - case 4: // Hour - case 5: // Minute + case 4: + case 5: c = ':'; break; - case 6: // Second + case 6: c = '.'; break; } - if (string_get(sp, p) != c) { - // 2000T08:00Z - if (i < 3 && string_get(sp, p) == 'T') { - i = 3; - } - else break; - } + if (string_get(sp, p) != c) + break; p++; if (i == 6) { if (string_get_milliseconds(sp, &p, &fields[i])) @@ -48574,9 +48476,6 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, goto done; } } - // Hour only is invalid - if (i == 4) goto done; - /* no time: UTC by default */ is_local = (i > 3); fields[1] -= 1; @@ -48614,250 +48513,68 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, goto done; } } else { - // Check contents of first words if not number - int64_t month = -1; - int word_start = p; - char c = string_get(sp, p); - - while (!is_digit(c)) { - if (c == ' ' || c == '(') { - if (p - word_start >= 3) { - month = find_abbrev(sp, word_start, month_names, 12); - } - string_skip_spaces_and_comments(sp, &p); - word_start = p; - } else { - p++; - } - - c = string_get(sp, p); - } - - // Missing delimiter between month and day (like "January29")? - if (month == -1 && word_start != p) { - month = find_abbrev(sp, word_start, month_names, 12); - } - - string_skip_spaces_and_comments(sp, &p); - if (sp->len <= p) + /* toString or toUTCString format */ + /* skip the day of the week */ + string_skip_non_spaces(sp, &p); + string_skip_spaces(sp, &p); + if (p >= sp->len) goto done; - - // '09-Nov-99 23:12:40 GMT' - int64_t day = 0; - if (string_get_digits(sp, &p, &day)) - goto done; - - int64_t year = -1; - if (day > 31) { - if (string_get(sp, p) != '/') + c = string_get(sp, p); + if (c >= '0' && c <= '9') { + /* day of month first */ + if (string_get_digits(sp, &p, &fields[2])) goto done; - // looks like a YYYY/MM/DD date - p++; - if (sp->len <= p) - goto done; - - year = day; - if (string_get_digits(sp, &p, &month)) - goto done; - month--; - - if (string_get(sp, p) != '/') - goto done; - p++; - if (sp->len <= p) - goto done; - - if (string_get_digits(sp, &p, &day)) - goto done; - } else if (string_get(sp, p) == '/' && month == -1) { - p++; - // This looks like a MM/DD/YYYY date, not an RFC date. - month = day - 1; // 0-based - if (string_get_digits(sp, &p, &day)) - goto done; - - if (!is_space_like(string_get(sp, p))) - goto done; - p++; - if (sp->len <= p) + if (string_get_month(sp, &p, &fields[1])) goto done; } else { - if (string_get(sp, p) == '-') { - p++; - } - string_skip_spaces_and_comments(sp, &p); - - // Jan,2000,08:00:00 UT - if (month == -1) { - month = find_abbrev(sp, p, month_names, 12); - if (month == -1) - goto done; - - while (p < sp->len && !is_space_like(string_get(sp, p))) { - p++; - } - if (sp->len <= p) - goto done; - p++; - } - } - - string_skip_spaces_and_comments(sp, &p); - - if (year < 0) { - // Year following, e.g. 01 Jan 2000 08:00:00 UT - // Time following, e.g. Jan 01 08:00:00 UT 2000 - if (sp->len <= p + 2 || string_get(sp, p + 2) != ':') { - if (string_get_digits(sp, &p, &year)) - goto done; - } - } - - // Don't fail if the time is missing. - int64_t hour = 0; - int64_t minute = 0; - int64_t second = 0; - - if (sp->len > p) { - // ' 23:12:40 GMT' - if (string_get(sp, p) == ':') { - // There was no year; the number was the hour. - year = -1; - } else if (is_space_like(string_get(sp, p))) { - p++; - string_skip_spaces_and_comments(sp, &p); - } - - // Read a number? If not, this might be a timezone name. - if (!string_get_digits(sp, &p, &hour)) { - if (hour < 0 || hour > 23) { - goto done; - } - - if (sp->len <= p) - goto done; - - // ':12:40 GMT' - if (string_get(sp, p) != ':') { - goto done; - } - p++; - - if (string_get_digits(sp, &p, &minute)) - goto done; - - // ':40 GMT' - // seconds are optional in rfc822 + rfc2822 - if (string_get(sp, p) == ':') { - p++; - - if (string_get_digits(sp, &p, &second)) - goto done; - - // disallow trailing colon seconds - if (string_get(sp, p) == ':') { - goto done; - } - } else if (string_get(sp, p) != ' ') { - goto done; - } - - string_skip_spaces_and_comments(sp, &p); - - if (string_eq_ignorecase(sp, p, "AM", 2)) { - if (hour > 12) { - goto done; - } - if (hour == 12) { - hour = 0; - } - p += 2; - string_skip_spaces_and_comments(sp, &p); - } else if (string_eq_ignorecase(sp, p, "PM", 2)) { - if (hour > 12) { - goto done; - } - if (hour != 12) { - hour += 12; - } - p += 2; - string_skip_spaces_and_comments(sp, &p); - } - } - } - - // Don't fail if the time zone is missing. - // Some websites omit the time zone - if (sp->len > p) { - if (string_get(sp, p) == '+' || string_get(sp, p) == '-') { - if (string_get_num_timezone(sp, &p, &tz)) - goto done; - is_local = FALSE; - } else { - for (int i = 0; i < sizeof(known_zones) / sizeof(struct KnownZone); i++) { - if (string_eq_ignorecase(sp, p, known_zones[i].tzName, strlen(known_zones[i].tzName))) { - tz = known_zones[i].tzOffset; - p += strlen(known_zones[i].tzName); - is_local = FALSE; - - // TZ offset (GMT+0) - if (string_get(sp, p) == '+' || string_get(sp, p) == '-') { - int64_t o; - if (string_get_num_timezone(sp, &p, &o)) - goto done; - - tz += o; - } - break; - } - } - } - } - - string_skip_spaces_and_comments(sp, &p); - - if (sp->len > p && year == -1) { - if (string_get_digits(sp, &p, &year)) + /* month first */ + if (string_get_month(sp, &p, &fields[1])) + goto done; + string_skip_spaces(sp, &p); + if (string_get_digits(sp, &p, &fields[2])) goto done; } - - string_skip_spaces_and_comments(sp, &p); - - // Trailing garbage - if (sp->len > p) { + /* year */ + string_skip_spaces(sp, &p); + if (string_get_signed_digits(sp, &p, &fields[0])) goto done; - } - // Y2K: Handle 2 digit years. - if (year >= 0 && year < 100) { - if (year < 50) { - year += 2000; - } else { - year += 1900; + /* hour, min, seconds */ + string_skip_spaces(sp, &p); + for(i = 0; i < 3; i++) { + if (i == 1 || i == 2) { + if (p >= sp->len) + goto done; + if (string_get(sp, p) != ':') + goto done; + p++; + } + if (string_get_digits(sp, &p, &fields[3 + i])) + goto done; + } + // XXX: parse optional milliseconds? + + /* parse the time zone offset if present: [+-]HHmm */ + is_local = FALSE; + tz = 0; + for (tz = 0; p < sp->len; p++) { + sgn = string_get(sp, p); + if (sgn == '+' || sgn == '-') { + p++; + if (string_get_fixed_width_digits(sp, &p, 2, &hh)) + goto done; + if (string_get_fixed_width_digits(sp, &p, 2, &mm)) + goto done; + tz = hh * 60 + mm; + if (sgn == '-') + tz = -tz; + break; } } - - fields[0] = year; - fields[1] = month; - fields[2] = day; - fields[3] = hour; - fields[4] = minute; - fields[5] = second; } - - // Validate fields - if (fields[1] < 0 || fields[1] > 11 || - fields[2] < 1 || fields[2] > 31 || - fields[3] < 0 || fields[3] > 24 || - fields[4] < 0 || fields[4] > 59 || - fields[5] < 0 || fields[5] > 59 || - fields[6] < 0 || fields[6] > 999 || - fields[3] * 3600 * 1000 + fields[4] * 60000 + fields[5] * 1000 + fields[6] > 24 * 3600 * 1000 - ) goto done; - for(i = 0; i < 7; i++) fields1[i] = fields[i]; - d = set_date_fields(fields1, is_local) - (tz * 60000); + d = set_date_fields(fields1, is_local) - tz * 60000; rv = JS_NewFloat64(ctx, d); done: diff --git a/src/tests.rs b/src/tests.rs index 389ddd4..41eb286 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -1,6 +1,4 @@ -use std::{collections::HashMap, convert::TryInto}; - -use rstest::rstest; +use std::collections::HashMap; use super::*; @@ -580,302 +578,308 @@ fn test_bigint_serialize_bigint() { } } -#[test] -fn test_console() { - use console::Level; - use std::sync::{Arc, Mutex}; +#[cfg(feature = "patch_dateparser")] +mod dateparser { + use super::*; - let messages = Arc::new(Mutex::new(Vec::<(Level, Vec)>::new())); + use rstest::rstest; - let m = messages.clone(); - let c = Context::builder() - .console(move |level: Level, args: Vec| { - m.lock().unwrap().push((level, args)); - }) - .build() - .unwrap(); + #[test] + fn test_console() { + use console::Level; + use std::sync::{Arc, Mutex}; - c.eval( - r#" + let messages = Arc::new(Mutex::new(Vec::<(Level, Vec)>::new())); + + let m = messages.clone(); + let c = Context::builder() + .console(move |level: Level, args: Vec| { + m.lock().unwrap().push((level, args)); + }) + .build() + .unwrap(); + + c.eval( + r#" console.log("hi"); console.error(false); "#, - ) - .unwrap(); - - let m = messages.lock().unwrap(); - - assert_eq!( - *m, - vec![ - (Level::Log, vec![JsValue::from("hi")]), - (Level::Error, vec![JsValue::from(false)]), - ] - ); -} - -#[test] -fn test_global_setter() { - let ctx = Context::new().unwrap(); - ctx.set_global("a", "a").unwrap(); - ctx.eval("a + 1").unwrap(); -} - -// Test suite was taken from V8 -// Source: https://github.com/v8/v8/blob/9433ad119aadfe10d60935029195c31f25ab8624/test/mjsunit/date-parse.js - -#[rstest] -// testCasesES5Misc -#[case("2000-01-01T08:00:00.000Z", 946713600000)] -#[case("2000-01-01T08:00:00Z", 946713600000)] -#[case("2000-01-01T08:00Z", 946713600000)] -#[case("2000-01T08:00:00.000Z", 946713600000)] -#[case("2000T08:00:00.000Z", 946713600000)] -#[case("2000T08:00Z", 946713600000)] -#[case("2000-01T00:00:00.000-08:00", 946713600000)] -#[case("2000-01T08:00:00.001Z", 946713600001)] -#[case("2000-01T08:00:00.099Z", 946713600099)] -#[case("2000-01T08:00:00.999Z", 946713600999)] -#[case("2000-01T00:00:00.001-08:00", 946713600001)] -#[case("2000-01-01T24:00Z", 946771200000)] -#[case("2000-01-01T24:00:00Z", 946771200000)] -#[case("2000-01-01T24:00:00.000Z", 946771200000)] -fn test_date_iso(#[case] input: &str, #[case] expect: i64) { - let ctx = Context::new().unwrap(); - let res = ctx - .eval(&format!(r#"new Date("{input}").getTime()"#)) + ) .unwrap(); - let n: f64 = res.try_into().unwrap(); - assert_eq!(n, expect as f64); -} + let m = messages.lock().unwrap(); -#[rstest] -#[case("Sat, 01-Jan-2000 08:00:00 GMT", 946713600000)] -#[case("Sat, 01-Jan-2000 08:00:00 GMT+0", 946713600000)] -#[case("Sat, 01-Jan-2000 08:00:00 GMT+00", 946713600000)] -#[case("Sat, 01-Jan-2000 08:00:00 GMT+000", 946713600000)] -#[case("Sat, 01-Jan-2000 08:00:00 GMT+0000", 946713600000)] -#[case("Sat, 01-Jan-2000 08:00:00 GMT+00:00", 946713600000)] -#[case("Sat, 01 Jan 2000 08:00:00 GMT", 946713600000)] -#[case("Saturday, 01-Jan-00 08:00:00 GMT", 946713600000)] -#[case("01 Jan 00 08:00 -0000", 946713600000)] -#[case("01 Jan 00 08:00 +0000", 946713600000)] -fn test_date_gmt(#[case] input: &str, #[case] expect: i64) { - let ctx = Context::new().unwrap(); - let res = ctx - .eval(&format!(r#"new Date("{input}").getTime()"#)) - .unwrap(); - - let n: f64 = res.try_into().unwrap(); - assert_eq!(n, expect as f64); -} - -#[rstest] -// EST (-5:00) -#[case("Sat, 01-Jan-2000 03:00:00 UTC-0500", 946713600000)] -#[case("Sat, 01-Jan-2000 03:00:00 UTC-05:00", 946713600000)] -#[case("Sat, 01-Jan-2000 03:00:00 EST", 946713600000)] -#[case("Sat, 01 Jan 2000 03:00:00 EST", 946713600000)] -#[case("Saturday, 01-Jan-00 03:00:00 EST", 946713600000)] -#[case("01 Jan 00 03:00 -0500", 946713600000)] -// EDT (-4:00) -#[case("Sat, 01-Jan-2000 04:00:00 EDT", 946713600000)] -#[case("Sat, 01 Jan 2000 04:00:00 EDT", 946713600000)] -#[case("Saturday, 01-Jan-00 04:00:00 EDT", 946713600000)] -#[case("01 Jan 00 04:00 -0400", 946713600000)] -// CST (-6:00) -#[case("Sat, 01-Jan-2000 02:00:00 CST", 946713600000)] -#[case("Sat, 01 Jan 2000 02:00:00 CST", 946713600000)] -#[case("Saturday, 01-Jan-00 02:00:00 CST", 946713600000)] -#[case("01 Jan 00 02:00 -0600", 946713600000)] -// CDT (-5:00) -#[case("Sat, 01-Jan-2000 03:00:00 CDT", 946713600000)] -#[case("Sat, 01 Jan 2000 03:00:00 CDT", 946713600000)] -#[case("Saturday, 01-Jan-00 03:00:00 CDT", 946713600000)] -#[case("01 Jan 00 03:00 -0500", 946713600000)] -// MST (-7:00) -#[case("Sat, 01-Jan-2000 01:00:00 MST", 946713600000)] -#[case("Sat, 01 Jan 2000 01:00:00 MST", 946713600000)] -#[case("Saturday, 01-Jan-00 01:00:00 MST", 946713600000)] -#[case("01 Jan 00 01:00 -0700", 946713600000)] -// MDT (-6:00) -#[case("Sat, 01-Jan-2000 02:00:00 MDT", 946713600000)] -#[case("Sat, 01 Jan 2000 02:00:00 MDT", 946713600000)] -#[case("Saturday, 01-Jan-00 02:00:00 MDT", 946713600000)] -#[case("01 Jan 00 02:00 -0600", 946713600000)] -// PST (-8:00) -#[case("Sat, 01-Jan-2000 00:00:00 PST", 946713600000)] -#[case("Sat, 01 Jan 2000 00:00:00 PST", 946713600000)] -#[case("Saturday, 01-Jan-00 00:00:00 PST", 946713600000)] -#[case("01 Jan 00 00:00 -0800", 946713600000)] -#[case("Sat, 01-Jan-2000 PST", 946713600000)] -// PDT (-7:00) -#[case("Sat, 01-Jan-2000 01:00:00 PDT", 946713600000)] -#[case("Sat, 01 Jan 2000 01:00:00 PDT", 946713600000)] -#[case("Saturday, 01-Jan-00 01:00:00 PDT", 946713600000)] -#[case("01 Jan 00 01:00 -0700", 946713600000)] -fn test_date_tz(#[case] input: &str, #[case] expect: i64) { - let ctx = Context::new().unwrap(); - let res = ctx - .eval(&format!(r#"new Date("{input}").getTime()"#)) - .unwrap(); - - let n: f64 = res.try_into().unwrap(); - assert_eq!(n, expect as f64); -} - -#[rstest] -// Special handling for years in the [0, 100) range. -#[case("Sat, 01 Jan 0 08:00:00 UT", 946713600000)] // year 2000 -#[case("Sat, 01 Jan 49 08:00:00 UT", 2493100800000)] // year 2049 -#[case("Sat, 01 Jan 50 08:00:00 UT", -631123200000)] // year 1950 -#[case("Sat, 01 Jan 99 08:00:00 UT", 915177600000)] // year 1999 -#[case("Sat, 01 Jan 100 08:00:00 UT", -59011430400000)] // year 100 -// Test PM after time. -#[case("Sat, 01-Jan-2000 08:00 PM UT", 946756800000)] -#[case("Sat, 01 Jan 2000 08:00 PM UT", 946756800000)] -#[case("Jan 01 2000 08:00 PM UT", 946756800000)] -#[case("Jan 01 08:00 PM UT 2000", 946756800000)] -#[case("Saturday, 01-Jan-00 08:00 PM UT", 946756800000)] -#[case("01 Jan 00 08:00 PM +0000", 946756800000)] -fn test_date_special(#[case] input: &str, #[case] expect: i64) { - let ctx = Context::new().unwrap(); - let res = ctx - .eval(&format!(r#"new Date("{input}").getTime()"#)) - .unwrap(); - - let n: f64 = res.try_into().unwrap(); - assert_eq!(n, expect as f64); -} - -#[rstest] -#[case("2000-01-01TZ")] -#[case("2000-01-01T60Z")] -#[case("2000-01-01T60:60Z")] -#[case("2000-01-0108:00Z")] -#[case("2000-01-01T08Z")] -#[case("2000-01-01T24:01")] -#[case("2000-01-01T24:00:01")] -#[case("2000-01-01T24:00:00.001")] -#[case("2000-01-01T24:00:00.999Z")] -#[case("May 25 2008 1:30 (PM)) UTC")] -#[case("May 25 2008 1:30( )AM (PM)")] -#[case("a1")] -#[case("nasfdjklsfjoaifg1")] -#[case("x_2")] -#[case("May 25 2008 AAA (GMT)")] -fn test_date_invalid(#[case] input: &str) { - let ctx = Context::new().unwrap(); - let res = ctx - .eval(&format!(r#"new Date("{input}").getTime()"#)) - .unwrap(); - - let n: f64 = res.try_into().unwrap(); - assert!(n.is_nan(), "got: {n}"); -} - -#[test] -fn test_date_ut() { - let test_cases_ut = vec![ - "Sat, 01-Jan-2000 08:00:00 UT", - "Sat, 01 Jan 2000 08:00:00 UT", - "Jan 01 2000 08:00:00 UT", - "Jan 01 08:00:00 UT 2000", - "Saturday, 01-Jan-00 08:00:00 UT", - "01 Jan 00 08:00 +0000", - // Ignore weekdays. - "Mon, 01 Jan 2000 08:00:00 UT", - "Tue, 01 Jan 2000 08:00:00 UT", - // Ignore prefix that is not part of a date. - "[Saturday] Jan 01 08:00:00 UT 2000", - "Ignore all of this stuff because it is annoying 01 Jan 2000 08:00:00 UT", - "[Saturday] Jan 01 2000 08:00:00 UT", - "All of this stuff is really annnoying, so it will be ignored Jan 01 2000 08:00:00 UT", - // If the three first letters of the month is a - // month name we are happy - ignore the rest. - "Sat, 01-Janisamonth-2000 08:00:00 UT", - "Sat, 01 Janisamonth 2000 08:00:00 UT", - "Janisamonth 01 2000 08:00:00 UT", - "Janisamonth 01 08:00:00 UT 2000", - "Saturday, 01-Janisamonth-00 08:00:00 UT", - "01 Janisamonth 00 08:00 +0000", - // Allow missing space between month and day. - "Janisamonthandtherestisignored01 2000 08:00:00 UT", - "Jan01 2000 08:00:00 UT", - // Allow year/month/day format. - "Sat, 2000/01/01 08:00:00 UT", - // Allow month/day/year format. - "Sat, 01/01/2000 08:00:00 UT", - // Allow month/day year format. - "Sat, 01/01 2000 08:00:00 UT", - // Allow comma instead of space after day, month and year. - "Sat, 01,Jan,2000,08:00:00 UT", - // Seconds are optional. - "Sat, 01-Jan-2000 08:00 UT", - "Sat, 01 Jan 2000 08:00 UT", - "Jan 01 2000 08:00 UT", - "Jan 01 08:00 UT 2000", - "Saturday, 01-Jan-00 08:00 UT", - "01 Jan 00 08:00 +0000", - // Allow AM/PM after the time. - "Sat, 01-Jan-2000 08:00 AM UT", - "Sat, 01 Jan 2000 08:00 AM UT", - "Jan 01 2000 08:00 AM UT", - "Jan 01 08:00 AM UT 2000", - "Saturday, 01-Jan-00 08:00 AM UT", - "01 Jan 00 08:00 AM +0000", - // White space and stuff in parenthesis is - // apparently allowed in most places where white - // space is allowed. - " Sat, 01-Jan-2000 08:00:00 UT ", - " Sat, 01 Jan 2000 08:00:00 UT ", - " Saturday, 01-Jan-00 08:00:00 UT ", - " 01 Jan 00 08:00 +0000 ", - " ()(Sat, 01-Jan-2000) Sat, 01-Jan-2000 08:00:00 UT ", - " Sat()(Sat, 01-Jan-2000)01 Jan 2000 08:00:00 UT ", - " Sat,(02)01 Jan 2000 08:00:00 UT ", - " Sat, 01(02)Jan 2000 08:00:00 UT ", - " Sat, 01 Jan 2000 (2001)08:00:00 UT ", - " Sat, 01 Jan 2000 (01)08:00:00 UT ", - " Sat, 01 Jan 2000 (01:00:00)08:00:00 UT ", - " Sat, 01 Jan 2000 08:00:00 (CDT)UT ", - " Sat, 01 Jan 2000 08:00:00 UT((((CDT))))", - " Saturday, 01-Jan-00 ()(((asfd)))(Sat, 01-Jan-2000)08:00:00 UT ", - " 01 Jan 00 08:00 ()(((asdf)))(Sat, 01-Jan-2000)+0000 ", - " 01 Jan 00 08:00 +0000()((asfd)(Sat, 01-Jan-2000)) ", - ]; - - let mut passed = 0; - let mut failed = 0; - - for case in test_cases_ut { - let ctx = Context::new().unwrap(); - let res = ctx - .eval(&format!(r#"new Date("{case}").getTime()"#)) - .unwrap(); - let n: f64 = res.try_into().unwrap(); - - if n == 946713600000.0 { - passed += 1; - } else { - println!("FAIL: `{case}` - {n}"); - failed += 1; - } + assert_eq!( + *m, + vec![ + (Level::Log, vec![JsValue::from("hi")]), + (Level::Error, vec![JsValue::from(false)]), + ] + ); } - println!("{}/{} Passed", passed, passed + failed); - assert_eq!(failed, 0); -} + #[test] + fn test_global_setter() { + let ctx = Context::new().unwrap(); + ctx.set_global("a", "a").unwrap(); + ctx.eval("a + 1").unwrap(); + } -#[test] -// Test if the JS interpreter can parse its own date format -// (Dates from 1970 to ~2070 with 150h steps.) -fn test_date_selfparse() { - let ctx = Context::new().unwrap(); - let res = ctx - .eval( - r#" + // Test suite was taken from V8 + // Source: https://github.com/v8/v8/blob/9433ad119aadfe10d60935029195c31f25ab8624/test/mjsunit/date-parse.js + + #[rstest] + // testCasesES5Misc + #[case("2000-01-01T08:00:00.000Z", 946713600000)] + #[case("2000-01-01T08:00:00Z", 946713600000)] + #[case("2000-01-01T08:00Z", 946713600000)] + #[case("2000-01T08:00:00.000Z", 946713600000)] + #[case("2000T08:00:00.000Z", 946713600000)] + #[case("2000T08:00Z", 946713600000)] + #[case("2000-01T00:00:00.000-08:00", 946713600000)] + #[case("2000-01T08:00:00.001Z", 946713600001)] + #[case("2000-01T08:00:00.099Z", 946713600099)] + #[case("2000-01T08:00:00.999Z", 946713600999)] + #[case("2000-01T00:00:00.001-08:00", 946713600001)] + #[case("2000-01-01T24:00Z", 946771200000)] + #[case("2000-01-01T24:00:00Z", 946771200000)] + #[case("2000-01-01T24:00:00.000Z", 946771200000)] + fn test_date_iso(#[case] input: &str, #[case] expect: i64) { + let ctx = Context::new().unwrap(); + let res = ctx + .eval(&format!(r#"new Date("{input}").getTime()"#)) + .unwrap(); + + let n: f64 = res.try_into().unwrap(); + assert_eq!(n, expect as f64); + } + + #[rstest] + #[case("Sat, 01-Jan-2000 08:00:00 GMT", 946713600000)] + #[case("Sat, 01-Jan-2000 08:00:00 GMT+0", 946713600000)] + #[case("Sat, 01-Jan-2000 08:00:00 GMT+00", 946713600000)] + #[case("Sat, 01-Jan-2000 08:00:00 GMT+000", 946713600000)] + #[case("Sat, 01-Jan-2000 08:00:00 GMT+0000", 946713600000)] + #[case("Sat, 01-Jan-2000 08:00:00 GMT+00:00", 946713600000)] + #[case("Sat, 01 Jan 2000 08:00:00 GMT", 946713600000)] + #[case("Saturday, 01-Jan-00 08:00:00 GMT", 946713600000)] + #[case("01 Jan 00 08:00 -0000", 946713600000)] + #[case("01 Jan 00 08:00 +0000", 946713600000)] + fn test_date_gmt(#[case] input: &str, #[case] expect: i64) { + let ctx = Context::new().unwrap(); + let res = ctx + .eval(&format!(r#"new Date("{input}").getTime()"#)) + .unwrap(); + + let n: f64 = res.try_into().unwrap(); + assert_eq!(n, expect as f64); + } + + #[rstest] + // EST (-5:00) + #[case("Sat, 01-Jan-2000 03:00:00 UTC-0500", 946713600000)] + #[case("Sat, 01-Jan-2000 03:00:00 UTC-05:00", 946713600000)] + #[case("Sat, 01-Jan-2000 03:00:00 EST", 946713600000)] + #[case("Sat, 01 Jan 2000 03:00:00 EST", 946713600000)] + #[case("Saturday, 01-Jan-00 03:00:00 EST", 946713600000)] + #[case("01 Jan 00 03:00 -0500", 946713600000)] + // EDT (-4:00) + #[case("Sat, 01-Jan-2000 04:00:00 EDT", 946713600000)] + #[case("Sat, 01 Jan 2000 04:00:00 EDT", 946713600000)] + #[case("Saturday, 01-Jan-00 04:00:00 EDT", 946713600000)] + #[case("01 Jan 00 04:00 -0400", 946713600000)] + // CST (-6:00) + #[case("Sat, 01-Jan-2000 02:00:00 CST", 946713600000)] + #[case("Sat, 01 Jan 2000 02:00:00 CST", 946713600000)] + #[case("Saturday, 01-Jan-00 02:00:00 CST", 946713600000)] + #[case("01 Jan 00 02:00 -0600", 946713600000)] + // CDT (-5:00) + #[case("Sat, 01-Jan-2000 03:00:00 CDT", 946713600000)] + #[case("Sat, 01 Jan 2000 03:00:00 CDT", 946713600000)] + #[case("Saturday, 01-Jan-00 03:00:00 CDT", 946713600000)] + #[case("01 Jan 00 03:00 -0500", 946713600000)] + // MST (-7:00) + #[case("Sat, 01-Jan-2000 01:00:00 MST", 946713600000)] + #[case("Sat, 01 Jan 2000 01:00:00 MST", 946713600000)] + #[case("Saturday, 01-Jan-00 01:00:00 MST", 946713600000)] + #[case("01 Jan 00 01:00 -0700", 946713600000)] + // MDT (-6:00) + #[case("Sat, 01-Jan-2000 02:00:00 MDT", 946713600000)] + #[case("Sat, 01 Jan 2000 02:00:00 MDT", 946713600000)] + #[case("Saturday, 01-Jan-00 02:00:00 MDT", 946713600000)] + #[case("01 Jan 00 02:00 -0600", 946713600000)] + // PST (-8:00) + #[case("Sat, 01-Jan-2000 00:00:00 PST", 946713600000)] + #[case("Sat, 01 Jan 2000 00:00:00 PST", 946713600000)] + #[case("Saturday, 01-Jan-00 00:00:00 PST", 946713600000)] + #[case("01 Jan 00 00:00 -0800", 946713600000)] + #[case("Sat, 01-Jan-2000 PST", 946713600000)] + // PDT (-7:00) + #[case("Sat, 01-Jan-2000 01:00:00 PDT", 946713600000)] + #[case("Sat, 01 Jan 2000 01:00:00 PDT", 946713600000)] + #[case("Saturday, 01-Jan-00 01:00:00 PDT", 946713600000)] + #[case("01 Jan 00 01:00 -0700", 946713600000)] + fn test_date_tz(#[case] input: &str, #[case] expect: i64) { + let ctx = Context::new().unwrap(); + let res = ctx + .eval(&format!(r#"new Date("{input}").getTime()"#)) + .unwrap(); + + let n: f64 = res.try_into().unwrap(); + assert_eq!(n, expect as f64); + } + + #[rstest] + // Special handling for years in the [0, 100) range. + #[case("Sat, 01 Jan 0 08:00:00 UT", 946713600000)] // year 2000 + #[case("Sat, 01 Jan 49 08:00:00 UT", 2493100800000)] // year 2049 + #[case("Sat, 01 Jan 50 08:00:00 UT", -631123200000)] // year 1950 + #[case("Sat, 01 Jan 99 08:00:00 UT", 915177600000)] // year 1999 + #[case("Sat, 01 Jan 100 08:00:00 UT", -59011430400000)] // year 100 + // Test PM after time. + #[case("Sat, 01-Jan-2000 08:00 PM UT", 946756800000)] + #[case("Sat, 01 Jan 2000 08:00 PM UT", 946756800000)] + #[case("Jan 01 2000 08:00 PM UT", 946756800000)] + #[case("Jan 01 08:00 PM UT 2000", 946756800000)] + #[case("Saturday, 01-Jan-00 08:00 PM UT", 946756800000)] + #[case("01 Jan 00 08:00 PM +0000", 946756800000)] + fn test_date_special(#[case] input: &str, #[case] expect: i64) { + let ctx = Context::new().unwrap(); + let res = ctx + .eval(&format!(r#"new Date("{input}").getTime()"#)) + .unwrap(); + + let n: f64 = res.try_into().unwrap(); + assert_eq!(n, expect as f64); + } + + #[rstest] + #[case("2000-01-01TZ")] + #[case("2000-01-01T60Z")] + #[case("2000-01-01T60:60Z")] + #[case("2000-01-0108:00Z")] + #[case("2000-01-01T08Z")] + #[case("2000-01-01T24:01")] + #[case("2000-01-01T24:00:01")] + #[case("2000-01-01T24:00:00.001")] + #[case("2000-01-01T24:00:00.999Z")] + #[case("May 25 2008 1:30 (PM)) UTC")] + #[case("May 25 2008 1:30( )AM (PM)")] + #[case("a1")] + #[case("nasfdjklsfjoaifg1")] + #[case("x_2")] + #[case("May 25 2008 AAA (GMT)")] + fn test_date_invalid(#[case] input: &str) { + let ctx = Context::new().unwrap(); + let res = ctx + .eval(&format!(r#"new Date("{input}").getTime()"#)) + .unwrap(); + + let n: f64 = res.try_into().unwrap(); + assert!(n.is_nan(), "got: {n}"); + } + + #[test] + fn test_date_ut() { + let test_cases_ut = vec![ + "Sat, 01-Jan-2000 08:00:00 UT", + "Sat, 01 Jan 2000 08:00:00 UT", + "Jan 01 2000 08:00:00 UT", + "Jan 01 08:00:00 UT 2000", + "Saturday, 01-Jan-00 08:00:00 UT", + "01 Jan 00 08:00 +0000", + // Ignore weekdays. + "Mon, 01 Jan 2000 08:00:00 UT", + "Tue, 01 Jan 2000 08:00:00 UT", + // Ignore prefix that is not part of a date. + "[Saturday] Jan 01 08:00:00 UT 2000", + "Ignore all of this stuff because it is annoying 01 Jan 2000 08:00:00 UT", + "[Saturday] Jan 01 2000 08:00:00 UT", + "All of this stuff is really annnoying, so it will be ignored Jan 01 2000 08:00:00 UT", + // If the three first letters of the month is a + // month name we are happy - ignore the rest. + "Sat, 01-Janisamonth-2000 08:00:00 UT", + "Sat, 01 Janisamonth 2000 08:00:00 UT", + "Janisamonth 01 2000 08:00:00 UT", + "Janisamonth 01 08:00:00 UT 2000", + "Saturday, 01-Janisamonth-00 08:00:00 UT", + "01 Janisamonth 00 08:00 +0000", + // Allow missing space between month and day. + "Janisamonthandtherestisignored01 2000 08:00:00 UT", + "Jan01 2000 08:00:00 UT", + // Allow year/month/day format. + "Sat, 2000/01/01 08:00:00 UT", + // Allow month/day/year format. + "Sat, 01/01/2000 08:00:00 UT", + // Allow month/day year format. + "Sat, 01/01 2000 08:00:00 UT", + // Allow comma instead of space after day, month and year. + "Sat, 01,Jan,2000,08:00:00 UT", + // Seconds are optional. + "Sat, 01-Jan-2000 08:00 UT", + "Sat, 01 Jan 2000 08:00 UT", + "Jan 01 2000 08:00 UT", + "Jan 01 08:00 UT 2000", + "Saturday, 01-Jan-00 08:00 UT", + "01 Jan 00 08:00 +0000", + // Allow AM/PM after the time. + "Sat, 01-Jan-2000 08:00 AM UT", + "Sat, 01 Jan 2000 08:00 AM UT", + "Jan 01 2000 08:00 AM UT", + "Jan 01 08:00 AM UT 2000", + "Saturday, 01-Jan-00 08:00 AM UT", + "01 Jan 00 08:00 AM +0000", + // White space and stuff in parenthesis is + // apparently allowed in most places where white + // space is allowed. + " Sat, 01-Jan-2000 08:00:00 UT ", + " Sat, 01 Jan 2000 08:00:00 UT ", + " Saturday, 01-Jan-00 08:00:00 UT ", + " 01 Jan 00 08:00 +0000 ", + " ()(Sat, 01-Jan-2000) Sat, 01-Jan-2000 08:00:00 UT ", + " Sat()(Sat, 01-Jan-2000)01 Jan 2000 08:00:00 UT ", + " Sat,(02)01 Jan 2000 08:00:00 UT ", + " Sat, 01(02)Jan 2000 08:00:00 UT ", + " Sat, 01 Jan 2000 (2001)08:00:00 UT ", + " Sat, 01 Jan 2000 (01)08:00:00 UT ", + " Sat, 01 Jan 2000 (01:00:00)08:00:00 UT ", + " Sat, 01 Jan 2000 08:00:00 (CDT)UT ", + " Sat, 01 Jan 2000 08:00:00 UT((((CDT))))", + " Saturday, 01-Jan-00 ()(((asfd)))(Sat, 01-Jan-2000)08:00:00 UT ", + " 01 Jan 00 08:00 ()(((asdf)))(Sat, 01-Jan-2000)+0000 ", + " 01 Jan 00 08:00 +0000()((asfd)(Sat, 01-Jan-2000)) ", + ]; + + let mut passed = 0; + let mut failed = 0; + + for case in test_cases_ut { + let ctx = Context::new().unwrap(); + let res = ctx + .eval(&format!(r#"new Date("{case}").getTime()"#)) + .unwrap(); + let n: f64 = res.try_into().unwrap(); + + if n == 946713600000.0 { + passed += 1; + } else { + println!("FAIL: `{case}` - {n}"); + failed += 1; + } + } + + println!("{}/{} Passed", passed, passed + failed); + assert_eq!(failed, 0); + } + + #[test] + // Test if the JS interpreter can parse its own date format + // (Dates from 1970 to ~2070 with 150h steps.) + fn test_date_selfparse() { + let ctx = Context::new().unwrap(); + let res = ctx + .eval( + r#" test = () => { for (var i = 0; i < 24 * 365 * 100; i += 150) { var ms = i * (3600 * 1000); @@ -886,8 +890,9 @@ fn test_date_selfparse() { } test(); "#, - ) - .unwrap(); - let res: bool = res.try_into().unwrap(); - assert!(res); + ) + .unwrap(); + let res: bool = res.try_into().unwrap(); + assert!(res); + } } From ca9956fcf188584c85c0f221155e2563b76734fc Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Sun, 5 Feb 2023 22:18:25 +0100 Subject: [PATCH 07/16] rename crates --- CHANGELOG.md | 2 ++ Cargo.toml | 20 +++++++++++--------- libquickjs-sys/Cargo.toml | 16 +++++++++------- libquickjs-sys/build.rs | 6 +++--- libquickjs-sys/release.toml | 2 +- release.toml | 2 +- 6 files changed, 27 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cb3dd4b..5c54e87 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Master branch +## v0.4.1 - 2023-02-05 + * Fixed use after free in `set_global` [#105](https://github.com/theduke/quickjs-rs/issues/105) * `add_callback` can now take `JsValue` arguments [#109](https://github.com/theduke/quickjs-rs/issues/109) * Enable chrono feature by default diff --git a/Cargo.toml b/Cargo.toml index b3d233d..2812282 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,26 +1,28 @@ [package] edition = "2021" -name = "quick-js" +name = "quick-js-dtp" description = "QuickJS Javascript engine wrapper" -version = "0.4.2-alpha.0" +version = "0.4.1" readme = "README.md" -documentation = "https://docs.rs/quick-js" -repository = "https://github.com/theduke/quickjs-rs" +repository = "https://github.com/Theta-Dev/quickjs-rs" license = "MIT" -authors = ["Christoph Herzog "] +authors = ["Christoph Herzog ", "ThetaDev "] keywords = ["quickjs", "javascript", "js", "engine", "interpreter"] +[lib] +name = "quick_js" + [package.metadata.docs.rs] features = [ "chrono", "bigint", "log" ] [features] default = ["chrono"] -patch_bigint = ["libquickjs-sys/patch_bigint"] -patch_dateparser = ["libquickjs-sys/patch_dateparser"] -bigint = ["num-bigint", "num-traits", "libquickjs-sys/patch_bigint"] +patch-bigint = ["libquickjs-dtp-sys/patch-bigint"] +patch-dateparser = ["libquickjs-dtp-sys/patch-dateparser"] +bigint = ["num-bigint", "num-traits", "libquickjs-dtp-sys/patch-bigint"] [dependencies] -libquickjs-sys = { version = ">= 0.9.0, < 0.10.0", path = "./libquickjs-sys" } +libquickjs-dtp-sys = { version = ">= 0.9.0, < 0.10.0", path = "./libquickjs-sys" } chrono = { version = "0.4.7", optional = true } num-bigint = { version = "0.4.0", optional = true } num-traits = { version = "0.2.0", optional = true } diff --git a/libquickjs-sys/Cargo.toml b/libquickjs-sys/Cargo.toml index 9e69eb5..7403069 100644 --- a/libquickjs-sys/Cargo.toml +++ b/libquickjs-sys/Cargo.toml @@ -1,22 +1,24 @@ [package] edition = "2021" -name = "libquickjs-sys" -description = "QuickJS Javascript Engine FFI bindings" +name = "libquickjs-dtp-sys" +description = "QuickJS Javascript Engine FFI bindings (with patched date parser)" version = "0.9.0" readme = "README.md" -documentation = "https://docs.rs/quickjs-sys" -repository = "https://github.com/theduke/quickjs-rs" +repository = "https://github.com/Theta-Dev/quickjs-rs" license = "MIT" -authors = ["Christoph Herzog "] +authors = ["Christoph Herzog ", "ThetaDev "] categories = ["external-ffi-bindings"] keywords = ["quickjs"] build = "build.rs" +[lib] +name = "libquickjs_sys" + [features] bundled = ["cc", "copy_dir"] -patch_bigint = ["bundled"] -patch_dateparser = ["bundled"] +patch-bigint = ["bundled"] +patch-dateparser = ["bundled"] default = ["bundled"] system = ["bindgen"] diff --git a/libquickjs-sys/build.rs b/libquickjs-sys/build.rs index cacd4d5..06a7fd2 100644 --- a/libquickjs-sys/build.rs +++ b/libquickjs-sys/build.rs @@ -55,10 +55,10 @@ fn main() { copy_dir::copy_dir(embed_path.join("quickjs"), &code_dir) .expect("Could not copy quickjs directory"); - #[cfg(feature = "patch_bigint")] + #[cfg(feature = "patch-bigint")] apply_patch(&code_dir, "js-tobigint64-overflow.patch"); - #[cfg(feature = "patch_dateparser")] + #[cfg(feature = "patch-dateparser")] apply_patch(&code_dir, "dateparser.patch"); std::fs::copy( @@ -118,7 +118,7 @@ fn main() { .expect("Could not copy bindings.rs"); } -#[cfg(any(feature = "patch_bigint", feature = "patch_dateparser"))] +#[cfg(any(feature = "patch-bigint", feature = "patch-dateparser"))] fn apply_patch(code_dir: &PathBuf, name: &str) { eprintln!("Applying {name}"); let patch_path = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()) diff --git a/libquickjs-sys/release.toml b/libquickjs-sys/release.toml index 3e00314..70a91e5 100644 --- a/libquickjs-sys/release.toml +++ b/libquickjs-sys/release.toml @@ -1,3 +1,3 @@ # Configuration for the [cargo-release](https://github.com/sunng87/cargo-release) tool. -tag-prefix = "libquickjs-sys-" +tag-prefix = "libquickjs-dtp-sys-" diff --git a/release.toml b/release.toml index eec9cfe..95b720b 100644 --- a/release.toml +++ b/release.toml @@ -4,4 +4,4 @@ pre-release-replacements = [ {file="README.md", search="quick-js = .*", replace="{{crate_name}} = \"{{version}}\""}, ] -tag-prefix = "quick-js-" +tag-prefix = "quick-js-dtp-" From 77e93c66fa431f89bbd03f793d4ca827dcc6be8e Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Sun, 5 Feb 2023 22:34:56 +0100 Subject: [PATCH 08/16] update README --- README.md | 12 ++++++++---- libquickjs-sys/README.md | 8 ++++++-- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 04b4f7e..c591405 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ -# quickjs-rs +# quick-js-dtp -[![Crates.io](https://img.shields.io/crates/v/quick-js.svg?maxAge=3600)](https://crates.io/crates/quick-js) -[![docs.rs](https://docs.rs/quick-js/badge.svg)](https://docs.rs/quick-js) -[![Build Status](https://github.com/theduke/quickjs-rs/workflows/CI/badge.svg) +[![Crates.io](https://img.shields.io/crates/v/quick-js-dtp.svg?maxAge=3600)](https://crates.io/crates/quick-js-dtp) +[![docs.rs](https://docs.rs/quick-js-dtp/badge.svg)](https://docs.rs/quick-js-dtp) +[![CI](https://github.com/Theta-Dev/quickjs-rs/actions/workflows/main.yml/badge.svg)](https://github.com/Theta-Dev/quickjs-rs/actions/workflows/main.yml) A Rust wrapper for [QuickJS](https://bellard.org/quickjs/). @@ -11,6 +11,10 @@ It is fast and supports the full ES2020 specification. This crate allows you to easily run and integrate with Javascript code from Rust. +This is a fork of the original [quick-js](https://crates.io/crates/quick-js) +crate which includes a fully featured date parser, capable of parsing dates like +`Sat, 01-Jan-2000 00:00:00 PST`. + ## Quickstart ```toml diff --git a/libquickjs-sys/README.md b/libquickjs-sys/README.md index 405f3a3..82067d3 100644 --- a/libquickjs-sys/README.md +++ b/libquickjs-sys/README.md @@ -1,8 +1,12 @@ -# libquickjs-sys +# libquickjs-dtp-sys FFI Bindings for [quickjs](https://bellard.org/quickjs/), a Javascript engine. -See the [quick](https://crates.io/crates/quickjs) crate for a high-level +This is a fork of the original [libquickjs-sys](https://crates.io/crates/libquickjs-sys) +crate which includes a fully featured date parser, capable of parsing dates like +`Sat, 01-Jan-2000 00:00:00 PST`. + +See the [quick-js-dtp](https://crates.io/crates/quick-js-dtp) crate for a high-level wrapper. From 097f416516ce1345f01155f1b448168c3c712cbc Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Sun, 5 Feb 2023 22:37:18 +0100 Subject: [PATCH 09/16] update crate description --- Cargo.toml | 2 +- libquickjs-sys/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 2812282..2d8c150 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] edition = "2021" name = "quick-js-dtp" -description = "QuickJS Javascript engine wrapper" +description = "QuickJS Javascript engine wrapper (with improved date parser)" version = "0.4.1" readme = "README.md" repository = "https://github.com/Theta-Dev/quickjs-rs" diff --git a/libquickjs-sys/Cargo.toml b/libquickjs-sys/Cargo.toml index 7403069..839159b 100644 --- a/libquickjs-sys/Cargo.toml +++ b/libquickjs-sys/Cargo.toml @@ -1,7 +1,7 @@ [package] edition = "2021" name = "libquickjs-dtp-sys" -description = "QuickJS Javascript Engine FFI bindings (with patched date parser)" +description = "QuickJS Javascript Engine FFI bindings (with improved date parser)" version = "0.9.0" readme = "README.md" repository = "https://github.com/Theta-Dev/quickjs-rs" From a702c33c57910ee06d0f4c9c3965b4925df69aa4 Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Sun, 5 Feb 2023 22:49:49 +0100 Subject: [PATCH 10/16] fix: warnings from deprecated chrono fn --- src/bindings/convert.rs | 23 +++++++++++++---------- src/tests.rs | 2 +- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/bindings/convert.rs b/src/bindings/convert.rs index 7f7efc6..9f04419 100644 --- a/src/bindings/convert.rs +++ b/src/bindings/convert.rs @@ -451,20 +451,23 @@ pub(super) fn deserialize_value( q::JS_FreeValue(context, date_constructor); }; - let res = if timestamp_raw.tag == TAG_FLOAT64 { - let f = unsafe { timestamp_raw.u.float64 } as i64; - let datetime = chrono::Utc.timestamp_millis(f); - Ok(JsValue::Date(datetime)) + let timestamp_ms = if timestamp_raw.tag == TAG_FLOAT64 { + (unsafe { timestamp_raw.u.float64 } as i64) } else if timestamp_raw.tag == TAG_INT { - let f = unsafe { timestamp_raw.u.int32 } as i64; - let datetime = chrono::Utc.timestamp_millis(f); - Ok(JsValue::Date(datetime)) + (unsafe { timestamp_raw.u.int32 } as i64) } else { - Err(ValueError::Internal( + return Err(ValueError::Internal( "Could not convert 'Date' instance to timestamp".into(), - )) + )); }; - return res; + + return chrono::Utc + .timestamp_millis_opt(timestamp_ms) + .single() + .map(|dt| JsValue::Date(dt)) + .ok_or(ValueError::Internal( + "Could not convert 'Date' instance to timestamp".into(), + )); } else { unsafe { q::JS_FreeValue(context, date_constructor) }; } diff --git a/src/tests.rs b/src/tests.rs index 41eb286..4885898 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -494,7 +494,7 @@ fn chrono_deserialize() { let c = build_context(); let value = c.eval(" new Date(1234567555) ").unwrap(); - let datetime = chrono::Utc.timestamp_millis(1234567555); + let datetime = chrono::Utc.timestamp_millis_opt(1234567555).unwrap(); assert_eq!(value, JsValue::Date(datetime)); } From bc638cb114f00be07b74baea60c3e4c907b1421a Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Sun, 5 Feb 2023 23:00:18 +0100 Subject: [PATCH 11/16] add documentation for `patch-dateparser` feature [skip ci] --- README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c591405..5afcbc1 100644 --- a/README.md +++ b/README.md @@ -55,10 +55,13 @@ The crate supports the following features: * `log`: allows forwarding `console.log` messages to the `log` crate. Note: must be enabled with `ContextBuilder::console(quick_js::console::LogConsole);` -* `patched` +* `patch-bigint` Enabled automatically for some other features, like `bigint`. You should not need to enable this manually. - Applies QuickJS patches that can be found in `libquickjs-sys/embed/patches` directory. + +* `patch-dateparser` + Enables the improved JS date parser that supports additional date formats like + `Sat, 01-Jan-2000 00:00:00 PST` ## Installation From f6c341e67f3aaca6c43db29a0c5bb43003f43cee Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Sun, 5 Feb 2023 23:05:16 +0100 Subject: [PATCH 12/16] fix cargo-release replacements --- README.md | 2 +- release.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5afcbc1..6d088f4 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ crate which includes a fully featured date parser, capable of parsing dates like ```toml [dependencies] -quick-js = "0.4.1" +quick-js-dtp = "0.4.1" ``` ```rust diff --git a/release.toml b/release.toml index 95b720b..86d7edd 100644 --- a/release.toml +++ b/release.toml @@ -1,7 +1,7 @@ # Configuration for the [cargo-release](https://github.com/sunng87/cargo-release) tool. pre-release-replacements = [ - {file="README.md", search="quick-js = .*", replace="{{crate_name}} = \"{{version}}\""}, + {file="README.md", search="quick-js-dtp = .*", replace="{{crate_name}} = \"{{version}}\""}, ] tag-prefix = "quick-js-dtp-" From a9a6f559d41cbdec99bb67a8ace1f7175ebdc2c6 Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Sun, 5 Feb 2023 23:35:37 +0100 Subject: [PATCH 13/16] disable rstest default features --- Cargo.toml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 2d8c150..c3ae08b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,14 +6,17 @@ version = "0.4.1" readme = "README.md" repository = "https://github.com/Theta-Dev/quickjs-rs" license = "MIT" -authors = ["Christoph Herzog ", "ThetaDev "] +authors = [ + "Christoph Herzog ", + "ThetaDev ", +] keywords = ["quickjs", "javascript", "js", "engine", "interpreter"] [lib] name = "quick_js" [package.metadata.docs.rs] -features = [ "chrono", "bigint", "log" ] +features = ["chrono", "bigint", "log"] [features] default = ["chrono"] @@ -30,9 +33,7 @@ log = { version = "0.4.8", optional = true } once_cell = "1.2.0" [dev-dependencies] -rstest = "0.16.0" +rstest = { version = "0.16.0", default-features = false } [workspace] -members = [ - "libquickjs-sys", -] +members = ["libquickjs-sys"] From fb9644c07c64a0b9c00cbd6999b398d1d1a55e7a Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Sun, 5 Feb 2023 23:38:46 +0100 Subject: [PATCH 14/16] fix: clippy lints --- src/bindings/convert.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bindings/convert.rs b/src/bindings/convert.rs index 9f04419..5dbe1d8 100644 --- a/src/bindings/convert.rs +++ b/src/bindings/convert.rs @@ -464,7 +464,7 @@ pub(super) fn deserialize_value( return chrono::Utc .timestamp_millis_opt(timestamp_ms) .single() - .map(|dt| JsValue::Date(dt)) + .map(JsValue::Date) .ok_or(ValueError::Internal( "Could not convert 'Date' instance to timestamp".into(), )); From a3b3d3bc517c7801b1253986530c1f0fcfeda14c Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Sat, 23 Mar 2024 01:21:50 +0100 Subject: [PATCH 15/16] chore: update quickjs to 2024-01-13 --- CHANGELOG.md | 5 + Cargo.toml | 6 +- justfile | 2 +- libquickjs-sys/Cargo.toml | 4 +- libquickjs-sys/README.md | 4 +- libquickjs-sys/embed/bindings.rs | 18 +- libquickjs-sys/embed/quickjs/Changelog | 27 + libquickjs-sys/embed/quickjs/Makefile | 101 +- libquickjs-sys/embed/quickjs/TODO | 7 +- libquickjs-sys/embed/quickjs/VERSION | 2 +- libquickjs-sys/embed/quickjs/cutils.h | 3 + libquickjs-sys/embed/quickjs/libbf.c | 41 +- libquickjs-sys/embed/quickjs/libbf.h | 2 +- .../embed/quickjs/libregexp-opcode.h | 3 +- libquickjs-sys/embed/quickjs/libregexp.c | 193 +- libquickjs-sys/embed/quickjs/libregexp.h | 1 + .../embed/quickjs/libunicode-table.h | 4362 ++++++------- libquickjs-sys/embed/quickjs/libunicode.c | 386 +- libquickjs-sys/embed/quickjs/libunicode.h | 3 + libquickjs-sys/embed/quickjs/list.h | 3 +- libquickjs-sys/embed/quickjs/qjs.c | 23 +- libquickjs-sys/embed/quickjs/qjsc.c | 7 +- libquickjs-sys/embed/quickjs/quickjs-atom.h | 12 +- libquickjs-sys/embed/quickjs/quickjs-libc.c | 74 +- libquickjs-sys/embed/quickjs/quickjs-opcode.h | 13 +- libquickjs-sys/embed/quickjs/quickjs.c | 5638 +++++++++++------ libquickjs-sys/embed/quickjs/quickjs.h | 21 +- libquickjs-sys/embed/quickjs/unicode_gen.c | 204 +- .../embed/quickjs/unicode_gen_def.h | 7 + src/bindings/mod.rs | 1 + src/tests.rs | 2 +- 31 files changed, 6600 insertions(+), 4575 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c54e87..59857bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ## Master branch +## v0.4.2 - 2024-03-23 + +* Update to QuickJS `2024-01-13` +* Update dependencies + ## v0.4.1 - 2023-02-05 * Fixed use after free in `set_global` [#105](https://github.com/theduke/quickjs-rs/issues/105) diff --git a/Cargo.toml b/Cargo.toml index c3ae08b..90dac52 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ edition = "2021" name = "quick-js-dtp" description = "QuickJS Javascript engine wrapper (with improved date parser)" -version = "0.4.1" +version = "0.4.2" readme = "README.md" repository = "https://github.com/Theta-Dev/quickjs-rs" license = "MIT" @@ -25,7 +25,7 @@ patch-dateparser = ["libquickjs-dtp-sys/patch-dateparser"] bigint = ["num-bigint", "num-traits", "libquickjs-dtp-sys/patch-bigint"] [dependencies] -libquickjs-dtp-sys = { version = ">= 0.9.0, < 0.10.0", path = "./libquickjs-sys" } +libquickjs-dtp-sys = { version = "0.10.0", path = "./libquickjs-sys" } chrono = { version = "0.4.7", optional = true } num-bigint = { version = "0.4.0", optional = true } num-traits = { version = "0.2.0", optional = true } @@ -33,7 +33,7 @@ log = { version = "0.4.8", optional = true } once_cell = "1.2.0" [dev-dependencies] -rstest = { version = "0.16.0", default-features = false } +rstest = { version = "0.18.0", default-features = false } [workspace] members = ["libquickjs-sys"] diff --git a/justfile b/justfile index 5bcf226..4fa982a 100644 --- a/justfile +++ b/justfile @@ -1,6 +1,6 @@ embed_dir := "./libquickjs-sys/embed/quickjs" -DOWNLOAD_URL := "https://bellard.org/quickjs/quickjs-2021-03-27.tar.xz" +DOWNLOAD_URL := "https://bellard.org/quickjs/quickjs-2024-01-13.tar.xz" FEATURES := "--all-features" download-new: diff --git a/libquickjs-sys/Cargo.toml b/libquickjs-sys/Cargo.toml index 839159b..4af8896 100644 --- a/libquickjs-sys/Cargo.toml +++ b/libquickjs-sys/Cargo.toml @@ -2,7 +2,7 @@ edition = "2021" name = "libquickjs-dtp-sys" description = "QuickJS Javascript Engine FFI bindings (with improved date parser)" -version = "0.9.0" +version = "0.10.0" readme = "README.md" repository = "https://github.com/Theta-Dev/quickjs-rs" license = "MIT" @@ -24,6 +24,6 @@ default = ["bundled"] system = ["bindgen"] [build-dependencies] -bindgen = { version = "0.63.0", optional = true } +bindgen = { version = "0.69.0", optional = true } cc = { version = "1.0.66", optional = true } copy_dir = { version = "0.1.2", optional = true } diff --git a/libquickjs-sys/README.md b/libquickjs-sys/README.md index 82067d3..cc0a1f0 100644 --- a/libquickjs-sys/README.md +++ b/libquickjs-sys/README.md @@ -10,8 +10,8 @@ See the [quick-js-dtp](https://crates.io/crates/quick-js-dtp) crate for a high-l wrapper. -*Version 0.9.0* -**Embedded VERSION: 2021-03-27** +*Version 0.10.0* +**Embedded VERSION: 2024-01-13** ## Embedded vs system diff --git a/libquickjs-sys/embed/bindings.rs b/libquickjs-sys/embed/bindings.rs index 198dee4..8a14324 100644 --- a/libquickjs-sys/embed/bindings.rs +++ b/libquickjs-sys/embed/bindings.rs @@ -168,6 +168,7 @@ pub const JS_EVAL_FLAG_STRICT: u32 = 8; pub const JS_EVAL_FLAG_STRIP: u32 = 16; pub const JS_EVAL_FLAG_COMPILE_ONLY: u32 = 32; pub const JS_EVAL_FLAG_BACKTRACE_BARRIER: u32 = 64; +pub const JS_EVAL_FLAG_ASYNC: u32 = 128; pub const JS_ATOM_NULL: u32 = 0; pub const JS_CALL_FLAG_CONSTRUCTOR: u32 = 1; pub const JS_GPN_STRING_MASK: u32 = 1; @@ -2678,9 +2679,10 @@ extern "C" { extern "C" { pub fn JS_SetPropertyInternal( ctx: *mut JSContext, - this_obj: JSValue, + obj: JSValue, prop: JSAtom, val: JSValue, + this_obj: JSValue, flags: ::std::os::raw::c_int, ) -> ::std::os::raw::c_int; } @@ -3026,9 +3028,19 @@ extern "C" { sf: *const JSSharedArrayBufferFunctions, ); } +pub const JSPromiseStateEnum_JS_PROMISE_PENDING: JSPromiseStateEnum = 0; +pub const JSPromiseStateEnum_JS_PROMISE_FULFILLED: JSPromiseStateEnum = 1; +pub const JSPromiseStateEnum_JS_PROMISE_REJECTED: JSPromiseStateEnum = 2; +pub type JSPromiseStateEnum = ::std::os::raw::c_uint; extern "C" { pub fn JS_NewPromiseCapability(ctx: *mut JSContext, resolving_funcs: *mut JSValue) -> JSValue; } +extern "C" { + pub fn JS_PromiseState(ctx: *mut JSContext, promise: JSValue) -> JSPromiseStateEnum; +} +extern "C" { + pub fn JS_PromiseResult(ctx: *mut JSContext, promise: JSValue) -> JSValue; +} pub type JSHostPromiseRejectionTracker = ::std::option::Option< unsafe extern "C" fn( ctx: *mut JSContext, @@ -3161,11 +3173,11 @@ extern "C" { ) -> JSAtom; } extern "C" { - pub fn JS_RunModule( + pub fn JS_LoadModule( ctx: *mut JSContext, basename: *const ::std::os::raw::c_char, filename: *const ::std::os::raw::c_char, - ) -> *mut JSModuleDef; + ) -> JSValue; } pub const JSCFunctionEnum_JS_CFUNC_generic: JSCFunctionEnum = 0; pub const JSCFunctionEnum_JS_CFUNC_generic_magic: JSCFunctionEnum = 1; diff --git a/libquickjs-sys/embed/quickjs/Changelog b/libquickjs-sys/embed/quickjs/Changelog index c09af91..944d96a 100644 --- a/libquickjs-sys/embed/quickjs/Changelog +++ b/libquickjs-sys/embed/quickjs/Changelog @@ -1,3 +1,30 @@ +2024-01-13: + +- top-level-await support in modules +- allow 'await' in the REPL +- added Array.prototype.{with,toReversed,toSpliced,toSorted} and +TypedArray.prototype.{with,toReversed,toSorted} +- added String.prototype.isWellFormed and String.prototype.toWellFormed +- added Object.groupBy and Map.groupBy +- added Promise.withResolvers +- class static block +- 'in' operator support for private fields +- optional chaining fixes +- added RegExp 'd' flag +- fixed RegExp zero length match logic +- fixed RegExp case insensitive flag +- added os.getpid() and os.now() +- added cosmopolitan build +- misc bug fixes + +2023-12-09: + +- added Object.hasOwn, {String|Array|TypedArray}.prototype.at, + {Array|TypedArray}.prototype.findLast{Index} +- BigInt support is enabled even if CONFIG_BIGNUM disabled +- updated to Unicode 15.0.0 +- misc bug fixes + 2021-03-27: - faster Array.prototype.push and Array.prototype.unshift diff --git a/libquickjs-sys/embed/quickjs/Makefile b/libquickjs-sys/embed/quickjs/Makefile index 49b1f6f..57cdd7e 100644 --- a/libquickjs-sys/embed/quickjs/Makefile +++ b/libquickjs-sys/embed/quickjs/Makefile @@ -33,6 +33,20 @@ CONFIG_LTO=y #CONFIG_WERROR=y # force 32 bit build for some utilities #CONFIG_M32=y +# cosmopolitan build (see https://github.com/jart/cosmopolitan) +#CONFIG_COSMO=y + +# installation directory +PREFIX?=/usr/local + +# use the gprof profiler +#CONFIG_PROFILE=y +# use address sanitizer +#CONFIG_ASAN=y +# include the code for BigFloat/BigDecimal, math mode and faster large integers +CONFIG_BIGNUM=y + +OBJDIR=.obj ifdef CONFIG_DARWIN # use clang instead of gcc @@ -40,33 +54,22 @@ CONFIG_CLANG=y CONFIG_DEFAULT_AR=y endif -# installation directory -prefix=/usr/local - -# use the gprof profiler -#CONFIG_PROFILE=y -# use address sanitizer -#CONFIG_ASAN=y -# include the code for BigInt/BigFloat/BigDecimal and math mode -CONFIG_BIGNUM=y - -OBJDIR=.obj - ifdef CONFIG_WIN32 ifdef CONFIG_M32 - CROSS_PREFIX=i686-w64-mingw32- + CROSS_PREFIX?=i686-w64-mingw32- else - CROSS_PREFIX=x86_64-w64-mingw32- + CROSS_PREFIX?=x86_64-w64-mingw32- endif EXE=.exe else - CROSS_PREFIX= + CROSS_PREFIX?= EXE= endif + ifdef CONFIG_CLANG HOST_CC=clang CC=$(CROSS_PREFIX)clang - CFLAGS=-g -Wall -MMD -MF $(OBJDIR)/$(@F).d + CFLAGS+=-g -Wall -MMD -MF $(OBJDIR)/$(@F).d CFLAGS += -Wextra CFLAGS += -Wno-sign-compare CFLAGS += -Wno-missing-field-initializers @@ -84,10 +87,18 @@ ifdef CONFIG_CLANG AR=$(CROSS_PREFIX)ar endif endif +else ifdef CONFIG_COSMO + CONFIG_LTO= + HOST_CC=gcc + CC=cosmocc + # cosmocc does not correct support -MF + CFLAGS=-g -Wall #-MMD -MF $(OBJDIR)/$(@F).d + CFLAGS += -Wno-array-bounds -Wno-format-truncation + AR=cosmoar else HOST_CC=gcc CC=$(CROSS_PREFIX)gcc - CFLAGS=-g -Wall -MMD -MF $(OBJDIR)/$(@F).d + CFLAGS+=-g -Wall -MMD -MF $(OBJDIR)/$(@F).d CFLAGS += -Wno-array-bounds -Wno-format-truncation ifdef CONFIG_LTO AR=$(CROSS_PREFIX)gcc-ar @@ -96,6 +107,7 @@ else endif endif STRIP=$(CROSS_PREFIX)strip +CFLAGS+=-fwrapv # ensure that signed overflows behave as expected ifdef CONFIG_WERROR CFLAGS+=-Werror endif @@ -112,7 +124,11 @@ CFLAGS_DEBUG=$(CFLAGS) -O0 CFLAGS_SMALL=$(CFLAGS) -Os CFLAGS_OPT=$(CFLAGS) -O2 CFLAGS_NOLTO:=$(CFLAGS_OPT) -LDFLAGS=-g +ifdef CONFIG_COSMO +LDFLAGS+=-s # better to strip by default +else +LDFLAGS+=-g +endif ifdef CONFIG_LTO CFLAGS_SMALL+=-flto CFLAGS_OPT+=-flto @@ -132,6 +148,12 @@ else LDEXPORT=-rdynamic endif +ifndef CONFIG_COSMO +ifndef CONFIG_DARWIN +CONFIG_SHARED_LIBS=y # building shared libraries is supported +endif +endif + PROGS=qjs$(EXE) qjsc$(EXE) run-test262 ifneq ($(CROSS_PREFIX),) QJSC_CC=gcc @@ -154,23 +176,21 @@ endif # examples ifeq ($(CROSS_PREFIX),) -ifdef CONFIG_ASAN -PROGS+= -else -PROGS+=examples/hello examples/hello_module examples/test_fib -ifndef CONFIG_DARWIN -PROGS+=examples/fib.so examples/point.so +PROGS+=examples/hello +ifndef CONFIG_ASAN +PROGS+=examples/hello_module endif +ifdef CONFIG_SHARED_LIBS +PROGS+=examples/test_fib examples/fib.so examples/point.so endif endif all: $(OBJDIR) $(OBJDIR)/quickjs.check.o $(OBJDIR)/qjs.check.o $(PROGS) -QJS_LIB_OBJS=$(OBJDIR)/quickjs.o $(OBJDIR)/libregexp.o $(OBJDIR)/libunicode.o $(OBJDIR)/cutils.o $(OBJDIR)/quickjs-libc.o +QJS_LIB_OBJS=$(OBJDIR)/quickjs.o $(OBJDIR)/libregexp.o $(OBJDIR)/libunicode.o $(OBJDIR)/cutils.o $(OBJDIR)/quickjs-libc.o $(OBJDIR)/libbf.o QJS_OBJS=$(OBJDIR)/qjs.o $(OBJDIR)/repl.o $(QJS_LIB_OBJS) ifdef CONFIG_BIGNUM -QJS_LIB_OBJS+=$(OBJDIR)/libbf.o QJS_OBJS+=$(OBJDIR)/qjscalc.o endif @@ -201,11 +221,11 @@ $(QJSC): $(OBJDIR)/qjsc.host.o \ endif #CROSS_PREFIX -QJSC_DEFINES:=-DCONFIG_CC=\"$(QJSC_CC)\" -DCONFIG_PREFIX=\"$(prefix)\" +QJSC_DEFINES:=-DCONFIG_CC=\"$(QJSC_CC)\" -DCONFIG_PREFIX=\"$(PREFIX)\" ifdef CONFIG_LTO QJSC_DEFINES+=-DCONFIG_LTO endif -QJSC_HOST_DEFINES:=-DCONFIG_CC=\"$(HOST_CC)\" -DCONFIG_PREFIX=\"$(prefix)\" +QJSC_HOST_DEFINES:=-DCONFIG_CC=\"$(HOST_CC)\" -DCONFIG_PREFIX=\"$(PREFIX)\" $(OBJDIR)/qjsc.o: CFLAGS+=$(QJSC_DEFINES) $(OBJDIR)/qjsc.host.o: CFLAGS+=$(QJSC_HOST_DEFINES) @@ -298,17 +318,17 @@ clean: rm -rf run-test262-debug run-test262-32 install: all - mkdir -p "$(DESTDIR)$(prefix)/bin" + mkdir -p "$(DESTDIR)$(PREFIX)/bin" $(STRIP) qjs qjsc - install -m755 qjs qjsc "$(DESTDIR)$(prefix)/bin" - ln -sf qjs "$(DESTDIR)$(prefix)/bin/qjscalc" - mkdir -p "$(DESTDIR)$(prefix)/lib/quickjs" - install -m644 libquickjs.a "$(DESTDIR)$(prefix)/lib/quickjs" + install -m755 qjs qjsc "$(DESTDIR)$(PREFIX)/bin" + ln -sf qjs "$(DESTDIR)$(PREFIX)/bin/qjscalc" + mkdir -p "$(DESTDIR)$(PREFIX)/lib/quickjs" + install -m644 libquickjs.a "$(DESTDIR)$(PREFIX)/lib/quickjs" ifdef CONFIG_LTO - install -m644 libquickjs.lto.a "$(DESTDIR)$(prefix)/lib/quickjs" + install -m644 libquickjs.lto.a "$(DESTDIR)$(PREFIX)/lib/quickjs" endif - mkdir -p "$(DESTDIR)$(prefix)/include/quickjs" - install -m644 quickjs.h quickjs-libc.h "$(DESTDIR)$(prefix)/include/quickjs" + mkdir -p "$(DESTDIR)$(PREFIX)/include/quickjs" + install -m644 quickjs.h quickjs-libc.h "$(DESTDIR)$(PREFIX)/include/quickjs" ############################################################################### # examples @@ -317,10 +337,7 @@ endif HELLO_SRCS=examples/hello.js HELLO_OPTS=-fno-string-normalize -fno-map -fno-promise -fno-typedarray \ -fno-typedarray -fno-regexp -fno-json -fno-eval -fno-proxy \ - -fno-date -fno-module-loader -ifdef CONFIG_BIGNUM -HELLO_OPTS+=-fno-bigint -endif + -fno-date -fno-module-loader -fno-bigint hello.c: $(QJSC) $(HELLO_SRCS) $(QJSC) -e $(HELLO_OPTS) -o $@ $(HELLO_SRCS) @@ -377,7 +394,7 @@ doc/%.html: doc/%.html.pre ############################################################################### # tests -ifndef CONFIG_DARWIN +ifdef CONFIG_SHARED_LIBS test: tests/bjson.so examples/point.so endif ifdef CONFIG_M32 @@ -391,7 +408,7 @@ test: qjs ./qjs tests/test_loop.js ./qjs tests/test_std.js ./qjs tests/test_worker.js -ifndef CONFIG_DARWIN +ifdef CONFIG_SHARED_LIBS ifdef CONFIG_BIGNUM ./qjs --bignum tests/test_bjson.js else diff --git a/libquickjs-sys/embed/quickjs/TODO b/libquickjs-sys/embed/quickjs/TODO index 2a3b3c3..bbd1a45 100644 --- a/libquickjs-sys/embed/quickjs/TODO +++ b/libquickjs-sys/embed/quickjs/TODO @@ -1,6 +1,3 @@ -Bugs: -- modules: better error handling with cyclic module references - Misc ideas: - use custom printf to avoid compatibility issues with floating point numbers - consistent naming for preprocessor defines @@ -66,5 +63,5 @@ Optimization ideas: Test262o: 0/11262 errors, 463 excluded Test262o commit: 7da91bceb9ce7613f87db47ddd1292a2dda58b42 (es5-tests branch) -Result: 35/75280 errors, 909 excluded, 585 skipped -Test262 commit: 31126581e7290f9233c29cefd93f66c6ac78f1c9 +Result: 10/76947 errors, 1497 excluded, 8117 skipped +Test262 commit: 6cbb6da9473c56d95358d8e679c5a6d2b4574efb diff --git a/libquickjs-sys/embed/quickjs/VERSION b/libquickjs-sys/embed/quickjs/VERSION index 22ffec1..e89de35 100644 --- a/libquickjs-sys/embed/quickjs/VERSION +++ b/libquickjs-sys/embed/quickjs/VERSION @@ -1 +1 @@ -2021-03-27 +2024-01-13 diff --git a/libquickjs-sys/embed/quickjs/cutils.h b/libquickjs-sys/embed/quickjs/cutils.h index 31f7cd8..8399d61 100644 --- a/libquickjs-sys/embed/quickjs/cutils.h +++ b/libquickjs-sys/embed/quickjs/cutils.h @@ -49,6 +49,9 @@ #define countof(x) (sizeof(x) / sizeof((x)[0])) #endif +/* return the pointer of type 'type *' containing 'ptr' as field 'member' */ +#define container_of(ptr, type, member) ((type *)((uint8_t *)(ptr) - offsetof(type, member))) + typedef int BOOL; #ifndef FALSE diff --git a/libquickjs-sys/embed/quickjs/libbf.c b/libquickjs-sys/embed/quickjs/libbf.c index fe1628e..234b956 100644 --- a/libquickjs-sys/embed/quickjs/libbf.c +++ b/libquickjs-sys/embed/quickjs/libbf.c @@ -37,10 +37,12 @@ /* enable it to check the multiplication result */ //#define USE_MUL_CHECK +#ifdef CONFIG_BIGNUM /* enable it to use FFT/NTT multiplication */ #define USE_FFT_MUL /* enable decimal floating point support */ #define USE_BF_DEC +#endif //#define inline __attribute__((always_inline)) @@ -164,6 +166,21 @@ static inline slimb_t sat_add(slimb_t a, slimb_t b) return r; } +static inline __maybe_unused limb_t shrd(limb_t low, limb_t high, long shift) +{ + if (shift != 0) + low = (low >> shift) | (high << (LIMB_BITS - shift)); + return low; +} + +static inline __maybe_unused limb_t shld(limb_t a1, limb_t a0, long shift) +{ + if (shift != 0) + return (a1 << shift) | (a0 >> (LIMB_BITS - shift)); + else + return a1; +} + #define malloc(s) malloc_is_forbidden(s) #define free(p) free_is_forbidden(p) #define realloc(p, s) realloc_is_forbidden(p, s) @@ -236,7 +253,7 @@ int bf_set_ui(bf_t *r, uint64_t a) a1 = a >> 32; shift = clz(a1); r->tab[0] = a0 << shift; - r->tab[1] = (a1 << shift) | (a0 >> (LIMB_BITS - shift)); + r->tab[1] = shld(a1, a0, shift); r->expn = 2 * LIMB_BITS - shift; } #endif @@ -1585,7 +1602,9 @@ int bf_mul(bf_t *r, const bf_t *a, const bf_t *b, limb_t prec, r = &tmp; } if (bf_resize(r, a_len + b_len)) { +#ifdef USE_FFT_MUL fail: +#endif bf_set_nan(r); ret = BF_ST_MEM_ERROR; goto done; @@ -2282,11 +2301,14 @@ static int bf_pow_ui_ui(bf_t *r, limb_t a1, limb_t b, bf_t a; int ret; +#ifdef USE_BF_DEC if (a1 == 10 && b <= LIMB_DIGITS) { /* use precomputed powers. We do not round at this point because we expect the caller to do it */ ret = bf_set_ui(r, mp_pow_dec[b]); - } else { + } else +#endif + { bf_init(r->ctx, &a); ret = bf_set_ui(&a, a1); ret |= bf_pow_ui(r, &a, b, prec, flags); @@ -5392,21 +5414,6 @@ int bf_acos(bf_t *r, const bf_t *a, limb_t prec, bf_flags_t flags) #endif /* LIMB_BITS != 64 */ -static inline __maybe_unused limb_t shrd(limb_t low, limb_t high, long shift) -{ - if (shift != 0) - low = (low >> shift) | (high << (LIMB_BITS - shift)); - return low; -} - -static inline __maybe_unused limb_t shld(limb_t a1, limb_t a0, long shift) -{ - if (shift != 0) - return (a1 << shift) | (a0 >> (LIMB_BITS - shift)); - else - return a1; -} - #if LIMB_DIGITS == 19 /* WARNING: hardcoded for b = 1e19. It is assumed that: diff --git a/libquickjs-sys/embed/quickjs/libbf.h b/libquickjs-sys/embed/quickjs/libbf.h index 48e9d95..0457c18 100644 --- a/libquickjs-sys/embed/quickjs/libbf.h +++ b/libquickjs-sys/embed/quickjs/libbf.h @@ -27,7 +27,7 @@ #include #include -#if INTPTR_MAX >= INT64_MAX +#if defined(__SIZEOF_INT128__) && (INTPTR_MAX >= INT64_MAX) #define LIMB_LOG2_BITS 6 #else #define LIMB_LOG2_BITS 5 diff --git a/libquickjs-sys/embed/quickjs/libregexp-opcode.h b/libquickjs-sys/embed/quickjs/libregexp-opcode.h index f90c23b..189d121 100644 --- a/libquickjs-sys/embed/quickjs/libregexp-opcode.h +++ b/libquickjs-sys/embed/quickjs/libregexp-opcode.h @@ -50,8 +50,7 @@ DEF(range32, 3) /* variable length */ DEF(lookahead, 5) DEF(negative_lookahead, 5) DEF(push_char_pos, 1) /* push the character position on the stack */ -DEF(bne_char_pos, 5) /* pop one stack element and jump if equal to the character - position */ +DEF(check_advance, 1) /* pop one stack element and check that it is different from the character position */ DEF(prev, 1) /* go to the previous char */ DEF(simple_greedy_quant, 17) diff --git a/libquickjs-sys/embed/quickjs/libregexp.c b/libquickjs-sys/embed/quickjs/libregexp.c index 379bfc7..b6af454 100644 --- a/libquickjs-sys/embed/quickjs/libregexp.c +++ b/libquickjs-sys/embed/quickjs/libregexp.c @@ -34,9 +34,6 @@ /* TODO: - - Add full unicode canonicalize rules for character ranges (not - really useful but needed for exact "ignorecase" compatibility). - - Add a lock step execution mode (=linear time execution guaranteed) when the regular expression is "simple" i.e. no backreference nor complicated lookahead. The opcodes are designed for this execution @@ -120,33 +117,6 @@ static int dbuf_insert(DynBuf *s, int pos, int len) return 0; } -/* canonicalize with the specific JS regexp rules */ -static uint32_t lre_canonicalize(uint32_t c, BOOL is_utf16) -{ - uint32_t res[LRE_CC_RES_LEN_MAX]; - int len; - if (is_utf16) { - if (likely(c < 128)) { - if (c >= 'A' && c <= 'Z') - c = c - 'A' + 'a'; - } else { - lre_case_conv(res, c, 2); - c = res[0]; - } - } else { - if (likely(c < 128)) { - if (c >= 'a' && c <= 'z') - c = c - 'a' + 'A'; - } else { - /* legacy regexp: to upper case if single char >= 128 */ - len = lre_case_conv(res, c, FALSE); - if (len == 1 && res[0] >= 128) - c = res[0]; - } - } - return c; -} - static const uint16_t char_range_d[] = { 1, 0x0030, 0x0039 + 1, @@ -245,31 +215,6 @@ static int cr_init_char_range(REParseState *s, CharRange *cr, uint32_t c) return -1; } -static int cr_canonicalize(CharRange *cr) -{ - CharRange a; - uint32_t pt[2]; - int i, ret; - - cr_init(&a, cr->mem_opaque, lre_realloc); - pt[0] = 'a'; - pt[1] = 'z' + 1; - ret = cr_op(&a, cr->points, cr->len, pt, 2, CR_OP_INTER); - if (ret) - goto fail; - /* convert to upper case */ - /* XXX: the generic unicode case would be much more complicated - and not really useful */ - for(i = 0; i < a.len; i++) { - a.points[i] += 'A' - 'a'; - } - /* Note: for simplicity we keep the lower case ranges */ - ret = cr_union1(cr, a.points, a.len); - fail: - cr_free(&a); - return ret; -} - #ifdef DUMP_REOP static __maybe_unused void lre_dump_bytecode(const uint8_t *buf, int buf_len) @@ -335,7 +280,6 @@ static __maybe_unused void lre_dump_bytecode(const uint8_t *buf, case REOP_loop: case REOP_lookahead: case REOP_negative_lookahead: - case REOP_bne_char_pos: val = get_u32(buf + pos + 1); val += (pos + 5); printf(" %u", val); @@ -922,7 +866,7 @@ static int re_parse_char_class(REParseState *s, const uint8_t **pp) } } if (s->ignore_case) { - if (cr_canonicalize(cr)) + if (cr_regexp_canonicalize(cr, s->is_utf16)) goto memory_error; } if (invert) { @@ -943,22 +887,17 @@ static int re_parse_char_class(REParseState *s, const uint8_t **pp) } /* Return: - 1 if the opcodes in bc_buf[] always advance the character pointer. - 0 if the character pointer may not be advanced. - -1 if the code may depend on side effects of its previous execution (backreference) + - true if the opcodes may not advance the char pointer + - false if the opcodes always advance the char pointer */ -static int re_check_advance(const uint8_t *bc_buf, int bc_buf_len) +static BOOL re_need_check_advance(const uint8_t *bc_buf, int bc_buf_len) { - int pos, opcode, ret, len, i; - uint32_t val, last; - BOOL has_back_reference; - uint8_t capture_bitmap[CAPTURE_COUNT_MAX]; + int pos, opcode, len; + uint32_t val; + BOOL ret; - ret = -2; /* not known yet */ + ret = TRUE; pos = 0; - has_back_reference = FALSE; - memset(capture_bitmap, 0, sizeof(capture_bitmap)); - while (pos < bc_buf_len) { opcode = bc_buf[pos]; len = reopcode_info[opcode].size; @@ -976,8 +915,7 @@ static int re_check_advance(const uint8_t *bc_buf, int bc_buf_len) case REOP_dot: case REOP_any: simple_char: - if (ret == -2) - ret = 1; + ret = FALSE; break; case REOP_line_start: case REOP_line_end: @@ -991,41 +929,16 @@ static int re_check_advance(const uint8_t *bc_buf, int bc_buf_len) break; case REOP_save_start: case REOP_save_end: - val = bc_buf[pos + 1]; - capture_bitmap[val] |= 1; - break; case REOP_save_reset: - { - val = bc_buf[pos + 1]; - last = bc_buf[pos + 2]; - while (val < last) - capture_bitmap[val++] |= 1; - } - break; case REOP_back_reference: case REOP_backward_back_reference: - val = bc_buf[pos + 1]; - capture_bitmap[val] |= 2; - has_back_reference = TRUE; break; default: /* safe behvior: we cannot predict the outcome */ - if (ret == -2) - ret = 0; - break; + return TRUE; } pos += len; } - if (has_back_reference) { - /* check if there is back reference which references a capture - made in the some code */ - for(i = 0; i < CAPTURE_COUNT_MAX; i++) { - if (capture_bitmap[i] == 3) - return -1; - } - } - if (ret == -2) - ret = 0; return ret; } @@ -1071,11 +984,10 @@ static int re_is_simple_quantifier(const uint8_t *bc_buf, int bc_buf_len) } /* '*pp' is the first char after '<' */ -static int re_parse_group_name(char *buf, int buf_size, - const uint8_t **pp, BOOL is_utf16) +static int re_parse_group_name(char *buf, int buf_size, const uint8_t **pp) { - const uint8_t *p; - uint32_t c; + const uint8_t *p, *p1; + uint32_t c, d; char *q; p = *pp; @@ -1086,11 +998,18 @@ static int re_parse_group_name(char *buf, int buf_size, p++; if (*p != 'u') return -1; - c = lre_parse_escape(&p, is_utf16 * 2); + c = lre_parse_escape(&p, 2); // accept surrogate pairs } else if (c == '>') { break; } else if (c >= 128) { c = unicode_from_utf8(p, UTF8_CHAR_LEN_MAX, &p); + if (c >= 0xD800 && c <= 0xDBFF) { + d = unicode_from_utf8(p, UTF8_CHAR_LEN_MAX, &p1); + if (d >= 0xDC00 && d <= 0xDFFF) { + c = 0x10000 + 0x400 * (c - 0xD800) + (d - 0xDC00); + p = p1; + } + } } else { p++; } @@ -1140,8 +1059,7 @@ static int re_parse_captures(REParseState *s, int *phas_named_captures, /* potential named capture */ if (capture_name) { p += 3; - if (re_parse_group_name(name, sizeof(name), &p, - s->is_utf16) == 0) { + if (re_parse_group_name(name, sizeof(name), &p) == 0) { if (!strcmp(name, capture_name)) return capture_index; } @@ -1314,7 +1232,7 @@ static int re_parse_term(REParseState *s, BOOL is_backward_dir) } else if (p[2] == '<') { p += 3; if (re_parse_group_name(s->u.tmp_buf, sizeof(s->u.tmp_buf), - &p, s->is_utf16)) { + &p)) { return re_parse_error(s, "invalid group name"); } if (find_group_name(s, s->u.tmp_buf) > 0) { @@ -1378,7 +1296,7 @@ static int re_parse_term(REParseState *s, BOOL is_backward_dir) } p1 += 3; if (re_parse_group_name(s->u.tmp_buf, sizeof(s->u.tmp_buf), - &p1, s->is_utf16)) { + &p1)) { if (s->is_utf16 || re_has_named_captures(s)) return re_parse_error(s, "invalid group name"); else @@ -1591,8 +1509,12 @@ static int re_parse_term(REParseState *s, BOOL is_backward_dir) if (dbuf_error(&s->byte_code)) goto out_of_memory; - add_zero_advance_check = (re_check_advance(s->byte_code.buf + last_atom_start, - s->byte_code.size - last_atom_start) == 0); + /* the spec tells that if there is no advance when + running the atom after the first quant_min times, + then there is no match. We remove this test when we + are sure the atom always advances the position. */ + add_zero_advance_check = re_need_check_advance(s->byte_code.buf + last_atom_start, + s->byte_code.size - last_atom_start); } else { add_zero_advance_check = FALSE; } @@ -1612,38 +1534,34 @@ static int re_parse_term(REParseState *s, BOOL is_backward_dir) } if (quant_max == 0) { s->byte_code.size = last_atom_start; - } else if (quant_max == 1) { - if (dbuf_insert(&s->byte_code, last_atom_start, 5)) - goto out_of_memory; - s->byte_code.buf[last_atom_start] = REOP_split_goto_first + - greedy; - put_u32(s->byte_code.buf + last_atom_start + 1, len); - } else if (quant_max == INT32_MAX) { + } else if (quant_max == 1 || quant_max == INT32_MAX) { + BOOL has_goto = (quant_max == INT32_MAX); if (dbuf_insert(&s->byte_code, last_atom_start, 5 + add_zero_advance_check)) goto out_of_memory; s->byte_code.buf[last_atom_start] = REOP_split_goto_first + greedy; put_u32(s->byte_code.buf + last_atom_start + 1, - len + 5 + add_zero_advance_check); + len + 5 * has_goto + add_zero_advance_check * 2); if (add_zero_advance_check) { - /* avoid infinite loop by stoping the - recursion if no advance was made in the - atom (only works if the atom has no - side effect) */ s->byte_code.buf[last_atom_start + 1 + 4] = REOP_push_char_pos; - re_emit_goto(s, REOP_bne_char_pos, last_atom_start); - } else { - re_emit_goto(s, REOP_goto, last_atom_start); + re_emit_op(s, REOP_check_advance); } + if (has_goto) + re_emit_goto(s, REOP_goto, last_atom_start); } else { - if (dbuf_insert(&s->byte_code, last_atom_start, 10)) + if (dbuf_insert(&s->byte_code, last_atom_start, 10 + add_zero_advance_check)) goto out_of_memory; pos = last_atom_start; s->byte_code.buf[pos++] = REOP_push_i32; put_u32(s->byte_code.buf + pos, quant_max); pos += 4; s->byte_code.buf[pos++] = REOP_split_goto_first + greedy; - put_u32(s->byte_code.buf + pos, len + 5); + put_u32(s->byte_code.buf + pos, len + 5 + add_zero_advance_check * 2); + pos += 4; + if (add_zero_advance_check) { + s->byte_code.buf[pos++] = REOP_push_char_pos; + re_emit_op(s, REOP_check_advance); + } re_emit_goto(s, REOP_loop, last_atom_start + 5); re_emit_op(s, REOP_drop); } @@ -1667,22 +1585,25 @@ static int re_parse_term(REParseState *s, BOOL is_backward_dir) if (quant_max == INT32_MAX) { pos = s->byte_code.size; re_emit_op_u32(s, REOP_split_goto_first + greedy, - len + 5 + add_zero_advance_check); + len + 5 + add_zero_advance_check * 2); if (add_zero_advance_check) re_emit_op(s, REOP_push_char_pos); /* copy the atom */ dbuf_put_self(&s->byte_code, last_atom_start, len); if (add_zero_advance_check) - re_emit_goto(s, REOP_bne_char_pos, pos); - else - re_emit_goto(s, REOP_goto, pos); + re_emit_op(s, REOP_check_advance); + re_emit_goto(s, REOP_goto, pos); } else if (quant_max > quant_min) { re_emit_op_u32(s, REOP_push_i32, quant_max - quant_min); pos = s->byte_code.size; - re_emit_op_u32(s, REOP_split_goto_first + greedy, len + 5); + re_emit_op_u32(s, REOP_split_goto_first + greedy, + len + 5 + add_zero_advance_check * 2); + if (add_zero_advance_check) + re_emit_op(s, REOP_push_char_pos); /* copy the atom */ dbuf_put_self(&s->byte_code, last_atom_start, len); - + if (add_zero_advance_check) + re_emit_op(s, REOP_check_advance); re_emit_goto(s, REOP_loop, pos); re_emit_op(s, REOP_drop); } @@ -1796,7 +1717,7 @@ static int compute_stack_size(const uint8_t *bc_buf, int bc_buf_len) } break; case REOP_drop: - case REOP_bne_char_pos: + case REOP_check_advance: assert(stack_size > 0); stack_size--; break; @@ -2292,11 +2213,9 @@ static intptr_t lre_exec_backtrack(REExecContext *s, uint8_t **capture, case REOP_push_char_pos: stack[stack_len++] = (uintptr_t)cptr; break; - case REOP_bne_char_pos: - val = get_u32(pc); - pc += 4; - if (stack[--stack_len] != (uintptr_t)cptr) - pc += (int)val; + case REOP_check_advance: + if (stack[--stack_len] == (uintptr_t)cptr) + goto no_match; break; case REOP_word_boundary: case REOP_not_word_boundary: diff --git a/libquickjs-sys/embed/quickjs/libregexp.h b/libquickjs-sys/embed/quickjs/libregexp.h index 9aedb7e..c0bc58d 100644 --- a/libquickjs-sys/embed/quickjs/libregexp.h +++ b/libquickjs-sys/embed/quickjs/libregexp.h @@ -36,6 +36,7 @@ #define LRE_FLAG_DOTALL (1 << 3) #define LRE_FLAG_UTF16 (1 << 4) #define LRE_FLAG_STICKY (1 << 5) +#define LRE_FLAG_INDICES (1 << 6) /* Unused by libregexp, just recorded. */ #define LRE_FLAG_NAMED_GROUPS (1 << 7) /* named groups are present in the regexp */ diff --git a/libquickjs-sys/embed/quickjs/libunicode-table.h b/libquickjs-sys/embed/quickjs/libunicode-table.h index 0ef2113..513ed94 100644 --- a/libquickjs-sys/embed/quickjs/libunicode-table.h +++ b/libquickjs-sys/embed/quickjs/libunicode-table.h @@ -3,7 +3,7 @@ #include -static const uint32_t case_conv_table1[361] = { +static const uint32_t case_conv_table1[370] = { 0x00209a30, 0x00309a00, 0x005a8173, 0x00601730, 0x006c0730, 0x006f81b3, 0x00701700, 0x007c0700, 0x007f8100, 0x00803040, 0x009801c3, 0x00988190, @@ -74,8 +74,8 @@ static const uint32_t case_conv_table1[361] = { 0x0ffb01b2, 0x0ffb81d9, 0x0ffc0230, 0x0ffd0230, 0x0ffe0162, 0x109301a0, 0x109501a0, 0x109581a0, 0x10990131, 0x10a70101, 0x10b01031, 0x10b81001, - 0x10c18240, 0x125b1a31, 0x12681a01, 0x16002f31, - 0x16182f01, 0x16300240, 0x16310130, 0x16318130, + 0x10c18240, 0x125b1a31, 0x12681a01, 0x16003031, + 0x16183001, 0x16300240, 0x16310130, 0x16318130, 0x16320130, 0x16328100, 0x16330100, 0x16338640, 0x16368130, 0x16370130, 0x16378130, 0x16380130, 0x16390240, 0x163a8240, 0x163f0230, 0x16406440, @@ -85,19 +85,21 @@ static const uint32_t case_conv_table1[361] = { 0x53c58240, 0x53c68130, 0x53c80440, 0x53ca0101, 0x53cb1440, 0x53d50130, 0x53d58130, 0x53d60130, 0x53d68130, 0x53d70130, 0x53d80130, 0x53d88130, - 0x53d90130, 0x53d98131, 0x53da0c40, 0x53e10240, - 0x53e20131, 0x53e28130, 0x53e30130, 0x53e38440, - 0x53fa8240, 0x55a98101, 0x55b85020, 0x7d8001b2, - 0x7d8081b2, 0x7d8101b2, 0x7d8181da, 0x7d8201da, - 0x7d8281b3, 0x7d8301b3, 0x7d8981bb, 0x7d8a01bb, - 0x7d8a81bb, 0x7d8b01bc, 0x7d8b81bb, 0x7f909a31, - 0x7fa09a01, 0x82002831, 0x82142801, 0x82582431, - 0x826c2401, 0x86403331, 0x86603301, 0x8c502031, - 0x8c602001, 0xb7202031, 0xb7302001, 0xf4802231, - 0xf4912201, + 0x53d90130, 0x53d98131, 0x53da1040, 0x53e20131, + 0x53e28130, 0x53e30130, 0x53e38440, 0x53e80240, + 0x53eb0440, 0x53fa8240, 0x55a98101, 0x55b85020, + 0x7d8001b2, 0x7d8081b2, 0x7d8101b2, 0x7d8181da, + 0x7d8201da, 0x7d8281b3, 0x7d8301b3, 0x7d8981bb, + 0x7d8a01bb, 0x7d8a81bb, 0x7d8b01bc, 0x7d8b81bb, + 0x7f909a31, 0x7fa09a01, 0x82002831, 0x82142801, + 0x82582431, 0x826c2401, 0x82b80b31, 0x82be0f31, + 0x82c60731, 0x82ca0231, 0x82cb8b01, 0x82d18f01, + 0x82d98701, 0x82dd8201, 0x86403331, 0x86603301, + 0x8c502031, 0x8c602001, 0xb7202031, 0xb7302001, + 0xf4802231, 0xf4912201, }; -static const uint8_t case_conv_table2[361] = { +static const uint8_t case_conv_table2[370] = { 0x01, 0x00, 0x9c, 0x06, 0x07, 0x4d, 0x03, 0x04, 0x10, 0x00, 0x8f, 0x0b, 0x00, 0x00, 0x11, 0x00, 0x08, 0x00, 0x53, 0x4a, 0x51, 0x00, 0x52, 0x00, @@ -110,7 +112,7 @@ static const uint8_t case_conv_table2[361] = { 0x2a, 0x00, 0x13, 0x6b, 0x6d, 0x00, 0x26, 0x24, 0x27, 0x14, 0x16, 0x18, 0x1b, 0x1c, 0x3e, 0x1e, 0x3f, 0x1f, 0x39, 0x3d, 0x22, 0x21, 0x41, 0x1e, - 0x40, 0x25, 0x25, 0x26, 0x28, 0x20, 0x2a, 0x49, + 0x40, 0x25, 0x25, 0x26, 0x28, 0x20, 0x2a, 0x48, 0x2c, 0x43, 0x2e, 0x4b, 0x30, 0x4c, 0x32, 0x44, 0x42, 0x99, 0x00, 0x00, 0x95, 0x8f, 0x7d, 0x7e, 0x83, 0x84, 0x12, 0x80, 0x82, 0x76, 0x77, 0x12, @@ -119,9 +121,9 @@ static const uint8_t case_conv_table2[361] = { 0x33, 0x95, 0x00, 0x8e, 0x00, 0x74, 0x99, 0x98, 0x97, 0x96, 0x00, 0x00, 0x9e, 0x00, 0x9c, 0x00, 0xa1, 0xa0, 0x15, 0x2e, 0x2f, 0x30, 0xb4, 0xb5, - 0x4e, 0xaa, 0xa9, 0x12, 0x14, 0x1e, 0x21, 0x22, + 0x4f, 0xaa, 0xa9, 0x12, 0x14, 0x1e, 0x21, 0x22, 0x22, 0x2a, 0x34, 0x35, 0xa6, 0xa7, 0x36, 0x1f, - 0x4a, 0x00, 0x00, 0x97, 0x01, 0x5a, 0xda, 0x1d, + 0x49, 0x00, 0x00, 0x97, 0x01, 0x5a, 0xda, 0x1d, 0x36, 0x05, 0x00, 0xc4, 0xc3, 0xc6, 0xc5, 0xc8, 0xc7, 0xca, 0xc9, 0xcc, 0xcb, 0xc4, 0xd5, 0x45, 0xd6, 0x42, 0xd7, 0x46, 0xd8, 0xce, 0xd0, 0xd2, @@ -137,13 +139,14 @@ static const uint8_t case_conv_table2[361] = { 0x65, 0x44, 0x47, 0x00, 0x4f, 0x62, 0x4e, 0x50, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0xa3, 0xa4, 0xa5, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb6, 0x00, - 0x00, 0x5a, 0x00, 0x48, 0x00, 0x5b, 0x56, 0x58, - 0x60, 0x5e, 0x70, 0x69, 0x6f, 0x4d, 0x00, 0x00, - 0x3b, 0x67, 0xb8, 0x00, 0x00, 0x45, 0xa8, 0x8a, - 0x8b, 0x8c, 0xab, 0xac, 0x58, 0x58, 0xaf, 0x94, - 0xb0, 0x6f, 0xb2, 0x5c, 0x5b, 0x5e, 0x5d, 0x60, - 0x5f, 0x62, 0x61, 0x64, 0x63, 0x66, 0x65, 0x68, - 0x67, + 0x00, 0x5a, 0x00, 0x47, 0x00, 0x5b, 0x56, 0x58, + 0x60, 0x5e, 0x70, 0x69, 0x6f, 0x4e, 0x00, 0x3b, + 0x67, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x45, 0xa8, + 0x8a, 0x8b, 0x8c, 0xab, 0xac, 0x58, 0x58, 0xaf, + 0x94, 0xb0, 0x6f, 0xb2, 0x5d, 0x5c, 0x5f, 0x5e, + 0x61, 0x60, 0x66, 0x67, 0x68, 0x69, 0x62, 0x63, + 0x64, 0x65, 0x6b, 0x6a, 0x6d, 0x6c, 0x6f, 0x6e, + 0x71, 0x70, }; static const uint16_t case_conv_ext[58] = { @@ -157,38 +160,41 @@ static const uint16_t case_conv_ext[58] = { 0x006b, 0x00e5, }; -static const uint8_t unicode_prop_Cased1_table[172] = { +static const uint8_t unicode_prop_Cased1_table[196] = { 0x40, 0xa9, 0x80, 0x8e, 0x80, 0xfc, 0x80, 0xd3, 0x80, 0x8c, 0x80, 0x8d, 0x81, 0x8d, 0x02, 0x80, 0xe1, 0x80, 0x91, 0x85, 0x9a, 0x01, 0x00, 0x01, 0x11, 0x00, 0x01, 0x04, 0x08, 0x01, 0x08, 0x30, 0x08, 0x01, 0x15, 0x20, 0x00, 0x39, 0x99, 0x31, 0x9d, 0x84, 0x40, 0x94, 0x80, 0xd6, 0x82, 0xa6, - 0x80, 0x41, 0x62, 0x80, 0xa6, 0x80, 0x57, 0x76, - 0xf8, 0x02, 0x80, 0x8f, 0x80, 0xb0, 0x40, 0xdb, - 0x08, 0x80, 0x41, 0xd0, 0x80, 0x8c, 0x80, 0x8f, - 0x8c, 0xe4, 0x03, 0x01, 0x89, 0x00, 0x14, 0x28, - 0x10, 0x11, 0x02, 0x01, 0x18, 0x0b, 0x24, 0x4b, - 0x26, 0x01, 0x01, 0x86, 0xe5, 0x80, 0x60, 0x79, - 0xb6, 0x81, 0x40, 0x91, 0x81, 0xbd, 0x88, 0x94, - 0x05, 0x80, 0x98, 0x80, 0xc7, 0x82, 0x43, 0x34, - 0xa2, 0x06, 0x80, 0x8c, 0x61, 0x28, 0x96, 0xd4, - 0x80, 0xc6, 0x01, 0x08, 0x09, 0x0b, 0x80, 0x8b, - 0x00, 0x06, 0x80, 0xc0, 0x03, 0x0f, 0x06, 0x80, - 0x9b, 0x03, 0x04, 0x00, 0x16, 0x80, 0x41, 0x53, - 0x81, 0x98, 0x80, 0x98, 0x80, 0x9e, 0x80, 0x98, - 0x80, 0x9e, 0x80, 0x98, 0x80, 0x9e, 0x80, 0x98, - 0x80, 0x9e, 0x80, 0x98, 0x07, 0x59, 0x63, 0x99, + 0x80, 0x41, 0x62, 0x80, 0xa6, 0x80, 0x4b, 0x72, + 0x80, 0x4c, 0x02, 0xf8, 0x02, 0x80, 0x8f, 0x80, + 0xb0, 0x40, 0xdb, 0x08, 0x80, 0x41, 0xd0, 0x80, + 0x8c, 0x80, 0x8f, 0x8c, 0xe4, 0x03, 0x01, 0x89, + 0x00, 0x14, 0x28, 0x10, 0x11, 0x02, 0x01, 0x18, + 0x0b, 0x24, 0x4b, 0x26, 0x01, 0x01, 0x86, 0xe5, + 0x80, 0x60, 0x79, 0xb6, 0x81, 0x40, 0x91, 0x81, + 0xbd, 0x88, 0x94, 0x05, 0x80, 0x98, 0x80, 0xa2, + 0x00, 0x80, 0x9b, 0x12, 0x82, 0x43, 0x34, 0xa2, + 0x06, 0x80, 0x8d, 0x60, 0x5c, 0x15, 0x01, 0x10, + 0xa9, 0x80, 0x88, 0x60, 0xcc, 0x44, 0xd4, 0x80, + 0xc6, 0x01, 0x08, 0x09, 0x0b, 0x80, 0x8b, 0x00, + 0x06, 0x80, 0xc0, 0x03, 0x0f, 0x06, 0x80, 0x9b, + 0x03, 0x04, 0x00, 0x16, 0x80, 0x41, 0x53, 0x81, + 0x98, 0x80, 0x98, 0x80, 0x9e, 0x80, 0x98, 0x80, + 0x9e, 0x80, 0x98, 0x80, 0x9e, 0x80, 0x98, 0x80, + 0x9e, 0x80, 0x98, 0x07, 0x47, 0x33, 0x89, 0x80, + 0x93, 0x2d, 0x41, 0x04, 0xbd, 0x50, 0xc1, 0x99, 0x85, 0x99, 0x85, 0x99, }; -static const uint8_t unicode_prop_Cased1_index[18] = { - 0xb9, 0x02, 0xe0, 0xa0, 0x1e, 0x40, 0x9e, 0xa6, - 0x40, 0xba, 0xd4, 0x01, 0x89, 0xd7, 0x01, 0x8a, - 0xf1, 0x01, +static const uint8_t unicode_prop_Cased1_index[21] = { + 0xb9, 0x02, 0xe0, 0xc0, 0x1d, 0x20, 0xe5, 0x2c, + 0x20, 0xb1, 0x07, 0x21, 0xc1, 0xd6, 0x21, 0x4a, + 0xf1, 0x01, 0x8a, 0xf1, 0x01, }; -static const uint8_t unicode_prop_Case_Ignorable_table[692] = { +static const uint8_t unicode_prop_Case_Ignorable_table[737] = { 0xa6, 0x05, 0x80, 0x8a, 0x80, 0xa2, 0x00, 0x80, 0xc6, 0x03, 0x00, 0x03, 0x01, 0x81, 0x41, 0xf6, 0x40, 0xbf, 0x19, 0x18, 0x88, 0x08, 0x80, 0x40, @@ -197,100 +203,106 @@ static const uint8_t unicode_prop_Case_Ignorable_table[692] = { 0x89, 0x8a, 0x00, 0xa2, 0x80, 0x89, 0x94, 0x8f, 0x80, 0xe4, 0x38, 0x89, 0x03, 0xa0, 0x00, 0x80, 0x9d, 0x9a, 0xda, 0x8a, 0xb9, 0x8a, 0x18, 0x08, - 0x97, 0x97, 0xaa, 0x82, 0xf6, 0xaf, 0xb6, 0x00, - 0x03, 0x3b, 0x02, 0x86, 0x89, 0x81, 0x8c, 0x80, - 0x8e, 0x80, 0xb9, 0x03, 0x1f, 0x80, 0x93, 0x81, - 0x99, 0x01, 0x81, 0xb8, 0x03, 0x0b, 0x09, 0x12, - 0x80, 0x9d, 0x0a, 0x80, 0x8a, 0x81, 0xb8, 0x03, - 0x20, 0x0b, 0x80, 0x93, 0x81, 0x95, 0x28, 0x80, - 0xb9, 0x01, 0x00, 0x1f, 0x06, 0x81, 0x8a, 0x81, - 0x9d, 0x80, 0xbc, 0x80, 0x8b, 0x80, 0xb1, 0x02, - 0x80, 0xb8, 0x14, 0x10, 0x1e, 0x81, 0x8a, 0x81, - 0x9c, 0x80, 0xb9, 0x01, 0x05, 0x04, 0x81, 0x93, - 0x81, 0x9b, 0x81, 0xb8, 0x0b, 0x1f, 0x80, 0x93, - 0x81, 0x9c, 0x80, 0xc7, 0x06, 0x10, 0x80, 0xd9, - 0x01, 0x86, 0x8a, 0x88, 0xe1, 0x01, 0x88, 0x88, - 0x00, 0x85, 0xc9, 0x81, 0x9a, 0x00, 0x00, 0x80, - 0xb6, 0x8d, 0x04, 0x01, 0x84, 0x8a, 0x80, 0xa3, - 0x88, 0x80, 0xe5, 0x18, 0x28, 0x09, 0x81, 0x98, - 0x0b, 0x82, 0x8f, 0x83, 0x8c, 0x01, 0x0d, 0x80, - 0x8e, 0x80, 0xdd, 0x80, 0x42, 0x5f, 0x82, 0x43, - 0xb1, 0x82, 0x9c, 0x82, 0x9c, 0x81, 0x9d, 0x81, - 0xbf, 0x08, 0x37, 0x01, 0x8a, 0x10, 0x20, 0xac, - 0x83, 0xb3, 0x80, 0xc0, 0x81, 0xa1, 0x80, 0xf5, - 0x13, 0x81, 0x88, 0x05, 0x82, 0x40, 0xda, 0x09, - 0x80, 0xb9, 0x00, 0x30, 0x00, 0x01, 0x3d, 0x89, - 0x08, 0xa6, 0x07, 0x90, 0xbe, 0x83, 0xaf, 0x00, - 0x20, 0x04, 0x80, 0xa7, 0x88, 0x8b, 0x81, 0x9f, - 0x19, 0x08, 0x82, 0xb7, 0x00, 0x0a, 0x00, 0x82, - 0xb9, 0x39, 0x81, 0xbf, 0x85, 0xd1, 0x10, 0x8c, - 0x06, 0x18, 0x28, 0x11, 0xb1, 0xbe, 0x8c, 0x80, - 0xa1, 0xde, 0x04, 0x41, 0xbc, 0x00, 0x82, 0x8a, - 0x82, 0x8c, 0x82, 0x8c, 0x82, 0x8c, 0x81, 0x8b, - 0x27, 0x81, 0x89, 0x01, 0x01, 0x84, 0xb0, 0x20, - 0x89, 0x00, 0x8c, 0x80, 0x8f, 0x8c, 0xb2, 0xa0, - 0x4b, 0x8a, 0x81, 0xf0, 0x82, 0xfc, 0x80, 0x8e, - 0x80, 0xdf, 0x9f, 0xae, 0x80, 0x41, 0xd4, 0x80, - 0xa3, 0x1a, 0x24, 0x80, 0xdc, 0x85, 0xdc, 0x82, - 0x60, 0x6f, 0x15, 0x80, 0x44, 0xe1, 0x85, 0x41, - 0x0d, 0x80, 0xe1, 0x18, 0x89, 0x00, 0x9b, 0x83, - 0xcf, 0x81, 0x8d, 0xa1, 0xcd, 0x80, 0x96, 0x82, - 0xec, 0x0f, 0x02, 0x03, 0x80, 0x98, 0x0c, 0x80, - 0x40, 0x96, 0x81, 0x99, 0x91, 0x8c, 0x80, 0xa5, - 0x87, 0x98, 0x8a, 0xad, 0x82, 0xaf, 0x01, 0x19, - 0x81, 0x90, 0x80, 0x94, 0x81, 0xc1, 0x29, 0x09, - 0x81, 0x8b, 0x07, 0x80, 0xa2, 0x80, 0x8a, 0x80, - 0xb2, 0x00, 0x11, 0x0c, 0x08, 0x80, 0x9a, 0x80, - 0x8d, 0x0c, 0x08, 0x80, 0xe3, 0x84, 0x88, 0x82, - 0xf8, 0x01, 0x03, 0x80, 0x60, 0x4f, 0x2f, 0x80, - 0x40, 0x92, 0x8f, 0x42, 0x3d, 0x8f, 0x10, 0x8b, - 0x8f, 0xa1, 0x01, 0x80, 0x40, 0xa8, 0x06, 0x05, - 0x80, 0x8a, 0x80, 0xa2, 0x00, 0x80, 0xae, 0x80, - 0xac, 0x81, 0xc2, 0x80, 0x94, 0x82, 0x42, 0x00, - 0x80, 0x40, 0xe1, 0x80, 0x40, 0x94, 0x84, 0x46, - 0x85, 0x10, 0x0c, 0x83, 0xa7, 0x13, 0x80, 0x40, - 0xa4, 0x81, 0x42, 0x3c, 0x83, 0x41, 0x82, 0x81, - 0x40, 0x98, 0x8a, 0x40, 0xaf, 0x80, 0xb5, 0x8e, - 0xb7, 0x82, 0xb0, 0x19, 0x09, 0x80, 0x8e, 0x80, - 0xb1, 0x82, 0xa3, 0x20, 0x87, 0xbd, 0x80, 0x8b, - 0x81, 0xb3, 0x88, 0x89, 0x19, 0x80, 0xde, 0x11, - 0x00, 0x0d, 0x80, 0x40, 0x9f, 0x02, 0x87, 0x94, - 0x81, 0xb8, 0x0a, 0x80, 0xa4, 0x32, 0x84, 0x40, - 0xc2, 0x39, 0x10, 0x80, 0x96, 0x80, 0xd3, 0x28, - 0x03, 0x08, 0x81, 0x40, 0xed, 0x1d, 0x08, 0x81, - 0x9a, 0x81, 0xd4, 0x39, 0x00, 0x81, 0xe9, 0x00, - 0x01, 0x28, 0x80, 0xe4, 0x11, 0x18, 0x84, 0x41, - 0x02, 0x88, 0x01, 0x40, 0xff, 0x08, 0x03, 0x80, - 0x40, 0x8f, 0x19, 0x0b, 0x80, 0x9f, 0x89, 0xa7, - 0x29, 0x1f, 0x80, 0x88, 0x29, 0x82, 0xad, 0x8c, - 0x01, 0x41, 0x95, 0x30, 0x28, 0x80, 0xd1, 0x95, - 0x0e, 0x01, 0x01, 0xf9, 0x2a, 0x00, 0x08, 0x30, - 0x80, 0xc7, 0x0a, 0x00, 0x80, 0x41, 0x5a, 0x81, - 0x55, 0x3a, 0x88, 0x60, 0x36, 0xb6, 0x84, 0xba, - 0x86, 0x88, 0x83, 0x44, 0x0a, 0x80, 0xbe, 0x90, - 0xbf, 0x08, 0x81, 0x60, 0x4c, 0xb7, 0x08, 0x83, - 0x54, 0xc2, 0x82, 0x88, 0x8f, 0x0e, 0x9d, 0x83, - 0x40, 0x93, 0x82, 0x47, 0xba, 0xb6, 0x83, 0xb1, - 0x38, 0x8d, 0x80, 0x95, 0x20, 0x8e, 0x45, 0x4f, - 0x30, 0x90, 0x0e, 0x01, 0x04, 0x41, 0x04, 0x8d, - 0x41, 0xad, 0x83, 0x45, 0xdf, 0x86, 0xec, 0x87, - 0x4a, 0xae, 0x84, 0x6c, 0x0c, 0x00, 0x80, 0x9d, - 0xdf, 0xff, 0x40, 0xef, + 0x97, 0x97, 0xaa, 0x82, 0xab, 0x06, 0x0d, 0x87, + 0xa8, 0xb9, 0xb6, 0x00, 0x03, 0x3b, 0x02, 0x86, + 0x89, 0x81, 0x8c, 0x80, 0x8e, 0x80, 0xb9, 0x03, + 0x1f, 0x80, 0x93, 0x81, 0x99, 0x01, 0x81, 0xb8, + 0x03, 0x0b, 0x09, 0x12, 0x80, 0x9d, 0x0a, 0x80, + 0x8a, 0x81, 0xb8, 0x03, 0x20, 0x0b, 0x80, 0x93, + 0x81, 0x95, 0x28, 0x80, 0xb9, 0x01, 0x00, 0x1f, + 0x06, 0x81, 0x8a, 0x81, 0x9d, 0x80, 0xbc, 0x80, + 0x8b, 0x80, 0xb1, 0x02, 0x80, 0xb6, 0x00, 0x14, + 0x10, 0x1e, 0x81, 0x8a, 0x81, 0x9c, 0x80, 0xb9, + 0x01, 0x05, 0x04, 0x81, 0x93, 0x81, 0x9b, 0x81, + 0xb8, 0x0b, 0x1f, 0x80, 0x93, 0x81, 0x9c, 0x80, + 0xc7, 0x06, 0x10, 0x80, 0xd9, 0x01, 0x86, 0x8a, + 0x88, 0xe1, 0x01, 0x88, 0x88, 0x00, 0x86, 0xc8, + 0x81, 0x9a, 0x00, 0x00, 0x80, 0xb6, 0x8d, 0x04, + 0x01, 0x84, 0x8a, 0x80, 0xa3, 0x88, 0x80, 0xe5, + 0x18, 0x28, 0x09, 0x81, 0x98, 0x0b, 0x82, 0x8f, + 0x83, 0x8c, 0x01, 0x0d, 0x80, 0x8e, 0x80, 0xdd, + 0x80, 0x42, 0x5f, 0x82, 0x43, 0xb1, 0x82, 0x9c, + 0x81, 0x9d, 0x81, 0x9d, 0x81, 0xbf, 0x08, 0x37, + 0x01, 0x8a, 0x10, 0x20, 0xac, 0x84, 0xb2, 0x80, + 0xc0, 0x81, 0xa1, 0x80, 0xf5, 0x13, 0x81, 0x88, + 0x05, 0x82, 0x40, 0xda, 0x09, 0x80, 0xb9, 0x00, + 0x30, 0x00, 0x01, 0x3d, 0x89, 0x08, 0xa6, 0x07, + 0x9e, 0xb0, 0x83, 0xaf, 0x00, 0x20, 0x04, 0x80, + 0xa7, 0x88, 0x8b, 0x81, 0x9f, 0x19, 0x08, 0x82, + 0xb7, 0x00, 0x0a, 0x00, 0x82, 0xb9, 0x39, 0x81, + 0xbf, 0x85, 0xd1, 0x10, 0x8c, 0x06, 0x18, 0x28, + 0x11, 0xb1, 0xbe, 0x8c, 0x80, 0xa1, 0xe4, 0x41, + 0xbc, 0x00, 0x82, 0x8a, 0x82, 0x8c, 0x82, 0x8c, + 0x82, 0x8c, 0x81, 0x8b, 0x27, 0x81, 0x89, 0x01, + 0x01, 0x84, 0xb0, 0x20, 0x89, 0x00, 0x8c, 0x80, + 0x8f, 0x8c, 0xb2, 0xa0, 0x4b, 0x8a, 0x81, 0xf0, + 0x82, 0xfc, 0x80, 0x8e, 0x80, 0xdf, 0x9f, 0xae, + 0x80, 0x41, 0xd4, 0x80, 0xa3, 0x1a, 0x24, 0x80, + 0xdc, 0x85, 0xdc, 0x82, 0x60, 0x6f, 0x15, 0x80, + 0x44, 0xe1, 0x85, 0x41, 0x0d, 0x80, 0xe1, 0x18, + 0x89, 0x00, 0x9b, 0x83, 0xcf, 0x81, 0x8d, 0xa1, + 0xcd, 0x80, 0x96, 0x82, 0xe6, 0x12, 0x0f, 0x02, + 0x03, 0x80, 0x98, 0x0c, 0x80, 0x40, 0x96, 0x81, + 0x99, 0x91, 0x8c, 0x80, 0xa5, 0x87, 0x98, 0x8a, + 0xad, 0x82, 0xaf, 0x01, 0x19, 0x81, 0x90, 0x80, + 0x94, 0x81, 0xc1, 0x29, 0x09, 0x81, 0x8b, 0x07, + 0x80, 0xa2, 0x80, 0x8a, 0x80, 0xb2, 0x00, 0x11, + 0x0c, 0x08, 0x80, 0x9a, 0x80, 0x8d, 0x0c, 0x08, + 0x80, 0xe3, 0x84, 0x88, 0x82, 0xf8, 0x01, 0x03, + 0x80, 0x60, 0x4f, 0x2f, 0x80, 0x40, 0x92, 0x90, + 0x42, 0x3c, 0x8f, 0x10, 0x8b, 0x8f, 0xa1, 0x01, + 0x80, 0x40, 0xa8, 0x06, 0x05, 0x80, 0x8a, 0x80, + 0xa2, 0x00, 0x80, 0xae, 0x80, 0xac, 0x81, 0xc2, + 0x80, 0x94, 0x82, 0x42, 0x00, 0x80, 0x40, 0xe1, + 0x80, 0x40, 0x94, 0x84, 0x44, 0x04, 0x28, 0xa9, + 0x80, 0x88, 0x42, 0x45, 0x10, 0x0c, 0x83, 0xa7, + 0x13, 0x80, 0x40, 0xa4, 0x81, 0x42, 0x3c, 0x83, + 0x41, 0x82, 0x81, 0xcf, 0x82, 0xc5, 0x8a, 0xb0, + 0x83, 0xfa, 0x80, 0xb5, 0x8e, 0xa8, 0x01, 0x81, + 0x89, 0x82, 0xb0, 0x19, 0x09, 0x03, 0x80, 0x89, + 0x80, 0xb1, 0x82, 0xa3, 0x20, 0x87, 0xbd, 0x80, + 0x8b, 0x81, 0xb3, 0x88, 0x89, 0x19, 0x80, 0xde, + 0x11, 0x00, 0x0d, 0x01, 0x80, 0x40, 0x9c, 0x02, + 0x87, 0x94, 0x81, 0xb8, 0x0a, 0x80, 0xa4, 0x32, + 0x84, 0x40, 0xc2, 0x39, 0x10, 0x80, 0x96, 0x80, + 0xd3, 0x28, 0x03, 0x08, 0x81, 0x40, 0xed, 0x1d, + 0x08, 0x81, 0x9a, 0x81, 0xd4, 0x39, 0x00, 0x81, + 0xe9, 0x00, 0x01, 0x28, 0x80, 0xe4, 0x11, 0x18, + 0x84, 0x41, 0x02, 0x88, 0x01, 0x40, 0xff, 0x08, + 0x03, 0x80, 0x40, 0x8f, 0x19, 0x0b, 0x80, 0x9f, + 0x89, 0xa7, 0x29, 0x1f, 0x80, 0x88, 0x29, 0x82, + 0xad, 0x8c, 0x01, 0x41, 0x95, 0x30, 0x28, 0x80, + 0xd1, 0x95, 0x0e, 0x01, 0x01, 0xf9, 0x2a, 0x00, + 0x08, 0x30, 0x80, 0xc7, 0x0a, 0x00, 0x80, 0x41, + 0x5a, 0x81, 0x8a, 0x81, 0xb3, 0x24, 0x00, 0x80, + 0x54, 0xec, 0x90, 0x85, 0x8e, 0x60, 0x36, 0x99, + 0x84, 0xba, 0x86, 0x88, 0x83, 0x44, 0x0a, 0x80, + 0xbe, 0x90, 0xbf, 0x08, 0x81, 0x60, 0x40, 0x0a, + 0x18, 0x30, 0x81, 0x4c, 0x9d, 0x08, 0x83, 0x52, + 0x5b, 0xad, 0x81, 0x96, 0x42, 0x1f, 0x82, 0x88, + 0x8f, 0x0e, 0x9d, 0x83, 0x40, 0x93, 0x82, 0x47, + 0xba, 0xb6, 0x83, 0xb1, 0x38, 0x8d, 0x80, 0x95, + 0x20, 0x8e, 0x45, 0x4f, 0x30, 0x90, 0x0e, 0x01, + 0x04, 0x84, 0xbd, 0xa0, 0x80, 0x40, 0x9f, 0x8d, + 0x41, 0x6f, 0x80, 0xbc, 0x83, 0x41, 0xfa, 0x84, + 0x43, 0xdf, 0x86, 0xec, 0x87, 0x4a, 0xae, 0x84, + 0x6c, 0x0c, 0x00, 0x80, 0x9d, 0xdf, 0xff, 0x40, + 0xef, }; -static const uint8_t unicode_prop_Case_Ignorable_index[66] = { +static const uint8_t unicode_prop_Case_Ignorable_index[69] = { 0xbe, 0x05, 0x00, 0xfe, 0x07, 0x00, 0x52, 0x0a, - 0x20, 0x05, 0x0c, 0x20, 0x3b, 0x0e, 0x40, 0x61, - 0x10, 0x40, 0x0f, 0x18, 0x20, 0x43, 0x1b, 0x60, - 0x79, 0x1d, 0x00, 0xf1, 0x20, 0x00, 0x0d, 0xa6, - 0x40, 0x2e, 0xa9, 0x20, 0xde, 0xaa, 0x00, 0x0f, - 0xff, 0x20, 0xe7, 0x0a, 0x41, 0x82, 0x11, 0x21, - 0xc4, 0x14, 0x61, 0x44, 0x19, 0x01, 0x48, 0x1d, - 0x21, 0xa4, 0xbc, 0x01, 0x3e, 0xe1, 0x01, 0xf0, - 0x01, 0x0e, + 0xa0, 0xc1, 0x0b, 0x00, 0x82, 0x0d, 0x00, 0x3f, + 0x10, 0x80, 0xd4, 0x17, 0x40, 0xcf, 0x1a, 0x20, + 0xf5, 0x1c, 0x00, 0x80, 0x20, 0x00, 0x16, 0xa0, + 0x00, 0xc6, 0xa8, 0x00, 0xc2, 0xaa, 0x60, 0x56, + 0xfe, 0x20, 0xb1, 0x07, 0x01, 0x75, 0x10, 0x01, + 0xeb, 0x12, 0x21, 0x41, 0x16, 0x01, 0x5c, 0x1a, + 0x01, 0x43, 0x1f, 0x01, 0x2e, 0xcf, 0x41, 0x25, + 0xe0, 0x01, 0xf0, 0x01, 0x0e, }; -static const uint8_t unicode_prop_ID_Start_table[1045] = { +static const uint8_t unicode_prop_ID_Start_table[1100] = { 0xc0, 0x99, 0x85, 0x99, 0xae, 0x80, 0x89, 0x03, 0x04, 0x96, 0x80, 0x9e, 0x80, 0x41, 0xc9, 0x83, 0x8b, 0x8d, 0x26, 0x00, 0x80, 0x40, 0x80, 0x20, @@ -301,241 +313,253 @@ static const uint8_t unicode_prop_ID_Start_table[1045] = { 0x89, 0x11, 0x80, 0x8f, 0x00, 0x9d, 0x9c, 0xd8, 0x8a, 0x80, 0x97, 0xa0, 0x88, 0x0b, 0x04, 0x95, 0x18, 0x88, 0x02, 0x80, 0x96, 0x98, 0x86, 0x8a, - 0xb4, 0x94, 0x80, 0x91, 0xbb, 0xb5, 0x10, 0x91, - 0x06, 0x89, 0x8e, 0x8f, 0x1f, 0x09, 0x81, 0x95, - 0x06, 0x00, 0x13, 0x10, 0x8f, 0x80, 0x8c, 0x08, - 0x82, 0x8d, 0x81, 0x89, 0x07, 0x2b, 0x09, 0x95, - 0x06, 0x01, 0x01, 0x01, 0x9e, 0x18, 0x80, 0x92, - 0x82, 0x8f, 0x88, 0x02, 0x80, 0x95, 0x06, 0x01, - 0x04, 0x10, 0x91, 0x80, 0x8e, 0x81, 0x96, 0x80, - 0x8a, 0x39, 0x09, 0x95, 0x06, 0x01, 0x04, 0x10, - 0x9d, 0x08, 0x82, 0x8e, 0x80, 0x90, 0x00, 0x2a, - 0x10, 0x1a, 0x08, 0x00, 0x0a, 0x0a, 0x12, 0x8b, - 0x95, 0x80, 0xb3, 0x38, 0x10, 0x96, 0x80, 0x8f, - 0x10, 0x99, 0x14, 0x81, 0x9d, 0x03, 0x38, 0x10, - 0x96, 0x80, 0x89, 0x04, 0x10, 0x9f, 0x00, 0x81, - 0x8e, 0x81, 0x90, 0x88, 0x02, 0x80, 0xa8, 0x08, - 0x8f, 0x04, 0x17, 0x82, 0x97, 0x2c, 0x91, 0x82, - 0x97, 0x80, 0x88, 0x00, 0x0e, 0xb9, 0xaf, 0x01, - 0x8b, 0x86, 0xb9, 0x08, 0x00, 0x20, 0x97, 0x00, - 0x80, 0x89, 0x01, 0x88, 0x01, 0x20, 0x80, 0x94, - 0x83, 0x9f, 0x80, 0xbe, 0x38, 0xa3, 0x9a, 0x84, - 0xf2, 0xaa, 0x93, 0x80, 0x8f, 0x2b, 0x1a, 0x02, - 0x0e, 0x13, 0x8c, 0x8b, 0x80, 0x90, 0xa5, 0x00, - 0x20, 0x81, 0xaa, 0x80, 0x41, 0x4c, 0x03, 0x0e, - 0x00, 0x03, 0x81, 0xa8, 0x03, 0x81, 0xa0, 0x03, - 0x0e, 0x00, 0x03, 0x81, 0x8e, 0x80, 0xb8, 0x03, - 0x81, 0xc2, 0xa4, 0x8f, 0x8f, 0xd5, 0x0d, 0x82, - 0x42, 0x6b, 0x81, 0x90, 0x80, 0x99, 0x84, 0xca, - 0x82, 0x8a, 0x86, 0x8c, 0x03, 0x8d, 0x91, 0x8d, - 0x91, 0x8d, 0x8c, 0x02, 0x8e, 0xb3, 0xa2, 0x03, - 0x80, 0xc2, 0xd8, 0x86, 0xa8, 0x00, 0x84, 0xc5, - 0x89, 0x9e, 0xb0, 0x9d, 0x0c, 0x8a, 0xab, 0x83, - 0x99, 0xb5, 0x96, 0x88, 0xb4, 0xd1, 0x80, 0xdc, - 0xae, 0x90, 0x86, 0xb6, 0x9d, 0x8c, 0x81, 0x89, - 0xab, 0x99, 0xa3, 0xa8, 0x82, 0x89, 0xa3, 0x81, - 0x88, 0x86, 0xaa, 0x0a, 0xa8, 0x18, 0x28, 0x0a, - 0x04, 0x40, 0xbf, 0xbf, 0x41, 0x15, 0x0d, 0x81, - 0xa5, 0x0d, 0x0f, 0x00, 0x00, 0x00, 0x80, 0x9e, - 0x81, 0xb4, 0x06, 0x00, 0x12, 0x06, 0x13, 0x0d, - 0x83, 0x8c, 0x22, 0x06, 0xf3, 0x80, 0x8c, 0x80, - 0x8f, 0x8c, 0xe4, 0x03, 0x01, 0x89, 0x00, 0x0d, - 0x28, 0x00, 0x00, 0x80, 0x8f, 0x0b, 0x24, 0x18, - 0x90, 0xa8, 0x4a, 0x76, 0xae, 0x80, 0xae, 0x80, - 0x40, 0x84, 0x2b, 0x11, 0x8b, 0xa5, 0x00, 0x20, - 0x81, 0xb7, 0x30, 0x8f, 0x96, 0x88, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x86, 0x42, 0x25, - 0x82, 0x98, 0x88, 0x34, 0x0c, 0x83, 0xd5, 0x1c, - 0x80, 0xd9, 0x03, 0x84, 0xaa, 0x80, 0xdd, 0x90, - 0x9f, 0xaf, 0x8f, 0x41, 0xff, 0x59, 0xbf, 0xbf, - 0x60, 0x51, 0xfc, 0x82, 0x44, 0x8c, 0xc2, 0xad, - 0x81, 0x41, 0x0c, 0x82, 0x8f, 0x89, 0x81, 0x93, - 0xae, 0x8f, 0x9e, 0x81, 0xcf, 0xa6, 0x88, 0x81, - 0xe6, 0x81, 0xb4, 0x81, 0x88, 0xa9, 0x8c, 0x02, - 0x03, 0x80, 0x96, 0x9c, 0xb3, 0x8d, 0xb1, 0xbd, - 0x2a, 0x00, 0x81, 0x8a, 0x9b, 0x89, 0x96, 0x98, - 0x9c, 0x86, 0xae, 0x9b, 0x80, 0x8f, 0x20, 0x89, - 0x89, 0x20, 0xa8, 0x96, 0x10, 0x87, 0x93, 0x96, - 0x10, 0x82, 0xb1, 0x00, 0x11, 0x0c, 0x08, 0x00, - 0x97, 0x11, 0x8a, 0x32, 0x8b, 0x29, 0x29, 0x85, - 0x88, 0x30, 0x30, 0xaa, 0x80, 0x8d, 0x85, 0xf2, - 0x9c, 0x60, 0x2b, 0xa3, 0x8b, 0x96, 0x83, 0xb0, - 0x60, 0x21, 0x03, 0x41, 0x6d, 0x81, 0xe9, 0xa5, - 0x86, 0x8b, 0x24, 0x00, 0x89, 0x80, 0x8c, 0x04, - 0x00, 0x01, 0x01, 0x80, 0xeb, 0xa0, 0x41, 0x6a, - 0x91, 0xbf, 0x81, 0xb5, 0xa7, 0x8b, 0xf3, 0x20, - 0x40, 0x86, 0xa3, 0x99, 0x85, 0x99, 0x8a, 0xd8, - 0x15, 0x0d, 0x0d, 0x0a, 0xa2, 0x8b, 0x80, 0x99, - 0x80, 0x92, 0x01, 0x80, 0x8e, 0x81, 0x8d, 0xa1, - 0xfa, 0xc4, 0xb4, 0x41, 0x0a, 0x9c, 0x82, 0xb0, - 0xae, 0x9f, 0x8c, 0x9d, 0x84, 0xa5, 0x89, 0x9d, - 0x81, 0xa3, 0x1f, 0x04, 0xa9, 0x40, 0x9d, 0x91, - 0xa3, 0x83, 0xa3, 0x83, 0xa7, 0x87, 0xb3, 0x40, - 0x9b, 0x41, 0x36, 0x88, 0x95, 0x89, 0x87, 0x40, - 0x97, 0x29, 0x00, 0xab, 0x01, 0x10, 0x81, 0x96, - 0x89, 0x96, 0x88, 0x9e, 0xc0, 0x92, 0x01, 0x89, - 0x95, 0x89, 0x99, 0xc5, 0xb7, 0x29, 0xbf, 0x80, - 0x8e, 0x18, 0x10, 0x9c, 0xa9, 0x9c, 0x82, 0x9c, - 0xa2, 0x38, 0x9b, 0x9a, 0xb5, 0x89, 0x95, 0x89, - 0x92, 0x8c, 0x91, 0xed, 0xc8, 0xb6, 0xb2, 0x8c, - 0xb2, 0x8c, 0xa3, 0x41, 0x5b, 0xa9, 0x29, 0xcd, - 0x9c, 0x89, 0x07, 0x95, 0xe9, 0x94, 0x9a, 0x96, - 0x8b, 0xb4, 0xca, 0xac, 0x9f, 0x98, 0x99, 0xa3, - 0x9c, 0x01, 0x07, 0xa2, 0x10, 0x8b, 0xaf, 0x8d, - 0x83, 0x94, 0x00, 0x80, 0xa2, 0x91, 0x80, 0x98, - 0xd3, 0x30, 0x00, 0x18, 0x8e, 0x80, 0x89, 0x86, - 0xae, 0xa5, 0x39, 0x09, 0x95, 0x06, 0x01, 0x04, - 0x10, 0x91, 0x80, 0x8b, 0x84, 0x40, 0x9d, 0xb4, - 0x91, 0x83, 0x93, 0x82, 0x9d, 0xaf, 0x93, 0x08, - 0x80, 0x40, 0xb7, 0xae, 0xa8, 0x83, 0xa3, 0xaf, - 0x93, 0x80, 0xba, 0xaa, 0x8c, 0x80, 0xc6, 0x9a, - 0x40, 0xe4, 0xab, 0xf3, 0xbf, 0x9e, 0x39, 0x01, - 0x38, 0x08, 0x97, 0x8e, 0x00, 0x80, 0xdd, 0x39, - 0xa6, 0x8f, 0x00, 0x80, 0x9b, 0x80, 0x89, 0xa7, - 0x30, 0x94, 0x80, 0x8a, 0xad, 0x92, 0x80, 0xa1, - 0xb8, 0x41, 0x06, 0x88, 0x80, 0xa4, 0x90, 0x80, - 0xb0, 0x9d, 0xef, 0x30, 0x08, 0xa5, 0x94, 0x80, - 0x98, 0x28, 0x08, 0x9f, 0x8d, 0x80, 0x41, 0x46, - 0x92, 0x40, 0xbc, 0x80, 0xce, 0x43, 0x99, 0xe5, - 0xee, 0x90, 0x40, 0xc3, 0x4a, 0xbb, 0x44, 0x2e, - 0x4f, 0xd0, 0x42, 0x46, 0x60, 0x21, 0xb8, 0x42, - 0x38, 0x86, 0x9e, 0xf0, 0x9d, 0x91, 0xaf, 0x8f, - 0x83, 0x9e, 0x94, 0x84, 0x92, 0x42, 0xaf, 0xbf, - 0xff, 0xca, 0x20, 0xc1, 0x8c, 0xbf, 0x08, 0x80, - 0x9b, 0x57, 0xf7, 0x87, 0x44, 0xd5, 0xa9, 0x88, - 0x60, 0x22, 0xf6, 0x41, 0x1e, 0xb0, 0x82, 0x90, - 0x1f, 0x41, 0x8b, 0x49, 0x03, 0xea, 0x84, 0x8c, - 0x82, 0x88, 0x86, 0x89, 0x57, 0x65, 0xd4, 0x80, - 0xc6, 0x01, 0x08, 0x09, 0x0b, 0x80, 0x8b, 0x00, - 0x06, 0x80, 0xc0, 0x03, 0x0f, 0x06, 0x80, 0x9b, - 0x03, 0x04, 0x00, 0x16, 0x80, 0x41, 0x53, 0x81, - 0x98, 0x80, 0x98, 0x80, 0x9e, 0x80, 0x98, 0x80, - 0x9e, 0x80, 0x98, 0x80, 0x9e, 0x80, 0x98, 0x80, - 0x9e, 0x80, 0x98, 0x07, 0x49, 0x33, 0xac, 0x89, - 0x86, 0x8f, 0x80, 0x41, 0x70, 0xab, 0x45, 0x13, - 0x40, 0xc4, 0xba, 0xc3, 0x30, 0x44, 0xb3, 0x18, - 0x9a, 0x01, 0x00, 0x08, 0x80, 0x89, 0x03, 0x00, - 0x00, 0x28, 0x18, 0x00, 0x00, 0x02, 0x01, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0b, - 0x06, 0x03, 0x03, 0x00, 0x80, 0x89, 0x80, 0x90, - 0x22, 0x04, 0x80, 0x90, 0x51, 0x43, 0x60, 0xa6, - 0xdd, 0xa1, 0x50, 0x34, 0x8a, 0x40, 0xdd, 0x81, - 0x56, 0x81, 0x8d, 0x5d, 0x30, 0x4c, 0x1e, 0x42, - 0x1d, 0x45, 0xe1, 0x53, 0x4a, + 0x84, 0x97, 0x05, 0x90, 0xa9, 0xb9, 0xb5, 0x10, + 0x91, 0x06, 0x89, 0x8e, 0x8f, 0x1f, 0x09, 0x81, + 0x95, 0x06, 0x00, 0x13, 0x10, 0x8f, 0x80, 0x8c, + 0x08, 0x82, 0x8d, 0x81, 0x89, 0x07, 0x2b, 0x09, + 0x95, 0x06, 0x01, 0x01, 0x01, 0x9e, 0x18, 0x80, + 0x92, 0x82, 0x8f, 0x88, 0x02, 0x80, 0x95, 0x06, + 0x01, 0x04, 0x10, 0x91, 0x80, 0x8e, 0x81, 0x96, + 0x80, 0x8a, 0x39, 0x09, 0x95, 0x06, 0x01, 0x04, + 0x10, 0x9d, 0x08, 0x82, 0x8e, 0x80, 0x90, 0x00, + 0x2a, 0x10, 0x1a, 0x08, 0x00, 0x0a, 0x0a, 0x12, + 0x8b, 0x95, 0x80, 0xb3, 0x38, 0x10, 0x96, 0x80, + 0x8f, 0x10, 0x99, 0x11, 0x01, 0x81, 0x9d, 0x03, + 0x38, 0x10, 0x96, 0x80, 0x89, 0x04, 0x10, 0x9e, + 0x08, 0x81, 0x8e, 0x81, 0x90, 0x88, 0x02, 0x80, + 0xa8, 0x08, 0x8f, 0x04, 0x17, 0x82, 0x97, 0x2c, + 0x91, 0x82, 0x97, 0x80, 0x88, 0x00, 0x0e, 0xb9, + 0xaf, 0x01, 0x8b, 0x86, 0xb9, 0x08, 0x00, 0x20, + 0x97, 0x00, 0x80, 0x89, 0x01, 0x88, 0x01, 0x20, + 0x80, 0x94, 0x83, 0x9f, 0x80, 0xbe, 0x38, 0xa3, + 0x9a, 0x84, 0xf2, 0xaa, 0x93, 0x80, 0x8f, 0x2b, + 0x1a, 0x02, 0x0e, 0x13, 0x8c, 0x8b, 0x80, 0x90, + 0xa5, 0x00, 0x20, 0x81, 0xaa, 0x80, 0x41, 0x4c, + 0x03, 0x0e, 0x00, 0x03, 0x81, 0xa8, 0x03, 0x81, + 0xa0, 0x03, 0x0e, 0x00, 0x03, 0x81, 0x8e, 0x80, + 0xb8, 0x03, 0x81, 0xc2, 0xa4, 0x8f, 0x8f, 0xd5, + 0x0d, 0x82, 0x42, 0x6b, 0x81, 0x90, 0x80, 0x99, + 0x84, 0xca, 0x82, 0x8a, 0x86, 0x91, 0x8c, 0x92, + 0x8d, 0x91, 0x8d, 0x8c, 0x02, 0x8e, 0xb3, 0xa2, + 0x03, 0x80, 0xc2, 0xd8, 0x86, 0xa8, 0x00, 0x84, + 0xc5, 0x89, 0x9e, 0xb0, 0x9d, 0x0c, 0x8a, 0xab, + 0x83, 0x99, 0xb5, 0x96, 0x88, 0xb4, 0xd1, 0x80, + 0xdc, 0xae, 0x90, 0x87, 0xb5, 0x9d, 0x8c, 0x81, + 0x89, 0xab, 0x99, 0xa3, 0xa8, 0x82, 0x89, 0xa3, + 0x81, 0x88, 0x86, 0xaa, 0x0a, 0xa8, 0x18, 0x28, + 0x0a, 0x04, 0x40, 0xbf, 0xbf, 0x41, 0x15, 0x0d, + 0x81, 0xa5, 0x0d, 0x0f, 0x00, 0x00, 0x00, 0x80, + 0x9e, 0x81, 0xb4, 0x06, 0x00, 0x12, 0x06, 0x13, + 0x0d, 0x83, 0x8c, 0x22, 0x06, 0xf3, 0x80, 0x8c, + 0x80, 0x8f, 0x8c, 0xe4, 0x03, 0x01, 0x89, 0x00, + 0x0d, 0x28, 0x00, 0x00, 0x80, 0x8f, 0x0b, 0x24, + 0x18, 0x90, 0xa8, 0x4a, 0x76, 0x40, 0xe4, 0x2b, + 0x11, 0x8b, 0xa5, 0x00, 0x20, 0x81, 0xb7, 0x30, + 0x8f, 0x96, 0x88, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x86, 0x42, 0x25, 0x82, 0x98, 0x88, + 0x34, 0x0c, 0x83, 0xd5, 0x1c, 0x80, 0xd9, 0x03, + 0x84, 0xaa, 0x80, 0xdd, 0x90, 0x9f, 0xaf, 0x8f, + 0x41, 0xff, 0x59, 0xbf, 0xbf, 0x60, 0x56, 0x8c, + 0xc2, 0xad, 0x81, 0x41, 0x0c, 0x82, 0x8f, 0x89, + 0x81, 0x93, 0xae, 0x8f, 0x9e, 0x81, 0xcf, 0xa6, + 0x88, 0x81, 0xe6, 0x81, 0xbf, 0x21, 0x00, 0x04, + 0x97, 0x8f, 0x02, 0x03, 0x80, 0x96, 0x9c, 0xb3, + 0x8d, 0xb1, 0xbd, 0x2a, 0x00, 0x81, 0x8a, 0x9b, + 0x89, 0x96, 0x98, 0x9c, 0x86, 0xae, 0x9b, 0x80, + 0x8f, 0x20, 0x89, 0x89, 0x20, 0xa8, 0x96, 0x10, + 0x87, 0x93, 0x96, 0x10, 0x82, 0xb1, 0x00, 0x11, + 0x0c, 0x08, 0x00, 0x97, 0x11, 0x8a, 0x32, 0x8b, + 0x29, 0x29, 0x85, 0x88, 0x30, 0x30, 0xaa, 0x80, + 0x8d, 0x85, 0xf2, 0x9c, 0x60, 0x2b, 0xa3, 0x8b, + 0x96, 0x83, 0xb0, 0x60, 0x21, 0x03, 0x41, 0x6d, + 0x81, 0xe9, 0xa5, 0x86, 0x8b, 0x24, 0x00, 0x89, + 0x80, 0x8c, 0x04, 0x00, 0x01, 0x01, 0x80, 0xeb, + 0xa0, 0x41, 0x6a, 0x91, 0xbf, 0x81, 0xb5, 0xa7, + 0x8b, 0xf3, 0x20, 0x40, 0x86, 0xa3, 0x99, 0x85, + 0x99, 0x8a, 0xd8, 0x15, 0x0d, 0x0d, 0x0a, 0xa2, + 0x8b, 0x80, 0x99, 0x80, 0x92, 0x01, 0x80, 0x8e, + 0x81, 0x8d, 0xa1, 0xfa, 0xc4, 0xb4, 0x41, 0x0a, + 0x9c, 0x82, 0xb0, 0xae, 0x9f, 0x8c, 0x9d, 0x84, + 0xa5, 0x89, 0x9d, 0x81, 0xa3, 0x1f, 0x04, 0xa9, + 0x40, 0x9d, 0x91, 0xa3, 0x83, 0xa3, 0x83, 0xa7, + 0x87, 0xb3, 0x8b, 0x8a, 0x80, 0x8e, 0x06, 0x01, + 0x80, 0x8a, 0x80, 0x8e, 0x06, 0x01, 0xc2, 0x41, + 0x36, 0x88, 0x95, 0x89, 0x87, 0x97, 0x28, 0xa9, + 0x80, 0x88, 0xc4, 0x29, 0x00, 0xab, 0x01, 0x10, + 0x81, 0x96, 0x89, 0x96, 0x88, 0x9e, 0xc0, 0x92, + 0x01, 0x89, 0x95, 0x89, 0x99, 0xc5, 0xb7, 0x29, + 0xbf, 0x80, 0x8e, 0x18, 0x10, 0x9c, 0xa9, 0x9c, + 0x82, 0x9c, 0xa2, 0x38, 0x9b, 0x9a, 0xb5, 0x89, + 0x95, 0x89, 0x92, 0x8c, 0x91, 0xed, 0xc8, 0xb6, + 0xb2, 0x8c, 0xb2, 0x8c, 0xa3, 0x41, 0x5b, 0xa9, + 0x29, 0xcd, 0x9c, 0x89, 0x07, 0x95, 0xa9, 0x91, + 0xad, 0x94, 0x9a, 0x96, 0x8b, 0xb4, 0xb8, 0x09, + 0x80, 0x8c, 0xac, 0x9f, 0x98, 0x99, 0xa3, 0x9c, + 0x01, 0x07, 0xa2, 0x10, 0x8b, 0xaf, 0x8d, 0x83, + 0x94, 0x00, 0x80, 0xa2, 0x91, 0x80, 0x98, 0x92, + 0x81, 0xbe, 0x30, 0x00, 0x18, 0x8e, 0x80, 0x89, + 0x86, 0xae, 0xa5, 0x39, 0x09, 0x95, 0x06, 0x01, + 0x04, 0x10, 0x91, 0x80, 0x8b, 0x84, 0x40, 0x9d, + 0xb4, 0x91, 0x83, 0x93, 0x82, 0x9d, 0xaf, 0x93, + 0x08, 0x80, 0x40, 0xb7, 0xae, 0xa8, 0x83, 0xa3, + 0xaf, 0x93, 0x80, 0xba, 0xaa, 0x8c, 0x80, 0xc6, + 0x9a, 0xa4, 0x86, 0x40, 0xb8, 0xab, 0xf3, 0xbf, + 0x9e, 0x39, 0x01, 0x38, 0x08, 0x97, 0x8e, 0x00, + 0x80, 0xdd, 0x39, 0xa6, 0x8f, 0x00, 0x80, 0x9b, + 0x80, 0x89, 0xa7, 0x30, 0x94, 0x80, 0x8a, 0xad, + 0x92, 0x80, 0x91, 0xc8, 0x41, 0x06, 0x88, 0x80, + 0xa4, 0x90, 0x80, 0xb0, 0x9d, 0xef, 0x30, 0x08, + 0xa5, 0x94, 0x80, 0x98, 0x28, 0x08, 0x9f, 0x8d, + 0x80, 0x41, 0x46, 0x92, 0x8e, 0x00, 0x8c, 0x80, + 0xa1, 0xfb, 0x80, 0xce, 0x43, 0x99, 0xe5, 0xee, + 0x90, 0x40, 0xc3, 0x4a, 0x4b, 0xe0, 0x8e, 0x44, + 0x2f, 0x90, 0x85, 0x4f, 0xb8, 0x42, 0x46, 0x60, + 0x21, 0xb8, 0x42, 0x38, 0x86, 0x9e, 0x90, 0xce, + 0x90, 0x9d, 0x91, 0xaf, 0x8f, 0x83, 0x9e, 0x94, + 0x84, 0x92, 0x42, 0xaf, 0xbf, 0xff, 0xca, 0x20, + 0xc1, 0x8c, 0xbf, 0x08, 0x80, 0x9b, 0x57, 0xf7, + 0x87, 0x44, 0xd5, 0xa9, 0x88, 0x60, 0x22, 0xe6, + 0x18, 0x30, 0x08, 0x41, 0x22, 0x8e, 0x80, 0x9c, + 0x11, 0x80, 0x8d, 0x1f, 0x41, 0x8b, 0x49, 0x03, + 0xea, 0x84, 0x8c, 0x82, 0x88, 0x86, 0x89, 0x57, + 0x65, 0xd4, 0x80, 0xc6, 0x01, 0x08, 0x09, 0x0b, + 0x80, 0x8b, 0x00, 0x06, 0x80, 0xc0, 0x03, 0x0f, + 0x06, 0x80, 0x9b, 0x03, 0x04, 0x00, 0x16, 0x80, + 0x41, 0x53, 0x81, 0x98, 0x80, 0x98, 0x80, 0x9e, + 0x80, 0x98, 0x80, 0x9e, 0x80, 0x98, 0x80, 0x9e, + 0x80, 0x98, 0x80, 0x9e, 0x80, 0x98, 0x07, 0x47, + 0x33, 0x9e, 0x2d, 0x41, 0x04, 0xbd, 0x40, 0x91, + 0xac, 0x89, 0x86, 0x8f, 0x80, 0x41, 0x40, 0x9d, + 0x91, 0xab, 0x41, 0xe3, 0x9b, 0x42, 0xf3, 0x30, + 0x18, 0x08, 0x8e, 0x80, 0x40, 0xc4, 0xba, 0xc3, + 0x30, 0x44, 0xb3, 0x18, 0x9a, 0x01, 0x00, 0x08, + 0x80, 0x89, 0x03, 0x00, 0x00, 0x28, 0x18, 0x00, + 0x00, 0x02, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x0b, 0x06, 0x03, 0x03, 0x00, + 0x80, 0x89, 0x80, 0x90, 0x22, 0x04, 0x80, 0x90, + 0x51, 0x43, 0x60, 0xa6, 0xdf, 0x9f, 0x50, 0x39, + 0x85, 0x40, 0xdd, 0x81, 0x56, 0x81, 0x8d, 0x5d, + 0x30, 0x4c, 0x1e, 0x42, 0x1d, 0x45, 0xe1, 0x53, + 0x4a, 0x84, 0x50, 0x5f, }; -static const uint8_t unicode_prop_ID_Start_index[99] = { +static const uint8_t unicode_prop_ID_Start_index[105] = { 0xf6, 0x03, 0x20, 0xa6, 0x07, 0x00, 0xa9, 0x09, - 0x00, 0xb4, 0x0a, 0x00, 0xba, 0x0b, 0x00, 0x3e, - 0x0d, 0x00, 0xe0, 0x0e, 0x20, 0x57, 0x12, 0x00, - 0xeb, 0x16, 0x00, 0xca, 0x19, 0x20, 0xc0, 0x1d, - 0x60, 0x80, 0x20, 0x00, 0x2e, 0x2d, 0x00, 0xc0, - 0x31, 0x20, 0x89, 0xa7, 0x20, 0xf0, 0xa9, 0x00, - 0xe3, 0xab, 0x00, 0x3e, 0xfd, 0x00, 0xfb, 0x00, - 0x21, 0x37, 0x07, 0x61, 0x01, 0x0a, 0x01, 0x1d, - 0x0f, 0x21, 0x2c, 0x12, 0x01, 0xc8, 0x14, 0x21, - 0xd1, 0x19, 0x21, 0x47, 0x1d, 0x01, 0x39, 0x6a, - 0x21, 0x09, 0x8d, 0x01, 0xbc, 0xd4, 0x01, 0xa9, - 0xd7, 0x21, 0x3a, 0xee, 0x01, 0xde, 0xa6, 0x22, - 0x4b, 0x13, 0x03, + 0x20, 0xb1, 0x0a, 0x00, 0xba, 0x0b, 0x20, 0x3b, + 0x0d, 0x20, 0xc7, 0x0e, 0x20, 0x49, 0x12, 0x00, + 0x9b, 0x16, 0x00, 0xac, 0x19, 0x00, 0xc0, 0x1d, + 0x80, 0x80, 0x20, 0x20, 0x70, 0x2d, 0x00, 0x00, + 0x32, 0x00, 0xda, 0xa7, 0x00, 0x4c, 0xaa, 0x20, + 0xc7, 0xd7, 0x20, 0xfc, 0xfd, 0x20, 0x9d, 0x02, + 0x21, 0x96, 0x05, 0x01, 0xf3, 0x08, 0x01, 0xb3, + 0x0c, 0x21, 0x73, 0x11, 0x61, 0x34, 0x13, 0x01, + 0x1b, 0x17, 0x21, 0x8a, 0x1a, 0x01, 0x34, 0x1f, + 0x21, 0xbf, 0x6a, 0x01, 0x23, 0xb1, 0xa1, 0xad, + 0xd4, 0x01, 0x6f, 0xd7, 0x01, 0xff, 0xe7, 0x61, + 0x5e, 0xee, 0x01, 0xe1, 0xeb, 0x22, 0xb0, 0x23, + 0x03, }; -static const uint8_t unicode_prop_ID_Continue1_table[626] = { +static const uint8_t unicode_prop_ID_Continue1_table[660] = { 0xaf, 0x89, 0xa4, 0x80, 0xd6, 0x80, 0x42, 0x47, 0xef, 0x96, 0x80, 0x40, 0xfa, 0x84, 0x41, 0x08, 0xac, 0x00, 0x01, 0x01, 0x00, 0xc7, 0x8a, 0xaf, 0x9e, 0x28, 0xe4, 0x31, 0x29, 0x08, 0x19, 0x89, 0x96, 0x80, 0x9d, 0x9a, 0xda, 0x8a, 0x8e, 0x89, 0xa0, 0x88, 0x88, 0x80, 0x97, 0x18, 0x88, 0x02, - 0x04, 0xaa, 0x82, 0xf6, 0x8e, 0x80, 0xa0, 0xb5, - 0x10, 0x91, 0x06, 0x89, 0x09, 0x89, 0x90, 0x82, - 0xb7, 0x00, 0x31, 0x09, 0x82, 0x88, 0x80, 0x89, - 0x09, 0x89, 0x8d, 0x01, 0x82, 0xb7, 0x00, 0x23, - 0x09, 0x12, 0x80, 0x93, 0x8b, 0x10, 0x8a, 0x82, - 0xb7, 0x00, 0x38, 0x10, 0x82, 0x93, 0x09, 0x89, - 0x89, 0x28, 0x82, 0xb7, 0x00, 0x31, 0x09, 0x16, - 0x82, 0x89, 0x09, 0x89, 0x91, 0x80, 0xba, 0x22, - 0x10, 0x83, 0x88, 0x80, 0x8d, 0x89, 0x8f, 0x84, - 0xb8, 0x30, 0x10, 0x1e, 0x81, 0x8a, 0x09, 0x89, - 0x90, 0x82, 0xb7, 0x00, 0x30, 0x10, 0x1e, 0x81, - 0x8a, 0x09, 0x89, 0x8f, 0x83, 0xb6, 0x08, 0x30, - 0x10, 0x83, 0x88, 0x80, 0x89, 0x09, 0x89, 0x90, - 0x82, 0xc5, 0x03, 0x28, 0x00, 0x3d, 0x89, 0x09, - 0xbc, 0x01, 0x86, 0x8b, 0x38, 0x89, 0xd6, 0x01, - 0x88, 0x8a, 0x29, 0x89, 0xbd, 0x0d, 0x89, 0x8a, - 0x00, 0x00, 0x03, 0x81, 0xb0, 0x93, 0x01, 0x84, - 0x8a, 0x80, 0xa3, 0x88, 0x80, 0xe3, 0x93, 0x80, - 0x89, 0x8b, 0x1b, 0x10, 0x11, 0x32, 0x83, 0x8c, - 0x8b, 0x80, 0x8e, 0x42, 0xbe, 0x82, 0x88, 0x88, - 0x43, 0x9f, 0x82, 0x9c, 0x82, 0x9c, 0x81, 0x9d, - 0x81, 0xbf, 0x9f, 0x88, 0x01, 0x89, 0xa0, 0x11, - 0x89, 0x40, 0x8e, 0x80, 0xf5, 0x8b, 0x83, 0x8b, - 0x89, 0x89, 0xff, 0x8a, 0xbb, 0x84, 0xb8, 0x89, - 0x80, 0x9c, 0x81, 0x8a, 0x85, 0x89, 0x95, 0x8d, - 0x01, 0xbe, 0x84, 0xae, 0x90, 0x8a, 0x89, 0x90, - 0x88, 0x8b, 0x82, 0x9d, 0x8c, 0x81, 0x89, 0xab, - 0x8d, 0xaf, 0x93, 0x87, 0x89, 0x85, 0x89, 0xf5, - 0x10, 0x94, 0x18, 0x28, 0x0a, 0x40, 0xc5, 0xb9, - 0x04, 0x42, 0x3e, 0x81, 0x92, 0x80, 0xfa, 0x8c, - 0x18, 0x82, 0x8b, 0x4b, 0xfd, 0x82, 0x40, 0x8c, - 0x80, 0xdf, 0x9f, 0x42, 0x29, 0x85, 0xe8, 0x81, - 0x60, 0x75, 0x84, 0x89, 0xc4, 0x03, 0x89, 0x9f, - 0x81, 0xcf, 0x81, 0x41, 0x0f, 0x02, 0x03, 0x80, - 0x96, 0x23, 0x80, 0xd2, 0x81, 0xb1, 0x91, 0x89, - 0x89, 0x85, 0x91, 0x8c, 0x8a, 0x9b, 0x87, 0x98, - 0x8c, 0xab, 0x83, 0xae, 0x8d, 0x8e, 0x89, 0x8a, - 0x80, 0x89, 0x89, 0xae, 0x8d, 0x8b, 0x07, 0x09, - 0x89, 0xa0, 0x82, 0xb1, 0x00, 0x11, 0x0c, 0x08, - 0x80, 0xa8, 0x24, 0x81, 0x40, 0xeb, 0x38, 0x09, - 0x89, 0x60, 0x4f, 0x23, 0x80, 0x42, 0xe0, 0x8f, - 0x8f, 0x8f, 0x11, 0x97, 0x82, 0x40, 0xbf, 0x89, - 0xa4, 0x80, 0x42, 0xbc, 0x80, 0x40, 0xe1, 0x80, - 0x40, 0x94, 0x84, 0x41, 0x24, 0x89, 0x45, 0x56, - 0x10, 0x0c, 0x83, 0xa7, 0x13, 0x80, 0x40, 0xa4, - 0x81, 0x42, 0x3c, 0x1f, 0x89, 0x41, 0x70, 0x81, - 0x40, 0x98, 0x8a, 0x40, 0xae, 0x82, 0xb4, 0x8e, - 0x9e, 0x89, 0x8e, 0x83, 0xac, 0x8a, 0xb4, 0x89, + 0x04, 0xaa, 0x82, 0xbb, 0x87, 0xa9, 0x97, 0x80, + 0xa0, 0xb5, 0x10, 0x91, 0x06, 0x89, 0x09, 0x89, + 0x90, 0x82, 0xb7, 0x00, 0x31, 0x09, 0x82, 0x88, + 0x80, 0x89, 0x09, 0x89, 0x8d, 0x01, 0x82, 0xb7, + 0x00, 0x23, 0x09, 0x12, 0x80, 0x93, 0x8b, 0x10, + 0x8a, 0x82, 0xb7, 0x00, 0x38, 0x10, 0x82, 0x93, + 0x09, 0x89, 0x89, 0x28, 0x82, 0xb7, 0x00, 0x31, + 0x09, 0x16, 0x82, 0x89, 0x09, 0x89, 0x91, 0x80, + 0xba, 0x22, 0x10, 0x83, 0x88, 0x80, 0x8d, 0x89, + 0x8f, 0x84, 0xb6, 0x00, 0x30, 0x10, 0x1e, 0x81, + 0x8a, 0x09, 0x89, 0x90, 0x82, 0xb7, 0x00, 0x30, + 0x10, 0x1e, 0x81, 0x8a, 0x09, 0x89, 0x10, 0x8b, + 0x83, 0xb6, 0x08, 0x30, 0x10, 0x83, 0x88, 0x80, + 0x89, 0x09, 0x89, 0x90, 0x82, 0xc5, 0x03, 0x28, + 0x00, 0x3d, 0x89, 0x09, 0xbc, 0x01, 0x86, 0x8b, + 0x38, 0x89, 0xd6, 0x01, 0x88, 0x8a, 0x30, 0x89, + 0xbd, 0x0d, 0x89, 0x8a, 0x00, 0x00, 0x03, 0x81, + 0xb0, 0x93, 0x01, 0x84, 0x8a, 0x80, 0xa3, 0x88, + 0x80, 0xe3, 0x93, 0x80, 0x89, 0x8b, 0x1b, 0x10, + 0x11, 0x32, 0x83, 0x8c, 0x8b, 0x80, 0x8e, 0x42, + 0xbe, 0x82, 0x88, 0x88, 0x43, 0x9f, 0x83, 0x9b, + 0x82, 0x9c, 0x81, 0x9d, 0x81, 0xbf, 0x9f, 0x88, + 0x01, 0x89, 0xa0, 0x10, 0x8a, 0x40, 0x8e, 0x80, + 0xf5, 0x8b, 0x83, 0x8b, 0x89, 0x89, 0xff, 0x8a, + 0xbb, 0x84, 0xb8, 0x89, 0x80, 0x9c, 0x81, 0x8a, + 0x85, 0x89, 0x95, 0x8d, 0x80, 0x8f, 0xb0, 0x84, + 0xae, 0x90, 0x8a, 0x89, 0x90, 0x88, 0x8b, 0x82, + 0x9d, 0x8c, 0x81, 0x89, 0xab, 0x8d, 0xaf, 0x93, + 0x87, 0x89, 0x85, 0x89, 0xf5, 0x10, 0x94, 0x18, + 0x28, 0x0a, 0x40, 0xc5, 0xbf, 0x42, 0x3e, 0x81, + 0x92, 0x80, 0xfa, 0x8c, 0x18, 0x82, 0x8b, 0x4b, + 0xfd, 0x82, 0x40, 0x8c, 0x80, 0xdf, 0x9f, 0x42, + 0x29, 0x85, 0xe8, 0x81, 0x60, 0x75, 0x84, 0x89, + 0xc4, 0x03, 0x89, 0x9f, 0x81, 0xcf, 0x81, 0x41, + 0x0f, 0x02, 0x03, 0x80, 0x96, 0x23, 0x80, 0xd2, + 0x81, 0xb1, 0x91, 0x89, 0x89, 0x85, 0x91, 0x8c, + 0x8a, 0x9b, 0x87, 0x98, 0x8c, 0xab, 0x83, 0xae, + 0x8d, 0x8e, 0x89, 0x8a, 0x80, 0x89, 0x89, 0xae, + 0x8d, 0x8b, 0x07, 0x09, 0x89, 0xa0, 0x82, 0xb1, + 0x00, 0x11, 0x0c, 0x08, 0x80, 0xa8, 0x24, 0x81, + 0x40, 0xeb, 0x38, 0x09, 0x89, 0x60, 0x4f, 0x23, + 0x80, 0x42, 0xe0, 0x8f, 0x8f, 0x8f, 0x11, 0x97, + 0x82, 0x40, 0xbf, 0x89, 0xa4, 0x80, 0x42, 0xbc, + 0x80, 0x40, 0xe1, 0x80, 0x40, 0x94, 0x84, 0x41, + 0x24, 0x89, 0x45, 0x56, 0x10, 0x0c, 0x83, 0xa7, + 0x13, 0x80, 0x40, 0xa4, 0x81, 0x42, 0x3c, 0x1f, + 0x89, 0x41, 0x70, 0x81, 0xcf, 0x82, 0xc5, 0x8a, + 0xb0, 0x83, 0xf9, 0x82, 0xb4, 0x8e, 0x9e, 0x8a, + 0x09, 0x89, 0x83, 0xac, 0x8a, 0x30, 0xac, 0x89, 0x2a, 0xa3, 0x8d, 0x80, 0x89, 0x21, 0xab, 0x80, 0x8b, 0x82, 0xaf, 0x8d, 0x3b, 0x80, 0x8b, 0xd1, - 0x8b, 0x28, 0x40, 0x9f, 0x8b, 0x84, 0x89, 0x2b, - 0xb6, 0x08, 0x31, 0x09, 0x82, 0x88, 0x80, 0x89, - 0x09, 0x32, 0x84, 0x40, 0xbf, 0x91, 0x88, 0x89, - 0x18, 0xd0, 0x93, 0x8b, 0x89, 0x40, 0xd4, 0x31, - 0x88, 0x9a, 0x81, 0xd1, 0x90, 0x8e, 0x89, 0xd0, - 0x8c, 0x87, 0x89, 0xd2, 0x8e, 0x83, 0x89, 0x40, - 0xf1, 0x8e, 0x40, 0xa4, 0x89, 0xc5, 0x28, 0x09, - 0x18, 0x00, 0x81, 0x8b, 0x89, 0xf6, 0x31, 0x32, - 0x80, 0x9b, 0x89, 0xa7, 0x30, 0x1f, 0x80, 0x88, - 0x8a, 0xad, 0x8f, 0x41, 0x94, 0x38, 0x87, 0x8f, - 0x89, 0xb7, 0x95, 0x80, 0x8d, 0xf9, 0x2a, 0x00, - 0x08, 0x30, 0x07, 0x89, 0xaf, 0x20, 0x08, 0x27, - 0x89, 0x41, 0x48, 0x83, 0x60, 0x4b, 0x68, 0x89, - 0x40, 0x85, 0x84, 0xba, 0x86, 0x98, 0x89, 0x43, - 0xf4, 0x00, 0xb6, 0x33, 0xd0, 0x80, 0x8a, 0x81, - 0x60, 0x4c, 0xaa, 0x81, 0x54, 0xc5, 0x22, 0x2f, - 0x39, 0x86, 0x9d, 0x83, 0x40, 0x93, 0x82, 0x45, - 0x88, 0xb1, 0x41, 0xff, 0xb6, 0x83, 0xb1, 0x38, - 0x8d, 0x80, 0x95, 0x20, 0x8e, 0x45, 0x4f, 0x30, - 0x90, 0x0e, 0x01, 0x04, 0x41, 0x04, 0x86, 0x88, - 0x89, 0x41, 0xa1, 0x8d, 0x45, 0xd5, 0x86, 0xec, - 0x34, 0x89, 0x52, 0x95, 0x89, 0x6c, 0x05, 0x05, - 0x40, 0xef, + 0x8b, 0x28, 0x08, 0x40, 0x9c, 0x8b, 0x84, 0x89, + 0x2b, 0xb6, 0x08, 0x31, 0x09, 0x82, 0x88, 0x80, + 0x89, 0x09, 0x32, 0x84, 0x40, 0xbf, 0x91, 0x88, + 0x89, 0x18, 0xd0, 0x93, 0x8b, 0x89, 0x40, 0xd4, + 0x31, 0x88, 0x9a, 0x81, 0xd1, 0x90, 0x8e, 0x89, + 0xd0, 0x8c, 0x87, 0x89, 0xd2, 0x8e, 0x83, 0x89, + 0x40, 0xf1, 0x8e, 0x40, 0xa4, 0x89, 0xc5, 0x28, + 0x09, 0x18, 0x00, 0x81, 0x8b, 0x89, 0xf6, 0x31, + 0x32, 0x80, 0x9b, 0x89, 0xa7, 0x30, 0x1f, 0x80, + 0x88, 0x8a, 0xad, 0x8f, 0x41, 0x94, 0x38, 0x87, + 0x8f, 0x89, 0xb7, 0x95, 0x80, 0x8d, 0xf9, 0x2a, + 0x00, 0x08, 0x30, 0x07, 0x89, 0xaf, 0x20, 0x08, + 0x27, 0x89, 0x41, 0x48, 0x83, 0x88, 0x08, 0x80, + 0xaf, 0x32, 0x84, 0x8c, 0x89, 0x54, 0xe5, 0x05, + 0x8e, 0x60, 0x36, 0x09, 0x89, 0xd5, 0x89, 0xa5, + 0x84, 0xba, 0x86, 0x98, 0x89, 0x43, 0xf4, 0x00, + 0xb6, 0x33, 0xd0, 0x80, 0x8a, 0x81, 0x60, 0x4c, + 0xaa, 0x81, 0x52, 0x60, 0xad, 0x81, 0x96, 0x42, + 0x1d, 0x22, 0x2f, 0x39, 0x86, 0x9d, 0x83, 0x40, + 0x93, 0x82, 0x45, 0x88, 0xb1, 0x41, 0xff, 0xb6, + 0x83, 0xb1, 0x38, 0x8d, 0x80, 0x95, 0x20, 0x8e, + 0x45, 0x4f, 0x30, 0x90, 0x0e, 0x01, 0x04, 0xe3, + 0x80, 0x40, 0x9f, 0x86, 0x88, 0x89, 0x41, 0x63, + 0x80, 0xbc, 0x8d, 0x41, 0xf1, 0x8d, 0x43, 0xd5, + 0x86, 0xec, 0x34, 0x89, 0x52, 0x95, 0x89, 0x6c, + 0x05, 0x05, 0x40, 0xef, }; -static const uint8_t unicode_prop_ID_Continue1_index[60] = { - 0xfa, 0x06, 0x00, 0x84, 0x09, 0x00, 0xf0, 0x0a, - 0x00, 0x70, 0x0c, 0x00, 0xf4, 0x0d, 0x00, 0x4a, - 0x10, 0x20, 0x1a, 0x18, 0x20, 0x74, 0x1b, 0x20, - 0xdd, 0x20, 0x00, 0x0c, 0xa8, 0x00, 0x5a, 0xaa, - 0x20, 0x1a, 0xff, 0x00, 0xad, 0x0e, 0x01, 0x38, - 0x12, 0x21, 0xc1, 0x15, 0x21, 0xe5, 0x19, 0x21, - 0xaa, 0x1d, 0x21, 0x8c, 0xd1, 0x41, 0x4a, 0xe1, - 0x21, 0xf0, 0x01, 0x0e, +static const uint8_t unicode_prop_ID_Continue1_index[63] = { + 0xfa, 0x06, 0x00, 0x70, 0x09, 0x00, 0xf0, 0x0a, + 0x40, 0x57, 0x0c, 0x00, 0xf0, 0x0d, 0x60, 0xc7, + 0x0f, 0x20, 0xea, 0x17, 0x40, 0x05, 0x1b, 0x00, + 0x41, 0x20, 0x00, 0x0c, 0xa8, 0x80, 0x37, 0xaa, + 0x20, 0x50, 0xfe, 0x20, 0x3a, 0x0d, 0x21, 0x74, + 0x11, 0x01, 0x5a, 0x14, 0x21, 0x44, 0x19, 0x81, + 0x5a, 0x1d, 0xa1, 0xf5, 0x6a, 0x21, 0x45, 0xd2, + 0x41, 0xaf, 0xe2, 0x21, 0xf0, 0x01, 0x0e, }; #ifdef CONFIG_ALL_UNICODE -static const uint8_t unicode_cc_table[851] = { +static const uint8_t unicode_cc_table[899] = { 0xb2, 0xcf, 0xd4, 0x00, 0xe8, 0x03, 0xdc, 0x00, 0xe8, 0x00, 0xd8, 0x04, 0xdc, 0x01, 0xca, 0x03, 0xdc, 0x01, 0xca, 0x0a, 0xdc, 0x04, 0x01, 0x03, @@ -559,34 +583,36 @@ static const uint8_t unicode_cc_table[851] = { 0xc0, 0x00, 0xdc, 0xc0, 0x00, 0xdc, 0xc1, 0xb0, 0x6f, 0xc6, 0x00, 0xdc, 0xc0, 0x88, 0x00, 0xdc, 0x97, 0xc3, 0x80, 0xc8, 0x80, 0xc2, 0x80, 0xc4, - 0xaa, 0x02, 0xdc, 0xb0, 0x46, 0x00, 0xdc, 0xcd, - 0x80, 0x00, 0xdc, 0xc1, 0x00, 0xdc, 0xc1, 0x00, - 0xdc, 0xc2, 0x02, 0xdc, 0x42, 0x1b, 0xc2, 0x00, - 0xdc, 0xc1, 0x01, 0xdc, 0xc4, 0xb0, 0x0b, 0x00, - 0x07, 0x8f, 0x00, 0x09, 0x82, 0xc0, 0x00, 0xdc, - 0xc1, 0xb0, 0x36, 0x00, 0x07, 0x8f, 0x00, 0x09, - 0xaf, 0xc0, 0xb0, 0x0c, 0x00, 0x07, 0x8f, 0x00, + 0xaa, 0x02, 0xdc, 0xb0, 0x0b, 0xc0, 0x02, 0xdc, + 0xc3, 0xa9, 0xc4, 0x04, 0xdc, 0xcd, 0x80, 0x00, + 0xdc, 0xc1, 0x00, 0xdc, 0xc1, 0x00, 0xdc, 0xc2, + 0x02, 0xdc, 0x42, 0x1b, 0xc2, 0x00, 0xdc, 0xc1, + 0x01, 0xdc, 0xc4, 0xb0, 0x0b, 0x00, 0x07, 0x8f, + 0x00, 0x09, 0x82, 0xc0, 0x00, 0xdc, 0xc1, 0xb0, + 0x36, 0x00, 0x07, 0x8f, 0x00, 0x09, 0xaf, 0xc0, + 0xb0, 0x0c, 0x00, 0x07, 0x8f, 0x00, 0x09, 0xb0, + 0x3d, 0x00, 0x07, 0x8f, 0x00, 0x09, 0xb0, 0x3d, + 0x00, 0x07, 0x8f, 0x00, 0x09, 0xb0, 0x4e, 0x00, 0x09, 0xb0, 0x3d, 0x00, 0x07, 0x8f, 0x00, 0x09, - 0xb0, 0x3d, 0x00, 0x07, 0x8f, 0x00, 0x09, 0xb0, - 0x4e, 0x00, 0x09, 0xb0, 0x4e, 0x00, 0x09, 0x86, - 0x00, 0x54, 0x00, 0x5b, 0xb0, 0x34, 0x00, 0x07, - 0x8f, 0x00, 0x09, 0xb0, 0x3c, 0x01, 0x09, 0x8f, - 0x00, 0x09, 0xb0, 0x4b, 0x00, 0x09, 0xb0, 0x3c, - 0x01, 0x67, 0x00, 0x09, 0x8c, 0x03, 0x6b, 0xb0, - 0x3b, 0x01, 0x76, 0x00, 0x09, 0x8c, 0x03, 0x7a, - 0xb0, 0x1b, 0x01, 0xdc, 0x9a, 0x00, 0xdc, 0x80, - 0x00, 0xdc, 0x80, 0x00, 0xd8, 0xb0, 0x06, 0x41, - 0x81, 0x80, 0x00, 0x84, 0x84, 0x03, 0x82, 0x81, - 0x00, 0x82, 0x80, 0xc1, 0x00, 0x09, 0x80, 0xc1, - 0xb0, 0x0d, 0x00, 0xdc, 0xb0, 0x3f, 0x00, 0x07, - 0x80, 0x01, 0x09, 0xb0, 0x21, 0x00, 0xdc, 0xb2, - 0x9e, 0xc2, 0xb3, 0x83, 0x00, 0x09, 0x9e, 0x00, - 0x09, 0xb0, 0x6c, 0x00, 0x09, 0x89, 0xc0, 0xb0, - 0x9a, 0x00, 0xe4, 0xb0, 0x5e, 0x00, 0xde, 0xc0, - 0x00, 0xdc, 0xb0, 0xaa, 0xc0, 0x00, 0xdc, 0xb0, - 0x16, 0x00, 0x09, 0x93, 0xc7, 0x81, 0x00, 0xdc, - 0xaf, 0xc4, 0x05, 0xdc, 0xc1, 0x00, 0xdc, 0x80, - 0x01, 0xdc, 0xb0, 0x42, 0x00, 0x07, 0x8e, 0x00, + 0x86, 0x00, 0x54, 0x00, 0x5b, 0xb0, 0x34, 0x00, + 0x07, 0x8f, 0x00, 0x09, 0xb0, 0x3c, 0x01, 0x09, + 0x8f, 0x00, 0x09, 0xb0, 0x4b, 0x00, 0x09, 0xb0, + 0x3c, 0x01, 0x67, 0x00, 0x09, 0x8c, 0x03, 0x6b, + 0xb0, 0x3b, 0x01, 0x76, 0x00, 0x09, 0x8c, 0x03, + 0x7a, 0xb0, 0x1b, 0x01, 0xdc, 0x9a, 0x00, 0xdc, + 0x80, 0x00, 0xdc, 0x80, 0x00, 0xd8, 0xb0, 0x06, + 0x41, 0x81, 0x80, 0x00, 0x84, 0x84, 0x03, 0x82, + 0x81, 0x00, 0x82, 0x80, 0xc1, 0x00, 0x09, 0x80, + 0xc1, 0xb0, 0x0d, 0x00, 0xdc, 0xb0, 0x3f, 0x00, + 0x07, 0x80, 0x01, 0x09, 0xb0, 0x21, 0x00, 0xdc, + 0xb2, 0x9e, 0xc2, 0xb3, 0x83, 0x01, 0x09, 0x9d, + 0x00, 0x09, 0xb0, 0x6c, 0x00, 0x09, 0x89, 0xc0, + 0xb0, 0x9a, 0x00, 0xe4, 0xb0, 0x5e, 0x00, 0xde, + 0xc0, 0x00, 0xdc, 0xb0, 0xaa, 0xc0, 0x00, 0xdc, + 0xb0, 0x16, 0x00, 0x09, 0x93, 0xc7, 0x81, 0x00, + 0xdc, 0xaf, 0xc4, 0x05, 0xdc, 0xc1, 0x00, 0xdc, + 0x80, 0x01, 0xdc, 0xc1, 0x01, 0xdc, 0xc4, 0x00, + 0xdc, 0xc3, 0xb0, 0x34, 0x00, 0x07, 0x8e, 0x00, 0x09, 0xa5, 0xc0, 0x00, 0xdc, 0xc6, 0xb0, 0x05, 0x01, 0x09, 0xb0, 0x09, 0x00, 0x07, 0x8a, 0x01, 0x09, 0xb0, 0x12, 0x00, 0x07, 0xb0, 0x67, 0xc2, @@ -595,71 +621,75 @@ static const uint8_t unicode_cc_table[851] = { 0xc0, 0x82, 0xc1, 0xb0, 0x95, 0xc1, 0x00, 0xdc, 0xc6, 0x00, 0xdc, 0xc1, 0x00, 0xea, 0x00, 0xd6, 0x00, 0xdc, 0x00, 0xca, 0xe4, 0x00, 0xe8, 0x01, - 0xe4, 0x00, 0xdc, 0x80, 0xc0, 0x00, 0xe9, 0x00, - 0xdc, 0xc0, 0x00, 0xdc, 0xb2, 0x9f, 0xc1, 0x01, - 0x01, 0xc3, 0x02, 0x01, 0xc1, 0x83, 0xc0, 0x82, - 0x01, 0x01, 0xc0, 0x00, 0xdc, 0xc0, 0x01, 0x01, - 0x03, 0xdc, 0xc0, 0xb8, 0x03, 0xcd, 0xc2, 0xb0, - 0x5c, 0x00, 0x09, 0xb0, 0x2f, 0xdf, 0xb1, 0xf9, - 0x00, 0xda, 0x00, 0xe4, 0x00, 0xe8, 0x00, 0xde, - 0x01, 0xe0, 0xb0, 0x38, 0x01, 0x08, 0xb8, 0x6d, - 0xa3, 0xc0, 0x83, 0xc9, 0x9f, 0xc1, 0xb0, 0x1f, - 0xc1, 0xb0, 0xe3, 0x00, 0x09, 0xa4, 0x00, 0x09, - 0xb0, 0x66, 0x00, 0x09, 0x9a, 0xd1, 0xb0, 0x08, - 0x02, 0xdc, 0xa4, 0x00, 0x09, 0xb0, 0x2e, 0x00, - 0x07, 0x8b, 0x00, 0x09, 0xb0, 0xbe, 0xc0, 0x80, - 0xc1, 0x00, 0xdc, 0x81, 0xc1, 0x84, 0xc1, 0x80, - 0xc0, 0xb0, 0x03, 0x00, 0x09, 0xb0, 0xc5, 0x00, - 0x09, 0xb8, 0x46, 0xff, 0x00, 0x1a, 0xb2, 0xd0, - 0xc6, 0x06, 0xdc, 0xc1, 0xb3, 0x9c, 0x00, 0xdc, - 0xb0, 0xb1, 0x00, 0xdc, 0xb0, 0x64, 0xc4, 0xb6, - 0x61, 0x00, 0xdc, 0x80, 0xc0, 0xa7, 0xc0, 0x00, - 0x01, 0x00, 0xdc, 0x83, 0x00, 0x09, 0xb0, 0x74, - 0xc0, 0x00, 0xdc, 0xb2, 0x0c, 0xc3, 0xb1, 0x52, - 0xc1, 0xb0, 0x68, 0x01, 0xdc, 0xc2, 0x00, 0xdc, - 0xc0, 0x03, 0xdc, 0xb0, 0xc4, 0x00, 0x09, 0xb0, - 0x07, 0x00, 0x09, 0xb0, 0x08, 0x00, 0x09, 0x00, - 0x07, 0xb0, 0x14, 0xc2, 0xaf, 0x01, 0x09, 0xb0, - 0x0d, 0x00, 0x07, 0xb0, 0x1b, 0x00, 0x09, 0x88, - 0x00, 0x07, 0xb0, 0x39, 0x00, 0x09, 0x00, 0x07, - 0xb0, 0x81, 0x00, 0x07, 0x00, 0x09, 0xb0, 0x1f, - 0x01, 0x07, 0x8f, 0x00, 0x09, 0x97, 0xc6, 0x82, - 0xc4, 0xb0, 0x9c, 0x00, 0x09, 0x82, 0x00, 0x07, - 0x96, 0xc0, 0xb0, 0x32, 0x00, 0x09, 0x00, 0x07, - 0xb0, 0xca, 0x00, 0x09, 0x00, 0x07, 0xb0, 0x4d, - 0x00, 0x09, 0xb0, 0x45, 0x00, 0x09, 0x00, 0x07, - 0xb0, 0x42, 0x00, 0x09, 0xb0, 0xdc, 0x00, 0x09, - 0x00, 0x07, 0xb0, 0xd1, 0x01, 0x09, 0x83, 0x00, - 0x07, 0xb0, 0x6b, 0x00, 0x09, 0xb0, 0x22, 0x00, - 0x09, 0x91, 0x00, 0x09, 0xb0, 0x20, 0x00, 0x09, - 0xb1, 0x74, 0x00, 0x09, 0xb0, 0xd1, 0x00, 0x07, - 0x80, 0x01, 0x09, 0xb0, 0x20, 0x00, 0x09, 0xb8, - 0x45, 0x27, 0x04, 0x01, 0xb0, 0x0a, 0xc6, 0xb4, - 0x88, 0x01, 0x06, 0xb8, 0x44, 0x7b, 0x00, 0x01, - 0xb8, 0x0c, 0x95, 0x01, 0xd8, 0x02, 0x01, 0x82, - 0x00, 0xe2, 0x04, 0xd8, 0x87, 0x07, 0xdc, 0x81, - 0xc4, 0x01, 0xdc, 0x9d, 0xc3, 0xb0, 0x63, 0xc2, - 0xb8, 0x05, 0x8a, 0xc6, 0x80, 0xd0, 0x81, 0xc6, - 0x80, 0xc1, 0x80, 0xc4, 0xb0, 0xd4, 0xc6, 0xb1, - 0x84, 0xc3, 0xb5, 0xaf, 0x06, 0xdc, 0xb0, 0x3c, + 0xe4, 0x00, 0xdc, 0x00, 0xda, 0xc0, 0x00, 0xe9, + 0x00, 0xdc, 0xc0, 0x00, 0xdc, 0xb2, 0x9f, 0xc1, + 0x01, 0x01, 0xc3, 0x02, 0x01, 0xc1, 0x83, 0xc0, + 0x82, 0x01, 0x01, 0xc0, 0x00, 0xdc, 0xc0, 0x01, + 0x01, 0x03, 0xdc, 0xc0, 0xb8, 0x03, 0xcd, 0xc2, + 0xb0, 0x5c, 0x00, 0x09, 0xb0, 0x2f, 0xdf, 0xb1, + 0xf9, 0x00, 0xda, 0x00, 0xe4, 0x00, 0xe8, 0x00, + 0xde, 0x01, 0xe0, 0xb0, 0x38, 0x01, 0x08, 0xb8, + 0x6d, 0xa3, 0xc0, 0x83, 0xc9, 0x9f, 0xc1, 0xb0, + 0x1f, 0xc1, 0xb0, 0xe3, 0x00, 0x09, 0xa4, 0x00, + 0x09, 0xb0, 0x66, 0x00, 0x09, 0x9a, 0xd1, 0xb0, + 0x08, 0x02, 0xdc, 0xa4, 0x00, 0x09, 0xb0, 0x2e, + 0x00, 0x07, 0x8b, 0x00, 0x09, 0xb0, 0xbe, 0xc0, + 0x80, 0xc1, 0x00, 0xdc, 0x81, 0xc1, 0x84, 0xc1, + 0x80, 0xc0, 0xb0, 0x03, 0x00, 0x09, 0xb0, 0xc5, + 0x00, 0x09, 0xb8, 0x46, 0xff, 0x00, 0x1a, 0xb2, + 0xd0, 0xc6, 0x06, 0xdc, 0xc1, 0xb3, 0x9c, 0x00, + 0xdc, 0xb0, 0xb1, 0x00, 0xdc, 0xb0, 0x64, 0xc4, + 0xb6, 0x61, 0x00, 0xdc, 0x80, 0xc0, 0xa7, 0xc0, + 0x00, 0x01, 0x00, 0xdc, 0x83, 0x00, 0x09, 0xb0, + 0x74, 0xc0, 0x00, 0xdc, 0xb2, 0x0c, 0xc3, 0xb1, + 0x52, 0xc1, 0xb0, 0x1f, 0x02, 0xdc, 0xb0, 0x15, + 0x01, 0xdc, 0xc2, 0x00, 0xdc, 0xc0, 0x03, 0xdc, + 0xb0, 0x00, 0xc0, 0x00, 0xdc, 0xc0, 0x00, 0xdc, + 0xb0, 0x8f, 0x00, 0x09, 0xa8, 0x00, 0x09, 0x8d, + 0x00, 0x09, 0xb0, 0x08, 0x00, 0x09, 0x00, 0x07, + 0xb0, 0x14, 0xc2, 0xaf, 0x01, 0x09, 0xb0, 0x0d, + 0x00, 0x07, 0xb0, 0x1b, 0x00, 0x09, 0x88, 0x00, + 0x07, 0xb0, 0x39, 0x00, 0x09, 0x00, 0x07, 0xb0, + 0x81, 0x00, 0x07, 0x00, 0x09, 0xb0, 0x1f, 0x01, + 0x07, 0x8f, 0x00, 0x09, 0x97, 0xc6, 0x82, 0xc4, + 0xb0, 0x9c, 0x00, 0x09, 0x82, 0x00, 0x07, 0x96, + 0xc0, 0xb0, 0x32, 0x00, 0x09, 0x00, 0x07, 0xb0, + 0xca, 0x00, 0x09, 0x00, 0x07, 0xb0, 0x4d, 0x00, + 0x09, 0xb0, 0x45, 0x00, 0x09, 0x00, 0x07, 0xb0, + 0x42, 0x00, 0x09, 0xb0, 0xdc, 0x00, 0x09, 0x00, + 0x07, 0xb0, 0xd1, 0x01, 0x09, 0x83, 0x00, 0x07, + 0xb0, 0x6b, 0x00, 0x09, 0xb0, 0x22, 0x00, 0x09, + 0x91, 0x00, 0x09, 0xb0, 0x20, 0x00, 0x09, 0xb1, + 0x74, 0x00, 0x09, 0xb0, 0xd1, 0x00, 0x07, 0x80, + 0x01, 0x09, 0xb0, 0x20, 0x00, 0x09, 0xb1, 0x78, + 0x01, 0x09, 0xb8, 0x43, 0x7c, 0x04, 0x01, 0xb0, + 0x0a, 0xc6, 0xb4, 0x88, 0x01, 0x06, 0xb8, 0x44, + 0x7b, 0x00, 0x01, 0xb8, 0x0c, 0x95, 0x01, 0xd8, + 0x02, 0x01, 0x82, 0x00, 0xe2, 0x04, 0xd8, 0x87, + 0x07, 0xdc, 0x81, 0xc4, 0x01, 0xdc, 0x9d, 0xc3, + 0xb0, 0x63, 0xc2, 0xb8, 0x05, 0x8a, 0xc6, 0x80, + 0xd0, 0x81, 0xc6, 0x80, 0xc1, 0x80, 0xc4, 0xb0, + 0x33, 0xc0, 0xb0, 0x6f, 0xc6, 0xb1, 0x46, 0xc0, + 0xb0, 0x0c, 0xc3, 0xb1, 0xcb, 0x01, 0xe8, 0x00, + 0xdc, 0xc0, 0xb3, 0xaf, 0x06, 0xdc, 0xb0, 0x3c, 0xc5, 0x00, 0x07, }; -static const uint8_t unicode_cc_index[81] = { +static const uint8_t unicode_cc_index[87] = { 0x4d, 0x03, 0x00, 0x97, 0x05, 0x20, 0xc6, 0x05, - 0x00, 0xe7, 0x06, 0x00, 0x45, 0x07, 0x00, 0xe2, - 0x08, 0x00, 0x53, 0x09, 0x00, 0xcd, 0x0b, 0x20, - 0x38, 0x0e, 0x00, 0x73, 0x0f, 0x20, 0x5d, 0x13, - 0x20, 0x60, 0x1a, 0x20, 0xaa, 0x1b, 0x00, 0xf4, - 0x1c, 0x00, 0xfe, 0x1d, 0x20, 0x7f, 0x2d, 0x20, - 0xf0, 0xa6, 0x00, 0xb2, 0xaa, 0x00, 0xfe, 0x01, - 0x01, 0xab, 0x0e, 0x01, 0x73, 0x11, 0x21, 0x70, - 0x13, 0x01, 0xb8, 0x16, 0x01, 0x9a, 0x1a, 0x01, - 0x9f, 0xbc, 0x01, 0x22, 0xe0, 0x01, 0x4b, 0xe9, - 0x01, + 0x00, 0xe7, 0x06, 0x00, 0x45, 0x07, 0x00, 0x9c, + 0x08, 0x00, 0x4d, 0x09, 0x00, 0x3c, 0x0b, 0x00, + 0x3d, 0x0d, 0x00, 0x36, 0x0f, 0x00, 0x38, 0x10, + 0x20, 0x3a, 0x19, 0x00, 0xcb, 0x1a, 0x20, 0xd3, + 0x1c, 0x00, 0xcf, 0x1d, 0x00, 0xe2, 0x20, 0x00, + 0x2e, 0x30, 0x20, 0x2b, 0xa9, 0x20, 0xed, 0xab, + 0x00, 0x39, 0x0a, 0x01, 0x51, 0x0f, 0x01, 0x73, + 0x11, 0x01, 0x75, 0x13, 0x01, 0x2b, 0x17, 0x21, + 0x3f, 0x1c, 0x21, 0x9e, 0xbc, 0x21, 0x08, 0xe0, + 0x01, 0x44, 0xe9, 0x01, 0x4b, 0xe9, 0x01, }; -static const uint32_t unicode_decomp_table1[690] = { +static const uint32_t unicode_decomp_table1[699] = { 0x00280081, 0x002a0097, 0x002a8081, 0x002bc097, 0x002c8115, 0x002d0097, 0x002d4081, 0x002e0097, 0x002e4115, 0x002f0199, 0x00302016, 0x00400842, @@ -786,56 +816,58 @@ static const uint32_t unicode_decomp_table1[690] = { 0x0cf54119, 0x0cf5c097, 0x0cf6009b, 0x0cf64099, 0x0cf68217, 0x0cf78119, 0x0cf804a1, 0x0cfa4525, 0x0cfcc525, 0x0cff4125, 0x0cffc099, 0x29a70103, - 0x29dc0081, 0x29fe0103, 0x2ad70203, 0x2ada4081, - 0x3e401482, 0x3e4a7f82, 0x3e6a3f82, 0x3e8aa102, - 0x3e9b0110, 0x3e9c2f82, 0x3eb3c590, 0x3ec00197, - 0x3ec0c119, 0x3ec1413f, 0x3ec4c2af, 0x3ec74184, - 0x3ec804ad, 0x3eca4081, 0x3eca8304, 0x3ecc03a0, - 0x3ece02a0, 0x3ecf8084, 0x3ed00120, 0x3ed0c120, - 0x3ed184ae, 0x3ed3c085, 0x3ed4312d, 0x3ef4cbad, - 0x3efa892f, 0x3eff022d, 0x3f002f2f, 0x3f1782a5, - 0x3f18c0b1, 0x3f1907af, 0x3f1cffaf, 0x3f3c81a5, - 0x3f3d64af, 0x3f542031, 0x3f649b31, 0x3f7c0131, - 0x3f7c83b3, 0x3f7e40b1, 0x3f7e80bd, 0x3f7ec0bb, - 0x3f7f00b3, 0x3f840503, 0x3f8c01ad, 0x3f8cc315, - 0x3f8e462d, 0x3f91cc03, 0x3f97c695, 0x3f9c01af, - 0x3f9d0085, 0x3f9d852f, 0x3fa03aad, 0x3fbd442f, - 0x3fc06f1f, 0x3fd7c11f, 0x3fd85fad, 0x3fe80081, - 0x3fe84f1f, 0x3ff0831f, 0x3ff2831f, 0x3ff4831f, - 0x3ff6819f, 0x3ff80783, 0x44268192, 0x442ac092, - 0x444b8112, 0x44d2c112, 0x452ec212, 0x456e8112, - 0x464e0092, 0x74578392, 0x746ec312, 0x75000d1f, - 0x75068d1f, 0x750d0d1f, 0x7513839f, 0x7515891f, - 0x751a0d1f, 0x75208d1f, 0x75271015, 0x752f439f, - 0x7531459f, 0x75340d1f, 0x753a8d1f, 0x75410395, - 0x7543441f, 0x7545839f, 0x75478d1f, 0x754e0795, - 0x7552839f, 0x75548d1f, 0x755b0d1f, 0x75618d1f, - 0x75680d1f, 0x756e8d1f, 0x75750d1f, 0x757b8d1f, - 0x75820d1f, 0x75888d1f, 0x758f0d1f, 0x75958d1f, - 0x759c0d1f, 0x75a28d1f, 0x75a90103, 0x75aa089f, - 0x75ae4081, 0x75ae839f, 0x75b04081, 0x75b08c9f, - 0x75b6c081, 0x75b7032d, 0x75b8889f, 0x75bcc081, - 0x75bd039f, 0x75bec081, 0x75bf0c9f, 0x75c54081, - 0x75c5832d, 0x75c7089f, 0x75cb4081, 0x75cb839f, - 0x75cd4081, 0x75cd8c9f, 0x75d3c081, 0x75d4032d, - 0x75d5889f, 0x75d9c081, 0x75da039f, 0x75dbc081, - 0x75dc0c9f, 0x75e24081, 0x75e2832d, 0x75e4089f, - 0x75e84081, 0x75e8839f, 0x75ea4081, 0x75ea8c9f, - 0x75f0c081, 0x75f1042d, 0x75f3851f, 0x75f6051f, - 0x75f8851f, 0x75fb051f, 0x75fd851f, 0x7b80022d, - 0x7b814dad, 0x7b884203, 0x7b89c081, 0x7b8a452d, - 0x7b8d0403, 0x7b908081, 0x7b91dc03, 0x7ba0052d, - 0x7ba2c8ad, 0x7ba84483, 0x7baac8ad, 0x7c400097, - 0x7c404521, 0x7c440d25, 0x7c4a8087, 0x7c4ac115, - 0x7c4b4117, 0x7c4c0d1f, 0x7c528217, 0x7c538099, - 0x7c53c097, 0x7c5a8197, 0x7c640097, 0x7c80012f, - 0x7c808081, 0x7c841603, 0x7c9004c1, 0x7c940103, - 0x7efc051f, 0xbe0001ac, 0xbe00d110, 0xbe0947ac, - 0xbe0d3910, 0xbe29872c, 0xbe2d022c, 0xbe2e3790, - 0xbe49ff90, 0xbe69bc10, + 0x29dc0081, 0x29fc8195, 0x29fe0103, 0x2ad70203, + 0x2ada4081, 0x3e401482, 0x3e4a7f82, 0x3e6a3f82, + 0x3e8aa102, 0x3e9b0110, 0x3e9c2f82, 0x3eb3c590, + 0x3ec00197, 0x3ec0c119, 0x3ec1413f, 0x3ec4c2af, + 0x3ec74184, 0x3ec804ad, 0x3eca4081, 0x3eca8304, + 0x3ecc03a0, 0x3ece02a0, 0x3ecf8084, 0x3ed00120, + 0x3ed0c120, 0x3ed184ae, 0x3ed3c085, 0x3ed4312d, + 0x3ef4cbad, 0x3efa892f, 0x3eff022d, 0x3f002f2f, + 0x3f1782a5, 0x3f18c0b1, 0x3f1907af, 0x3f1cffaf, + 0x3f3c81a5, 0x3f3d64af, 0x3f542031, 0x3f649b31, + 0x3f7c0131, 0x3f7c83b3, 0x3f7e40b1, 0x3f7e80bd, + 0x3f7ec0bb, 0x3f7f00b3, 0x3f840503, 0x3f8c01ad, + 0x3f8cc315, 0x3f8e462d, 0x3f91cc03, 0x3f97c695, + 0x3f9c01af, 0x3f9d0085, 0x3f9d852f, 0x3fa03aad, + 0x3fbd442f, 0x3fc06f1f, 0x3fd7c11f, 0x3fd85fad, + 0x3fe80081, 0x3fe84f1f, 0x3ff0831f, 0x3ff2831f, + 0x3ff4831f, 0x3ff6819f, 0x3ff80783, 0x41e04d83, + 0x41e70f91, 0x44268192, 0x442ac092, 0x444b8112, + 0x44d2c112, 0x452ec212, 0x456e8112, 0x464e0092, + 0x74578392, 0x746ec312, 0x75000d1f, 0x75068d1f, + 0x750d0d1f, 0x7513839f, 0x7515891f, 0x751a0d1f, + 0x75208d1f, 0x75271015, 0x752f439f, 0x7531459f, + 0x75340d1f, 0x753a8d1f, 0x75410395, 0x7543441f, + 0x7545839f, 0x75478d1f, 0x754e0795, 0x7552839f, + 0x75548d1f, 0x755b0d1f, 0x75618d1f, 0x75680d1f, + 0x756e8d1f, 0x75750d1f, 0x757b8d1f, 0x75820d1f, + 0x75888d1f, 0x758f0d1f, 0x75958d1f, 0x759c0d1f, + 0x75a28d1f, 0x75a90103, 0x75aa089f, 0x75ae4081, + 0x75ae839f, 0x75b04081, 0x75b08c9f, 0x75b6c081, + 0x75b7032d, 0x75b8889f, 0x75bcc081, 0x75bd039f, + 0x75bec081, 0x75bf0c9f, 0x75c54081, 0x75c5832d, + 0x75c7089f, 0x75cb4081, 0x75cb839f, 0x75cd4081, + 0x75cd8c9f, 0x75d3c081, 0x75d4032d, 0x75d5889f, + 0x75d9c081, 0x75da039f, 0x75dbc081, 0x75dc0c9f, + 0x75e24081, 0x75e2832d, 0x75e4089f, 0x75e84081, + 0x75e8839f, 0x75ea4081, 0x75ea8c9f, 0x75f0c081, + 0x75f1042d, 0x75f3851f, 0x75f6051f, 0x75f8851f, + 0x75fb051f, 0x75fd851f, 0x780c049f, 0x780e419f, + 0x780f059f, 0x7811c203, 0x7812d0ad, 0x781b0103, + 0x7b80022d, 0x7b814dad, 0x7b884203, 0x7b89c081, + 0x7b8a452d, 0x7b8d0403, 0x7b908081, 0x7b91dc03, + 0x7ba0052d, 0x7ba2c8ad, 0x7ba84483, 0x7baac8ad, + 0x7c400097, 0x7c404521, 0x7c440d25, 0x7c4a8087, + 0x7c4ac115, 0x7c4b4117, 0x7c4c0d1f, 0x7c528217, + 0x7c538099, 0x7c53c097, 0x7c5a8197, 0x7c640097, + 0x7c80012f, 0x7c808081, 0x7c841603, 0x7c9004c1, + 0x7c940103, 0x7efc051f, 0xbe0001ac, 0xbe00d110, + 0xbe0947ac, 0xbe0d3910, 0xbe29872c, 0xbe2d022c, + 0xbe2e3790, 0xbe49ff90, 0xbe69bc10, }; -static const uint16_t unicode_decomp_table2[690] = { +static const uint16_t unicode_decomp_table2[699] = { 0x0020, 0x0000, 0x0061, 0x0002, 0x0004, 0x0006, 0x03bc, 0x0008, 0x000a, 0x000c, 0x0015, 0x0095, 0x00a5, 0x00b9, 0x00c1, 0x00c3, 0x00c7, 0x00cb, 0x00d1, 0x00d7, 0x00dd, 0x00e0, 0x00e6, 0x00f8, @@ -899,33 +931,34 @@ static const uint16_t unicode_decomp_table2[690] = { 0x10f4, 0x1100, 0x1105, 0x1111, 0x1141, 0x1149, 0x114d, 0x1153, 0x1157, 0x115a, 0x116e, 0x1171, 0x1175, 0x117b, 0x117d, 0x1181, 0x1184, 0x118c, 0x1192, 0x1196, 0x119c, 0x11a2, 0x11a8, 0x11ab, - 0xa76f, 0x11af, 0x11b3, 0x028d, 0x11bb, 0x120d, 0x130b, 0x1409, - 0x148d, 0x1492, 0x1550, 0x1569, 0x156f, 0x1575, 0x157b, 0x1587, - 0x1593, 0x002b, 0x159e, 0x15b6, 0x15ba, 0x15be, 0x15c2, 0x15c6, - 0x15ca, 0x15de, 0x15e2, 0x1646, 0x165f, 0x1685, 0x168b, 0x1749, - 0x174f, 0x1754, 0x1774, 0x1874, 0x187a, 0x190e, 0x19d0, 0x1a74, - 0x1a7c, 0x1a9a, 0x1a9f, 0x1ab3, 0x1abd, 0x1ac3, 0x1ad7, 0x1adc, - 0x1ae2, 0x1af0, 0x1b20, 0x1b2d, 0x1b35, 0x1b39, 0x1b4f, 0x1bc6, - 0x1bd8, 0x1bda, 0x1bdc, 0x3164, 0x1c1d, 0x1c1f, 0x1c21, 0x1c23, - 0x1c25, 0x1c27, 0x1c45, 0x1c53, 0x1c58, 0x1c61, 0x1c6a, 0x1c7c, - 0x1c85, 0x1c8a, 0x1caa, 0x1cc5, 0x1cc7, 0x1cc9, 0x1ccb, 0x1ccd, - 0x1ccf, 0x1cd1, 0x1cd3, 0x1cf3, 0x1cf5, 0x1cf7, 0x1cf9, 0x1cfb, - 0x1d02, 0x1d04, 0x1d06, 0x1d08, 0x1d17, 0x1d19, 0x1d1b, 0x1d1d, - 0x1d1f, 0x1d21, 0x1d23, 0x1d25, 0x1d27, 0x1d29, 0x1d2b, 0x1d2d, - 0x1d2f, 0x1d31, 0x1d33, 0x1d37, 0x03f4, 0x1d39, 0x2207, 0x1d3b, - 0x2202, 0x1d3d, 0x1d45, 0x03f4, 0x1d47, 0x2207, 0x1d49, 0x2202, - 0x1d4b, 0x1d53, 0x03f4, 0x1d55, 0x2207, 0x1d57, 0x2202, 0x1d59, - 0x1d61, 0x03f4, 0x1d63, 0x2207, 0x1d65, 0x2202, 0x1d67, 0x1d6f, - 0x03f4, 0x1d71, 0x2207, 0x1d73, 0x2202, 0x1d75, 0x1d7f, 0x1d81, - 0x1d83, 0x1d85, 0x1d87, 0x1d89, 0x1d8f, 0x1dac, 0x062d, 0x1db4, - 0x1dc0, 0x062c, 0x1dd0, 0x1e40, 0x1e4c, 0x1e5f, 0x1e71, 0x1e84, - 0x1e86, 0x1e8a, 0x1e90, 0x1e96, 0x1e98, 0x1e9c, 0x1e9e, 0x1ea6, - 0x1ea9, 0x1eab, 0x1eb1, 0x1eb3, 0x30b5, 0x1eb9, 0x1f11, 0x1f27, - 0x1f2b, 0x1f2d, 0x1f32, 0x1f7f, 0x1f90, 0x2091, 0x20a1, 0x20a7, - 0x21a1, 0x22bf, + 0xa76f, 0x11af, 0x11b2, 0x11b6, 0x028d, 0x11be, 0x1210, 0x130e, + 0x140c, 0x1490, 0x1495, 0x1553, 0x156c, 0x1572, 0x1578, 0x157e, + 0x158a, 0x1596, 0x002b, 0x15a1, 0x15b9, 0x15bd, 0x15c1, 0x15c5, + 0x15c9, 0x15cd, 0x15e1, 0x15e5, 0x1649, 0x1662, 0x1688, 0x168e, + 0x174c, 0x1752, 0x1757, 0x1777, 0x1877, 0x187d, 0x1911, 0x19d3, + 0x1a77, 0x1a7f, 0x1a9d, 0x1aa2, 0x1ab6, 0x1ac0, 0x1ac6, 0x1ada, + 0x1adf, 0x1ae5, 0x1af3, 0x1b23, 0x1b30, 0x1b38, 0x1b3c, 0x1b52, + 0x1bc9, 0x1bdb, 0x1bdd, 0x1bdf, 0x3164, 0x1c20, 0x1c22, 0x1c24, + 0x1c26, 0x1c28, 0x1c2a, 0x1c48, 0x1c7e, 0x1cc4, 0x1cd2, 0x1cd7, + 0x1ce0, 0x1ce9, 0x1cfb, 0x1d04, 0x1d09, 0x1d29, 0x1d44, 0x1d46, + 0x1d48, 0x1d4a, 0x1d4c, 0x1d4e, 0x1d50, 0x1d52, 0x1d72, 0x1d74, + 0x1d76, 0x1d78, 0x1d7a, 0x1d81, 0x1d83, 0x1d85, 0x1d87, 0x1d96, + 0x1d98, 0x1d9a, 0x1d9c, 0x1d9e, 0x1da0, 0x1da2, 0x1da4, 0x1da6, + 0x1da8, 0x1daa, 0x1dac, 0x1dae, 0x1db0, 0x1db2, 0x1db6, 0x03f4, + 0x1db8, 0x2207, 0x1dba, 0x2202, 0x1dbc, 0x1dc4, 0x03f4, 0x1dc6, + 0x2207, 0x1dc8, 0x2202, 0x1dca, 0x1dd2, 0x03f4, 0x1dd4, 0x2207, + 0x1dd6, 0x2202, 0x1dd8, 0x1de0, 0x03f4, 0x1de2, 0x2207, 0x1de4, + 0x2202, 0x1de6, 0x1dee, 0x03f4, 0x1df0, 0x2207, 0x1df2, 0x2202, + 0x1df4, 0x1dfe, 0x1e00, 0x1e02, 0x1e04, 0x1e06, 0x1e08, 0x1e0a, + 0x1e0c, 0x1e0e, 0x1e16, 0x1e39, 0x1e3d, 0x1e43, 0x1e60, 0x062d, + 0x1e68, 0x1e74, 0x062c, 0x1e84, 0x1ef4, 0x1f00, 0x1f13, 0x1f25, + 0x1f38, 0x1f3a, 0x1f3e, 0x1f44, 0x1f4a, 0x1f4c, 0x1f50, 0x1f52, + 0x1f5a, 0x1f5d, 0x1f5f, 0x1f65, 0x1f67, 0x30b5, 0x1f6d, 0x1fc5, + 0x1fdb, 0x1fdf, 0x1fe1, 0x1fe6, 0x2033, 0x2044, 0x2145, 0x2155, + 0x215b, 0x2255, 0x2373, }; -static const uint8_t unicode_decomp_data[9165] = { +static const uint8_t unicode_decomp_data[9345] = { 0x20, 0x88, 0x20, 0x84, 0x32, 0x33, 0x20, 0x81, 0x20, 0xa7, 0x31, 0x6f, 0x31, 0xd0, 0x34, 0x31, 0xd0, 0x32, 0x33, 0xd0, 0x34, 0x41, 0x80, 0x41, @@ -1491,587 +1524,610 @@ static const uint8_t unicode_decomp_data[9165] = { 0xd1, 0x6d, 0x31, 0x00, 0xe5, 0x65, 0x31, 0x00, 0x30, 0x00, 0xe5, 0x65, 0x32, 0x00, 0x30, 0x00, 0xe5, 0x65, 0x33, 0x00, 0x30, 0x00, 0xe5, 0x65, - 0x67, 0x61, 0x6c, 0x4a, 0x04, 0x4c, 0x04, 0x26, - 0x01, 0x53, 0x01, 0x27, 0xa7, 0x37, 0xab, 0x6b, - 0x02, 0x52, 0xab, 0x48, 0x8c, 0xf4, 0x66, 0xca, - 0x8e, 0xc8, 0x8c, 0xd1, 0x6e, 0x32, 0x4e, 0xe5, - 0x53, 0x9c, 0x9f, 0x9c, 0x9f, 0x51, 0x59, 0xd1, - 0x91, 0x87, 0x55, 0x48, 0x59, 0xf6, 0x61, 0x69, - 0x76, 0x85, 0x7f, 0x3f, 0x86, 0xba, 0x87, 0xf8, - 0x88, 0x8f, 0x90, 0x02, 0x6a, 0x1b, 0x6d, 0xd9, - 0x70, 0xde, 0x73, 0x3d, 0x84, 0x6a, 0x91, 0xf1, - 0x99, 0x82, 0x4e, 0x75, 0x53, 0x04, 0x6b, 0x1b, - 0x72, 0x2d, 0x86, 0x1e, 0x9e, 0x50, 0x5d, 0xeb, - 0x6f, 0xcd, 0x85, 0x64, 0x89, 0xc9, 0x62, 0xd8, - 0x81, 0x1f, 0x88, 0xca, 0x5e, 0x17, 0x67, 0x6a, - 0x6d, 0xfc, 0x72, 0xce, 0x90, 0x86, 0x4f, 0xb7, - 0x51, 0xde, 0x52, 0xc4, 0x64, 0xd3, 0x6a, 0x10, - 0x72, 0xe7, 0x76, 0x01, 0x80, 0x06, 0x86, 0x5c, - 0x86, 0xef, 0x8d, 0x32, 0x97, 0x6f, 0x9b, 0xfa, - 0x9d, 0x8c, 0x78, 0x7f, 0x79, 0xa0, 0x7d, 0xc9, - 0x83, 0x04, 0x93, 0x7f, 0x9e, 0xd6, 0x8a, 0xdf, - 0x58, 0x04, 0x5f, 0x60, 0x7c, 0x7e, 0x80, 0x62, - 0x72, 0xca, 0x78, 0xc2, 0x8c, 0xf7, 0x96, 0xd8, - 0x58, 0x62, 0x5c, 0x13, 0x6a, 0xda, 0x6d, 0x0f, - 0x6f, 0x2f, 0x7d, 0x37, 0x7e, 0x4b, 0x96, 0xd2, - 0x52, 0x8b, 0x80, 0xdc, 0x51, 0xcc, 0x51, 0x1c, - 0x7a, 0xbe, 0x7d, 0xf1, 0x83, 0x75, 0x96, 0x80, - 0x8b, 0xcf, 0x62, 0x02, 0x6a, 0xfe, 0x8a, 0x39, - 0x4e, 0xe7, 0x5b, 0x12, 0x60, 0x87, 0x73, 0x70, - 0x75, 0x17, 0x53, 0xfb, 0x78, 0xbf, 0x4f, 0xa9, - 0x5f, 0x0d, 0x4e, 0xcc, 0x6c, 0x78, 0x65, 0x22, - 0x7d, 0xc3, 0x53, 0x5e, 0x58, 0x01, 0x77, 0x49, - 0x84, 0xaa, 0x8a, 0xba, 0x6b, 0xb0, 0x8f, 0x88, - 0x6c, 0xfe, 0x62, 0xe5, 0x82, 0xa0, 0x63, 0x65, - 0x75, 0xae, 0x4e, 0x69, 0x51, 0xc9, 0x51, 0x81, - 0x68, 0xe7, 0x7c, 0x6f, 0x82, 0xd2, 0x8a, 0xcf, - 0x91, 0xf5, 0x52, 0x42, 0x54, 0x73, 0x59, 0xec, - 0x5e, 0xc5, 0x65, 0xfe, 0x6f, 0x2a, 0x79, 0xad, - 0x95, 0x6a, 0x9a, 0x97, 0x9e, 0xce, 0x9e, 0x9b, - 0x52, 0xc6, 0x66, 0x77, 0x6b, 0x62, 0x8f, 0x74, - 0x5e, 0x90, 0x61, 0x00, 0x62, 0x9a, 0x64, 0x23, - 0x6f, 0x49, 0x71, 0x89, 0x74, 0xca, 0x79, 0xf4, - 0x7d, 0x6f, 0x80, 0x26, 0x8f, 0xee, 0x84, 0x23, - 0x90, 0x4a, 0x93, 0x17, 0x52, 0xa3, 0x52, 0xbd, - 0x54, 0xc8, 0x70, 0xc2, 0x88, 0xaa, 0x8a, 0xc9, - 0x5e, 0xf5, 0x5f, 0x7b, 0x63, 0xae, 0x6b, 0x3e, - 0x7c, 0x75, 0x73, 0xe4, 0x4e, 0xf9, 0x56, 0xe7, - 0x5b, 0xba, 0x5d, 0x1c, 0x60, 0xb2, 0x73, 0x69, - 0x74, 0x9a, 0x7f, 0x46, 0x80, 0x34, 0x92, 0xf6, - 0x96, 0x48, 0x97, 0x18, 0x98, 0x8b, 0x4f, 0xae, - 0x79, 0xb4, 0x91, 0xb8, 0x96, 0xe1, 0x60, 0x86, - 0x4e, 0xda, 0x50, 0xee, 0x5b, 0x3f, 0x5c, 0x99, - 0x65, 0x02, 0x6a, 0xce, 0x71, 0x42, 0x76, 0xfc, - 0x84, 0x7c, 0x90, 0x8d, 0x9f, 0x88, 0x66, 0x2e, - 0x96, 0x89, 0x52, 0x7b, 0x67, 0xf3, 0x67, 0x41, - 0x6d, 0x9c, 0x6e, 0x09, 0x74, 0x59, 0x75, 0x6b, - 0x78, 0x10, 0x7d, 0x5e, 0x98, 0x6d, 0x51, 0x2e, - 0x62, 0x78, 0x96, 0x2b, 0x50, 0x19, 0x5d, 0xea, - 0x6d, 0x2a, 0x8f, 0x8b, 0x5f, 0x44, 0x61, 0x17, - 0x68, 0x87, 0x73, 0x86, 0x96, 0x29, 0x52, 0x0f, - 0x54, 0x65, 0x5c, 0x13, 0x66, 0x4e, 0x67, 0xa8, - 0x68, 0xe5, 0x6c, 0x06, 0x74, 0xe2, 0x75, 0x79, - 0x7f, 0xcf, 0x88, 0xe1, 0x88, 0xcc, 0x91, 0xe2, - 0x96, 0x3f, 0x53, 0xba, 0x6e, 0x1d, 0x54, 0xd0, - 0x71, 0x98, 0x74, 0xfa, 0x85, 0xa3, 0x96, 0x57, - 0x9c, 0x9f, 0x9e, 0x97, 0x67, 0xcb, 0x6d, 0xe8, - 0x81, 0xcb, 0x7a, 0x20, 0x7b, 0x92, 0x7c, 0xc0, - 0x72, 0x99, 0x70, 0x58, 0x8b, 0xc0, 0x4e, 0x36, - 0x83, 0x3a, 0x52, 0x07, 0x52, 0xa6, 0x5e, 0xd3, - 0x62, 0xd6, 0x7c, 0x85, 0x5b, 0x1e, 0x6d, 0xb4, - 0x66, 0x3b, 0x8f, 0x4c, 0x88, 0x4d, 0x96, 0x8b, - 0x89, 0xd3, 0x5e, 0x40, 0x51, 0xc0, 0x55, 0x00, - 0x00, 0x00, 0x00, 0x5a, 0x58, 0x00, 0x00, 0x74, - 0x66, 0x00, 0x00, 0x00, 0x00, 0xde, 0x51, 0x2a, - 0x73, 0xca, 0x76, 0x3c, 0x79, 0x5e, 0x79, 0x65, - 0x79, 0x8f, 0x79, 0x56, 0x97, 0xbe, 0x7c, 0xbd, - 0x7f, 0x00, 0x00, 0x12, 0x86, 0x00, 0x00, 0xf8, - 0x8a, 0x00, 0x00, 0x00, 0x00, 0x38, 0x90, 0xfd, - 0x90, 0xef, 0x98, 0xfc, 0x98, 0x28, 0x99, 0xb4, - 0x9d, 0xde, 0x90, 0xb7, 0x96, 0xae, 0x4f, 0xe7, - 0x50, 0x4d, 0x51, 0xc9, 0x52, 0xe4, 0x52, 0x51, - 0x53, 0x9d, 0x55, 0x06, 0x56, 0x68, 0x56, 0x40, - 0x58, 0xa8, 0x58, 0x64, 0x5c, 0x6e, 0x5c, 0x94, - 0x60, 0x68, 0x61, 0x8e, 0x61, 0xf2, 0x61, 0x4f, - 0x65, 0xe2, 0x65, 0x91, 0x66, 0x85, 0x68, 0x77, - 0x6d, 0x1a, 0x6e, 0x22, 0x6f, 0x6e, 0x71, 0x2b, - 0x72, 0x22, 0x74, 0x91, 0x78, 0x3e, 0x79, 0x49, - 0x79, 0x48, 0x79, 0x50, 0x79, 0x56, 0x79, 0x5d, - 0x79, 0x8d, 0x79, 0x8e, 0x79, 0x40, 0x7a, 0x81, - 0x7a, 0xc0, 0x7b, 0xf4, 0x7d, 0x09, 0x7e, 0x41, - 0x7e, 0x72, 0x7f, 0x05, 0x80, 0xed, 0x81, 0x79, - 0x82, 0x79, 0x82, 0x57, 0x84, 0x10, 0x89, 0x96, - 0x89, 0x01, 0x8b, 0x39, 0x8b, 0xd3, 0x8c, 0x08, - 0x8d, 0xb6, 0x8f, 0x38, 0x90, 0xe3, 0x96, 0xff, - 0x97, 0x3b, 0x98, 0x75, 0x60, 0xee, 0x42, 0x18, - 0x82, 0x02, 0x26, 0x4e, 0xb5, 0x51, 0x68, 0x51, - 0x80, 0x4f, 0x45, 0x51, 0x80, 0x51, 0xc7, 0x52, - 0xfa, 0x52, 0x9d, 0x55, 0x55, 0x55, 0x99, 0x55, - 0xe2, 0x55, 0x5a, 0x58, 0xb3, 0x58, 0x44, 0x59, - 0x54, 0x59, 0x62, 0x5a, 0x28, 0x5b, 0xd2, 0x5e, - 0xd9, 0x5e, 0x69, 0x5f, 0xad, 0x5f, 0xd8, 0x60, - 0x4e, 0x61, 0x08, 0x61, 0x8e, 0x61, 0x60, 0x61, - 0xf2, 0x61, 0x34, 0x62, 0xc4, 0x63, 0x1c, 0x64, - 0x52, 0x64, 0x56, 0x65, 0x74, 0x66, 0x17, 0x67, - 0x1b, 0x67, 0x56, 0x67, 0x79, 0x6b, 0xba, 0x6b, - 0x41, 0x6d, 0xdb, 0x6e, 0xcb, 0x6e, 0x22, 0x6f, - 0x1e, 0x70, 0x6e, 0x71, 0xa7, 0x77, 0x35, 0x72, - 0xaf, 0x72, 0x2a, 0x73, 0x71, 0x74, 0x06, 0x75, - 0x3b, 0x75, 0x1d, 0x76, 0x1f, 0x76, 0xca, 0x76, - 0xdb, 0x76, 0xf4, 0x76, 0x4a, 0x77, 0x40, 0x77, - 0xcc, 0x78, 0xb1, 0x7a, 0xc0, 0x7b, 0x7b, 0x7c, - 0x5b, 0x7d, 0xf4, 0x7d, 0x3e, 0x7f, 0x05, 0x80, - 0x52, 0x83, 0xef, 0x83, 0x79, 0x87, 0x41, 0x89, - 0x86, 0x89, 0x96, 0x89, 0xbf, 0x8a, 0xf8, 0x8a, - 0xcb, 0x8a, 0x01, 0x8b, 0xfe, 0x8a, 0xed, 0x8a, - 0x39, 0x8b, 0x8a, 0x8b, 0x08, 0x8d, 0x38, 0x8f, - 0x72, 0x90, 0x99, 0x91, 0x76, 0x92, 0x7c, 0x96, - 0xe3, 0x96, 0x56, 0x97, 0xdb, 0x97, 0xff, 0x97, - 0x0b, 0x98, 0x3b, 0x98, 0x12, 0x9b, 0x9c, 0x9f, - 0x4a, 0x28, 0x44, 0x28, 0xd5, 0x33, 0x9d, 0x3b, - 0x18, 0x40, 0x39, 0x40, 0x49, 0x52, 0xd0, 0x5c, - 0xd3, 0x7e, 0x43, 0x9f, 0x8e, 0x9f, 0x2a, 0xa0, - 0x02, 0x66, 0x66, 0x66, 0x69, 0x66, 0x6c, 0x66, - 0x66, 0x69, 0x66, 0x66, 0x6c, 0x7f, 0x01, 0x74, - 0x73, 0x00, 0x74, 0x65, 0x05, 0x0f, 0x11, 0x0f, - 0x00, 0x0f, 0x06, 0x19, 0x11, 0x0f, 0x08, 0xd9, - 0x05, 0xb4, 0x05, 0x00, 0x00, 0x00, 0x00, 0xf2, - 0x05, 0xb7, 0x05, 0xd0, 0x05, 0x12, 0x00, 0x03, - 0x04, 0x0b, 0x0c, 0x0d, 0x18, 0x1a, 0xe9, 0x05, - 0xc1, 0x05, 0xe9, 0x05, 0xc2, 0x05, 0x49, 0xfb, - 0xc1, 0x05, 0x49, 0xfb, 0xc2, 0x05, 0xd0, 0x05, - 0xb7, 0x05, 0xd0, 0x05, 0xb8, 0x05, 0xd0, 0x05, - 0xbc, 0x05, 0xd8, 0x05, 0xbc, 0x05, 0xde, 0x05, - 0xbc, 0x05, 0xe0, 0x05, 0xbc, 0x05, 0xe3, 0x05, - 0xbc, 0x05, 0xb9, 0x05, 0x2d, 0x03, 0x2e, 0x03, - 0x2f, 0x03, 0x30, 0x03, 0x31, 0x03, 0x1c, 0x00, - 0x18, 0x06, 0x22, 0x06, 0x2b, 0x06, 0xd0, 0x05, - 0xdc, 0x05, 0x71, 0x06, 0x00, 0x00, 0x0a, 0x0a, - 0x0a, 0x0a, 0x0d, 0x0d, 0x0d, 0x0d, 0x0f, 0x0f, - 0x0f, 0x0f, 0x09, 0x09, 0x09, 0x09, 0x0e, 0x0e, - 0x0e, 0x0e, 0x08, 0x08, 0x08, 0x08, 0x33, 0x33, - 0x33, 0x33, 0x35, 0x35, 0x35, 0x35, 0x13, 0x13, - 0x13, 0x13, 0x12, 0x12, 0x12, 0x12, 0x15, 0x15, - 0x15, 0x15, 0x16, 0x16, 0x16, 0x16, 0x1c, 0x1c, - 0x1b, 0x1b, 0x1d, 0x1d, 0x17, 0x17, 0x27, 0x27, - 0x20, 0x20, 0x38, 0x38, 0x38, 0x38, 0x3e, 0x3e, - 0x3e, 0x3e, 0x42, 0x42, 0x42, 0x42, 0x40, 0x40, - 0x40, 0x40, 0x49, 0x49, 0x4a, 0x4a, 0x4a, 0x4a, - 0x4f, 0x4f, 0x50, 0x50, 0x50, 0x50, 0x4d, 0x4d, - 0x4d, 0x4d, 0x61, 0x61, 0x62, 0x62, 0x49, 0x06, - 0x64, 0x64, 0x64, 0x64, 0x7e, 0x7e, 0x7d, 0x7d, - 0x7f, 0x7f, 0x2e, 0x82, 0x82, 0x7c, 0x7c, 0x80, - 0x80, 0x87, 0x87, 0x87, 0x87, 0x00, 0x00, 0x26, - 0x06, 0x00, 0x01, 0x00, 0x01, 0x00, 0xaf, 0x00, - 0xaf, 0x00, 0x22, 0x00, 0x22, 0x00, 0xa1, 0x00, - 0xa1, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa2, 0x00, - 0xa2, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, - 0x23, 0x00, 0x23, 0x00, 0x23, 0xcc, 0x06, 0x00, - 0x00, 0x00, 0x00, 0x26, 0x06, 0x00, 0x06, 0x00, - 0x07, 0x00, 0x1f, 0x00, 0x23, 0x00, 0x24, 0x02, - 0x06, 0x02, 0x07, 0x02, 0x08, 0x02, 0x1f, 0x02, - 0x23, 0x02, 0x24, 0x04, 0x06, 0x04, 0x07, 0x04, - 0x08, 0x04, 0x1f, 0x04, 0x23, 0x04, 0x24, 0x05, - 0x06, 0x05, 0x1f, 0x05, 0x23, 0x05, 0x24, 0x06, - 0x07, 0x06, 0x1f, 0x07, 0x06, 0x07, 0x1f, 0x08, - 0x06, 0x08, 0x07, 0x08, 0x1f, 0x0d, 0x06, 0x0d, - 0x07, 0x0d, 0x08, 0x0d, 0x1f, 0x0f, 0x07, 0x0f, - 0x1f, 0x10, 0x06, 0x10, 0x07, 0x10, 0x08, 0x10, - 0x1f, 0x11, 0x07, 0x11, 0x1f, 0x12, 0x1f, 0x13, - 0x06, 0x13, 0x1f, 0x14, 0x06, 0x14, 0x1f, 0x1b, - 0x06, 0x1b, 0x07, 0x1b, 0x08, 0x1b, 0x1f, 0x1b, - 0x23, 0x1b, 0x24, 0x1c, 0x07, 0x1c, 0x1f, 0x1c, - 0x23, 0x1c, 0x24, 0x1d, 0x01, 0x1d, 0x06, 0x1d, - 0x07, 0x1d, 0x08, 0x1d, 0x1e, 0x1d, 0x1f, 0x1d, - 0x23, 0x1d, 0x24, 0x1e, 0x06, 0x1e, 0x07, 0x1e, - 0x08, 0x1e, 0x1f, 0x1e, 0x23, 0x1e, 0x24, 0x1f, - 0x06, 0x1f, 0x07, 0x1f, 0x08, 0x1f, 0x1f, 0x1f, - 0x23, 0x1f, 0x24, 0x20, 0x06, 0x20, 0x07, 0x20, - 0x08, 0x20, 0x1f, 0x20, 0x23, 0x20, 0x24, 0x21, - 0x06, 0x21, 0x1f, 0x21, 0x23, 0x21, 0x24, 0x24, - 0x06, 0x24, 0x07, 0x24, 0x08, 0x24, 0x1f, 0x24, - 0x23, 0x24, 0x24, 0x0a, 0x4a, 0x0b, 0x4a, 0x23, - 0x4a, 0x20, 0x00, 0x4c, 0x06, 0x51, 0x06, 0x51, - 0x06, 0xff, 0x00, 0x1f, 0x26, 0x06, 0x00, 0x0b, - 0x00, 0x0c, 0x00, 0x1f, 0x00, 0x20, 0x00, 0x23, - 0x00, 0x24, 0x02, 0x0b, 0x02, 0x0c, 0x02, 0x1f, - 0x02, 0x20, 0x02, 0x23, 0x02, 0x24, 0x04, 0x0b, - 0x04, 0x0c, 0x04, 0x1f, 0x26, 0x06, 0x04, 0x20, - 0x04, 0x23, 0x04, 0x24, 0x05, 0x0b, 0x05, 0x0c, - 0x05, 0x1f, 0x05, 0x20, 0x05, 0x23, 0x05, 0x24, - 0x1b, 0x23, 0x1b, 0x24, 0x1c, 0x23, 0x1c, 0x24, - 0x1d, 0x01, 0x1d, 0x1e, 0x1d, 0x1f, 0x1d, 0x23, - 0x1d, 0x24, 0x1e, 0x1f, 0x1e, 0x23, 0x1e, 0x24, - 0x1f, 0x01, 0x1f, 0x1f, 0x20, 0x0b, 0x20, 0x0c, - 0x20, 0x1f, 0x20, 0x20, 0x20, 0x23, 0x20, 0x24, - 0x23, 0x4a, 0x24, 0x0b, 0x24, 0x0c, 0x24, 0x1f, - 0x24, 0x20, 0x24, 0x23, 0x24, 0x24, 0x00, 0x06, - 0x00, 0x07, 0x00, 0x08, 0x00, 0x1f, 0x00, 0x21, - 0x02, 0x06, 0x02, 0x07, 0x02, 0x08, 0x02, 0x1f, - 0x02, 0x21, 0x04, 0x06, 0x04, 0x07, 0x04, 0x08, - 0x04, 0x1f, 0x04, 0x21, 0x05, 0x1f, 0x06, 0x07, - 0x06, 0x1f, 0x07, 0x06, 0x07, 0x1f, 0x08, 0x06, - 0x08, 0x1f, 0x0d, 0x06, 0x0d, 0x07, 0x0d, 0x08, - 0x0d, 0x1f, 0x0f, 0x07, 0x0f, 0x08, 0x0f, 0x1f, - 0x10, 0x06, 0x10, 0x07, 0x10, 0x08, 0x10, 0x1f, - 0x11, 0x07, 0x12, 0x1f, 0x13, 0x06, 0x13, 0x1f, - 0x14, 0x06, 0x14, 0x1f, 0x1b, 0x06, 0x1b, 0x07, - 0x1b, 0x08, 0x1b, 0x1f, 0x1c, 0x07, 0x1c, 0x1f, + 0x67, 0x61, 0x6c, 0x4a, 0x04, 0x4c, 0x04, 0x43, + 0x46, 0x51, 0x26, 0x01, 0x53, 0x01, 0x27, 0xa7, + 0x37, 0xab, 0x6b, 0x02, 0x52, 0xab, 0x48, 0x8c, + 0xf4, 0x66, 0xca, 0x8e, 0xc8, 0x8c, 0xd1, 0x6e, + 0x32, 0x4e, 0xe5, 0x53, 0x9c, 0x9f, 0x9c, 0x9f, + 0x51, 0x59, 0xd1, 0x91, 0x87, 0x55, 0x48, 0x59, + 0xf6, 0x61, 0x69, 0x76, 0x85, 0x7f, 0x3f, 0x86, + 0xba, 0x87, 0xf8, 0x88, 0x8f, 0x90, 0x02, 0x6a, + 0x1b, 0x6d, 0xd9, 0x70, 0xde, 0x73, 0x3d, 0x84, + 0x6a, 0x91, 0xf1, 0x99, 0x82, 0x4e, 0x75, 0x53, + 0x04, 0x6b, 0x1b, 0x72, 0x2d, 0x86, 0x1e, 0x9e, + 0x50, 0x5d, 0xeb, 0x6f, 0xcd, 0x85, 0x64, 0x89, + 0xc9, 0x62, 0xd8, 0x81, 0x1f, 0x88, 0xca, 0x5e, + 0x17, 0x67, 0x6a, 0x6d, 0xfc, 0x72, 0xce, 0x90, + 0x86, 0x4f, 0xb7, 0x51, 0xde, 0x52, 0xc4, 0x64, + 0xd3, 0x6a, 0x10, 0x72, 0xe7, 0x76, 0x01, 0x80, + 0x06, 0x86, 0x5c, 0x86, 0xef, 0x8d, 0x32, 0x97, + 0x6f, 0x9b, 0xfa, 0x9d, 0x8c, 0x78, 0x7f, 0x79, + 0xa0, 0x7d, 0xc9, 0x83, 0x04, 0x93, 0x7f, 0x9e, + 0xd6, 0x8a, 0xdf, 0x58, 0x04, 0x5f, 0x60, 0x7c, + 0x7e, 0x80, 0x62, 0x72, 0xca, 0x78, 0xc2, 0x8c, + 0xf7, 0x96, 0xd8, 0x58, 0x62, 0x5c, 0x13, 0x6a, + 0xda, 0x6d, 0x0f, 0x6f, 0x2f, 0x7d, 0x37, 0x7e, + 0x4b, 0x96, 0xd2, 0x52, 0x8b, 0x80, 0xdc, 0x51, + 0xcc, 0x51, 0x1c, 0x7a, 0xbe, 0x7d, 0xf1, 0x83, + 0x75, 0x96, 0x80, 0x8b, 0xcf, 0x62, 0x02, 0x6a, + 0xfe, 0x8a, 0x39, 0x4e, 0xe7, 0x5b, 0x12, 0x60, + 0x87, 0x73, 0x70, 0x75, 0x17, 0x53, 0xfb, 0x78, + 0xbf, 0x4f, 0xa9, 0x5f, 0x0d, 0x4e, 0xcc, 0x6c, + 0x78, 0x65, 0x22, 0x7d, 0xc3, 0x53, 0x5e, 0x58, + 0x01, 0x77, 0x49, 0x84, 0xaa, 0x8a, 0xba, 0x6b, + 0xb0, 0x8f, 0x88, 0x6c, 0xfe, 0x62, 0xe5, 0x82, + 0xa0, 0x63, 0x65, 0x75, 0xae, 0x4e, 0x69, 0x51, + 0xc9, 0x51, 0x81, 0x68, 0xe7, 0x7c, 0x6f, 0x82, + 0xd2, 0x8a, 0xcf, 0x91, 0xf5, 0x52, 0x42, 0x54, + 0x73, 0x59, 0xec, 0x5e, 0xc5, 0x65, 0xfe, 0x6f, + 0x2a, 0x79, 0xad, 0x95, 0x6a, 0x9a, 0x97, 0x9e, + 0xce, 0x9e, 0x9b, 0x52, 0xc6, 0x66, 0x77, 0x6b, + 0x62, 0x8f, 0x74, 0x5e, 0x90, 0x61, 0x00, 0x62, + 0x9a, 0x64, 0x23, 0x6f, 0x49, 0x71, 0x89, 0x74, + 0xca, 0x79, 0xf4, 0x7d, 0x6f, 0x80, 0x26, 0x8f, + 0xee, 0x84, 0x23, 0x90, 0x4a, 0x93, 0x17, 0x52, + 0xa3, 0x52, 0xbd, 0x54, 0xc8, 0x70, 0xc2, 0x88, + 0xaa, 0x8a, 0xc9, 0x5e, 0xf5, 0x5f, 0x7b, 0x63, + 0xae, 0x6b, 0x3e, 0x7c, 0x75, 0x73, 0xe4, 0x4e, + 0xf9, 0x56, 0xe7, 0x5b, 0xba, 0x5d, 0x1c, 0x60, + 0xb2, 0x73, 0x69, 0x74, 0x9a, 0x7f, 0x46, 0x80, + 0x34, 0x92, 0xf6, 0x96, 0x48, 0x97, 0x18, 0x98, + 0x8b, 0x4f, 0xae, 0x79, 0xb4, 0x91, 0xb8, 0x96, + 0xe1, 0x60, 0x86, 0x4e, 0xda, 0x50, 0xee, 0x5b, + 0x3f, 0x5c, 0x99, 0x65, 0x02, 0x6a, 0xce, 0x71, + 0x42, 0x76, 0xfc, 0x84, 0x7c, 0x90, 0x8d, 0x9f, + 0x88, 0x66, 0x2e, 0x96, 0x89, 0x52, 0x7b, 0x67, + 0xf3, 0x67, 0x41, 0x6d, 0x9c, 0x6e, 0x09, 0x74, + 0x59, 0x75, 0x6b, 0x78, 0x10, 0x7d, 0x5e, 0x98, + 0x6d, 0x51, 0x2e, 0x62, 0x78, 0x96, 0x2b, 0x50, + 0x19, 0x5d, 0xea, 0x6d, 0x2a, 0x8f, 0x8b, 0x5f, + 0x44, 0x61, 0x17, 0x68, 0x87, 0x73, 0x86, 0x96, + 0x29, 0x52, 0x0f, 0x54, 0x65, 0x5c, 0x13, 0x66, + 0x4e, 0x67, 0xa8, 0x68, 0xe5, 0x6c, 0x06, 0x74, + 0xe2, 0x75, 0x79, 0x7f, 0xcf, 0x88, 0xe1, 0x88, + 0xcc, 0x91, 0xe2, 0x96, 0x3f, 0x53, 0xba, 0x6e, + 0x1d, 0x54, 0xd0, 0x71, 0x98, 0x74, 0xfa, 0x85, + 0xa3, 0x96, 0x57, 0x9c, 0x9f, 0x9e, 0x97, 0x67, + 0xcb, 0x6d, 0xe8, 0x81, 0xcb, 0x7a, 0x20, 0x7b, + 0x92, 0x7c, 0xc0, 0x72, 0x99, 0x70, 0x58, 0x8b, + 0xc0, 0x4e, 0x36, 0x83, 0x3a, 0x52, 0x07, 0x52, + 0xa6, 0x5e, 0xd3, 0x62, 0xd6, 0x7c, 0x85, 0x5b, + 0x1e, 0x6d, 0xb4, 0x66, 0x3b, 0x8f, 0x4c, 0x88, + 0x4d, 0x96, 0x8b, 0x89, 0xd3, 0x5e, 0x40, 0x51, + 0xc0, 0x55, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x58, + 0x00, 0x00, 0x74, 0x66, 0x00, 0x00, 0x00, 0x00, + 0xde, 0x51, 0x2a, 0x73, 0xca, 0x76, 0x3c, 0x79, + 0x5e, 0x79, 0x65, 0x79, 0x8f, 0x79, 0x56, 0x97, + 0xbe, 0x7c, 0xbd, 0x7f, 0x00, 0x00, 0x12, 0x86, + 0x00, 0x00, 0xf8, 0x8a, 0x00, 0x00, 0x00, 0x00, + 0x38, 0x90, 0xfd, 0x90, 0xef, 0x98, 0xfc, 0x98, + 0x28, 0x99, 0xb4, 0x9d, 0xde, 0x90, 0xb7, 0x96, + 0xae, 0x4f, 0xe7, 0x50, 0x4d, 0x51, 0xc9, 0x52, + 0xe4, 0x52, 0x51, 0x53, 0x9d, 0x55, 0x06, 0x56, + 0x68, 0x56, 0x40, 0x58, 0xa8, 0x58, 0x64, 0x5c, + 0x6e, 0x5c, 0x94, 0x60, 0x68, 0x61, 0x8e, 0x61, + 0xf2, 0x61, 0x4f, 0x65, 0xe2, 0x65, 0x91, 0x66, + 0x85, 0x68, 0x77, 0x6d, 0x1a, 0x6e, 0x22, 0x6f, + 0x6e, 0x71, 0x2b, 0x72, 0x22, 0x74, 0x91, 0x78, + 0x3e, 0x79, 0x49, 0x79, 0x48, 0x79, 0x50, 0x79, + 0x56, 0x79, 0x5d, 0x79, 0x8d, 0x79, 0x8e, 0x79, + 0x40, 0x7a, 0x81, 0x7a, 0xc0, 0x7b, 0xf4, 0x7d, + 0x09, 0x7e, 0x41, 0x7e, 0x72, 0x7f, 0x05, 0x80, + 0xed, 0x81, 0x79, 0x82, 0x79, 0x82, 0x57, 0x84, + 0x10, 0x89, 0x96, 0x89, 0x01, 0x8b, 0x39, 0x8b, + 0xd3, 0x8c, 0x08, 0x8d, 0xb6, 0x8f, 0x38, 0x90, + 0xe3, 0x96, 0xff, 0x97, 0x3b, 0x98, 0x75, 0x60, + 0xee, 0x42, 0x18, 0x82, 0x02, 0x26, 0x4e, 0xb5, + 0x51, 0x68, 0x51, 0x80, 0x4f, 0x45, 0x51, 0x80, + 0x51, 0xc7, 0x52, 0xfa, 0x52, 0x9d, 0x55, 0x55, + 0x55, 0x99, 0x55, 0xe2, 0x55, 0x5a, 0x58, 0xb3, + 0x58, 0x44, 0x59, 0x54, 0x59, 0x62, 0x5a, 0x28, + 0x5b, 0xd2, 0x5e, 0xd9, 0x5e, 0x69, 0x5f, 0xad, + 0x5f, 0xd8, 0x60, 0x4e, 0x61, 0x08, 0x61, 0x8e, + 0x61, 0x60, 0x61, 0xf2, 0x61, 0x34, 0x62, 0xc4, + 0x63, 0x1c, 0x64, 0x52, 0x64, 0x56, 0x65, 0x74, + 0x66, 0x17, 0x67, 0x1b, 0x67, 0x56, 0x67, 0x79, + 0x6b, 0xba, 0x6b, 0x41, 0x6d, 0xdb, 0x6e, 0xcb, + 0x6e, 0x22, 0x6f, 0x1e, 0x70, 0x6e, 0x71, 0xa7, + 0x77, 0x35, 0x72, 0xaf, 0x72, 0x2a, 0x73, 0x71, + 0x74, 0x06, 0x75, 0x3b, 0x75, 0x1d, 0x76, 0x1f, + 0x76, 0xca, 0x76, 0xdb, 0x76, 0xf4, 0x76, 0x4a, + 0x77, 0x40, 0x77, 0xcc, 0x78, 0xb1, 0x7a, 0xc0, + 0x7b, 0x7b, 0x7c, 0x5b, 0x7d, 0xf4, 0x7d, 0x3e, + 0x7f, 0x05, 0x80, 0x52, 0x83, 0xef, 0x83, 0x79, + 0x87, 0x41, 0x89, 0x86, 0x89, 0x96, 0x89, 0xbf, + 0x8a, 0xf8, 0x8a, 0xcb, 0x8a, 0x01, 0x8b, 0xfe, + 0x8a, 0xed, 0x8a, 0x39, 0x8b, 0x8a, 0x8b, 0x08, + 0x8d, 0x38, 0x8f, 0x72, 0x90, 0x99, 0x91, 0x76, + 0x92, 0x7c, 0x96, 0xe3, 0x96, 0x56, 0x97, 0xdb, + 0x97, 0xff, 0x97, 0x0b, 0x98, 0x3b, 0x98, 0x12, + 0x9b, 0x9c, 0x9f, 0x4a, 0x28, 0x44, 0x28, 0xd5, + 0x33, 0x9d, 0x3b, 0x18, 0x40, 0x39, 0x40, 0x49, + 0x52, 0xd0, 0x5c, 0xd3, 0x7e, 0x43, 0x9f, 0x8e, + 0x9f, 0x2a, 0xa0, 0x02, 0x66, 0x66, 0x66, 0x69, + 0x66, 0x6c, 0x66, 0x66, 0x69, 0x66, 0x66, 0x6c, + 0x7f, 0x01, 0x74, 0x73, 0x00, 0x74, 0x65, 0x05, + 0x0f, 0x11, 0x0f, 0x00, 0x0f, 0x06, 0x19, 0x11, + 0x0f, 0x08, 0xd9, 0x05, 0xb4, 0x05, 0x00, 0x00, + 0x00, 0x00, 0xf2, 0x05, 0xb7, 0x05, 0xd0, 0x05, + 0x12, 0x00, 0x03, 0x04, 0x0b, 0x0c, 0x0d, 0x18, + 0x1a, 0xe9, 0x05, 0xc1, 0x05, 0xe9, 0x05, 0xc2, + 0x05, 0x49, 0xfb, 0xc1, 0x05, 0x49, 0xfb, 0xc2, + 0x05, 0xd0, 0x05, 0xb7, 0x05, 0xd0, 0x05, 0xb8, + 0x05, 0xd0, 0x05, 0xbc, 0x05, 0xd8, 0x05, 0xbc, + 0x05, 0xde, 0x05, 0xbc, 0x05, 0xe0, 0x05, 0xbc, + 0x05, 0xe3, 0x05, 0xbc, 0x05, 0xb9, 0x05, 0x2d, + 0x03, 0x2e, 0x03, 0x2f, 0x03, 0x30, 0x03, 0x31, + 0x03, 0x1c, 0x00, 0x18, 0x06, 0x22, 0x06, 0x2b, + 0x06, 0xd0, 0x05, 0xdc, 0x05, 0x71, 0x06, 0x00, + 0x00, 0x0a, 0x0a, 0x0a, 0x0a, 0x0d, 0x0d, 0x0d, + 0x0d, 0x0f, 0x0f, 0x0f, 0x0f, 0x09, 0x09, 0x09, + 0x09, 0x0e, 0x0e, 0x0e, 0x0e, 0x08, 0x08, 0x08, + 0x08, 0x33, 0x33, 0x33, 0x33, 0x35, 0x35, 0x35, + 0x35, 0x13, 0x13, 0x13, 0x13, 0x12, 0x12, 0x12, + 0x12, 0x15, 0x15, 0x15, 0x15, 0x16, 0x16, 0x16, + 0x16, 0x1c, 0x1c, 0x1b, 0x1b, 0x1d, 0x1d, 0x17, + 0x17, 0x27, 0x27, 0x20, 0x20, 0x38, 0x38, 0x38, + 0x38, 0x3e, 0x3e, 0x3e, 0x3e, 0x42, 0x42, 0x42, + 0x42, 0x40, 0x40, 0x40, 0x40, 0x49, 0x49, 0x4a, + 0x4a, 0x4a, 0x4a, 0x4f, 0x4f, 0x50, 0x50, 0x50, + 0x50, 0x4d, 0x4d, 0x4d, 0x4d, 0x61, 0x61, 0x62, + 0x62, 0x49, 0x06, 0x64, 0x64, 0x64, 0x64, 0x7e, + 0x7e, 0x7d, 0x7d, 0x7f, 0x7f, 0x2e, 0x82, 0x82, + 0x7c, 0x7c, 0x80, 0x80, 0x87, 0x87, 0x87, 0x87, + 0x00, 0x00, 0x26, 0x06, 0x00, 0x01, 0x00, 0x01, + 0x00, 0xaf, 0x00, 0xaf, 0x00, 0x22, 0x00, 0x22, + 0x00, 0xa1, 0x00, 0xa1, 0x00, 0xa0, 0x00, 0xa0, + 0x00, 0xa2, 0x00, 0xa2, 0x00, 0xaa, 0x00, 0xaa, + 0x00, 0xaa, 0x00, 0x23, 0x00, 0x23, 0x00, 0x23, + 0xcc, 0x06, 0x00, 0x00, 0x00, 0x00, 0x26, 0x06, + 0x00, 0x06, 0x00, 0x07, 0x00, 0x1f, 0x00, 0x23, + 0x00, 0x24, 0x02, 0x06, 0x02, 0x07, 0x02, 0x08, + 0x02, 0x1f, 0x02, 0x23, 0x02, 0x24, 0x04, 0x06, + 0x04, 0x07, 0x04, 0x08, 0x04, 0x1f, 0x04, 0x23, + 0x04, 0x24, 0x05, 0x06, 0x05, 0x1f, 0x05, 0x23, + 0x05, 0x24, 0x06, 0x07, 0x06, 0x1f, 0x07, 0x06, + 0x07, 0x1f, 0x08, 0x06, 0x08, 0x07, 0x08, 0x1f, + 0x0d, 0x06, 0x0d, 0x07, 0x0d, 0x08, 0x0d, 0x1f, + 0x0f, 0x07, 0x0f, 0x1f, 0x10, 0x06, 0x10, 0x07, + 0x10, 0x08, 0x10, 0x1f, 0x11, 0x07, 0x11, 0x1f, + 0x12, 0x1f, 0x13, 0x06, 0x13, 0x1f, 0x14, 0x06, + 0x14, 0x1f, 0x1b, 0x06, 0x1b, 0x07, 0x1b, 0x08, + 0x1b, 0x1f, 0x1b, 0x23, 0x1b, 0x24, 0x1c, 0x07, + 0x1c, 0x1f, 0x1c, 0x23, 0x1c, 0x24, 0x1d, 0x01, 0x1d, 0x06, 0x1d, 0x07, 0x1d, 0x08, 0x1d, 0x1e, - 0x1d, 0x1f, 0x1e, 0x06, 0x1e, 0x07, 0x1e, 0x08, - 0x1e, 0x1f, 0x1e, 0x21, 0x1f, 0x06, 0x1f, 0x07, - 0x1f, 0x08, 0x1f, 0x1f, 0x20, 0x06, 0x20, 0x07, - 0x20, 0x08, 0x20, 0x1f, 0x20, 0x21, 0x21, 0x06, - 0x21, 0x1f, 0x21, 0x4a, 0x24, 0x06, 0x24, 0x07, - 0x24, 0x08, 0x24, 0x1f, 0x24, 0x21, 0x00, 0x1f, - 0x00, 0x21, 0x02, 0x1f, 0x02, 0x21, 0x04, 0x1f, - 0x04, 0x21, 0x05, 0x1f, 0x05, 0x21, 0x0d, 0x1f, - 0x0d, 0x21, 0x0e, 0x1f, 0x0e, 0x21, 0x1d, 0x1e, - 0x1d, 0x1f, 0x1e, 0x1f, 0x20, 0x1f, 0x20, 0x21, - 0x24, 0x1f, 0x24, 0x21, 0x40, 0x06, 0x4e, 0x06, - 0x51, 0x06, 0x27, 0x06, 0x10, 0x22, 0x10, 0x23, - 0x12, 0x22, 0x12, 0x23, 0x13, 0x22, 0x13, 0x23, - 0x0c, 0x22, 0x0c, 0x23, 0x0d, 0x22, 0x0d, 0x23, - 0x06, 0x22, 0x06, 0x23, 0x05, 0x22, 0x05, 0x23, - 0x07, 0x22, 0x07, 0x23, 0x0e, 0x22, 0x0e, 0x23, - 0x0f, 0x22, 0x0f, 0x23, 0x0d, 0x05, 0x0d, 0x06, - 0x0d, 0x07, 0x0d, 0x1e, 0x0d, 0x0a, 0x0c, 0x0a, - 0x0e, 0x0a, 0x0f, 0x0a, 0x10, 0x22, 0x10, 0x23, - 0x12, 0x22, 0x12, 0x23, 0x13, 0x22, 0x13, 0x23, - 0x0c, 0x22, 0x0c, 0x23, 0x0d, 0x22, 0x0d, 0x23, - 0x06, 0x22, 0x06, 0x23, 0x05, 0x22, 0x05, 0x23, - 0x07, 0x22, 0x07, 0x23, 0x0e, 0x22, 0x0e, 0x23, - 0x0f, 0x22, 0x0f, 0x23, 0x0d, 0x05, 0x0d, 0x06, - 0x0d, 0x07, 0x0d, 0x1e, 0x0d, 0x0a, 0x0c, 0x0a, - 0x0e, 0x0a, 0x0f, 0x0a, 0x0d, 0x05, 0x0d, 0x06, - 0x0d, 0x07, 0x0d, 0x1e, 0x0c, 0x20, 0x0d, 0x20, - 0x10, 0x1e, 0x0c, 0x05, 0x0c, 0x06, 0x0c, 0x07, - 0x0d, 0x05, 0x0d, 0x06, 0x0d, 0x07, 0x10, 0x1e, - 0x11, 0x1e, 0x00, 0x24, 0x00, 0x24, 0x2a, 0x06, - 0x00, 0x02, 0x1b, 0x00, 0x03, 0x02, 0x00, 0x03, - 0x02, 0x00, 0x03, 0x1b, 0x00, 0x04, 0x1b, 0x00, - 0x1b, 0x02, 0x00, 0x1b, 0x03, 0x00, 0x1b, 0x04, - 0x02, 0x1b, 0x03, 0x02, 0x1b, 0x03, 0x03, 0x1b, - 0x20, 0x03, 0x1b, 0x1f, 0x09, 0x03, 0x02, 0x09, - 0x02, 0x03, 0x09, 0x02, 0x1f, 0x09, 0x1b, 0x03, - 0x09, 0x1b, 0x03, 0x09, 0x1b, 0x02, 0x09, 0x1b, - 0x1b, 0x09, 0x1b, 0x1b, 0x0b, 0x03, 0x03, 0x0b, - 0x03, 0x03, 0x0b, 0x1b, 0x1b, 0x0a, 0x03, 0x1b, - 0x0a, 0x03, 0x1b, 0x0a, 0x02, 0x20, 0x0a, 0x1b, - 0x04, 0x0a, 0x1b, 0x04, 0x0a, 0x1b, 0x1b, 0x0a, - 0x1b, 0x1b, 0x0c, 0x03, 0x1f, 0x0c, 0x04, 0x1b, - 0x0c, 0x04, 0x1b, 0x0d, 0x1b, 0x03, 0x0d, 0x1b, - 0x03, 0x0d, 0x1b, 0x1b, 0x0d, 0x1b, 0x20, 0x0f, - 0x02, 0x1b, 0x0f, 0x1b, 0x1b, 0x0f, 0x1b, 0x1b, - 0x0f, 0x1b, 0x1f, 0x10, 0x1b, 0x1b, 0x10, 0x1b, - 0x20, 0x10, 0x1b, 0x1f, 0x17, 0x04, 0x1b, 0x17, - 0x04, 0x1b, 0x18, 0x1b, 0x03, 0x18, 0x1b, 0x1b, - 0x1a, 0x03, 0x1b, 0x1a, 0x03, 0x20, 0x1a, 0x03, - 0x1f, 0x1a, 0x02, 0x02, 0x1a, 0x02, 0x02, 0x1a, - 0x04, 0x1b, 0x1a, 0x04, 0x1b, 0x1a, 0x1b, 0x03, - 0x1a, 0x1b, 0x03, 0x1b, 0x03, 0x02, 0x1b, 0x03, - 0x1b, 0x1b, 0x03, 0x20, 0x1b, 0x02, 0x03, 0x1b, - 0x02, 0x1b, 0x1b, 0x04, 0x02, 0x1b, 0x04, 0x1b, - 0x28, 0x06, 0x1d, 0x04, 0x06, 0x1f, 0x1d, 0x04, - 0x1f, 0x1d, 0x1d, 0x1e, 0x05, 0x1d, 0x1e, 0x05, - 0x21, 0x1e, 0x04, 0x1d, 0x1e, 0x04, 0x1d, 0x1e, - 0x04, 0x21, 0x1e, 0x1d, 0x22, 0x1e, 0x1d, 0x21, - 0x22, 0x1d, 0x1d, 0x22, 0x1d, 0x1d, 0x00, 0x06, - 0x22, 0x02, 0x04, 0x22, 0x02, 0x04, 0x21, 0x02, - 0x06, 0x22, 0x02, 0x06, 0x21, 0x02, 0x1d, 0x22, - 0x02, 0x1d, 0x21, 0x04, 0x1d, 0x22, 0x04, 0x05, - 0x21, 0x04, 0x1d, 0x21, 0x0b, 0x06, 0x21, 0x0d, - 0x05, 0x22, 0x0c, 0x05, 0x22, 0x0e, 0x05, 0x22, - 0x1c, 0x04, 0x22, 0x1c, 0x1d, 0x22, 0x22, 0x05, - 0x22, 0x22, 0x04, 0x22, 0x22, 0x1d, 0x22, 0x1d, - 0x1d, 0x22, 0x1a, 0x1d, 0x22, 0x1e, 0x05, 0x22, - 0x1a, 0x1d, 0x05, 0x1c, 0x05, 0x1d, 0x11, 0x1d, - 0x22, 0x1b, 0x1d, 0x22, 0x1e, 0x04, 0x05, 0x1d, - 0x06, 0x22, 0x1c, 0x04, 0x1d, 0x1b, 0x1d, 0x1d, - 0x1c, 0x04, 0x1d, 0x1e, 0x04, 0x05, 0x04, 0x05, - 0x22, 0x05, 0x04, 0x22, 0x1d, 0x04, 0x22, 0x19, - 0x1d, 0x22, 0x00, 0x05, 0x22, 0x1b, 0x1d, 0x1d, - 0x11, 0x04, 0x1d, 0x0d, 0x1d, 0x1d, 0x0b, 0x06, - 0x22, 0x1e, 0x04, 0x22, 0x35, 0x06, 0x00, 0x0f, - 0x9d, 0x0d, 0x0f, 0x9d, 0x27, 0x06, 0x00, 0x1d, - 0x1d, 0x20, 0x00, 0x1c, 0x01, 0x0a, 0x1e, 0x06, - 0x1e, 0x08, 0x0e, 0x1d, 0x12, 0x1e, 0x0a, 0x0c, - 0x21, 0x1d, 0x12, 0x1d, 0x23, 0x20, 0x21, 0x0c, - 0x1d, 0x1e, 0x35, 0x06, 0x00, 0x0f, 0x14, 0x27, - 0x06, 0x0e, 0x1d, 0x22, 0xff, 0x00, 0x1d, 0x1d, - 0x20, 0xff, 0x12, 0x1d, 0x23, 0x20, 0xff, 0x21, - 0x0c, 0x1d, 0x1e, 0x27, 0x06, 0x05, 0x1d, 0xff, - 0x05, 0x1d, 0x00, 0x1d, 0x20, 0x27, 0x06, 0x0a, - 0xa5, 0x00, 0x1d, 0x2c, 0x00, 0x01, 0x30, 0x02, - 0x30, 0x3a, 0x00, 0x3b, 0x00, 0x21, 0x00, 0x3f, - 0x00, 0x16, 0x30, 0x17, 0x30, 0x26, 0x20, 0x13, - 0x20, 0x12, 0x01, 0x00, 0x5f, 0x5f, 0x28, 0x29, - 0x7b, 0x7d, 0x08, 0x30, 0x0c, 0x0d, 0x08, 0x09, - 0x02, 0x03, 0x00, 0x01, 0x04, 0x05, 0x06, 0x07, - 0x5b, 0x00, 0x5d, 0x00, 0x3e, 0x20, 0x3e, 0x20, - 0x3e, 0x20, 0x3e, 0x20, 0x5f, 0x00, 0x5f, 0x00, - 0x5f, 0x00, 0x2c, 0x00, 0x01, 0x30, 0x2e, 0x00, - 0x00, 0x00, 0x3b, 0x00, 0x3a, 0x00, 0x3f, 0x00, - 0x21, 0x00, 0x14, 0x20, 0x28, 0x00, 0x29, 0x00, - 0x7b, 0x00, 0x7d, 0x00, 0x14, 0x30, 0x15, 0x30, - 0x23, 0x26, 0x2a, 0x2b, 0x2d, 0x3c, 0x3e, 0x3d, - 0x00, 0x5c, 0x24, 0x25, 0x40, 0x40, 0x06, 0xff, - 0x0b, 0x00, 0x0b, 0xff, 0x0c, 0x20, 0x00, 0x4d, - 0x06, 0x40, 0x06, 0xff, 0x0e, 0x00, 0x0e, 0xff, - 0x0f, 0x00, 0x0f, 0xff, 0x10, 0x00, 0x10, 0xff, - 0x11, 0x00, 0x11, 0xff, 0x12, 0x00, 0x12, 0x21, - 0x06, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, - 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, - 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, - 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, - 0x0b, 0x0b, 0x0c, 0x0c, 0x0c, 0x0c, 0x0d, 0x0d, - 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, 0x0f, 0x10, 0x10, - 0x11, 0x11, 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, - 0x13, 0x13, 0x14, 0x14, 0x14, 0x14, 0x15, 0x15, - 0x15, 0x15, 0x16, 0x16, 0x16, 0x16, 0x17, 0x17, - 0x17, 0x17, 0x18, 0x18, 0x18, 0x18, 0x19, 0x19, - 0x19, 0x19, 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, - 0x21, 0x21, 0x22, 0x22, 0x22, 0x22, 0x23, 0x23, - 0x23, 0x23, 0x24, 0x24, 0x24, 0x24, 0x25, 0x25, - 0x25, 0x25, 0x26, 0x26, 0x26, 0x26, 0x27, 0x27, - 0x28, 0x28, 0x29, 0x29, 0x29, 0x29, 0x22, 0x06, - 0x22, 0x00, 0x22, 0x00, 0x22, 0x01, 0x22, 0x01, - 0x22, 0x03, 0x22, 0x03, 0x22, 0x05, 0x22, 0x05, - 0x21, 0x00, 0x85, 0x29, 0x01, 0x30, 0x01, 0x0b, - 0x0c, 0x00, 0xfa, 0xf1, 0xa0, 0xa2, 0xa4, 0xa6, - 0xa8, 0xe2, 0xe4, 0xe6, 0xc2, 0xfb, 0xa1, 0xa3, - 0xa5, 0xa7, 0xa9, 0xaa, 0xac, 0xae, 0xb0, 0xb2, - 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe, 0xc0, 0xc3, - 0xc5, 0xc7, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, - 0xd1, 0xd4, 0xd7, 0xda, 0xdd, 0xde, 0xdf, 0xe0, - 0xe1, 0xe3, 0xe5, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, - 0xec, 0xee, 0xf2, 0x98, 0x99, 0x31, 0x31, 0x4f, - 0x31, 0x55, 0x31, 0x5b, 0x31, 0x61, 0x31, 0xa2, - 0x00, 0xa3, 0x00, 0xac, 0x00, 0xaf, 0x00, 0xa6, - 0x00, 0xa5, 0x00, 0xa9, 0x20, 0x00, 0x00, 0x02, - 0x25, 0x90, 0x21, 0x91, 0x21, 0x92, 0x21, 0x93, - 0x21, 0xa0, 0x25, 0xcb, 0x25, 0x99, 0x10, 0xba, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x10, 0xba, - 0x10, 0x05, 0x05, 0xa5, 0x10, 0xba, 0x10, 0x05, - 0x31, 0x11, 0x27, 0x11, 0x32, 0x11, 0x27, 0x11, - 0x55, 0x47, 0x13, 0x3e, 0x13, 0x47, 0x13, 0x57, - 0x13, 0x55, 0xb9, 0x14, 0xba, 0x14, 0xb9, 0x14, - 0xb0, 0x14, 0x00, 0x00, 0x00, 0x00, 0xb9, 0x14, - 0xbd, 0x14, 0x55, 0x50, 0xb8, 0x15, 0xaf, 0x15, - 0xb9, 0x15, 0xaf, 0x15, 0x55, 0x35, 0x19, 0x30, - 0x19, 0x05, 0x57, 0xd1, 0x65, 0xd1, 0x58, 0xd1, - 0x65, 0xd1, 0x5f, 0xd1, 0x6e, 0xd1, 0x5f, 0xd1, - 0x6f, 0xd1, 0x5f, 0xd1, 0x70, 0xd1, 0x5f, 0xd1, - 0x71, 0xd1, 0x5f, 0xd1, 0x72, 0xd1, 0x55, 0x55, - 0x55, 0x05, 0xb9, 0xd1, 0x65, 0xd1, 0xba, 0xd1, - 0x65, 0xd1, 0xbb, 0xd1, 0x6e, 0xd1, 0xbc, 0xd1, - 0x6e, 0xd1, 0xbb, 0xd1, 0x6f, 0xd1, 0xbc, 0xd1, - 0x6f, 0xd1, 0x55, 0x55, 0x55, 0x41, 0x00, 0x61, - 0x00, 0x41, 0x00, 0x61, 0x00, 0x69, 0x00, 0x41, - 0x00, 0x61, 0x00, 0x41, 0x00, 0x43, 0x44, 0x00, - 0x00, 0x47, 0x00, 0x00, 0x4a, 0x4b, 0x00, 0x00, - 0x4e, 0x4f, 0x50, 0x51, 0x00, 0x53, 0x54, 0x55, - 0x56, 0x57, 0x58, 0x59, 0x5a, 0x61, 0x62, 0x63, - 0x64, 0x00, 0x66, 0x68, 0x00, 0x70, 0x00, 0x41, - 0x00, 0x61, 0x00, 0x41, 0x42, 0x00, 0x44, 0x45, - 0x46, 0x47, 0x4a, 0x00, 0x53, 0x00, 0x61, 0x00, - 0x41, 0x42, 0x00, 0x44, 0x45, 0x46, 0x47, 0x00, - 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x00, 0x4f, 0x53, - 0x00, 0x61, 0x00, 0x41, 0x00, 0x61, 0x00, 0x41, - 0x00, 0x61, 0x00, 0x41, 0x00, 0x61, 0x00, 0x41, - 0x00, 0x61, 0x00, 0x41, 0x00, 0x61, 0x00, 0x41, - 0x00, 0x61, 0x00, 0x31, 0x01, 0x37, 0x02, 0x91, - 0x03, 0xa3, 0x03, 0xb1, 0x03, 0xd1, 0x03, 0x24, - 0x00, 0x1f, 0x04, 0x20, 0x05, 0x91, 0x03, 0xa3, - 0x03, 0xb1, 0x03, 0xd1, 0x03, 0x24, 0x00, 0x1f, - 0x04, 0x20, 0x05, 0x91, 0x03, 0xa3, 0x03, 0xb1, - 0x03, 0xd1, 0x03, 0x24, 0x00, 0x1f, 0x04, 0x20, - 0x05, 0x91, 0x03, 0xa3, 0x03, 0xb1, 0x03, 0xd1, - 0x03, 0x24, 0x00, 0x1f, 0x04, 0x20, 0x05, 0x91, - 0x03, 0xa3, 0x03, 0xb1, 0x03, 0xd1, 0x03, 0x24, - 0x00, 0x1f, 0x04, 0x20, 0x05, 0x0b, 0x0c, 0x30, - 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, - 0x00, 0x27, 0x06, 0x00, 0x01, 0x05, 0x08, 0x2a, - 0x06, 0x1e, 0x08, 0x03, 0x0d, 0x20, 0x19, 0x1a, + 0x1d, 0x1f, 0x1d, 0x23, 0x1d, 0x24, 0x1e, 0x06, + 0x1e, 0x07, 0x1e, 0x08, 0x1e, 0x1f, 0x1e, 0x23, + 0x1e, 0x24, 0x1f, 0x06, 0x1f, 0x07, 0x1f, 0x08, + 0x1f, 0x1f, 0x1f, 0x23, 0x1f, 0x24, 0x20, 0x06, + 0x20, 0x07, 0x20, 0x08, 0x20, 0x1f, 0x20, 0x23, + 0x20, 0x24, 0x21, 0x06, 0x21, 0x1f, 0x21, 0x23, + 0x21, 0x24, 0x24, 0x06, 0x24, 0x07, 0x24, 0x08, + 0x24, 0x1f, 0x24, 0x23, 0x24, 0x24, 0x0a, 0x4a, + 0x0b, 0x4a, 0x23, 0x4a, 0x20, 0x00, 0x4c, 0x06, + 0x51, 0x06, 0x51, 0x06, 0xff, 0x00, 0x1f, 0x26, + 0x06, 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x1f, 0x00, + 0x20, 0x00, 0x23, 0x00, 0x24, 0x02, 0x0b, 0x02, + 0x0c, 0x02, 0x1f, 0x02, 0x20, 0x02, 0x23, 0x02, + 0x24, 0x04, 0x0b, 0x04, 0x0c, 0x04, 0x1f, 0x26, + 0x06, 0x04, 0x20, 0x04, 0x23, 0x04, 0x24, 0x05, + 0x0b, 0x05, 0x0c, 0x05, 0x1f, 0x05, 0x20, 0x05, + 0x23, 0x05, 0x24, 0x1b, 0x23, 0x1b, 0x24, 0x1c, + 0x23, 0x1c, 0x24, 0x1d, 0x01, 0x1d, 0x1e, 0x1d, + 0x1f, 0x1d, 0x23, 0x1d, 0x24, 0x1e, 0x1f, 0x1e, + 0x23, 0x1e, 0x24, 0x1f, 0x01, 0x1f, 0x1f, 0x20, + 0x0b, 0x20, 0x0c, 0x20, 0x1f, 0x20, 0x20, 0x20, + 0x23, 0x20, 0x24, 0x23, 0x4a, 0x24, 0x0b, 0x24, + 0x0c, 0x24, 0x1f, 0x24, 0x20, 0x24, 0x23, 0x24, + 0x24, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08, 0x00, + 0x1f, 0x00, 0x21, 0x02, 0x06, 0x02, 0x07, 0x02, + 0x08, 0x02, 0x1f, 0x02, 0x21, 0x04, 0x06, 0x04, + 0x07, 0x04, 0x08, 0x04, 0x1f, 0x04, 0x21, 0x05, + 0x1f, 0x06, 0x07, 0x06, 0x1f, 0x07, 0x06, 0x07, + 0x1f, 0x08, 0x06, 0x08, 0x1f, 0x0d, 0x06, 0x0d, + 0x07, 0x0d, 0x08, 0x0d, 0x1f, 0x0f, 0x07, 0x0f, + 0x08, 0x0f, 0x1f, 0x10, 0x06, 0x10, 0x07, 0x10, + 0x08, 0x10, 0x1f, 0x11, 0x07, 0x12, 0x1f, 0x13, + 0x06, 0x13, 0x1f, 0x14, 0x06, 0x14, 0x1f, 0x1b, + 0x06, 0x1b, 0x07, 0x1b, 0x08, 0x1b, 0x1f, 0x1c, + 0x07, 0x1c, 0x1f, 0x1d, 0x06, 0x1d, 0x07, 0x1d, + 0x08, 0x1d, 0x1e, 0x1d, 0x1f, 0x1e, 0x06, 0x1e, + 0x07, 0x1e, 0x08, 0x1e, 0x1f, 0x1e, 0x21, 0x1f, + 0x06, 0x1f, 0x07, 0x1f, 0x08, 0x1f, 0x1f, 0x20, + 0x06, 0x20, 0x07, 0x20, 0x08, 0x20, 0x1f, 0x20, + 0x21, 0x21, 0x06, 0x21, 0x1f, 0x21, 0x4a, 0x24, + 0x06, 0x24, 0x07, 0x24, 0x08, 0x24, 0x1f, 0x24, + 0x21, 0x00, 0x1f, 0x00, 0x21, 0x02, 0x1f, 0x02, + 0x21, 0x04, 0x1f, 0x04, 0x21, 0x05, 0x1f, 0x05, + 0x21, 0x0d, 0x1f, 0x0d, 0x21, 0x0e, 0x1f, 0x0e, + 0x21, 0x1d, 0x1e, 0x1d, 0x1f, 0x1e, 0x1f, 0x20, + 0x1f, 0x20, 0x21, 0x24, 0x1f, 0x24, 0x21, 0x40, + 0x06, 0x4e, 0x06, 0x51, 0x06, 0x27, 0x06, 0x10, + 0x22, 0x10, 0x23, 0x12, 0x22, 0x12, 0x23, 0x13, + 0x22, 0x13, 0x23, 0x0c, 0x22, 0x0c, 0x23, 0x0d, + 0x22, 0x0d, 0x23, 0x06, 0x22, 0x06, 0x23, 0x05, + 0x22, 0x05, 0x23, 0x07, 0x22, 0x07, 0x23, 0x0e, + 0x22, 0x0e, 0x23, 0x0f, 0x22, 0x0f, 0x23, 0x0d, + 0x05, 0x0d, 0x06, 0x0d, 0x07, 0x0d, 0x1e, 0x0d, + 0x0a, 0x0c, 0x0a, 0x0e, 0x0a, 0x0f, 0x0a, 0x10, + 0x22, 0x10, 0x23, 0x12, 0x22, 0x12, 0x23, 0x13, + 0x22, 0x13, 0x23, 0x0c, 0x22, 0x0c, 0x23, 0x0d, + 0x22, 0x0d, 0x23, 0x06, 0x22, 0x06, 0x23, 0x05, + 0x22, 0x05, 0x23, 0x07, 0x22, 0x07, 0x23, 0x0e, + 0x22, 0x0e, 0x23, 0x0f, 0x22, 0x0f, 0x23, 0x0d, + 0x05, 0x0d, 0x06, 0x0d, 0x07, 0x0d, 0x1e, 0x0d, + 0x0a, 0x0c, 0x0a, 0x0e, 0x0a, 0x0f, 0x0a, 0x0d, + 0x05, 0x0d, 0x06, 0x0d, 0x07, 0x0d, 0x1e, 0x0c, + 0x20, 0x0d, 0x20, 0x10, 0x1e, 0x0c, 0x05, 0x0c, + 0x06, 0x0c, 0x07, 0x0d, 0x05, 0x0d, 0x06, 0x0d, + 0x07, 0x10, 0x1e, 0x11, 0x1e, 0x00, 0x24, 0x00, + 0x24, 0x2a, 0x06, 0x00, 0x02, 0x1b, 0x00, 0x03, + 0x02, 0x00, 0x03, 0x02, 0x00, 0x03, 0x1b, 0x00, + 0x04, 0x1b, 0x00, 0x1b, 0x02, 0x00, 0x1b, 0x03, + 0x00, 0x1b, 0x04, 0x02, 0x1b, 0x03, 0x02, 0x1b, + 0x03, 0x03, 0x1b, 0x20, 0x03, 0x1b, 0x1f, 0x09, + 0x03, 0x02, 0x09, 0x02, 0x03, 0x09, 0x02, 0x1f, + 0x09, 0x1b, 0x03, 0x09, 0x1b, 0x03, 0x09, 0x1b, + 0x02, 0x09, 0x1b, 0x1b, 0x09, 0x1b, 0x1b, 0x0b, + 0x03, 0x03, 0x0b, 0x03, 0x03, 0x0b, 0x1b, 0x1b, + 0x0a, 0x03, 0x1b, 0x0a, 0x03, 0x1b, 0x0a, 0x02, + 0x20, 0x0a, 0x1b, 0x04, 0x0a, 0x1b, 0x04, 0x0a, + 0x1b, 0x1b, 0x0a, 0x1b, 0x1b, 0x0c, 0x03, 0x1f, + 0x0c, 0x04, 0x1b, 0x0c, 0x04, 0x1b, 0x0d, 0x1b, + 0x03, 0x0d, 0x1b, 0x03, 0x0d, 0x1b, 0x1b, 0x0d, + 0x1b, 0x20, 0x0f, 0x02, 0x1b, 0x0f, 0x1b, 0x1b, + 0x0f, 0x1b, 0x1b, 0x0f, 0x1b, 0x1f, 0x10, 0x1b, + 0x1b, 0x10, 0x1b, 0x20, 0x10, 0x1b, 0x1f, 0x17, + 0x04, 0x1b, 0x17, 0x04, 0x1b, 0x18, 0x1b, 0x03, + 0x18, 0x1b, 0x1b, 0x1a, 0x03, 0x1b, 0x1a, 0x03, + 0x20, 0x1a, 0x03, 0x1f, 0x1a, 0x02, 0x02, 0x1a, + 0x02, 0x02, 0x1a, 0x04, 0x1b, 0x1a, 0x04, 0x1b, + 0x1a, 0x1b, 0x03, 0x1a, 0x1b, 0x03, 0x1b, 0x03, + 0x02, 0x1b, 0x03, 0x1b, 0x1b, 0x03, 0x20, 0x1b, + 0x02, 0x03, 0x1b, 0x02, 0x1b, 0x1b, 0x04, 0x02, + 0x1b, 0x04, 0x1b, 0x28, 0x06, 0x1d, 0x04, 0x06, + 0x1f, 0x1d, 0x04, 0x1f, 0x1d, 0x1d, 0x1e, 0x05, + 0x1d, 0x1e, 0x05, 0x21, 0x1e, 0x04, 0x1d, 0x1e, + 0x04, 0x1d, 0x1e, 0x04, 0x21, 0x1e, 0x1d, 0x22, + 0x1e, 0x1d, 0x21, 0x22, 0x1d, 0x1d, 0x22, 0x1d, + 0x1d, 0x00, 0x06, 0x22, 0x02, 0x04, 0x22, 0x02, + 0x04, 0x21, 0x02, 0x06, 0x22, 0x02, 0x06, 0x21, + 0x02, 0x1d, 0x22, 0x02, 0x1d, 0x21, 0x04, 0x1d, + 0x22, 0x04, 0x05, 0x21, 0x04, 0x1d, 0x21, 0x0b, + 0x06, 0x21, 0x0d, 0x05, 0x22, 0x0c, 0x05, 0x22, + 0x0e, 0x05, 0x22, 0x1c, 0x04, 0x22, 0x1c, 0x1d, + 0x22, 0x22, 0x05, 0x22, 0x22, 0x04, 0x22, 0x22, + 0x1d, 0x22, 0x1d, 0x1d, 0x22, 0x1a, 0x1d, 0x22, + 0x1e, 0x05, 0x22, 0x1a, 0x1d, 0x05, 0x1c, 0x05, + 0x1d, 0x11, 0x1d, 0x22, 0x1b, 0x1d, 0x22, 0x1e, + 0x04, 0x05, 0x1d, 0x06, 0x22, 0x1c, 0x04, 0x1d, + 0x1b, 0x1d, 0x1d, 0x1c, 0x04, 0x1d, 0x1e, 0x04, + 0x05, 0x04, 0x05, 0x22, 0x05, 0x04, 0x22, 0x1d, + 0x04, 0x22, 0x19, 0x1d, 0x22, 0x00, 0x05, 0x22, + 0x1b, 0x1d, 0x1d, 0x11, 0x04, 0x1d, 0x0d, 0x1d, + 0x1d, 0x0b, 0x06, 0x22, 0x1e, 0x04, 0x22, 0x35, + 0x06, 0x00, 0x0f, 0x9d, 0x0d, 0x0f, 0x9d, 0x27, + 0x06, 0x00, 0x1d, 0x1d, 0x20, 0x00, 0x1c, 0x01, + 0x0a, 0x1e, 0x06, 0x1e, 0x08, 0x0e, 0x1d, 0x12, + 0x1e, 0x0a, 0x0c, 0x21, 0x1d, 0x12, 0x1d, 0x23, + 0x20, 0x21, 0x0c, 0x1d, 0x1e, 0x35, 0x06, 0x00, + 0x0f, 0x14, 0x27, 0x06, 0x0e, 0x1d, 0x22, 0xff, + 0x00, 0x1d, 0x1d, 0x20, 0xff, 0x12, 0x1d, 0x23, + 0x20, 0xff, 0x21, 0x0c, 0x1d, 0x1e, 0x27, 0x06, + 0x05, 0x1d, 0xff, 0x05, 0x1d, 0x00, 0x1d, 0x20, + 0x27, 0x06, 0x0a, 0xa5, 0x00, 0x1d, 0x2c, 0x00, + 0x01, 0x30, 0x02, 0x30, 0x3a, 0x00, 0x3b, 0x00, + 0x21, 0x00, 0x3f, 0x00, 0x16, 0x30, 0x17, 0x30, + 0x26, 0x20, 0x13, 0x20, 0x12, 0x01, 0x00, 0x5f, + 0x5f, 0x28, 0x29, 0x7b, 0x7d, 0x08, 0x30, 0x0c, + 0x0d, 0x08, 0x09, 0x02, 0x03, 0x00, 0x01, 0x04, + 0x05, 0x06, 0x07, 0x5b, 0x00, 0x5d, 0x00, 0x3e, + 0x20, 0x3e, 0x20, 0x3e, 0x20, 0x3e, 0x20, 0x5f, + 0x00, 0x5f, 0x00, 0x5f, 0x00, 0x2c, 0x00, 0x01, + 0x30, 0x2e, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x3a, + 0x00, 0x3f, 0x00, 0x21, 0x00, 0x14, 0x20, 0x28, + 0x00, 0x29, 0x00, 0x7b, 0x00, 0x7d, 0x00, 0x14, + 0x30, 0x15, 0x30, 0x23, 0x26, 0x2a, 0x2b, 0x2d, + 0x3c, 0x3e, 0x3d, 0x00, 0x5c, 0x24, 0x25, 0x40, + 0x40, 0x06, 0xff, 0x0b, 0x00, 0x0b, 0xff, 0x0c, + 0x20, 0x00, 0x4d, 0x06, 0x40, 0x06, 0xff, 0x0e, + 0x00, 0x0e, 0xff, 0x0f, 0x00, 0x0f, 0xff, 0x10, + 0x00, 0x10, 0xff, 0x11, 0x00, 0x11, 0xff, 0x12, + 0x00, 0x12, 0x21, 0x06, 0x00, 0x01, 0x01, 0x02, + 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x05, + 0x05, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x08, + 0x08, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x0a, 0x0a, + 0x0a, 0x0b, 0x0b, 0x0b, 0x0b, 0x0c, 0x0c, 0x0c, + 0x0c, 0x0d, 0x0d, 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, + 0x0f, 0x10, 0x10, 0x11, 0x11, 0x12, 0x12, 0x12, + 0x12, 0x13, 0x13, 0x13, 0x13, 0x14, 0x14, 0x14, + 0x14, 0x15, 0x15, 0x15, 0x15, 0x16, 0x16, 0x16, + 0x16, 0x17, 0x17, 0x17, 0x17, 0x18, 0x18, 0x18, + 0x18, 0x19, 0x19, 0x19, 0x19, 0x20, 0x20, 0x20, + 0x20, 0x21, 0x21, 0x21, 0x21, 0x22, 0x22, 0x22, + 0x22, 0x23, 0x23, 0x23, 0x23, 0x24, 0x24, 0x24, + 0x24, 0x25, 0x25, 0x25, 0x25, 0x26, 0x26, 0x26, + 0x26, 0x27, 0x27, 0x28, 0x28, 0x29, 0x29, 0x29, + 0x29, 0x22, 0x06, 0x22, 0x00, 0x22, 0x00, 0x22, + 0x01, 0x22, 0x01, 0x22, 0x03, 0x22, 0x03, 0x22, + 0x05, 0x22, 0x05, 0x21, 0x00, 0x85, 0x29, 0x01, + 0x30, 0x01, 0x0b, 0x0c, 0x00, 0xfa, 0xf1, 0xa0, + 0xa2, 0xa4, 0xa6, 0xa8, 0xe2, 0xe4, 0xe6, 0xc2, + 0xfb, 0xa1, 0xa3, 0xa5, 0xa7, 0xa9, 0xaa, 0xac, + 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, + 0xbe, 0xc0, 0xc3, 0xc5, 0xc7, 0xc9, 0xca, 0xcb, + 0xcc, 0xcd, 0xce, 0xd1, 0xd4, 0xd7, 0xda, 0xdd, + 0xde, 0xdf, 0xe0, 0xe1, 0xe3, 0xe5, 0xe7, 0xe8, + 0xe9, 0xea, 0xeb, 0xec, 0xee, 0xf2, 0x98, 0x99, + 0x31, 0x31, 0x4f, 0x31, 0x55, 0x31, 0x5b, 0x31, + 0x61, 0x31, 0xa2, 0x00, 0xa3, 0x00, 0xac, 0x00, + 0xaf, 0x00, 0xa6, 0x00, 0xa5, 0x00, 0xa9, 0x20, + 0x00, 0x00, 0x02, 0x25, 0x90, 0x21, 0x91, 0x21, + 0x92, 0x21, 0x93, 0x21, 0xa0, 0x25, 0xcb, 0x25, + 0xd0, 0x02, 0xd1, 0x02, 0xe6, 0x00, 0x99, 0x02, + 0x53, 0x02, 0x00, 0x00, 0xa3, 0x02, 0x66, 0xab, + 0xa5, 0x02, 0xa4, 0x02, 0x56, 0x02, 0x57, 0x02, + 0x91, 0x1d, 0x58, 0x02, 0x5e, 0x02, 0xa9, 0x02, + 0x64, 0x02, 0x62, 0x02, 0x60, 0x02, 0x9b, 0x02, + 0x27, 0x01, 0x9c, 0x02, 0x67, 0x02, 0x84, 0x02, + 0xaa, 0x02, 0xab, 0x02, 0x6c, 0x02, 0x04, 0xdf, + 0x8e, 0xa7, 0x6e, 0x02, 0x05, 0xdf, 0x8e, 0x02, + 0x06, 0xdf, 0xf8, 0x00, 0x76, 0x02, 0x77, 0x02, + 0x71, 0x00, 0x7a, 0x02, 0x08, 0xdf, 0x7d, 0x02, + 0x7e, 0x02, 0x80, 0x02, 0xa8, 0x02, 0xa6, 0x02, + 0x67, 0xab, 0xa7, 0x02, 0x88, 0x02, 0x71, 0x2c, + 0x00, 0x00, 0x8f, 0x02, 0xa1, 0x02, 0xa2, 0x02, + 0x98, 0x02, 0xc0, 0x01, 0xc1, 0x01, 0xc2, 0x01, + 0x0a, 0xdf, 0x1e, 0xdf, 0x41, 0x04, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x14, 0x99, 0x10, 0xba, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x9b, 0x10, 0xba, 0x10, + 0x05, 0x05, 0xa5, 0x10, 0xba, 0x10, 0x05, 0x31, + 0x11, 0x27, 0x11, 0x32, 0x11, 0x27, 0x11, 0x55, + 0x47, 0x13, 0x3e, 0x13, 0x47, 0x13, 0x57, 0x13, + 0x55, 0xb9, 0x14, 0xba, 0x14, 0xb9, 0x14, 0xb0, + 0x14, 0x00, 0x00, 0x00, 0x00, 0xb9, 0x14, 0xbd, + 0x14, 0x55, 0x50, 0xb8, 0x15, 0xaf, 0x15, 0xb9, + 0x15, 0xaf, 0x15, 0x55, 0x35, 0x19, 0x30, 0x19, + 0x05, 0x57, 0xd1, 0x65, 0xd1, 0x58, 0xd1, 0x65, + 0xd1, 0x5f, 0xd1, 0x6e, 0xd1, 0x5f, 0xd1, 0x6f, + 0xd1, 0x5f, 0xd1, 0x70, 0xd1, 0x5f, 0xd1, 0x71, + 0xd1, 0x5f, 0xd1, 0x72, 0xd1, 0x55, 0x55, 0x55, + 0x05, 0xb9, 0xd1, 0x65, 0xd1, 0xba, 0xd1, 0x65, + 0xd1, 0xbb, 0xd1, 0x6e, 0xd1, 0xbc, 0xd1, 0x6e, + 0xd1, 0xbb, 0xd1, 0x6f, 0xd1, 0xbc, 0xd1, 0x6f, + 0xd1, 0x55, 0x55, 0x55, 0x41, 0x00, 0x61, 0x00, + 0x41, 0x00, 0x61, 0x00, 0x69, 0x00, 0x41, 0x00, + 0x61, 0x00, 0x41, 0x00, 0x43, 0x44, 0x00, 0x00, + 0x47, 0x00, 0x00, 0x4a, 0x4b, 0x00, 0x00, 0x4e, + 0x4f, 0x50, 0x51, 0x00, 0x53, 0x54, 0x55, 0x56, + 0x57, 0x58, 0x59, 0x5a, 0x61, 0x62, 0x63, 0x64, + 0x00, 0x66, 0x68, 0x00, 0x70, 0x00, 0x41, 0x00, + 0x61, 0x00, 0x41, 0x42, 0x00, 0x44, 0x45, 0x46, + 0x47, 0x4a, 0x00, 0x53, 0x00, 0x61, 0x00, 0x41, + 0x42, 0x00, 0x44, 0x45, 0x46, 0x47, 0x00, 0x49, + 0x4a, 0x4b, 0x4c, 0x4d, 0x00, 0x4f, 0x53, 0x00, + 0x61, 0x00, 0x41, 0x00, 0x61, 0x00, 0x41, 0x00, + 0x61, 0x00, 0x41, 0x00, 0x61, 0x00, 0x41, 0x00, + 0x61, 0x00, 0x41, 0x00, 0x61, 0x00, 0x41, 0x00, + 0x61, 0x00, 0x31, 0x01, 0x37, 0x02, 0x91, 0x03, + 0xa3, 0x03, 0xb1, 0x03, 0xd1, 0x03, 0x24, 0x00, + 0x1f, 0x04, 0x20, 0x05, 0x91, 0x03, 0xa3, 0x03, + 0xb1, 0x03, 0xd1, 0x03, 0x24, 0x00, 0x1f, 0x04, + 0x20, 0x05, 0x91, 0x03, 0xa3, 0x03, 0xb1, 0x03, + 0xd1, 0x03, 0x24, 0x00, 0x1f, 0x04, 0x20, 0x05, + 0x91, 0x03, 0xa3, 0x03, 0xb1, 0x03, 0xd1, 0x03, + 0x24, 0x00, 0x1f, 0x04, 0x20, 0x05, 0x91, 0x03, + 0xa3, 0x03, 0xb1, 0x03, 0xd1, 0x03, 0x24, 0x00, + 0x1f, 0x04, 0x20, 0x05, 0x0b, 0x0c, 0x30, 0x00, + 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, + 0x30, 0x04, 0x3a, 0x04, 0x3e, 0x04, 0x4b, 0x04, + 0x4d, 0x04, 0x4e, 0x04, 0x89, 0xa6, 0x30, 0x04, + 0xa9, 0x26, 0x28, 0xb9, 0x7f, 0x9f, 0x00, 0x01, + 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x0a, + 0x0b, 0x0e, 0x0f, 0x11, 0x13, 0x14, 0x15, 0x16, + 0x17, 0x18, 0x1a, 0x1b, 0x61, 0x26, 0x25, 0x2f, + 0x7b, 0x51, 0xa6, 0xb1, 0x04, 0x27, 0x06, 0x00, + 0x01, 0x05, 0x08, 0x2a, 0x06, 0x1e, 0x08, 0x03, + 0x0d, 0x20, 0x19, 0x1a, 0x1b, 0x1c, 0x09, 0x0f, + 0x17, 0x0b, 0x18, 0x07, 0x0a, 0x00, 0x01, 0x04, + 0x06, 0x0c, 0x0e, 0x10, 0x44, 0x90, 0x77, 0x45, + 0x28, 0x06, 0x2c, 0x06, 0x00, 0x00, 0x47, 0x06, + 0x33, 0x06, 0x17, 0x10, 0x11, 0x12, 0x13, 0x00, + 0x06, 0x0e, 0x02, 0x0f, 0x34, 0x06, 0x2a, 0x06, + 0x2b, 0x06, 0x2e, 0x06, 0x00, 0x00, 0x36, 0x06, + 0x00, 0x00, 0x3a, 0x06, 0x2d, 0x06, 0x00, 0x00, + 0x4a, 0x06, 0x00, 0x00, 0x44, 0x06, 0x00, 0x00, + 0x46, 0x06, 0x33, 0x06, 0x39, 0x06, 0x00, 0x00, + 0x35, 0x06, 0x42, 0x06, 0x00, 0x00, 0x34, 0x06, + 0x00, 0x00, 0x00, 0x00, 0x2e, 0x06, 0x00, 0x00, + 0x36, 0x06, 0x00, 0x00, 0x3a, 0x06, 0x00, 0x00, + 0xba, 0x06, 0x00, 0x00, 0x6f, 0x06, 0x00, 0x00, + 0x28, 0x06, 0x2c, 0x06, 0x00, 0x00, 0x47, 0x06, + 0x00, 0x00, 0x00, 0x00, 0x2d, 0x06, 0x37, 0x06, + 0x4a, 0x06, 0x43, 0x06, 0x00, 0x00, 0x45, 0x06, + 0x46, 0x06, 0x33, 0x06, 0x39, 0x06, 0x41, 0x06, + 0x35, 0x06, 0x42, 0x06, 0x00, 0x00, 0x34, 0x06, + 0x2a, 0x06, 0x2b, 0x06, 0x2e, 0x06, 0x00, 0x00, + 0x36, 0x06, 0x38, 0x06, 0x3a, 0x06, 0x6e, 0x06, + 0x00, 0x00, 0xa1, 0x06, 0x27, 0x06, 0x00, 0x01, + 0x05, 0x08, 0x20, 0x21, 0x0b, 0x06, 0x10, 0x23, + 0x2a, 0x06, 0x1a, 0x1b, 0x1c, 0x09, 0x0f, 0x17, + 0x0b, 0x18, 0x07, 0x0a, 0x00, 0x01, 0x04, 0x06, + 0x0c, 0x0e, 0x10, 0x28, 0x06, 0x2c, 0x06, 0x2f, + 0x06, 0x00, 0x00, 0x48, 0x06, 0x32, 0x06, 0x2d, + 0x06, 0x37, 0x06, 0x4a, 0x06, 0x2a, 0x06, 0x1a, 0x1b, 0x1c, 0x09, 0x0f, 0x17, 0x0b, 0x18, 0x07, 0x0a, 0x00, 0x01, 0x04, 0x06, 0x0c, 0x0e, 0x10, - 0x44, 0x90, 0x77, 0x45, 0x28, 0x06, 0x2c, 0x06, - 0x00, 0x00, 0x47, 0x06, 0x33, 0x06, 0x17, 0x10, - 0x11, 0x12, 0x13, 0x00, 0x06, 0x0e, 0x02, 0x0f, - 0x34, 0x06, 0x2a, 0x06, 0x2b, 0x06, 0x2e, 0x06, - 0x00, 0x00, 0x36, 0x06, 0x00, 0x00, 0x3a, 0x06, - 0x2d, 0x06, 0x00, 0x00, 0x4a, 0x06, 0x00, 0x00, - 0x44, 0x06, 0x00, 0x00, 0x46, 0x06, 0x33, 0x06, - 0x39, 0x06, 0x00, 0x00, 0x35, 0x06, 0x42, 0x06, - 0x00, 0x00, 0x34, 0x06, 0x00, 0x00, 0x00, 0x00, - 0x2e, 0x06, 0x00, 0x00, 0x36, 0x06, 0x00, 0x00, - 0x3a, 0x06, 0x00, 0x00, 0xba, 0x06, 0x00, 0x00, - 0x6f, 0x06, 0x00, 0x00, 0x28, 0x06, 0x2c, 0x06, - 0x00, 0x00, 0x47, 0x06, 0x00, 0x00, 0x00, 0x00, - 0x2d, 0x06, 0x37, 0x06, 0x4a, 0x06, 0x43, 0x06, - 0x00, 0x00, 0x45, 0x06, 0x46, 0x06, 0x33, 0x06, - 0x39, 0x06, 0x41, 0x06, 0x35, 0x06, 0x42, 0x06, - 0x00, 0x00, 0x34, 0x06, 0x2a, 0x06, 0x2b, 0x06, - 0x2e, 0x06, 0x00, 0x00, 0x36, 0x06, 0x38, 0x06, - 0x3a, 0x06, 0x6e, 0x06, 0x00, 0x00, 0xa1, 0x06, - 0x27, 0x06, 0x00, 0x01, 0x05, 0x08, 0x20, 0x21, - 0x0b, 0x06, 0x10, 0x23, 0x2a, 0x06, 0x1a, 0x1b, - 0x1c, 0x09, 0x0f, 0x17, 0x0b, 0x18, 0x07, 0x0a, - 0x00, 0x01, 0x04, 0x06, 0x0c, 0x0e, 0x10, 0x28, - 0x06, 0x2c, 0x06, 0x2f, 0x06, 0x00, 0x00, 0x48, - 0x06, 0x32, 0x06, 0x2d, 0x06, 0x37, 0x06, 0x4a, - 0x06, 0x2a, 0x06, 0x1a, 0x1b, 0x1c, 0x09, 0x0f, - 0x17, 0x0b, 0x18, 0x07, 0x0a, 0x00, 0x01, 0x04, - 0x06, 0x0c, 0x0e, 0x10, 0x30, 0x2e, 0x30, 0x00, - 0x2c, 0x00, 0x28, 0x00, 0x41, 0x00, 0x29, 0x00, - 0x14, 0x30, 0x53, 0x00, 0x15, 0x30, 0x43, 0x52, - 0x43, 0x44, 0x57, 0x5a, 0x41, 0x00, 0x48, 0x56, - 0x4d, 0x56, 0x53, 0x44, 0x53, 0x53, 0x50, 0x50, - 0x56, 0x57, 0x43, 0x4d, 0x43, 0x4d, 0x44, 0x4d, - 0x52, 0x44, 0x4a, 0x4b, 0x30, 0x30, 0x00, 0x68, - 0x68, 0x4b, 0x62, 0x57, 0x5b, 0xcc, 0x53, 0xc7, - 0x30, 0x8c, 0x4e, 0x1a, 0x59, 0xe3, 0x89, 0x29, - 0x59, 0xa4, 0x4e, 0x20, 0x66, 0x21, 0x71, 0x99, - 0x65, 0x4d, 0x52, 0x8c, 0x5f, 0x8d, 0x51, 0xb0, - 0x65, 0x1d, 0x52, 0x42, 0x7d, 0x1f, 0x75, 0xa9, - 0x8c, 0xf0, 0x58, 0x39, 0x54, 0x14, 0x6f, 0x95, - 0x62, 0x55, 0x63, 0x00, 0x4e, 0x09, 0x4e, 0x4a, - 0x90, 0xe6, 0x5d, 0x2d, 0x4e, 0xf3, 0x53, 0x07, - 0x63, 0x70, 0x8d, 0x53, 0x62, 0x81, 0x79, 0x7a, - 0x7a, 0x08, 0x54, 0x80, 0x6e, 0x09, 0x67, 0x08, - 0x67, 0x33, 0x75, 0x72, 0x52, 0xb6, 0x55, 0x4d, - 0x91, 0x14, 0x30, 0x15, 0x30, 0x2c, 0x67, 0x09, - 0x4e, 0x8c, 0x4e, 0x89, 0x5b, 0xb9, 0x70, 0x53, - 0x62, 0xd7, 0x76, 0xdd, 0x52, 0x57, 0x65, 0x97, - 0x5f, 0xef, 0x53, 0x30, 0x00, 0x38, 0x4e, 0x05, - 0x00, 0x09, 0x22, 0x01, 0x60, 0x4f, 0xae, 0x4f, - 0xbb, 0x4f, 0x02, 0x50, 0x7a, 0x50, 0x99, 0x50, - 0xe7, 0x50, 0xcf, 0x50, 0x9e, 0x34, 0x3a, 0x06, - 0x4d, 0x51, 0x54, 0x51, 0x64, 0x51, 0x77, 0x51, - 0x1c, 0x05, 0xb9, 0x34, 0x67, 0x51, 0x8d, 0x51, - 0x4b, 0x05, 0x97, 0x51, 0xa4, 0x51, 0xcc, 0x4e, - 0xac, 0x51, 0xb5, 0x51, 0xdf, 0x91, 0xf5, 0x51, - 0x03, 0x52, 0xdf, 0x34, 0x3b, 0x52, 0x46, 0x52, - 0x72, 0x52, 0x77, 0x52, 0x15, 0x35, 0x02, 0x00, - 0x20, 0x80, 0x80, 0x00, 0x08, 0x00, 0x00, 0xc7, - 0x52, 0x00, 0x02, 0x1d, 0x33, 0x3e, 0x3f, 0x50, - 0x82, 0x8a, 0x93, 0xac, 0xb6, 0xb8, 0xb8, 0xb8, - 0x2c, 0x0a, 0x70, 0x70, 0xca, 0x53, 0xdf, 0x53, - 0x63, 0x0b, 0xeb, 0x53, 0xf1, 0x53, 0x06, 0x54, - 0x9e, 0x54, 0x38, 0x54, 0x48, 0x54, 0x68, 0x54, - 0xa2, 0x54, 0xf6, 0x54, 0x10, 0x55, 0x53, 0x55, - 0x63, 0x55, 0x84, 0x55, 0x84, 0x55, 0x99, 0x55, - 0xab, 0x55, 0xb3, 0x55, 0xc2, 0x55, 0x16, 0x57, - 0x06, 0x56, 0x17, 0x57, 0x51, 0x56, 0x74, 0x56, - 0x07, 0x52, 0xee, 0x58, 0xce, 0x57, 0xf4, 0x57, - 0x0d, 0x58, 0x8b, 0x57, 0x32, 0x58, 0x31, 0x58, - 0xac, 0x58, 0xe4, 0x14, 0xf2, 0x58, 0xf7, 0x58, - 0x06, 0x59, 0x1a, 0x59, 0x22, 0x59, 0x62, 0x59, - 0xa8, 0x16, 0xea, 0x16, 0xec, 0x59, 0x1b, 0x5a, - 0x27, 0x5a, 0xd8, 0x59, 0x66, 0x5a, 0xee, 0x36, - 0xfc, 0x36, 0x08, 0x5b, 0x3e, 0x5b, 0x3e, 0x5b, - 0xc8, 0x19, 0xc3, 0x5b, 0xd8, 0x5b, 0xe7, 0x5b, - 0xf3, 0x5b, 0x18, 0x1b, 0xff, 0x5b, 0x06, 0x5c, - 0x53, 0x5f, 0x22, 0x5c, 0x81, 0x37, 0x60, 0x5c, - 0x6e, 0x5c, 0xc0, 0x5c, 0x8d, 0x5c, 0xe4, 0x1d, - 0x43, 0x5d, 0xe6, 0x1d, 0x6e, 0x5d, 0x6b, 0x5d, - 0x7c, 0x5d, 0xe1, 0x5d, 0xe2, 0x5d, 0x2f, 0x38, - 0xfd, 0x5d, 0x28, 0x5e, 0x3d, 0x5e, 0x69, 0x5e, - 0x62, 0x38, 0x83, 0x21, 0x7c, 0x38, 0xb0, 0x5e, - 0xb3, 0x5e, 0xb6, 0x5e, 0xca, 0x5e, 0x92, 0xa3, - 0xfe, 0x5e, 0x31, 0x23, 0x31, 0x23, 0x01, 0x82, - 0x22, 0x5f, 0x22, 0x5f, 0xc7, 0x38, 0xb8, 0x32, - 0xda, 0x61, 0x62, 0x5f, 0x6b, 0x5f, 0xe3, 0x38, - 0x9a, 0x5f, 0xcd, 0x5f, 0xd7, 0x5f, 0xf9, 0x5f, - 0x81, 0x60, 0x3a, 0x39, 0x1c, 0x39, 0x94, 0x60, - 0xd4, 0x26, 0xc7, 0x60, 0x02, 0x02, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0a, - 0x00, 0x00, 0x02, 0x08, 0x00, 0x80, 0x08, 0x00, - 0x00, 0x08, 0x80, 0x28, 0x80, 0x02, 0x00, 0x00, - 0x02, 0x48, 0x61, 0x00, 0x04, 0x06, 0x04, 0x32, - 0x46, 0x6a, 0x5c, 0x67, 0x96, 0xaa, 0xae, 0xc8, - 0xd3, 0x5d, 0x62, 0x00, 0x54, 0x77, 0xf3, 0x0c, - 0x2b, 0x3d, 0x63, 0xfc, 0x62, 0x68, 0x63, 0x83, - 0x63, 0xe4, 0x63, 0xf1, 0x2b, 0x22, 0x64, 0xc5, - 0x63, 0xa9, 0x63, 0x2e, 0x3a, 0x69, 0x64, 0x7e, - 0x64, 0x9d, 0x64, 0x77, 0x64, 0x6c, 0x3a, 0x4f, - 0x65, 0x6c, 0x65, 0x0a, 0x30, 0xe3, 0x65, 0xf8, - 0x66, 0x49, 0x66, 0x19, 0x3b, 0x91, 0x66, 0x08, - 0x3b, 0xe4, 0x3a, 0x92, 0x51, 0x95, 0x51, 0x00, - 0x67, 0x9c, 0x66, 0xad, 0x80, 0xd9, 0x43, 0x17, - 0x67, 0x1b, 0x67, 0x21, 0x67, 0x5e, 0x67, 0x53, - 0x67, 0xc3, 0x33, 0x49, 0x3b, 0xfa, 0x67, 0x85, - 0x67, 0x52, 0x68, 0x85, 0x68, 0x6d, 0x34, 0x8e, - 0x68, 0x1f, 0x68, 0x14, 0x69, 0x9d, 0x3b, 0x42, - 0x69, 0xa3, 0x69, 0xea, 0x69, 0xa8, 0x6a, 0xa3, - 0x36, 0xdb, 0x6a, 0x18, 0x3c, 0x21, 0x6b, 0xa7, - 0x38, 0x54, 0x6b, 0x4e, 0x3c, 0x72, 0x6b, 0x9f, - 0x6b, 0xba, 0x6b, 0xbb, 0x6b, 0x8d, 0x3a, 0x0b, - 0x1d, 0xfa, 0x3a, 0x4e, 0x6c, 0xbc, 0x3c, 0xbf, - 0x6c, 0xcd, 0x6c, 0x67, 0x6c, 0x16, 0x6d, 0x3e, - 0x6d, 0x77, 0x6d, 0x41, 0x6d, 0x69, 0x6d, 0x78, - 0x6d, 0x85, 0x6d, 0x1e, 0x3d, 0x34, 0x6d, 0x2f, - 0x6e, 0x6e, 0x6e, 0x33, 0x3d, 0xcb, 0x6e, 0xc7, - 0x6e, 0xd1, 0x3e, 0xf9, 0x6d, 0x6e, 0x6f, 0x5e, - 0x3f, 0x8e, 0x3f, 0xc6, 0x6f, 0x39, 0x70, 0x1e, - 0x70, 0x1b, 0x70, 0x96, 0x3d, 0x4a, 0x70, 0x7d, - 0x70, 0x77, 0x70, 0xad, 0x70, 0x25, 0x05, 0x45, - 0x71, 0x63, 0x42, 0x9c, 0x71, 0xab, 0x43, 0x28, - 0x72, 0x35, 0x72, 0x50, 0x72, 0x08, 0x46, 0x80, - 0x72, 0x95, 0x72, 0x35, 0x47, 0x02, 0x20, 0x00, - 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x08, 0x80, - 0x00, 0x00, 0x02, 0x02, 0x80, 0x8a, 0x00, 0x00, - 0x20, 0x00, 0x08, 0x0a, 0x00, 0x80, 0x88, 0x80, - 0x20, 0x14, 0x48, 0x7a, 0x73, 0x8b, 0x73, 0xac, - 0x3e, 0xa5, 0x73, 0xb8, 0x3e, 0xb8, 0x3e, 0x47, - 0x74, 0x5c, 0x74, 0x71, 0x74, 0x85, 0x74, 0xca, - 0x74, 0x1b, 0x3f, 0x24, 0x75, 0x36, 0x4c, 0x3e, - 0x75, 0x92, 0x4c, 0x70, 0x75, 0x9f, 0x21, 0x10, - 0x76, 0xa1, 0x4f, 0xb8, 0x4f, 0x44, 0x50, 0xfc, - 0x3f, 0x08, 0x40, 0xf4, 0x76, 0xf3, 0x50, 0xf2, - 0x50, 0x19, 0x51, 0x33, 0x51, 0x1e, 0x77, 0x1f, - 0x77, 0x1f, 0x77, 0x4a, 0x77, 0x39, 0x40, 0x8b, - 0x77, 0x46, 0x40, 0x96, 0x40, 0x1d, 0x54, 0x4e, - 0x78, 0x8c, 0x78, 0xcc, 0x78, 0xe3, 0x40, 0x26, - 0x56, 0x56, 0x79, 0x9a, 0x56, 0xc5, 0x56, 0x8f, - 0x79, 0xeb, 0x79, 0x2f, 0x41, 0x40, 0x7a, 0x4a, - 0x7a, 0x4f, 0x7a, 0x7c, 0x59, 0xa7, 0x5a, 0xa7, - 0x5a, 0xee, 0x7a, 0x02, 0x42, 0xab, 0x5b, 0xc6, - 0x7b, 0xc9, 0x7b, 0x27, 0x42, 0x80, 0x5c, 0xd2, - 0x7c, 0xa0, 0x42, 0xe8, 0x7c, 0xe3, 0x7c, 0x00, - 0x7d, 0x86, 0x5f, 0x63, 0x7d, 0x01, 0x43, 0xc7, - 0x7d, 0x02, 0x7e, 0x45, 0x7e, 0x34, 0x43, 0x28, - 0x62, 0x47, 0x62, 0x59, 0x43, 0xd9, 0x62, 0x7a, - 0x7f, 0x3e, 0x63, 0x95, 0x7f, 0xfa, 0x7f, 0x05, - 0x80, 0xda, 0x64, 0x23, 0x65, 0x60, 0x80, 0xa8, - 0x65, 0x70, 0x80, 0x5f, 0x33, 0xd5, 0x43, 0xb2, - 0x80, 0x03, 0x81, 0x0b, 0x44, 0x3e, 0x81, 0xb5, - 0x5a, 0xa7, 0x67, 0xb5, 0x67, 0x93, 0x33, 0x9c, - 0x33, 0x01, 0x82, 0x04, 0x82, 0x9e, 0x8f, 0x6b, - 0x44, 0x91, 0x82, 0x8b, 0x82, 0x9d, 0x82, 0xb3, - 0x52, 0xb1, 0x82, 0xb3, 0x82, 0xbd, 0x82, 0xe6, - 0x82, 0x3c, 0x6b, 0xe5, 0x82, 0x1d, 0x83, 0x63, - 0x83, 0xad, 0x83, 0x23, 0x83, 0xbd, 0x83, 0xe7, - 0x83, 0x57, 0x84, 0x53, 0x83, 0xca, 0x83, 0xcc, - 0x83, 0xdc, 0x83, 0x36, 0x6c, 0x6b, 0x6d, 0x02, - 0x00, 0x00, 0x20, 0x22, 0x2a, 0xa0, 0x0a, 0x00, - 0x20, 0x80, 0x28, 0x00, 0xa8, 0x20, 0x20, 0x00, - 0x02, 0x80, 0x22, 0x02, 0x8a, 0x08, 0x00, 0xaa, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x28, 0xd5, - 0x6c, 0x2b, 0x45, 0xf1, 0x84, 0xf3, 0x84, 0x16, - 0x85, 0xca, 0x73, 0x64, 0x85, 0x2c, 0x6f, 0x5d, - 0x45, 0x61, 0x45, 0xb1, 0x6f, 0xd2, 0x70, 0x6b, - 0x45, 0x50, 0x86, 0x5c, 0x86, 0x67, 0x86, 0x69, - 0x86, 0xa9, 0x86, 0x88, 0x86, 0x0e, 0x87, 0xe2, - 0x86, 0x79, 0x87, 0x28, 0x87, 0x6b, 0x87, 0x86, - 0x87, 0xd7, 0x45, 0xe1, 0x87, 0x01, 0x88, 0xf9, - 0x45, 0x60, 0x88, 0x63, 0x88, 0x67, 0x76, 0xd7, - 0x88, 0xde, 0x88, 0x35, 0x46, 0xfa, 0x88, 0xbb, - 0x34, 0xae, 0x78, 0x66, 0x79, 0xbe, 0x46, 0xc7, - 0x46, 0xa0, 0x8a, 0xed, 0x8a, 0x8a, 0x8b, 0x55, - 0x8c, 0xa8, 0x7c, 0xab, 0x8c, 0xc1, 0x8c, 0x1b, - 0x8d, 0x77, 0x8d, 0x2f, 0x7f, 0x04, 0x08, 0xcb, - 0x8d, 0xbc, 0x8d, 0xf0, 0x8d, 0xde, 0x08, 0xd4, - 0x8e, 0x38, 0x8f, 0xd2, 0x85, 0xed, 0x85, 0x94, - 0x90, 0xf1, 0x90, 0x11, 0x91, 0x2e, 0x87, 0x1b, - 0x91, 0x38, 0x92, 0xd7, 0x92, 0xd8, 0x92, 0x7c, - 0x92, 0xf9, 0x93, 0x15, 0x94, 0xfa, 0x8b, 0x8b, - 0x95, 0x95, 0x49, 0xb7, 0x95, 0x77, 0x8d, 0xe6, - 0x49, 0xc3, 0x96, 0xb2, 0x5d, 0x23, 0x97, 0x45, - 0x91, 0x1a, 0x92, 0x6e, 0x4a, 0x76, 0x4a, 0xe0, - 0x97, 0x0a, 0x94, 0xb2, 0x4a, 0x96, 0x94, 0x0b, - 0x98, 0x0b, 0x98, 0x29, 0x98, 0xb6, 0x95, 0xe2, - 0x98, 0x33, 0x4b, 0x29, 0x99, 0xa7, 0x99, 0xc2, - 0x99, 0xfe, 0x99, 0xce, 0x4b, 0x30, 0x9b, 0x12, - 0x9b, 0x40, 0x9c, 0xfd, 0x9c, 0xce, 0x4c, 0xed, - 0x4c, 0x67, 0x9d, 0xce, 0xa0, 0xf8, 0x4c, 0x05, - 0xa1, 0x0e, 0xa2, 0x91, 0xa2, 0xbb, 0x9e, 0x56, - 0x4d, 0xf9, 0x9e, 0xfe, 0x9e, 0x05, 0x9f, 0x0f, - 0x9f, 0x16, 0x9f, 0x3b, 0x9f, 0x00, 0xa6, 0x02, - 0x88, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, - 0x28, 0x00, 0x08, 0xa0, 0x80, 0xa0, 0x80, 0x00, - 0x80, 0x80, 0x00, 0x0a, 0x88, 0x80, 0x00, 0x80, - 0x00, 0x20, 0x2a, 0x00, 0x80, + 0x30, 0x2e, 0x30, 0x00, 0x2c, 0x00, 0x28, 0x00, + 0x41, 0x00, 0x29, 0x00, 0x14, 0x30, 0x53, 0x00, + 0x15, 0x30, 0x43, 0x52, 0x43, 0x44, 0x57, 0x5a, + 0x41, 0x00, 0x48, 0x56, 0x4d, 0x56, 0x53, 0x44, + 0x53, 0x53, 0x50, 0x50, 0x56, 0x57, 0x43, 0x4d, + 0x43, 0x4d, 0x44, 0x4d, 0x52, 0x44, 0x4a, 0x4b, + 0x30, 0x30, 0x00, 0x68, 0x68, 0x4b, 0x62, 0x57, + 0x5b, 0xcc, 0x53, 0xc7, 0x30, 0x8c, 0x4e, 0x1a, + 0x59, 0xe3, 0x89, 0x29, 0x59, 0xa4, 0x4e, 0x20, + 0x66, 0x21, 0x71, 0x99, 0x65, 0x4d, 0x52, 0x8c, + 0x5f, 0x8d, 0x51, 0xb0, 0x65, 0x1d, 0x52, 0x42, + 0x7d, 0x1f, 0x75, 0xa9, 0x8c, 0xf0, 0x58, 0x39, + 0x54, 0x14, 0x6f, 0x95, 0x62, 0x55, 0x63, 0x00, + 0x4e, 0x09, 0x4e, 0x4a, 0x90, 0xe6, 0x5d, 0x2d, + 0x4e, 0xf3, 0x53, 0x07, 0x63, 0x70, 0x8d, 0x53, + 0x62, 0x81, 0x79, 0x7a, 0x7a, 0x08, 0x54, 0x80, + 0x6e, 0x09, 0x67, 0x08, 0x67, 0x33, 0x75, 0x72, + 0x52, 0xb6, 0x55, 0x4d, 0x91, 0x14, 0x30, 0x15, + 0x30, 0x2c, 0x67, 0x09, 0x4e, 0x8c, 0x4e, 0x89, + 0x5b, 0xb9, 0x70, 0x53, 0x62, 0xd7, 0x76, 0xdd, + 0x52, 0x57, 0x65, 0x97, 0x5f, 0xef, 0x53, 0x30, + 0x00, 0x38, 0x4e, 0x05, 0x00, 0x09, 0x22, 0x01, + 0x60, 0x4f, 0xae, 0x4f, 0xbb, 0x4f, 0x02, 0x50, + 0x7a, 0x50, 0x99, 0x50, 0xe7, 0x50, 0xcf, 0x50, + 0x9e, 0x34, 0x3a, 0x06, 0x4d, 0x51, 0x54, 0x51, + 0x64, 0x51, 0x77, 0x51, 0x1c, 0x05, 0xb9, 0x34, + 0x67, 0x51, 0x8d, 0x51, 0x4b, 0x05, 0x97, 0x51, + 0xa4, 0x51, 0xcc, 0x4e, 0xac, 0x51, 0xb5, 0x51, + 0xdf, 0x91, 0xf5, 0x51, 0x03, 0x52, 0xdf, 0x34, + 0x3b, 0x52, 0x46, 0x52, 0x72, 0x52, 0x77, 0x52, + 0x15, 0x35, 0x02, 0x00, 0x20, 0x80, 0x80, 0x00, + 0x08, 0x00, 0x00, 0xc7, 0x52, 0x00, 0x02, 0x1d, + 0x33, 0x3e, 0x3f, 0x50, 0x82, 0x8a, 0x93, 0xac, + 0xb6, 0xb8, 0xb8, 0xb8, 0x2c, 0x0a, 0x70, 0x70, + 0xca, 0x53, 0xdf, 0x53, 0x63, 0x0b, 0xeb, 0x53, + 0xf1, 0x53, 0x06, 0x54, 0x9e, 0x54, 0x38, 0x54, + 0x48, 0x54, 0x68, 0x54, 0xa2, 0x54, 0xf6, 0x54, + 0x10, 0x55, 0x53, 0x55, 0x63, 0x55, 0x84, 0x55, + 0x84, 0x55, 0x99, 0x55, 0xab, 0x55, 0xb3, 0x55, + 0xc2, 0x55, 0x16, 0x57, 0x06, 0x56, 0x17, 0x57, + 0x51, 0x56, 0x74, 0x56, 0x07, 0x52, 0xee, 0x58, + 0xce, 0x57, 0xf4, 0x57, 0x0d, 0x58, 0x8b, 0x57, + 0x32, 0x58, 0x31, 0x58, 0xac, 0x58, 0xe4, 0x14, + 0xf2, 0x58, 0xf7, 0x58, 0x06, 0x59, 0x1a, 0x59, + 0x22, 0x59, 0x62, 0x59, 0xa8, 0x16, 0xea, 0x16, + 0xec, 0x59, 0x1b, 0x5a, 0x27, 0x5a, 0xd8, 0x59, + 0x66, 0x5a, 0xee, 0x36, 0xfc, 0x36, 0x08, 0x5b, + 0x3e, 0x5b, 0x3e, 0x5b, 0xc8, 0x19, 0xc3, 0x5b, + 0xd8, 0x5b, 0xe7, 0x5b, 0xf3, 0x5b, 0x18, 0x1b, + 0xff, 0x5b, 0x06, 0x5c, 0x53, 0x5f, 0x22, 0x5c, + 0x81, 0x37, 0x60, 0x5c, 0x6e, 0x5c, 0xc0, 0x5c, + 0x8d, 0x5c, 0xe4, 0x1d, 0x43, 0x5d, 0xe6, 0x1d, + 0x6e, 0x5d, 0x6b, 0x5d, 0x7c, 0x5d, 0xe1, 0x5d, + 0xe2, 0x5d, 0x2f, 0x38, 0xfd, 0x5d, 0x28, 0x5e, + 0x3d, 0x5e, 0x69, 0x5e, 0x62, 0x38, 0x83, 0x21, + 0x7c, 0x38, 0xb0, 0x5e, 0xb3, 0x5e, 0xb6, 0x5e, + 0xca, 0x5e, 0x92, 0xa3, 0xfe, 0x5e, 0x31, 0x23, + 0x31, 0x23, 0x01, 0x82, 0x22, 0x5f, 0x22, 0x5f, + 0xc7, 0x38, 0xb8, 0x32, 0xda, 0x61, 0x62, 0x5f, + 0x6b, 0x5f, 0xe3, 0x38, 0x9a, 0x5f, 0xcd, 0x5f, + 0xd7, 0x5f, 0xf9, 0x5f, 0x81, 0x60, 0x3a, 0x39, + 0x1c, 0x39, 0x94, 0x60, 0xd4, 0x26, 0xc7, 0x60, + 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x00, 0x0a, 0x00, 0x00, 0x02, 0x08, + 0x00, 0x80, 0x08, 0x00, 0x00, 0x08, 0x80, 0x28, + 0x80, 0x02, 0x00, 0x00, 0x02, 0x48, 0x61, 0x00, + 0x04, 0x06, 0x04, 0x32, 0x46, 0x6a, 0x5c, 0x67, + 0x96, 0xaa, 0xae, 0xc8, 0xd3, 0x5d, 0x62, 0x00, + 0x54, 0x77, 0xf3, 0x0c, 0x2b, 0x3d, 0x63, 0xfc, + 0x62, 0x68, 0x63, 0x83, 0x63, 0xe4, 0x63, 0xf1, + 0x2b, 0x22, 0x64, 0xc5, 0x63, 0xa9, 0x63, 0x2e, + 0x3a, 0x69, 0x64, 0x7e, 0x64, 0x9d, 0x64, 0x77, + 0x64, 0x6c, 0x3a, 0x4f, 0x65, 0x6c, 0x65, 0x0a, + 0x30, 0xe3, 0x65, 0xf8, 0x66, 0x49, 0x66, 0x19, + 0x3b, 0x91, 0x66, 0x08, 0x3b, 0xe4, 0x3a, 0x92, + 0x51, 0x95, 0x51, 0x00, 0x67, 0x9c, 0x66, 0xad, + 0x80, 0xd9, 0x43, 0x17, 0x67, 0x1b, 0x67, 0x21, + 0x67, 0x5e, 0x67, 0x53, 0x67, 0xc3, 0x33, 0x49, + 0x3b, 0xfa, 0x67, 0x85, 0x67, 0x52, 0x68, 0x85, + 0x68, 0x6d, 0x34, 0x8e, 0x68, 0x1f, 0x68, 0x14, + 0x69, 0x9d, 0x3b, 0x42, 0x69, 0xa3, 0x69, 0xea, + 0x69, 0xa8, 0x6a, 0xa3, 0x36, 0xdb, 0x6a, 0x18, + 0x3c, 0x21, 0x6b, 0xa7, 0x38, 0x54, 0x6b, 0x4e, + 0x3c, 0x72, 0x6b, 0x9f, 0x6b, 0xba, 0x6b, 0xbb, + 0x6b, 0x8d, 0x3a, 0x0b, 0x1d, 0xfa, 0x3a, 0x4e, + 0x6c, 0xbc, 0x3c, 0xbf, 0x6c, 0xcd, 0x6c, 0x67, + 0x6c, 0x16, 0x6d, 0x3e, 0x6d, 0x77, 0x6d, 0x41, + 0x6d, 0x69, 0x6d, 0x78, 0x6d, 0x85, 0x6d, 0x1e, + 0x3d, 0x34, 0x6d, 0x2f, 0x6e, 0x6e, 0x6e, 0x33, + 0x3d, 0xcb, 0x6e, 0xc7, 0x6e, 0xd1, 0x3e, 0xf9, + 0x6d, 0x6e, 0x6f, 0x5e, 0x3f, 0x8e, 0x3f, 0xc6, + 0x6f, 0x39, 0x70, 0x1e, 0x70, 0x1b, 0x70, 0x96, + 0x3d, 0x4a, 0x70, 0x7d, 0x70, 0x77, 0x70, 0xad, + 0x70, 0x25, 0x05, 0x45, 0x71, 0x63, 0x42, 0x9c, + 0x71, 0xab, 0x43, 0x28, 0x72, 0x35, 0x72, 0x50, + 0x72, 0x08, 0x46, 0x80, 0x72, 0x95, 0x72, 0x35, + 0x47, 0x02, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x80, 0x00, 0x00, 0x02, 0x02, + 0x80, 0x8a, 0x00, 0x00, 0x20, 0x00, 0x08, 0x0a, + 0x00, 0x80, 0x88, 0x80, 0x20, 0x14, 0x48, 0x7a, + 0x73, 0x8b, 0x73, 0xac, 0x3e, 0xa5, 0x73, 0xb8, + 0x3e, 0xb8, 0x3e, 0x47, 0x74, 0x5c, 0x74, 0x71, + 0x74, 0x85, 0x74, 0xca, 0x74, 0x1b, 0x3f, 0x24, + 0x75, 0x36, 0x4c, 0x3e, 0x75, 0x92, 0x4c, 0x70, + 0x75, 0x9f, 0x21, 0x10, 0x76, 0xa1, 0x4f, 0xb8, + 0x4f, 0x44, 0x50, 0xfc, 0x3f, 0x08, 0x40, 0xf4, + 0x76, 0xf3, 0x50, 0xf2, 0x50, 0x19, 0x51, 0x33, + 0x51, 0x1e, 0x77, 0x1f, 0x77, 0x1f, 0x77, 0x4a, + 0x77, 0x39, 0x40, 0x8b, 0x77, 0x46, 0x40, 0x96, + 0x40, 0x1d, 0x54, 0x4e, 0x78, 0x8c, 0x78, 0xcc, + 0x78, 0xe3, 0x40, 0x26, 0x56, 0x56, 0x79, 0x9a, + 0x56, 0xc5, 0x56, 0x8f, 0x79, 0xeb, 0x79, 0x2f, + 0x41, 0x40, 0x7a, 0x4a, 0x7a, 0x4f, 0x7a, 0x7c, + 0x59, 0xa7, 0x5a, 0xa7, 0x5a, 0xee, 0x7a, 0x02, + 0x42, 0xab, 0x5b, 0xc6, 0x7b, 0xc9, 0x7b, 0x27, + 0x42, 0x80, 0x5c, 0xd2, 0x7c, 0xa0, 0x42, 0xe8, + 0x7c, 0xe3, 0x7c, 0x00, 0x7d, 0x86, 0x5f, 0x63, + 0x7d, 0x01, 0x43, 0xc7, 0x7d, 0x02, 0x7e, 0x45, + 0x7e, 0x34, 0x43, 0x28, 0x62, 0x47, 0x62, 0x59, + 0x43, 0xd9, 0x62, 0x7a, 0x7f, 0x3e, 0x63, 0x95, + 0x7f, 0xfa, 0x7f, 0x05, 0x80, 0xda, 0x64, 0x23, + 0x65, 0x60, 0x80, 0xa8, 0x65, 0x70, 0x80, 0x5f, + 0x33, 0xd5, 0x43, 0xb2, 0x80, 0x03, 0x81, 0x0b, + 0x44, 0x3e, 0x81, 0xb5, 0x5a, 0xa7, 0x67, 0xb5, + 0x67, 0x93, 0x33, 0x9c, 0x33, 0x01, 0x82, 0x04, + 0x82, 0x9e, 0x8f, 0x6b, 0x44, 0x91, 0x82, 0x8b, + 0x82, 0x9d, 0x82, 0xb3, 0x52, 0xb1, 0x82, 0xb3, + 0x82, 0xbd, 0x82, 0xe6, 0x82, 0x3c, 0x6b, 0xe5, + 0x82, 0x1d, 0x83, 0x63, 0x83, 0xad, 0x83, 0x23, + 0x83, 0xbd, 0x83, 0xe7, 0x83, 0x57, 0x84, 0x53, + 0x83, 0xca, 0x83, 0xcc, 0x83, 0xdc, 0x83, 0x36, + 0x6c, 0x6b, 0x6d, 0x02, 0x00, 0x00, 0x20, 0x22, + 0x2a, 0xa0, 0x0a, 0x00, 0x20, 0x80, 0x28, 0x00, + 0xa8, 0x20, 0x20, 0x00, 0x02, 0x80, 0x22, 0x02, + 0x8a, 0x08, 0x00, 0xaa, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x28, 0xd5, 0x6c, 0x2b, 0x45, 0xf1, + 0x84, 0xf3, 0x84, 0x16, 0x85, 0xca, 0x73, 0x64, + 0x85, 0x2c, 0x6f, 0x5d, 0x45, 0x61, 0x45, 0xb1, + 0x6f, 0xd2, 0x70, 0x6b, 0x45, 0x50, 0x86, 0x5c, + 0x86, 0x67, 0x86, 0x69, 0x86, 0xa9, 0x86, 0x88, + 0x86, 0x0e, 0x87, 0xe2, 0x86, 0x79, 0x87, 0x28, + 0x87, 0x6b, 0x87, 0x86, 0x87, 0xd7, 0x45, 0xe1, + 0x87, 0x01, 0x88, 0xf9, 0x45, 0x60, 0x88, 0x63, + 0x88, 0x67, 0x76, 0xd7, 0x88, 0xde, 0x88, 0x35, + 0x46, 0xfa, 0x88, 0xbb, 0x34, 0xae, 0x78, 0x66, + 0x79, 0xbe, 0x46, 0xc7, 0x46, 0xa0, 0x8a, 0xed, + 0x8a, 0x8a, 0x8b, 0x55, 0x8c, 0xa8, 0x7c, 0xab, + 0x8c, 0xc1, 0x8c, 0x1b, 0x8d, 0x77, 0x8d, 0x2f, + 0x7f, 0x04, 0x08, 0xcb, 0x8d, 0xbc, 0x8d, 0xf0, + 0x8d, 0xde, 0x08, 0xd4, 0x8e, 0x38, 0x8f, 0xd2, + 0x85, 0xed, 0x85, 0x94, 0x90, 0xf1, 0x90, 0x11, + 0x91, 0x2e, 0x87, 0x1b, 0x91, 0x38, 0x92, 0xd7, + 0x92, 0xd8, 0x92, 0x7c, 0x92, 0xf9, 0x93, 0x15, + 0x94, 0xfa, 0x8b, 0x8b, 0x95, 0x95, 0x49, 0xb7, + 0x95, 0x77, 0x8d, 0xe6, 0x49, 0xc3, 0x96, 0xb2, + 0x5d, 0x23, 0x97, 0x45, 0x91, 0x1a, 0x92, 0x6e, + 0x4a, 0x76, 0x4a, 0xe0, 0x97, 0x0a, 0x94, 0xb2, + 0x4a, 0x96, 0x94, 0x0b, 0x98, 0x0b, 0x98, 0x29, + 0x98, 0xb6, 0x95, 0xe2, 0x98, 0x33, 0x4b, 0x29, + 0x99, 0xa7, 0x99, 0xc2, 0x99, 0xfe, 0x99, 0xce, + 0x4b, 0x30, 0x9b, 0x12, 0x9b, 0x40, 0x9c, 0xfd, + 0x9c, 0xce, 0x4c, 0xed, 0x4c, 0x67, 0x9d, 0xce, + 0xa0, 0xf8, 0x4c, 0x05, 0xa1, 0x0e, 0xa2, 0x91, + 0xa2, 0xbb, 0x9e, 0x56, 0x4d, 0xf9, 0x9e, 0xfe, + 0x9e, 0x05, 0x9f, 0x0f, 0x9f, 0x16, 0x9f, 0x3b, + 0x9f, 0x00, 0xa6, 0x02, 0x88, 0xa0, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x00, 0x28, 0x00, 0x08, 0xa0, + 0x80, 0xa0, 0x80, 0x00, 0x80, 0x80, 0x00, 0x0a, + 0x88, 0x80, 0x00, 0x80, 0x00, 0x20, 0x2a, 0x00, + 0x80, }; static const uint16_t unicode_comp_table[945] = { @@ -2191,9 +2247,9 @@ static const uint16_t unicode_comp_table[945] = { 0x5704, 0x5706, 0x5708, 0x570a, 0x570c, 0x570e, 0x5710, 0x5712, 0x5714, 0x5716, 0x5740, 0x5742, 0x5744, 0x5780, 0x5781, 0x57c0, 0x57c1, 0x5800, 0x5801, 0x5840, 0x5841, 0x5880, 0x5881, 0x5900, - 0x5901, 0x5902, 0x5903, 0x5940, 0x8e80, 0x8e82, 0x8ec0, 0x8f00, - 0x8f01, 0x8f40, 0x8f41, 0x8f81, 0x8f80, 0x8f83, 0x8fc0, 0x8fc1, - 0x9000, + 0x5901, 0x5902, 0x5903, 0x5940, 0x8f40, 0x8f42, 0x8f80, 0x8fc0, + 0x8fc1, 0x9000, 0x9001, 0x9041, 0x9040, 0x9043, 0x9080, 0x9081, + 0x90c0, }; typedef enum { @@ -2279,7 +2335,7 @@ static const char unicode_gc_name_table[] = "C,Other" "\0" ; -static const uint8_t unicode_gc_table[3790] = { +static const uint8_t unicode_gc_table[3948] = { 0xfa, 0x18, 0x17, 0x56, 0x0d, 0x56, 0x12, 0x13, 0x16, 0x0c, 0x16, 0x11, 0x36, 0xe9, 0x02, 0x36, 0x4c, 0x36, 0xe1, 0x12, 0x12, 0x16, 0x13, 0x0e, @@ -2312,129 +2368,130 @@ static const uint8_t unicode_gc_table[3790] = { 0x11, 0x06, 0x16, 0x26, 0x16, 0x26, 0x16, 0x06, 0xe0, 0x00, 0xe5, 0x13, 0x60, 0x65, 0x36, 0xe0, 0x03, 0xbb, 0x4c, 0x36, 0x0d, 0x36, 0x2f, 0xe6, - 0x03, 0x16, 0x1b, 0x00, 0x36, 0xe5, 0x18, 0x04, - 0xe5, 0x02, 0xe6, 0x0d, 0xe9, 0x02, 0x76, 0x25, - 0x06, 0xe5, 0x5b, 0x16, 0x05, 0xc6, 0x1b, 0x0f, - 0xa6, 0x24, 0x26, 0x0f, 0x66, 0x25, 0xe9, 0x02, - 0x45, 0x2f, 0x05, 0xf6, 0x06, 0x00, 0x1b, 0x05, - 0x06, 0xe5, 0x16, 0xe6, 0x13, 0x20, 0xe5, 0x51, - 0xe6, 0x03, 0x05, 0xe0, 0x06, 0xe9, 0x02, 0xe5, - 0x19, 0xe6, 0x01, 0x24, 0x0f, 0x56, 0x04, 0x20, - 0x06, 0x2d, 0xe5, 0x0e, 0x66, 0x04, 0xe6, 0x01, - 0x04, 0x46, 0x04, 0x86, 0x20, 0xf6, 0x07, 0x00, - 0xe5, 0x11, 0x46, 0x20, 0x16, 0x00, 0xe5, 0x03, - 0xe0, 0x2d, 0xe5, 0x0d, 0x00, 0xe5, 0x0a, 0xe0, - 0x03, 0xe6, 0x07, 0x1b, 0xe6, 0x18, 0x07, 0xe5, - 0x2e, 0x06, 0x07, 0x06, 0x05, 0x47, 0xe6, 0x00, - 0x67, 0x06, 0x27, 0x05, 0xc6, 0xe5, 0x02, 0x26, - 0x36, 0xe9, 0x02, 0x16, 0x04, 0xe5, 0x07, 0x06, - 0x27, 0x00, 0xe5, 0x00, 0x20, 0x25, 0x20, 0xe5, - 0x0e, 0x00, 0xc5, 0x00, 0x05, 0x40, 0x65, 0x20, - 0x06, 0x05, 0x47, 0x66, 0x20, 0x27, 0x20, 0x27, - 0x06, 0x05, 0xe0, 0x00, 0x07, 0x60, 0x25, 0x00, - 0x45, 0x26, 0x20, 0xe9, 0x02, 0x25, 0x2d, 0xab, - 0x0f, 0x0d, 0x05, 0x16, 0x06, 0x20, 0x26, 0x07, - 0x00, 0xa5, 0x60, 0x25, 0x20, 0xe5, 0x0e, 0x00, - 0xc5, 0x00, 0x25, 0x00, 0x25, 0x00, 0x25, 0x20, - 0x06, 0x00, 0x47, 0x26, 0x60, 0x26, 0x20, 0x46, - 0x40, 0x06, 0xc0, 0x65, 0x00, 0x05, 0xc0, 0xe9, - 0x02, 0x26, 0x45, 0x06, 0x16, 0xe0, 0x02, 0x26, - 0x07, 0x00, 0xe5, 0x01, 0x00, 0x45, 0x00, 0xe5, - 0x0e, 0x00, 0xc5, 0x00, 0x25, 0x00, 0x85, 0x20, - 0x06, 0x05, 0x47, 0x86, 0x00, 0x26, 0x07, 0x00, - 0x27, 0x06, 0x20, 0x05, 0xe0, 0x07, 0x25, 0x26, - 0x20, 0xe9, 0x02, 0x16, 0x0d, 0xc0, 0x05, 0xa6, - 0x00, 0x06, 0x27, 0x00, 0xe5, 0x00, 0x20, 0x25, - 0x20, 0xe5, 0x0e, 0x00, 0xc5, 0x00, 0x25, 0x00, - 0x85, 0x20, 0x06, 0x05, 0x07, 0x06, 0x07, 0x66, - 0x20, 0x27, 0x20, 0x27, 0x06, 0xc0, 0x26, 0x07, + 0x03, 0x16, 0x1b, 0x56, 0xe5, 0x18, 0x04, 0xe5, + 0x02, 0xe6, 0x0d, 0xe9, 0x02, 0x76, 0x25, 0x06, + 0xe5, 0x5b, 0x16, 0x05, 0xc6, 0x1b, 0x0f, 0xa6, + 0x24, 0x26, 0x0f, 0x66, 0x25, 0xe9, 0x02, 0x45, + 0x2f, 0x05, 0xf6, 0x06, 0x00, 0x1b, 0x05, 0x06, + 0xe5, 0x16, 0xe6, 0x13, 0x20, 0xe5, 0x51, 0xe6, + 0x03, 0x05, 0xe0, 0x06, 0xe9, 0x02, 0xe5, 0x19, + 0xe6, 0x01, 0x24, 0x0f, 0x56, 0x04, 0x20, 0x06, + 0x2d, 0xe5, 0x0e, 0x66, 0x04, 0xe6, 0x01, 0x04, + 0x46, 0x04, 0x86, 0x20, 0xf6, 0x07, 0x00, 0xe5, + 0x11, 0x46, 0x20, 0x16, 0x00, 0xe5, 0x03, 0x80, + 0xe5, 0x10, 0x0e, 0xa5, 0x00, 0x3b, 0xa0, 0xe6, + 0x00, 0xe5, 0x21, 0x04, 0xe6, 0x10, 0x1b, 0xe6, + 0x18, 0x07, 0xe5, 0x2e, 0x06, 0x07, 0x06, 0x05, + 0x47, 0xe6, 0x00, 0x67, 0x06, 0x27, 0x05, 0xc6, + 0xe5, 0x02, 0x26, 0x36, 0xe9, 0x02, 0x16, 0x04, + 0xe5, 0x07, 0x06, 0x27, 0x00, 0xe5, 0x00, 0x20, + 0x25, 0x20, 0xe5, 0x0e, 0x00, 0xc5, 0x00, 0x05, + 0x40, 0x65, 0x20, 0x06, 0x05, 0x47, 0x66, 0x20, + 0x27, 0x20, 0x27, 0x06, 0x05, 0xe0, 0x00, 0x07, 0x60, 0x25, 0x00, 0x45, 0x26, 0x20, 0xe9, 0x02, - 0x0f, 0x05, 0xab, 0xe0, 0x02, 0x06, 0x05, 0x00, - 0xa5, 0x40, 0x45, 0x00, 0x65, 0x40, 0x25, 0x00, - 0x05, 0x00, 0x25, 0x40, 0x25, 0x40, 0x45, 0x40, - 0xe5, 0x04, 0x60, 0x27, 0x06, 0x27, 0x40, 0x47, - 0x00, 0x47, 0x06, 0x20, 0x05, 0xa0, 0x07, 0xe0, - 0x06, 0xe9, 0x02, 0x4b, 0xaf, 0x0d, 0x0f, 0x80, - 0x06, 0x47, 0x06, 0xe5, 0x00, 0x00, 0x45, 0x00, - 0xe5, 0x0f, 0x00, 0xe5, 0x08, 0x40, 0x05, 0x46, - 0x67, 0x00, 0x46, 0x00, 0x66, 0xc0, 0x26, 0x00, - 0x45, 0x80, 0x25, 0x26, 0x20, 0xe9, 0x02, 0xc0, - 0x16, 0xcb, 0x0f, 0x05, 0x06, 0x27, 0x16, 0xe5, - 0x00, 0x00, 0x45, 0x00, 0xe5, 0x0f, 0x00, 0xe5, - 0x02, 0x00, 0x85, 0x20, 0x06, 0x05, 0x07, 0x06, - 0x87, 0x00, 0x06, 0x27, 0x00, 0x27, 0x26, 0xc0, - 0x27, 0xc0, 0x05, 0x00, 0x25, 0x26, 0x20, 0xe9, - 0x02, 0x00, 0x25, 0xe0, 0x05, 0x26, 0x27, 0xe5, - 0x01, 0x00, 0x45, 0x00, 0xe5, 0x21, 0x26, 0x05, - 0x47, 0x66, 0x00, 0x47, 0x00, 0x47, 0x06, 0x05, - 0x0f, 0x60, 0x45, 0x07, 0xcb, 0x45, 0x26, 0x20, - 0xe9, 0x02, 0xeb, 0x01, 0x0f, 0xa5, 0x00, 0x06, - 0x27, 0x00, 0xe5, 0x0a, 0x40, 0xe5, 0x10, 0x00, - 0xe5, 0x01, 0x00, 0x05, 0x20, 0xc5, 0x40, 0x06, - 0x60, 0x47, 0x46, 0x00, 0x06, 0x00, 0xe7, 0x00, - 0xa0, 0xe9, 0x02, 0x20, 0x27, 0x16, 0xe0, 0x04, - 0xe5, 0x28, 0x06, 0x25, 0xc6, 0x60, 0x0d, 0xa5, - 0x04, 0xe6, 0x00, 0x16, 0xe9, 0x02, 0x36, 0xe0, - 0x1d, 0x25, 0x00, 0x05, 0x00, 0x85, 0x00, 0xe5, - 0x10, 0x00, 0x05, 0x00, 0xe5, 0x02, 0x06, 0x25, - 0xe6, 0x01, 0x05, 0x20, 0x85, 0x00, 0x04, 0x00, - 0xa6, 0x20, 0xe9, 0x02, 0x20, 0x65, 0xe0, 0x18, - 0x05, 0x4f, 0xf6, 0x07, 0x0f, 0x16, 0x4f, 0x26, - 0xaf, 0xe9, 0x02, 0xeb, 0x02, 0x0f, 0x06, 0x0f, - 0x06, 0x0f, 0x06, 0x12, 0x13, 0x12, 0x13, 0x27, - 0xe5, 0x00, 0x00, 0xe5, 0x1c, 0x60, 0xe6, 0x06, - 0x07, 0x86, 0x16, 0x26, 0x85, 0xe6, 0x03, 0x00, - 0xe6, 0x1c, 0x00, 0xef, 0x00, 0x06, 0xaf, 0x00, - 0x2f, 0x96, 0x6f, 0x36, 0xe0, 0x1d, 0xe5, 0x23, - 0x27, 0x66, 0x07, 0xa6, 0x07, 0x26, 0x27, 0x26, - 0x05, 0xe9, 0x02, 0xb6, 0xa5, 0x27, 0x26, 0x65, - 0x46, 0x05, 0x47, 0x25, 0xc7, 0x45, 0x66, 0xe5, - 0x05, 0x06, 0x27, 0x26, 0xa7, 0x06, 0x05, 0x07, - 0xe9, 0x02, 0x47, 0x06, 0x2f, 0xe1, 0x1e, 0x00, - 0x01, 0x80, 0x01, 0x20, 0xe2, 0x23, 0x16, 0x04, - 0x42, 0xe5, 0x80, 0xc1, 0x00, 0x65, 0x20, 0xc5, - 0x00, 0x05, 0x00, 0x65, 0x20, 0xe5, 0x21, 0x00, - 0x65, 0x20, 0xe5, 0x19, 0x00, 0x65, 0x20, 0xc5, - 0x00, 0x05, 0x00, 0x65, 0x20, 0xe5, 0x07, 0x00, - 0xe5, 0x31, 0x00, 0x65, 0x20, 0xe5, 0x3b, 0x20, - 0x46, 0xf6, 0x01, 0xeb, 0x0c, 0x40, 0xe5, 0x08, - 0xef, 0x02, 0xa0, 0xe1, 0x4e, 0x20, 0xa2, 0x20, - 0x11, 0xe5, 0x81, 0xe4, 0x0f, 0x16, 0xe5, 0x09, - 0x17, 0xe5, 0x12, 0x12, 0x13, 0x40, 0xe5, 0x43, - 0x56, 0x4a, 0xe5, 0x00, 0xc0, 0xe5, 0x05, 0x00, - 0x65, 0x46, 0xe0, 0x03, 0xe5, 0x0a, 0x46, 0x36, - 0xe0, 0x01, 0xe5, 0x0a, 0x26, 0xe0, 0x04, 0xe5, - 0x05, 0x00, 0x45, 0x00, 0x26, 0xe0, 0x04, 0xe5, - 0x2c, 0x26, 0x07, 0xc6, 0xe7, 0x00, 0x06, 0x27, - 0xe6, 0x03, 0x56, 0x04, 0x56, 0x0d, 0x05, 0x06, - 0x20, 0xe9, 0x02, 0xa0, 0xeb, 0x02, 0xa0, 0xb6, - 0x11, 0x76, 0x46, 0x1b, 0x00, 0xe9, 0x02, 0xa0, - 0xe5, 0x1b, 0x04, 0xe5, 0x2d, 0xc0, 0x85, 0x26, - 0xe5, 0x1a, 0x06, 0x05, 0x80, 0xe5, 0x3e, 0xe0, - 0x02, 0xe5, 0x17, 0x00, 0x46, 0x67, 0x26, 0x47, - 0x60, 0x27, 0x06, 0xa7, 0x46, 0x60, 0x0f, 0x40, - 0x36, 0xe9, 0x02, 0xe5, 0x16, 0x20, 0x85, 0xe0, - 0x03, 0xe5, 0x24, 0x60, 0xe5, 0x12, 0xa0, 0xe9, - 0x02, 0x0b, 0x40, 0xef, 0x1a, 0xe5, 0x0f, 0x26, - 0x27, 0x06, 0x20, 0x36, 0xe5, 0x2d, 0x07, 0x06, - 0x07, 0xc6, 0x00, 0x06, 0x07, 0x06, 0x27, 0xe6, - 0x00, 0xa7, 0xe6, 0x02, 0x20, 0x06, 0xe9, 0x02, - 0xa0, 0xe9, 0x02, 0xa0, 0xd6, 0x04, 0xb6, 0x20, - 0xe6, 0x06, 0x08, 0x26, 0xe0, 0x37, 0x66, 0x07, + 0x25, 0x2d, 0xab, 0x0f, 0x0d, 0x05, 0x16, 0x06, + 0x20, 0x26, 0x07, 0x00, 0xa5, 0x60, 0x25, 0x20, + 0xe5, 0x0e, 0x00, 0xc5, 0x00, 0x25, 0x00, 0x25, + 0x00, 0x25, 0x20, 0x06, 0x00, 0x47, 0x26, 0x60, + 0x26, 0x20, 0x46, 0x40, 0x06, 0xc0, 0x65, 0x00, + 0x05, 0xc0, 0xe9, 0x02, 0x26, 0x45, 0x06, 0x16, + 0xe0, 0x02, 0x26, 0x07, 0x00, 0xe5, 0x01, 0x00, + 0x45, 0x00, 0xe5, 0x0e, 0x00, 0xc5, 0x00, 0x25, + 0x00, 0x85, 0x20, 0x06, 0x05, 0x47, 0x86, 0x00, + 0x26, 0x07, 0x00, 0x27, 0x06, 0x20, 0x05, 0xe0, + 0x07, 0x25, 0x26, 0x20, 0xe9, 0x02, 0x16, 0x0d, + 0xc0, 0x05, 0xa6, 0x00, 0x06, 0x27, 0x00, 0xe5, + 0x00, 0x20, 0x25, 0x20, 0xe5, 0x0e, 0x00, 0xc5, + 0x00, 0x25, 0x00, 0x85, 0x20, 0x06, 0x05, 0x07, + 0x06, 0x07, 0x66, 0x20, 0x27, 0x20, 0x27, 0x06, + 0xc0, 0x26, 0x07, 0x60, 0x25, 0x00, 0x45, 0x26, + 0x20, 0xe9, 0x02, 0x0f, 0x05, 0xab, 0xe0, 0x02, + 0x06, 0x05, 0x00, 0xa5, 0x40, 0x45, 0x00, 0x65, + 0x40, 0x25, 0x00, 0x05, 0x00, 0x25, 0x40, 0x25, + 0x40, 0x45, 0x40, 0xe5, 0x04, 0x60, 0x27, 0x06, + 0x27, 0x40, 0x47, 0x00, 0x47, 0x06, 0x20, 0x05, + 0xa0, 0x07, 0xe0, 0x06, 0xe9, 0x02, 0x4b, 0xaf, + 0x0d, 0x0f, 0x80, 0x06, 0x47, 0x06, 0xe5, 0x00, + 0x00, 0x45, 0x00, 0xe5, 0x0f, 0x00, 0xe5, 0x08, + 0x20, 0x06, 0x05, 0x46, 0x67, 0x00, 0x46, 0x00, + 0x66, 0xc0, 0x26, 0x00, 0x45, 0x20, 0x05, 0x20, + 0x25, 0x26, 0x20, 0xe9, 0x02, 0xc0, 0x16, 0xcb, + 0x0f, 0x05, 0x06, 0x27, 0x16, 0xe5, 0x00, 0x00, + 0x45, 0x00, 0xe5, 0x0f, 0x00, 0xe5, 0x02, 0x00, + 0x85, 0x20, 0x06, 0x05, 0x07, 0x06, 0x87, 0x00, + 0x06, 0x27, 0x00, 0x27, 0x26, 0xc0, 0x27, 0xa0, + 0x25, 0x00, 0x25, 0x26, 0x20, 0xe9, 0x02, 0x00, + 0x25, 0x07, 0xe0, 0x04, 0x26, 0x27, 0xe5, 0x01, + 0x00, 0x45, 0x00, 0xe5, 0x21, 0x26, 0x05, 0x47, + 0x66, 0x00, 0x47, 0x00, 0x47, 0x06, 0x05, 0x0f, + 0x60, 0x45, 0x07, 0xcb, 0x45, 0x26, 0x20, 0xe9, + 0x02, 0xeb, 0x01, 0x0f, 0xa5, 0x00, 0x06, 0x27, + 0x00, 0xe5, 0x0a, 0x40, 0xe5, 0x10, 0x00, 0xe5, + 0x01, 0x00, 0x05, 0x20, 0xc5, 0x40, 0x06, 0x60, + 0x47, 0x46, 0x00, 0x06, 0x00, 0xe7, 0x00, 0xa0, + 0xe9, 0x02, 0x20, 0x27, 0x16, 0xe0, 0x04, 0xe5, + 0x28, 0x06, 0x25, 0xc6, 0x60, 0x0d, 0xa5, 0x04, + 0xe6, 0x00, 0x16, 0xe9, 0x02, 0x36, 0xe0, 0x1d, + 0x25, 0x00, 0x05, 0x00, 0x85, 0x00, 0xe5, 0x10, + 0x00, 0x05, 0x00, 0xe5, 0x02, 0x06, 0x25, 0xe6, + 0x01, 0x05, 0x20, 0x85, 0x00, 0x04, 0x00, 0xc6, + 0x00, 0xe9, 0x02, 0x20, 0x65, 0xe0, 0x18, 0x05, + 0x4f, 0xf6, 0x07, 0x0f, 0x16, 0x4f, 0x26, 0xaf, + 0xe9, 0x02, 0xeb, 0x02, 0x0f, 0x06, 0x0f, 0x06, + 0x0f, 0x06, 0x12, 0x13, 0x12, 0x13, 0x27, 0xe5, + 0x00, 0x00, 0xe5, 0x1c, 0x60, 0xe6, 0x06, 0x07, + 0x86, 0x16, 0x26, 0x85, 0xe6, 0x03, 0x00, 0xe6, + 0x1c, 0x00, 0xef, 0x00, 0x06, 0xaf, 0x00, 0x2f, + 0x96, 0x6f, 0x36, 0xe0, 0x1d, 0xe5, 0x23, 0x27, + 0x66, 0x07, 0xa6, 0x07, 0x26, 0x27, 0x26, 0x05, + 0xe9, 0x02, 0xb6, 0xa5, 0x27, 0x26, 0x65, 0x46, + 0x05, 0x47, 0x25, 0xc7, 0x45, 0x66, 0xe5, 0x05, + 0x06, 0x27, 0x26, 0xa7, 0x06, 0x05, 0x07, 0xe9, + 0x02, 0x47, 0x06, 0x2f, 0xe1, 0x1e, 0x00, 0x01, + 0x80, 0x01, 0x20, 0xe2, 0x23, 0x16, 0x04, 0x42, + 0xe5, 0x80, 0xc1, 0x00, 0x65, 0x20, 0xc5, 0x00, + 0x05, 0x00, 0x65, 0x20, 0xe5, 0x21, 0x00, 0x65, + 0x20, 0xe5, 0x19, 0x00, 0x65, 0x20, 0xc5, 0x00, + 0x05, 0x00, 0x65, 0x20, 0xe5, 0x07, 0x00, 0xe5, + 0x31, 0x00, 0x65, 0x20, 0xe5, 0x3b, 0x20, 0x46, + 0xf6, 0x01, 0xeb, 0x0c, 0x40, 0xe5, 0x08, 0xef, + 0x02, 0xa0, 0xe1, 0x4e, 0x20, 0xa2, 0x20, 0x11, + 0xe5, 0x81, 0xe4, 0x0f, 0x16, 0xe5, 0x09, 0x17, + 0xe5, 0x12, 0x12, 0x13, 0x40, 0xe5, 0x43, 0x56, + 0x4a, 0xe5, 0x00, 0xc0, 0xe5, 0x0a, 0x46, 0x07, + 0xe0, 0x01, 0xe5, 0x0b, 0x26, 0x07, 0x36, 0xe0, + 0x01, 0xe5, 0x0a, 0x26, 0xe0, 0x04, 0xe5, 0x05, + 0x00, 0x45, 0x00, 0x26, 0xe0, 0x04, 0xe5, 0x2c, + 0x26, 0x07, 0xc6, 0xe7, 0x00, 0x06, 0x27, 0xe6, + 0x03, 0x56, 0x04, 0x56, 0x0d, 0x05, 0x06, 0x20, + 0xe9, 0x02, 0xa0, 0xeb, 0x02, 0xa0, 0xb6, 0x11, + 0x76, 0x46, 0x1b, 0x06, 0xe9, 0x02, 0xa0, 0xe5, + 0x1b, 0x04, 0xe5, 0x2d, 0xc0, 0x85, 0x26, 0xe5, + 0x1a, 0x06, 0x05, 0x80, 0xe5, 0x3e, 0xe0, 0x02, + 0xe5, 0x17, 0x00, 0x46, 0x67, 0x26, 0x47, 0x60, + 0x27, 0x06, 0xa7, 0x46, 0x60, 0x0f, 0x40, 0x36, + 0xe9, 0x02, 0xe5, 0x16, 0x20, 0x85, 0xe0, 0x03, + 0xe5, 0x24, 0x60, 0xe5, 0x12, 0xa0, 0xe9, 0x02, + 0x0b, 0x40, 0xef, 0x1a, 0xe5, 0x0f, 0x26, 0x27, + 0x06, 0x20, 0x36, 0xe5, 0x2d, 0x07, 0x06, 0x07, + 0xc6, 0x00, 0x06, 0x07, 0x06, 0x27, 0xe6, 0x00, + 0xa7, 0xe6, 0x02, 0x20, 0x06, 0xe9, 0x02, 0xa0, + 0xe9, 0x02, 0xa0, 0xd6, 0x04, 0xb6, 0x20, 0xe6, + 0x06, 0x08, 0xe6, 0x08, 0xe0, 0x29, 0x66, 0x07, 0xe5, 0x27, 0x06, 0x07, 0x86, 0x07, 0x06, 0x87, - 0x06, 0x27, 0xc5, 0x60, 0xe9, 0x02, 0xd6, 0xef, - 0x02, 0xe6, 0x01, 0xef, 0x01, 0x40, 0x26, 0x07, - 0xe5, 0x16, 0x07, 0x66, 0x27, 0x26, 0x07, 0x46, - 0x25, 0xe9, 0x02, 0xe5, 0x24, 0x06, 0x07, 0x26, - 0x47, 0x06, 0x07, 0x46, 0x27, 0xe0, 0x00, 0x76, - 0xe5, 0x1c, 0xe7, 0x00, 0xe6, 0x00, 0x27, 0x26, - 0x40, 0x96, 0xe9, 0x02, 0x40, 0x45, 0xe9, 0x02, - 0xe5, 0x16, 0xa4, 0x36, 0xe2, 0x01, 0xc0, 0xe1, - 0x23, 0x20, 0x41, 0xf6, 0x00, 0xe0, 0x00, 0x46, - 0x16, 0xe6, 0x05, 0x07, 0xc6, 0x65, 0x06, 0xa5, - 0x06, 0x25, 0x07, 0x26, 0x05, 0x80, 0xe2, 0x24, - 0xe4, 0x37, 0xe2, 0x05, 0x04, 0xe2, 0x1a, 0xe4, - 0x1d, 0xe6, 0x32, 0x00, 0x86, 0xff, 0x80, 0x0e, + 0x06, 0x27, 0xe5, 0x00, 0x40, 0xe9, 0x02, 0xd6, + 0xef, 0x02, 0xe6, 0x01, 0xef, 0x01, 0x36, 0x00, + 0x26, 0x07, 0xe5, 0x16, 0x07, 0x66, 0x27, 0x26, + 0x07, 0x46, 0x25, 0xe9, 0x02, 0xe5, 0x24, 0x06, + 0x07, 0x26, 0x47, 0x06, 0x07, 0x46, 0x27, 0xe0, + 0x00, 0x76, 0xe5, 0x1c, 0xe7, 0x00, 0xe6, 0x00, + 0x27, 0x26, 0x40, 0x96, 0xe9, 0x02, 0x40, 0x45, + 0xe9, 0x02, 0xe5, 0x16, 0xa4, 0x36, 0xe2, 0x01, + 0xc0, 0xe1, 0x23, 0x20, 0x41, 0xf6, 0x00, 0xe0, + 0x00, 0x46, 0x16, 0xe6, 0x05, 0x07, 0xc6, 0x65, + 0x06, 0xa5, 0x06, 0x25, 0x07, 0x26, 0x05, 0x80, + 0xe2, 0x24, 0xe4, 0x37, 0xe2, 0x05, 0x04, 0xe2, + 0x1a, 0xe4, 0x1d, 0xe6, 0x38, 0xff, 0x80, 0x0e, 0xe2, 0x00, 0xff, 0x5a, 0xe2, 0x00, 0xe1, 0x00, 0xa2, 0x20, 0xa1, 0x20, 0xe2, 0x00, 0xe1, 0x00, 0xe2, 0x00, 0xe1, 0x00, 0xa2, 0x20, 0xa1, 0x20, @@ -2452,8 +2509,8 @@ static const uint8_t unicode_gc_table[3790] = { 0xf6, 0x03, 0x0c, 0x16, 0x10, 0xf6, 0x02, 0x17, 0x9b, 0x00, 0xfb, 0x02, 0x0b, 0x04, 0x20, 0xab, 0x4c, 0x12, 0x13, 0x04, 0xeb, 0x02, 0x4c, 0x12, - 0x13, 0x00, 0xe4, 0x05, 0x40, 0xed, 0x18, 0xe0, - 0x08, 0xe6, 0x05, 0x68, 0x06, 0x48, 0xe6, 0x04, + 0x13, 0x00, 0xe4, 0x05, 0x40, 0xed, 0x19, 0xe0, + 0x07, 0xe6, 0x05, 0x68, 0x06, 0x48, 0xe6, 0x04, 0xe0, 0x07, 0x2f, 0x01, 0x6f, 0x01, 0x2f, 0x02, 0x41, 0x22, 0x41, 0x02, 0x0f, 0x01, 0x2f, 0x0c, 0x81, 0xaf, 0x01, 0x0f, 0x01, 0x0f, 0x01, 0x0f, @@ -2481,179 +2538,186 @@ static const uint8_t unicode_gc_table[3790] = { 0x13, 0x12, 0x13, 0xec, 0x18, 0x12, 0x13, 0xec, 0x80, 0x7a, 0xef, 0x28, 0xec, 0x0d, 0x2f, 0xac, 0xef, 0x1f, 0x20, 0xef, 0x18, 0x00, 0xef, 0x61, - 0xe1, 0x27, 0x00, 0xe2, 0x27, 0x00, 0x5f, 0x21, - 0x22, 0xdf, 0x41, 0x02, 0x3f, 0x02, 0x3f, 0x82, - 0x24, 0x41, 0x02, 0xff, 0x5a, 0x02, 0xaf, 0x7f, - 0x46, 0x3f, 0x80, 0x76, 0x0b, 0x36, 0xe2, 0x1e, - 0x00, 0x02, 0x80, 0x02, 0x20, 0xe5, 0x30, 0xc0, - 0x04, 0x16, 0xe0, 0x06, 0x06, 0xe5, 0x0f, 0xe0, - 0x01, 0xc5, 0x00, 0xc5, 0x00, 0xc5, 0x00, 0xc5, + 0xe1, 0x28, 0xe2, 0x28, 0x5f, 0x21, 0x22, 0xdf, + 0x41, 0x02, 0x3f, 0x02, 0x3f, 0x82, 0x24, 0x41, + 0x02, 0xff, 0x5a, 0x02, 0xaf, 0x7f, 0x46, 0x3f, + 0x80, 0x76, 0x0b, 0x36, 0xe2, 0x1e, 0x00, 0x02, + 0x80, 0x02, 0x20, 0xe5, 0x30, 0xc0, 0x04, 0x16, + 0xe0, 0x06, 0x06, 0xe5, 0x0f, 0xe0, 0x01, 0xc5, 0x00, 0xc5, 0x00, 0xc5, 0x00, 0xc5, 0x00, 0xc5, - 0x00, 0xe6, 0x18, 0x36, 0x14, 0x15, 0x14, 0x15, - 0x56, 0x14, 0x15, 0x16, 0x14, 0x15, 0xf6, 0x01, - 0x11, 0x36, 0x11, 0x16, 0x14, 0x15, 0x36, 0x14, - 0x15, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, - 0x13, 0x96, 0x04, 0xf6, 0x02, 0x31, 0x76, 0x11, - 0x16, 0x12, 0xf6, 0x05, 0x2f, 0x16, 0xe0, 0x25, - 0xef, 0x12, 0x00, 0xef, 0x51, 0xe0, 0x04, 0xef, - 0x80, 0x4e, 0xe0, 0x12, 0xef, 0x04, 0x60, 0x17, - 0x56, 0x0f, 0x04, 0x05, 0x0a, 0x12, 0x13, 0x12, - 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x2f, - 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, - 0x11, 0x12, 0x33, 0x0f, 0xea, 0x01, 0x66, 0x27, - 0x11, 0x84, 0x2f, 0x4a, 0x04, 0x05, 0x16, 0x2f, - 0x00, 0xe5, 0x4e, 0x20, 0x26, 0x2e, 0x24, 0x05, - 0x11, 0xe5, 0x52, 0x16, 0x44, 0x05, 0x80, 0xe5, - 0x23, 0x00, 0xe5, 0x56, 0x00, 0x2f, 0x6b, 0xef, - 0x02, 0xe5, 0x18, 0xef, 0x1c, 0xe0, 0x04, 0xe5, - 0x08, 0xef, 0x17, 0x00, 0xeb, 0x02, 0xef, 0x16, - 0xeb, 0x00, 0x0f, 0xeb, 0x07, 0xef, 0x18, 0xeb, - 0x02, 0xef, 0x1f, 0xeb, 0x07, 0xef, 0x80, 0xb8, - 0xe5, 0x99, 0x38, 0xef, 0x38, 0xe5, 0xc0, 0x11, - 0x75, 0x40, 0xe5, 0x0d, 0x04, 0xe5, 0x83, 0xef, - 0x40, 0xef, 0x2f, 0xe0, 0x01, 0xe5, 0x20, 0xa4, - 0x36, 0xe5, 0x80, 0x84, 0x04, 0x56, 0xe5, 0x08, - 0xe9, 0x02, 0x25, 0xe0, 0x0c, 0xff, 0x26, 0x05, - 0x06, 0x48, 0x16, 0xe6, 0x02, 0x16, 0x04, 0xff, - 0x14, 0x24, 0x26, 0xe5, 0x3e, 0xea, 0x02, 0x26, - 0xb6, 0xe0, 0x00, 0xee, 0x0f, 0xe4, 0x01, 0x2e, - 0xff, 0x06, 0x22, 0xff, 0x36, 0x04, 0xe2, 0x00, - 0x9f, 0xff, 0x02, 0x04, 0x2e, 0x7f, 0x05, 0x7f, - 0x22, 0xff, 0x0d, 0x61, 0x02, 0x81, 0x02, 0xff, - 0x02, 0x20, 0x5f, 0x41, 0x02, 0x3f, 0xe0, 0x22, - 0x3f, 0x05, 0x24, 0x02, 0xc5, 0x06, 0x45, 0x06, - 0x65, 0x06, 0xe5, 0x0f, 0x27, 0x26, 0x07, 0x6f, - 0x06, 0x40, 0xab, 0x2f, 0x0d, 0x0f, 0xa0, 0xe5, - 0x2c, 0x76, 0xe0, 0x00, 0x27, 0xe5, 0x2a, 0xe7, - 0x08, 0x26, 0xe0, 0x00, 0x36, 0xe9, 0x02, 0xa0, - 0xe6, 0x0a, 0xa5, 0x56, 0x05, 0x16, 0x25, 0x06, - 0xe9, 0x02, 0xe5, 0x14, 0xe6, 0x00, 0x36, 0xe5, - 0x0f, 0xe6, 0x03, 0x27, 0xe0, 0x03, 0x16, 0xe5, - 0x15, 0x40, 0x46, 0x07, 0xe5, 0x27, 0x06, 0x27, - 0x66, 0x27, 0x26, 0x47, 0xf6, 0x05, 0x00, 0x04, - 0xe9, 0x02, 0x60, 0x36, 0x85, 0x06, 0x04, 0xe5, - 0x01, 0xe9, 0x02, 0x85, 0x00, 0xe5, 0x21, 0xa6, - 0x27, 0x26, 0x27, 0x26, 0xe0, 0x01, 0x45, 0x06, - 0xe5, 0x00, 0x06, 0x07, 0x20, 0xe9, 0x02, 0x20, - 0x76, 0xe5, 0x08, 0x04, 0xa5, 0x4f, 0x05, 0x07, - 0x06, 0x07, 0xe5, 0x2a, 0x06, 0x05, 0x46, 0x25, - 0x26, 0x85, 0x26, 0x05, 0x06, 0x05, 0xe0, 0x10, - 0x25, 0x04, 0x36, 0xe5, 0x03, 0x07, 0x26, 0x27, - 0x36, 0x05, 0x24, 0x07, 0x06, 0xe0, 0x02, 0xa5, - 0x20, 0xa5, 0x20, 0xa5, 0xe0, 0x01, 0xc5, 0x00, - 0xc5, 0x00, 0xe2, 0x23, 0x0e, 0x64, 0xe2, 0x01, - 0x04, 0x2e, 0x60, 0xe2, 0x48, 0xe5, 0x1b, 0x27, - 0x06, 0x27, 0x06, 0x27, 0x16, 0x07, 0x06, 0x20, - 0xe9, 0x02, 0xa0, 0xe5, 0xab, 0x1c, 0xe0, 0x04, - 0xe5, 0x0f, 0x60, 0xe5, 0x29, 0x60, 0xfc, 0x87, - 0x78, 0xfd, 0x98, 0x78, 0xe5, 0x80, 0xe6, 0x20, - 0xe5, 0x62, 0xe0, 0x1e, 0xc2, 0xe0, 0x04, 0x82, - 0x80, 0x05, 0x06, 0xe5, 0x02, 0x0c, 0xe5, 0x05, - 0x00, 0x85, 0x00, 0x05, 0x00, 0x25, 0x00, 0x25, - 0x00, 0xe5, 0x64, 0xee, 0x08, 0xe0, 0x09, 0xe5, - 0x80, 0xe3, 0x13, 0x12, 0xe0, 0x08, 0xe5, 0x38, - 0x20, 0xe5, 0x2e, 0xe0, 0x20, 0xe5, 0x04, 0x0d, - 0x0f, 0x20, 0xe6, 0x08, 0xd6, 0x12, 0x13, 0x16, - 0xa0, 0xe6, 0x08, 0x16, 0x31, 0x30, 0x12, 0x13, - 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, - 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x36, 0x12, - 0x13, 0x76, 0x50, 0x56, 0x00, 0x76, 0x11, 0x12, - 0x13, 0x12, 0x13, 0x12, 0x13, 0x56, 0x0c, 0x11, - 0x4c, 0x00, 0x16, 0x0d, 0x36, 0x60, 0x85, 0x00, - 0xe5, 0x7f, 0x20, 0x1b, 0x00, 0x56, 0x0d, 0x56, - 0x12, 0x13, 0x16, 0x0c, 0x16, 0x11, 0x36, 0xe9, - 0x02, 0x36, 0x4c, 0x36, 0xe1, 0x12, 0x12, 0x16, - 0x13, 0x0e, 0x10, 0x0e, 0xe2, 0x12, 0x12, 0x0c, - 0x13, 0x0c, 0x12, 0x13, 0x16, 0x12, 0x13, 0x36, - 0xe5, 0x02, 0x04, 0xe5, 0x25, 0x24, 0xe5, 0x17, - 0x40, 0xa5, 0x20, 0xa5, 0x20, 0xa5, 0x20, 0x45, - 0x40, 0x2d, 0x0c, 0x0e, 0x0f, 0x2d, 0x00, 0x0f, - 0x6c, 0x2f, 0xe0, 0x02, 0x5b, 0x2f, 0x20, 0xe5, - 0x04, 0x00, 0xe5, 0x12, 0x00, 0xe5, 0x0b, 0x00, - 0x25, 0x00, 0xe5, 0x07, 0x20, 0xe5, 0x06, 0xe0, - 0x1a, 0xe5, 0x73, 0x80, 0x56, 0x60, 0xeb, 0x25, - 0x40, 0xef, 0x01, 0xea, 0x2d, 0x6b, 0xef, 0x09, - 0x2b, 0x4f, 0x00, 0xef, 0x05, 0x40, 0x0f, 0xe0, - 0x27, 0xef, 0x25, 0x06, 0xe0, 0x7a, 0xe5, 0x15, - 0x40, 0xe5, 0x29, 0xe0, 0x07, 0x06, 0xeb, 0x13, - 0x60, 0xe5, 0x18, 0x6b, 0xe0, 0x01, 0xe5, 0x0c, - 0x0a, 0xe5, 0x00, 0x0a, 0x80, 0xe5, 0x1e, 0x86, - 0x80, 0xe5, 0x16, 0x00, 0x16, 0xe5, 0x1c, 0x60, - 0xe5, 0x00, 0x16, 0x8a, 0xe0, 0x22, 0xe1, 0x20, - 0xe2, 0x20, 0xe5, 0x46, 0x20, 0xe9, 0x02, 0xa0, - 0xe1, 0x1c, 0x60, 0xe2, 0x1c, 0x60, 0xe5, 0x20, - 0xe0, 0x00, 0xe5, 0x2c, 0xe0, 0x03, 0x16, 0xe0, - 0x80, 0x08, 0xe5, 0x80, 0xaf, 0xe0, 0x01, 0xe5, - 0x0e, 0xe0, 0x02, 0xe5, 0x00, 0xe0, 0x80, 0x10, - 0xa5, 0x20, 0x05, 0x00, 0xe5, 0x24, 0x00, 0x25, - 0x40, 0x05, 0x20, 0xe5, 0x0f, 0x00, 0x16, 0xeb, - 0x00, 0xe5, 0x0f, 0x2f, 0xcb, 0xe5, 0x17, 0xe0, - 0x00, 0xeb, 0x01, 0xe0, 0x28, 0xe5, 0x0b, 0x00, - 0x25, 0x80, 0x8b, 0xe5, 0x0e, 0xab, 0x40, 0x16, - 0xe5, 0x12, 0x80, 0x16, 0xe0, 0x38, 0xe5, 0x30, - 0x60, 0x2b, 0x25, 0xeb, 0x08, 0x20, 0xeb, 0x26, - 0x05, 0x46, 0x00, 0x26, 0x80, 0x66, 0x65, 0x00, - 0x45, 0x00, 0xe5, 0x15, 0x20, 0x46, 0x60, 0x06, - 0xeb, 0x01, 0xc0, 0xf6, 0x01, 0xc0, 0xe5, 0x15, - 0x2b, 0x16, 0xe5, 0x15, 0x4b, 0xe0, 0x18, 0xe5, - 0x00, 0x0f, 0xe5, 0x14, 0x26, 0x60, 0x8b, 0xd6, - 0xe0, 0x01, 0xe5, 0x2e, 0x40, 0xd6, 0xe5, 0x0e, - 0x20, 0xeb, 0x00, 0xe5, 0x0b, 0x80, 0xeb, 0x00, - 0xe5, 0x0a, 0xc0, 0x76, 0xe0, 0x04, 0xcb, 0xe0, - 0x48, 0xe5, 0x41, 0xe0, 0x2f, 0xe1, 0x2b, 0xe0, - 0x05, 0xe2, 0x2b, 0xc0, 0xab, 0xe5, 0x1c, 0x66, - 0xe0, 0x00, 0xe9, 0x02, 0xe0, 0x80, 0x9e, 0xeb, - 0x17, 0x00, 0xe5, 0x22, 0x00, 0x26, 0x11, 0x20, - 0x25, 0xe0, 0x46, 0xe5, 0x15, 0xeb, 0x02, 0x05, - 0xe0, 0x00, 0xe5, 0x0e, 0xe6, 0x03, 0x6b, 0x96, - 0xe0, 0x4e, 0xe5, 0x0d, 0xcb, 0xe0, 0x0c, 0xe5, - 0x0f, 0xe0, 0x01, 0x07, 0x06, 0x07, 0xe5, 0x2d, - 0xe6, 0x07, 0xd6, 0x60, 0xeb, 0x0c, 0xe9, 0x02, - 0xe0, 0x07, 0x46, 0x07, 0xe5, 0x25, 0x47, 0x66, - 0x27, 0x26, 0x36, 0x1b, 0x76, 0xe0, 0x03, 0x1b, - 0x20, 0xe5, 0x11, 0xc0, 0xe9, 0x02, 0xa0, 0x46, - 0xe5, 0x1c, 0x86, 0x07, 0xe6, 0x00, 0x00, 0xe9, - 0x02, 0x76, 0x05, 0x27, 0x05, 0xe0, 0x00, 0xe5, - 0x1b, 0x06, 0x36, 0x05, 0xe0, 0x01, 0x26, 0x07, - 0xe5, 0x28, 0x47, 0xe6, 0x01, 0x27, 0x65, 0x76, - 0x66, 0x16, 0x07, 0x06, 0xe9, 0x02, 0x05, 0x16, - 0x05, 0x56, 0x00, 0xeb, 0x0c, 0xe0, 0x03, 0xe5, - 0x0a, 0x00, 0xe5, 0x11, 0x47, 0x46, 0x27, 0x06, - 0x07, 0x26, 0xb6, 0x06, 0xe0, 0x39, 0xc5, 0x00, - 0x05, 0x00, 0x65, 0x00, 0xe5, 0x07, 0x00, 0xe5, - 0x02, 0x16, 0xa0, 0xe5, 0x27, 0x06, 0x47, 0xe6, - 0x00, 0x80, 0xe9, 0x02, 0xa0, 0x26, 0x27, 0x00, - 0xe5, 0x00, 0x20, 0x25, 0x20, 0xe5, 0x0e, 0x00, - 0xc5, 0x00, 0x25, 0x00, 0x85, 0x00, 0x26, 0x05, - 0x27, 0x06, 0x67, 0x20, 0x27, 0x20, 0x47, 0x20, - 0x05, 0xa0, 0x07, 0x80, 0x85, 0x27, 0x20, 0xc6, - 0x40, 0x86, 0xe0, 0x80, 0x03, 0xe5, 0x2d, 0x47, - 0xe6, 0x00, 0x27, 0x46, 0x07, 0x06, 0x65, 0x96, - 0xe9, 0x02, 0x36, 0x00, 0x16, 0x06, 0x45, 0xe0, - 0x16, 0xe5, 0x28, 0x47, 0xa6, 0x07, 0x06, 0x67, - 0x26, 0x07, 0x26, 0x25, 0x16, 0x05, 0xe0, 0x00, - 0xe9, 0x02, 0xe0, 0x80, 0x1e, 0xe5, 0x27, 0x47, - 0x66, 0x20, 0x67, 0x26, 0x07, 0x26, 0xf6, 0x0f, - 0x65, 0x26, 0xe0, 0x1a, 0xe5, 0x28, 0x47, 0xe6, - 0x00, 0x27, 0x06, 0x07, 0x26, 0x56, 0x05, 0xe0, - 0x03, 0xe9, 0x02, 0xa0, 0xf6, 0x05, 0xe0, 0x0b, - 0xe5, 0x23, 0x06, 0x07, 0x06, 0x27, 0xa6, 0x07, - 0x06, 0x05, 0xc0, 0xe9, 0x02, 0xe0, 0x2e, 0xe5, - 0x13, 0x20, 0x46, 0x27, 0x66, 0x07, 0x86, 0x60, - 0xe9, 0x02, 0x2b, 0x56, 0x0f, 0xe0, 0x80, 0x38, - 0xe5, 0x24, 0x47, 0xe6, 0x01, 0x07, 0x26, 0x16, - 0xe0, 0x5c, 0xe1, 0x18, 0xe2, 0x18, 0xe9, 0x02, - 0xeb, 0x01, 0xe0, 0x04, 0xe5, 0x00, 0x20, 0x05, - 0x20, 0xe5, 0x00, 0x00, 0x25, 0x00, 0xe5, 0x10, - 0xa7, 0x00, 0x27, 0x20, 0x26, 0x07, 0x06, 0x05, - 0x07, 0x05, 0x07, 0x06, 0x56, 0xe0, 0x01, 0xe9, - 0x02, 0xe0, 0x3e, 0xe5, 0x00, 0x20, 0xe5, 0x1f, - 0x47, 0x66, 0x20, 0x26, 0x67, 0x06, 0x05, 0x16, - 0x05, 0x07, 0xe0, 0x13, 0x05, 0xe6, 0x02, 0xe5, - 0x20, 0xa6, 0x07, 0x05, 0x66, 0xf6, 0x00, 0x06, - 0xe0, 0x00, 0x05, 0xa6, 0x27, 0x46, 0xe5, 0x26, - 0xe6, 0x05, 0x07, 0x26, 0x56, 0x05, 0x96, 0xe0, - 0x15, 0xe5, 0x31, 0xe0, 0x80, 0x7f, 0xe5, 0x01, + 0x00, 0xc5, 0x00, 0xc5, 0x00, 0xc5, 0x00, 0xe6, + 0x18, 0x36, 0x14, 0x15, 0x14, 0x15, 0x56, 0x14, + 0x15, 0x16, 0x14, 0x15, 0xf6, 0x01, 0x11, 0x36, + 0x11, 0x16, 0x14, 0x15, 0x36, 0x14, 0x15, 0x12, + 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x96, + 0x04, 0xf6, 0x02, 0x31, 0x76, 0x11, 0x16, 0x12, + 0xf6, 0x05, 0x2f, 0x56, 0x12, 0x13, 0x12, 0x13, + 0x12, 0x13, 0x12, 0x13, 0x11, 0xe0, 0x1a, 0xef, + 0x12, 0x00, 0xef, 0x51, 0xe0, 0x04, 0xef, 0x80, + 0x4e, 0xe0, 0x12, 0xef, 0x04, 0x60, 0x17, 0x56, + 0x0f, 0x04, 0x05, 0x0a, 0x12, 0x13, 0x12, 0x13, + 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x2f, 0x12, + 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x11, + 0x12, 0x33, 0x0f, 0xea, 0x01, 0x66, 0x27, 0x11, + 0x84, 0x2f, 0x4a, 0x04, 0x05, 0x16, 0x2f, 0x00, + 0xe5, 0x4e, 0x20, 0x26, 0x2e, 0x24, 0x05, 0x11, + 0xe5, 0x52, 0x16, 0x44, 0x05, 0x80, 0xe5, 0x23, + 0x00, 0xe5, 0x56, 0x00, 0x2f, 0x6b, 0xef, 0x02, + 0xe5, 0x18, 0xef, 0x1c, 0xe0, 0x04, 0xe5, 0x08, + 0xef, 0x17, 0x00, 0xeb, 0x02, 0xef, 0x16, 0xeb, + 0x00, 0x0f, 0xeb, 0x07, 0xef, 0x18, 0xeb, 0x02, + 0xef, 0x1f, 0xeb, 0x07, 0xef, 0x80, 0xb8, 0xe5, + 0x99, 0x38, 0xef, 0x38, 0xe5, 0xc0, 0x11, 0x8d, + 0x04, 0xe5, 0x83, 0xef, 0x40, 0xef, 0x2f, 0xe0, + 0x01, 0xe5, 0x20, 0xa4, 0x36, 0xe5, 0x80, 0x84, + 0x04, 0x56, 0xe5, 0x08, 0xe9, 0x02, 0x25, 0xe0, + 0x0c, 0xff, 0x26, 0x05, 0x06, 0x48, 0x16, 0xe6, + 0x02, 0x16, 0x04, 0xff, 0x14, 0x24, 0x26, 0xe5, + 0x3e, 0xea, 0x02, 0x26, 0xb6, 0xe0, 0x00, 0xee, + 0x0f, 0xe4, 0x01, 0x2e, 0xff, 0x06, 0x22, 0xff, + 0x36, 0x04, 0xe2, 0x00, 0x9f, 0xff, 0x02, 0x04, + 0x2e, 0x7f, 0x05, 0x7f, 0x22, 0xff, 0x0d, 0x61, + 0x02, 0x81, 0x02, 0xff, 0x07, 0x41, 0x02, 0x3f, + 0x80, 0x3f, 0x00, 0x02, 0x00, 0x02, 0x7f, 0xe0, + 0x10, 0x44, 0x3f, 0x05, 0x24, 0x02, 0xc5, 0x06, + 0x45, 0x06, 0x65, 0x06, 0xe5, 0x0f, 0x27, 0x26, + 0x07, 0x6f, 0x06, 0x40, 0xab, 0x2f, 0x0d, 0x0f, + 0xa0, 0xe5, 0x2c, 0x76, 0xe0, 0x00, 0x27, 0xe5, + 0x2a, 0xe7, 0x08, 0x26, 0xe0, 0x00, 0x36, 0xe9, + 0x02, 0xa0, 0xe6, 0x0a, 0xa5, 0x56, 0x05, 0x16, + 0x25, 0x06, 0xe9, 0x02, 0xe5, 0x14, 0xe6, 0x00, + 0x36, 0xe5, 0x0f, 0xe6, 0x03, 0x27, 0xe0, 0x03, + 0x16, 0xe5, 0x15, 0x40, 0x46, 0x07, 0xe5, 0x27, + 0x06, 0x27, 0x66, 0x27, 0x26, 0x47, 0xf6, 0x05, + 0x00, 0x04, 0xe9, 0x02, 0x60, 0x36, 0x85, 0x06, + 0x04, 0xe5, 0x01, 0xe9, 0x02, 0x85, 0x00, 0xe5, + 0x21, 0xa6, 0x27, 0x26, 0x27, 0x26, 0xe0, 0x01, + 0x45, 0x06, 0xe5, 0x00, 0x06, 0x07, 0x20, 0xe9, + 0x02, 0x20, 0x76, 0xe5, 0x08, 0x04, 0xa5, 0x4f, + 0x05, 0x07, 0x06, 0x07, 0xe5, 0x2a, 0x06, 0x05, + 0x46, 0x25, 0x26, 0x85, 0x26, 0x05, 0x06, 0x05, + 0xe0, 0x10, 0x25, 0x04, 0x36, 0xe5, 0x03, 0x07, + 0x26, 0x27, 0x36, 0x05, 0x24, 0x07, 0x06, 0xe0, + 0x02, 0xa5, 0x20, 0xa5, 0x20, 0xa5, 0xe0, 0x01, + 0xc5, 0x00, 0xc5, 0x00, 0xe2, 0x23, 0x0e, 0x64, + 0xe2, 0x01, 0x04, 0x2e, 0x60, 0xe2, 0x48, 0xe5, + 0x1b, 0x27, 0x06, 0x27, 0x06, 0x27, 0x16, 0x07, + 0x06, 0x20, 0xe9, 0x02, 0xa0, 0xe5, 0xab, 0x1c, + 0xe0, 0x04, 0xe5, 0x0f, 0x60, 0xe5, 0x29, 0x60, + 0xfc, 0x87, 0x78, 0xfd, 0x98, 0x78, 0xe5, 0x80, + 0xe6, 0x20, 0xe5, 0x62, 0xe0, 0x1e, 0xc2, 0xe0, + 0x04, 0x82, 0x80, 0x05, 0x06, 0xe5, 0x02, 0x0c, + 0xe5, 0x05, 0x00, 0x85, 0x00, 0x05, 0x00, 0x25, + 0x00, 0x25, 0x00, 0xe5, 0x64, 0xee, 0x09, 0xe0, + 0x08, 0xe5, 0x80, 0xe3, 0x13, 0x12, 0xef, 0x08, + 0xe5, 0x38, 0x20, 0xe5, 0x2e, 0xc0, 0x0f, 0xe0, + 0x18, 0xe5, 0x04, 0x0d, 0x4f, 0xe6, 0x08, 0xd6, + 0x12, 0x13, 0x16, 0xa0, 0xe6, 0x08, 0x16, 0x31, + 0x30, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, + 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, + 0x13, 0x36, 0x12, 0x13, 0x76, 0x50, 0x56, 0x00, + 0x76, 0x11, 0x12, 0x13, 0x12, 0x13, 0x12, 0x13, + 0x56, 0x0c, 0x11, 0x4c, 0x00, 0x16, 0x0d, 0x36, + 0x60, 0x85, 0x00, 0xe5, 0x7f, 0x20, 0x1b, 0x00, + 0x56, 0x0d, 0x56, 0x12, 0x13, 0x16, 0x0c, 0x16, + 0x11, 0x36, 0xe9, 0x02, 0x36, 0x4c, 0x36, 0xe1, + 0x12, 0x12, 0x16, 0x13, 0x0e, 0x10, 0x0e, 0xe2, + 0x12, 0x12, 0x0c, 0x13, 0x0c, 0x12, 0x13, 0x16, + 0x12, 0x13, 0x36, 0xe5, 0x02, 0x04, 0xe5, 0x25, + 0x24, 0xe5, 0x17, 0x40, 0xa5, 0x20, 0xa5, 0x20, + 0xa5, 0x20, 0x45, 0x40, 0x2d, 0x0c, 0x0e, 0x0f, + 0x2d, 0x00, 0x0f, 0x6c, 0x2f, 0xe0, 0x02, 0x5b, + 0x2f, 0x20, 0xe5, 0x04, 0x00, 0xe5, 0x12, 0x00, + 0xe5, 0x0b, 0x00, 0x25, 0x00, 0xe5, 0x07, 0x20, + 0xe5, 0x06, 0xe0, 0x1a, 0xe5, 0x73, 0x80, 0x56, + 0x60, 0xeb, 0x25, 0x40, 0xef, 0x01, 0xea, 0x2d, + 0x6b, 0xef, 0x09, 0x2b, 0x4f, 0x00, 0xef, 0x05, + 0x40, 0x0f, 0xe0, 0x27, 0xef, 0x25, 0x06, 0xe0, + 0x7a, 0xe5, 0x15, 0x40, 0xe5, 0x29, 0xe0, 0x07, + 0x06, 0xeb, 0x13, 0x60, 0xe5, 0x18, 0x6b, 0xe0, + 0x01, 0xe5, 0x0c, 0x0a, 0xe5, 0x00, 0x0a, 0x80, + 0xe5, 0x1e, 0x86, 0x80, 0xe5, 0x16, 0x00, 0x16, + 0xe5, 0x1c, 0x60, 0xe5, 0x00, 0x16, 0x8a, 0xe0, + 0x22, 0xe1, 0x20, 0xe2, 0x20, 0xe5, 0x46, 0x20, + 0xe9, 0x02, 0xa0, 0xe1, 0x1c, 0x60, 0xe2, 0x1c, + 0x60, 0xe5, 0x20, 0xe0, 0x00, 0xe5, 0x2c, 0xe0, + 0x03, 0x16, 0xe1, 0x03, 0x00, 0xe1, 0x07, 0x00, + 0xc1, 0x00, 0x21, 0x00, 0xe2, 0x03, 0x00, 0xe2, + 0x07, 0x00, 0xc2, 0x00, 0x22, 0xe0, 0x3b, 0xe5, + 0x80, 0xaf, 0xe0, 0x01, 0xe5, 0x0e, 0xe0, 0x02, + 0xe5, 0x00, 0xe0, 0x10, 0xa4, 0x00, 0xe4, 0x22, + 0x00, 0xe4, 0x01, 0xe0, 0x3d, 0xa5, 0x20, 0x05, + 0x00, 0xe5, 0x24, 0x00, 0x25, 0x40, 0x05, 0x20, + 0xe5, 0x0f, 0x00, 0x16, 0xeb, 0x00, 0xe5, 0x0f, + 0x2f, 0xcb, 0xe5, 0x17, 0xe0, 0x00, 0xeb, 0x01, + 0xe0, 0x28, 0xe5, 0x0b, 0x00, 0x25, 0x80, 0x8b, + 0xe5, 0x0e, 0xab, 0x40, 0x16, 0xe5, 0x12, 0x80, + 0x16, 0xe0, 0x38, 0xe5, 0x30, 0x60, 0x2b, 0x25, + 0xeb, 0x08, 0x20, 0xeb, 0x26, 0x05, 0x46, 0x00, + 0x26, 0x80, 0x66, 0x65, 0x00, 0x45, 0x00, 0xe5, + 0x15, 0x20, 0x46, 0x60, 0x06, 0xeb, 0x01, 0xc0, + 0xf6, 0x01, 0xc0, 0xe5, 0x15, 0x2b, 0x16, 0xe5, + 0x15, 0x4b, 0xe0, 0x18, 0xe5, 0x00, 0x0f, 0xe5, + 0x14, 0x26, 0x60, 0x8b, 0xd6, 0xe0, 0x01, 0xe5, + 0x2e, 0x40, 0xd6, 0xe5, 0x0e, 0x20, 0xeb, 0x00, + 0xe5, 0x0b, 0x80, 0xeb, 0x00, 0xe5, 0x0a, 0xc0, + 0x76, 0xe0, 0x04, 0xcb, 0xe0, 0x48, 0xe5, 0x41, + 0xe0, 0x2f, 0xe1, 0x2b, 0xe0, 0x05, 0xe2, 0x2b, + 0xc0, 0xab, 0xe5, 0x1c, 0x66, 0xe0, 0x00, 0xe9, + 0x02, 0xe0, 0x80, 0x9e, 0xeb, 0x17, 0x00, 0xe5, + 0x22, 0x00, 0x26, 0x11, 0x20, 0x25, 0xe0, 0x43, + 0x46, 0xe5, 0x15, 0xeb, 0x02, 0x05, 0xe0, 0x00, + 0xe5, 0x0e, 0xe6, 0x03, 0x6b, 0x96, 0xe0, 0x0e, + 0xe5, 0x0a, 0x66, 0x76, 0xe0, 0x1e, 0xe5, 0x0d, + 0xcb, 0xe0, 0x0c, 0xe5, 0x0f, 0xe0, 0x01, 0x07, + 0x06, 0x07, 0xe5, 0x2d, 0xe6, 0x07, 0xd6, 0x60, + 0xeb, 0x0c, 0xe9, 0x02, 0x06, 0x25, 0x26, 0x05, + 0xe0, 0x01, 0x46, 0x07, 0xe5, 0x25, 0x47, 0x66, + 0x27, 0x26, 0x36, 0x1b, 0x76, 0x06, 0xe0, 0x02, + 0x1b, 0x20, 0xe5, 0x11, 0xc0, 0xe9, 0x02, 0xa0, + 0x46, 0xe5, 0x1c, 0x86, 0x07, 0xe6, 0x00, 0x00, + 0xe9, 0x02, 0x76, 0x05, 0x27, 0x05, 0xe0, 0x00, + 0xe5, 0x1b, 0x06, 0x36, 0x05, 0xe0, 0x01, 0x26, + 0x07, 0xe5, 0x28, 0x47, 0xe6, 0x01, 0x27, 0x65, + 0x76, 0x66, 0x16, 0x07, 0x06, 0xe9, 0x02, 0x05, + 0x16, 0x05, 0x56, 0x00, 0xeb, 0x0c, 0xe0, 0x03, + 0xe5, 0x0a, 0x00, 0xe5, 0x11, 0x47, 0x46, 0x27, + 0x06, 0x07, 0x26, 0xb6, 0x06, 0x25, 0x06, 0xe0, + 0x36, 0xc5, 0x00, 0x05, 0x00, 0x65, 0x00, 0xe5, + 0x07, 0x00, 0xe5, 0x02, 0x16, 0xa0, 0xe5, 0x27, + 0x06, 0x47, 0xe6, 0x00, 0x80, 0xe9, 0x02, 0xa0, + 0x26, 0x27, 0x00, 0xe5, 0x00, 0x20, 0x25, 0x20, + 0xe5, 0x0e, 0x00, 0xc5, 0x00, 0x25, 0x00, 0x85, + 0x00, 0x26, 0x05, 0x27, 0x06, 0x67, 0x20, 0x27, + 0x20, 0x47, 0x20, 0x05, 0xa0, 0x07, 0x80, 0x85, + 0x27, 0x20, 0xc6, 0x40, 0x86, 0xe0, 0x80, 0x03, + 0xe5, 0x2d, 0x47, 0xe6, 0x00, 0x27, 0x46, 0x07, + 0x06, 0x65, 0x96, 0xe9, 0x02, 0x36, 0x00, 0x16, + 0x06, 0x45, 0xe0, 0x16, 0xe5, 0x28, 0x47, 0xa6, + 0x07, 0x06, 0x67, 0x26, 0x07, 0x26, 0x25, 0x16, + 0x05, 0xe0, 0x00, 0xe9, 0x02, 0xe0, 0x80, 0x1e, + 0xe5, 0x27, 0x47, 0x66, 0x20, 0x67, 0x26, 0x07, + 0x26, 0xf6, 0x0f, 0x65, 0x26, 0xe0, 0x1a, 0xe5, + 0x28, 0x47, 0xe6, 0x00, 0x27, 0x06, 0x07, 0x26, + 0x56, 0x05, 0xe0, 0x03, 0xe9, 0x02, 0xa0, 0xf6, + 0x05, 0xe0, 0x0b, 0xe5, 0x23, 0x06, 0x07, 0x06, + 0x27, 0xa6, 0x07, 0x06, 0x05, 0x16, 0xa0, 0xe9, + 0x02, 0xe0, 0x2e, 0xe5, 0x13, 0x20, 0x46, 0x27, + 0x66, 0x07, 0x86, 0x60, 0xe9, 0x02, 0x2b, 0x56, + 0x0f, 0xc5, 0xe0, 0x80, 0x31, 0xe5, 0x24, 0x47, + 0xe6, 0x01, 0x07, 0x26, 0x16, 0xe0, 0x5c, 0xe1, + 0x18, 0xe2, 0x18, 0xe9, 0x02, 0xeb, 0x01, 0xe0, + 0x04, 0xe5, 0x00, 0x20, 0x05, 0x20, 0xe5, 0x00, + 0x00, 0x25, 0x00, 0xe5, 0x10, 0xa7, 0x00, 0x27, + 0x20, 0x26, 0x07, 0x06, 0x05, 0x07, 0x05, 0x07, + 0x06, 0x56, 0xe0, 0x01, 0xe9, 0x02, 0xe0, 0x3e, + 0xe5, 0x00, 0x20, 0xe5, 0x1f, 0x47, 0x66, 0x20, + 0x26, 0x67, 0x06, 0x05, 0x16, 0x05, 0x07, 0xe0, + 0x13, 0x05, 0xe6, 0x02, 0xe5, 0x20, 0xa6, 0x07, + 0x05, 0x66, 0xf6, 0x00, 0x06, 0xe0, 0x00, 0x05, + 0xa6, 0x27, 0x46, 0xe5, 0x26, 0xe6, 0x05, 0x07, + 0x26, 0x56, 0x05, 0x96, 0xe0, 0x05, 0xe5, 0x41, + 0xc0, 0xf6, 0x02, 0xe0, 0x80, 0x6e, 0xe5, 0x01, 0x00, 0xe5, 0x1d, 0x07, 0xc6, 0x00, 0xa6, 0x07, 0x06, 0x05, 0x96, 0xe0, 0x02, 0xe9, 0x02, 0xeb, 0x0b, 0x40, 0x36, 0xe5, 0x16, 0x20, 0xe6, 0x0e, @@ -2663,33 +2727,40 @@ static const uint8_t unicode_gc_table[3790] = { 0xe0, 0x00, 0xe9, 0x02, 0xa0, 0xa5, 0x00, 0x25, 0x00, 0xe5, 0x18, 0x87, 0x00, 0x26, 0x00, 0x27, 0x06, 0x07, 0x06, 0x05, 0xc0, 0xe9, 0x02, 0xe0, - 0x80, 0xae, 0xe5, 0x0b, 0x26, 0x27, 0x36, 0xe0, - 0x80, 0x2f, 0x05, 0xe0, 0x07, 0xeb, 0x0d, 0xef, - 0x00, 0x6d, 0xef, 0x09, 0xe0, 0x05, 0x16, 0xe5, - 0x83, 0x12, 0xe0, 0x5e, 0xea, 0x67, 0x00, 0x96, - 0xe0, 0x03, 0xe5, 0x80, 0x3c, 0xe0, 0x8a, 0x34, - 0xe5, 0x83, 0xa7, 0x00, 0xfb, 0x01, 0xe0, 0x8f, - 0x3f, 0xe5, 0x81, 0xbf, 0xe0, 0xa1, 0x31, 0xe5, - 0x81, 0xb1, 0xc0, 0xe5, 0x17, 0x00, 0xe9, 0x02, - 0x60, 0x36, 0xe0, 0x58, 0xe5, 0x16, 0x20, 0x86, - 0x16, 0xe0, 0x02, 0xe5, 0x28, 0xc6, 0x96, 0x6f, - 0x64, 0x16, 0x0f, 0xe0, 0x02, 0xe9, 0x02, 0x00, - 0xcb, 0x00, 0xe5, 0x0d, 0x80, 0xe5, 0x0b, 0xe0, - 0x82, 0x28, 0xe1, 0x18, 0xe2, 0x18, 0xeb, 0x0f, - 0x76, 0xe0, 0x5d, 0xe5, 0x43, 0x60, 0x06, 0x05, - 0xe7, 0x2f, 0xc0, 0x66, 0xe4, 0x05, 0xe0, 0x38, - 0x24, 0x16, 0x04, 0x06, 0xe0, 0x03, 0x27, 0xe0, - 0x06, 0xe5, 0x97, 0x70, 0xe0, 0x00, 0xe5, 0x84, - 0x4e, 0xe0, 0x22, 0xe5, 0x01, 0xe0, 0xa2, 0x6f, - 0xe5, 0x80, 0x97, 0xe0, 0x29, 0x45, 0xe0, 0x09, - 0x65, 0xe0, 0x00, 0xe5, 0x81, 0x04, 0xe0, 0x88, - 0x7c, 0xe5, 0x63, 0x80, 0xe5, 0x05, 0x40, 0xe5, - 0x01, 0xc0, 0xe5, 0x02, 0x20, 0x0f, 0x26, 0x16, - 0x7b, 0xe0, 0x92, 0xd4, 0xef, 0x80, 0x6e, 0xe0, - 0x02, 0xef, 0x1f, 0x20, 0xef, 0x34, 0x27, 0x46, - 0x4f, 0xa7, 0xfb, 0x00, 0xe6, 0x00, 0x2f, 0xc6, - 0xef, 0x16, 0x66, 0xef, 0x33, 0xe0, 0x0f, 0xef, - 0x3a, 0x46, 0x0f, 0xe0, 0x80, 0x12, 0xeb, 0x0c, + 0x80, 0xae, 0xe5, 0x0b, 0x26, 0x27, 0x36, 0xc0, + 0x26, 0x05, 0x07, 0xe5, 0x05, 0x00, 0xe5, 0x1a, + 0x27, 0x86, 0x40, 0x27, 0x06, 0x07, 0x06, 0xf6, + 0x05, 0xe9, 0x02, 0xe0, 0x4e, 0x05, 0xe0, 0x07, + 0xeb, 0x0d, 0xef, 0x00, 0x6d, 0xef, 0x09, 0xe0, + 0x05, 0x16, 0xe5, 0x83, 0x12, 0xe0, 0x5e, 0xea, + 0x67, 0x00, 0x96, 0xe0, 0x03, 0xe5, 0x80, 0x3c, + 0xe0, 0x89, 0xc4, 0xe5, 0x59, 0x36, 0xe0, 0x05, + 0xe5, 0x83, 0xa8, 0xfb, 0x08, 0x06, 0xa5, 0xe6, + 0x07, 0xe0, 0x8f, 0x22, 0xe5, 0x81, 0xbf, 0xe0, + 0xa1, 0x31, 0xe5, 0x81, 0xb1, 0xc0, 0xe5, 0x17, + 0x00, 0xe9, 0x02, 0x60, 0x36, 0xe5, 0x47, 0x00, + 0xe9, 0x02, 0xa0, 0xe5, 0x16, 0x20, 0x86, 0x16, + 0xe0, 0x02, 0xe5, 0x28, 0xc6, 0x96, 0x6f, 0x64, + 0x16, 0x0f, 0xe0, 0x02, 0xe9, 0x02, 0x00, 0xcb, + 0x00, 0xe5, 0x0d, 0x80, 0xe5, 0x0b, 0xe0, 0x82, + 0x28, 0xe1, 0x18, 0xe2, 0x18, 0xeb, 0x0f, 0x76, + 0xe0, 0x5d, 0xe5, 0x43, 0x60, 0x06, 0x05, 0xe7, + 0x2f, 0xc0, 0x66, 0xe4, 0x05, 0xe0, 0x38, 0x24, + 0x16, 0x04, 0x06, 0xe0, 0x03, 0x27, 0xe0, 0x06, + 0xe5, 0x97, 0x70, 0xe0, 0x00, 0xe5, 0x84, 0x4e, + 0xe0, 0x22, 0xe5, 0x01, 0xe0, 0xa2, 0x5f, 0x64, + 0x00, 0xc4, 0x00, 0x24, 0x00, 0xe5, 0x80, 0x9b, + 0xe0, 0x07, 0x05, 0xe0, 0x15, 0x45, 0x20, 0x05, + 0xe0, 0x06, 0x65, 0xe0, 0x00, 0xe5, 0x81, 0x04, + 0xe0, 0x88, 0x7c, 0xe5, 0x63, 0x80, 0xe5, 0x05, + 0x40, 0xe5, 0x01, 0xc0, 0xe5, 0x02, 0x20, 0x0f, + 0x26, 0x16, 0x7b, 0xe0, 0x91, 0xd4, 0xe6, 0x26, + 0x20, 0xe6, 0x0f, 0xe0, 0x01, 0xef, 0x6c, 0xe0, + 0x34, 0xef, 0x80, 0x6e, 0xe0, 0x02, 0xef, 0x1f, + 0x20, 0xef, 0x34, 0x27, 0x46, 0x4f, 0xa7, 0xfb, + 0x00, 0xe6, 0x00, 0x2f, 0xc6, 0xef, 0x16, 0x66, + 0xef, 0x35, 0xe0, 0x0d, 0xef, 0x3a, 0x46, 0x0f, + 0xe0, 0x72, 0xeb, 0x0c, 0xe0, 0x04, 0xeb, 0x0c, 0xe0, 0x04, 0xef, 0x4f, 0xe0, 0x01, 0xeb, 0x11, 0xe0, 0x7f, 0xe1, 0x12, 0xe2, 0x12, 0xe1, 0x12, 0xc2, 0x00, 0xe2, 0x0a, 0xe1, 0x12, 0xe2, 0x12, @@ -2709,51 +2780,56 @@ static const uint8_t unicode_gc_table[3790] = { 0x11, 0x0c, 0xa2, 0x3f, 0x20, 0xe9, 0x2a, 0xef, 0x81, 0x78, 0xe6, 0x2f, 0x6f, 0xe6, 0x2a, 0xef, 0x00, 0x06, 0xef, 0x06, 0x06, 0x2f, 0x96, 0xe0, - 0x07, 0x86, 0x00, 0xe6, 0x07, 0xe0, 0x84, 0xc8, - 0xc6, 0x00, 0xe6, 0x09, 0x20, 0xc6, 0x00, 0x26, - 0x00, 0x86, 0xe0, 0x80, 0x4d, 0xe5, 0x25, 0x40, - 0xc6, 0xc4, 0x20, 0xe9, 0x02, 0x60, 0x05, 0x0f, - 0xe0, 0x80, 0xe8, 0xe5, 0x24, 0x66, 0xe9, 0x02, - 0x80, 0x0d, 0xe0, 0x84, 0x78, 0xe5, 0x80, 0x3d, - 0x20, 0xeb, 0x01, 0xc6, 0xe0, 0x21, 0xe1, 0x1a, - 0xe2, 0x1a, 0xc6, 0x04, 0x60, 0xe9, 0x02, 0x60, - 0x36, 0xe0, 0x82, 0x89, 0xeb, 0x33, 0x0f, 0x4b, - 0x0d, 0x6b, 0xe0, 0x44, 0xeb, 0x25, 0x0f, 0xeb, - 0x07, 0xe0, 0x80, 0x3a, 0x65, 0x00, 0xe5, 0x13, - 0x00, 0x25, 0x00, 0x05, 0x20, 0x05, 0x00, 0xe5, - 0x02, 0x00, 0x65, 0x00, 0x05, 0x00, 0x05, 0xa0, - 0x05, 0x60, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, - 0x45, 0x00, 0x25, 0x00, 0x05, 0x20, 0x05, 0x00, - 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, - 0x25, 0x00, 0x05, 0x20, 0x65, 0x00, 0xc5, 0x00, - 0x65, 0x00, 0x65, 0x00, 0x05, 0x00, 0xe5, 0x02, - 0x00, 0xe5, 0x09, 0x80, 0x45, 0x00, 0x85, 0x00, - 0xe5, 0x09, 0xe0, 0x2c, 0x2c, 0xe0, 0x80, 0x86, - 0xef, 0x24, 0x60, 0xef, 0x5c, 0xe0, 0x04, 0xef, - 0x07, 0x20, 0xef, 0x07, 0x00, 0xef, 0x07, 0x00, - 0xef, 0x1d, 0xe0, 0x02, 0xeb, 0x05, 0xef, 0x80, - 0x19, 0xe0, 0x30, 0xef, 0x15, 0xe0, 0x05, 0xef, - 0x24, 0x60, 0xef, 0x01, 0xc0, 0x2f, 0xe0, 0x06, - 0xaf, 0xe0, 0x80, 0x12, 0xef, 0x80, 0x73, 0x8e, - 0xef, 0x82, 0x50, 0xe0, 0x00, 0xef, 0x05, 0x40, - 0xef, 0x05, 0x40, 0xef, 0x6c, 0xe0, 0x04, 0xef, - 0x51, 0xc0, 0xef, 0x04, 0xe0, 0x0c, 0xef, 0x04, - 0x60, 0xef, 0x30, 0xe0, 0x00, 0xef, 0x02, 0xa0, - 0xef, 0x20, 0xe0, 0x00, 0xef, 0x16, 0x20, 0x2f, - 0xe0, 0x46, 0xef, 0x71, 0x00, 0xef, 0x4a, 0x00, - 0xef, 0x7f, 0xe0, 0x04, 0xef, 0x06, 0x20, 0x8f, - 0x40, 0x4f, 0x80, 0xcf, 0xe0, 0x01, 0xef, 0x11, - 0xc0, 0xcf, 0xe0, 0x01, 0x4f, 0xe0, 0x05, 0xcf, - 0xe0, 0x21, 0xef, 0x80, 0x0b, 0x00, 0xef, 0x2f, - 0xe0, 0x1d, 0xe9, 0x02, 0xe0, 0x83, 0x7e, 0xe5, - 0xc0, 0x66, 0x56, 0xe0, 0x1a, 0xe5, 0x8f, 0xad, - 0xe0, 0x03, 0xe5, 0x80, 0x56, 0x20, 0xe5, 0x95, - 0xfa, 0xe0, 0x06, 0xe5, 0x9c, 0xa9, 0xe0, 0x8b, - 0x97, 0xe5, 0x81, 0x96, 0xe0, 0x85, 0x5a, 0xe5, - 0x92, 0xc3, 0xe0, 0xca, 0xac, 0x2e, 0x1b, 0xe0, - 0x16, 0xfb, 0x58, 0xe0, 0x78, 0xe6, 0x80, 0x68, - 0xe0, 0xc0, 0xbd, 0x88, 0xfd, 0xc0, 0xbf, 0x76, - 0x20, 0xfd, 0xc0, 0xbf, 0x76, 0x20, + 0x07, 0x86, 0x00, 0xe6, 0x07, 0xe0, 0x83, 0xc8, + 0xe2, 0x02, 0x05, 0xe2, 0x0c, 0xa0, 0xa2, 0xe0, + 0x80, 0x4d, 0xc6, 0x00, 0xe6, 0x09, 0x20, 0xc6, + 0x00, 0x26, 0x00, 0x86, 0x80, 0xe4, 0x36, 0xe0, + 0x19, 0x06, 0xe0, 0x68, 0xe5, 0x25, 0x40, 0xc6, + 0xc4, 0x20, 0xe9, 0x02, 0x60, 0x05, 0x0f, 0xe0, + 0x80, 0xb8, 0xe5, 0x16, 0x06, 0xe0, 0x09, 0xe5, + 0x24, 0x66, 0xe9, 0x02, 0x80, 0x0d, 0xe0, 0x81, + 0x48, 0xe5, 0x13, 0x04, 0x66, 0xe9, 0x02, 0xe0, + 0x82, 0x5e, 0xc5, 0x00, 0x65, 0x00, 0x25, 0x00, + 0xe5, 0x07, 0x00, 0xe5, 0x80, 0x3d, 0x20, 0xeb, + 0x01, 0xc6, 0xe0, 0x21, 0xe1, 0x1a, 0xe2, 0x1a, + 0xc6, 0x04, 0x60, 0xe9, 0x02, 0x60, 0x36, 0xe0, + 0x82, 0x89, 0xeb, 0x33, 0x0f, 0x4b, 0x0d, 0x6b, + 0xe0, 0x44, 0xeb, 0x25, 0x0f, 0xeb, 0x07, 0xe0, + 0x80, 0x3a, 0x65, 0x00, 0xe5, 0x13, 0x00, 0x25, + 0x00, 0x05, 0x20, 0x05, 0x00, 0xe5, 0x02, 0x00, + 0x65, 0x00, 0x05, 0x00, 0x05, 0xa0, 0x05, 0x60, + 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x45, 0x00, + 0x25, 0x00, 0x05, 0x20, 0x05, 0x00, 0x05, 0x00, + 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x25, 0x00, + 0x05, 0x20, 0x65, 0x00, 0xc5, 0x00, 0x65, 0x00, + 0x65, 0x00, 0x05, 0x00, 0xe5, 0x02, 0x00, 0xe5, + 0x09, 0x80, 0x45, 0x00, 0x85, 0x00, 0xe5, 0x09, + 0xe0, 0x2c, 0x2c, 0xe0, 0x80, 0x86, 0xef, 0x24, + 0x60, 0xef, 0x5c, 0xe0, 0x04, 0xef, 0x07, 0x20, + 0xef, 0x07, 0x00, 0xef, 0x07, 0x00, 0xef, 0x1d, + 0xe0, 0x02, 0xeb, 0x05, 0xef, 0x80, 0x19, 0xe0, + 0x30, 0xef, 0x15, 0xe0, 0x05, 0xef, 0x24, 0x60, + 0xef, 0x01, 0xc0, 0x2f, 0xe0, 0x06, 0xaf, 0xe0, + 0x80, 0x12, 0xef, 0x80, 0x73, 0x8e, 0xef, 0x82, + 0x50, 0x60, 0xef, 0x09, 0x40, 0xef, 0x05, 0x40, + 0xef, 0x6f, 0x60, 0xef, 0x57, 0xa0, 0xef, 0x04, + 0x60, 0x0f, 0xe0, 0x07, 0xef, 0x04, 0x60, 0xef, + 0x30, 0xe0, 0x00, 0xef, 0x02, 0xa0, 0xef, 0x20, + 0xe0, 0x00, 0xef, 0x16, 0x20, 0x2f, 0xe0, 0x46, + 0xef, 0x80, 0xcc, 0xe0, 0x04, 0xef, 0x06, 0x20, + 0xef, 0x05, 0x40, 0xef, 0x01, 0xc0, 0xef, 0x26, + 0x00, 0xcf, 0xe0, 0x00, 0xef, 0x06, 0x60, 0xef, + 0x01, 0xc0, 0xef, 0x01, 0xc0, 0xef, 0x80, 0x0b, + 0x00, 0xef, 0x2f, 0xe0, 0x1d, 0xe9, 0x02, 0xe0, + 0x83, 0x7e, 0xe5, 0xc0, 0x66, 0x58, 0xe0, 0x18, + 0xe5, 0x8f, 0xb2, 0xa0, 0xe5, 0x80, 0x56, 0x20, + 0xe5, 0x95, 0xfa, 0xe0, 0x06, 0xe5, 0x9c, 0xa9, + 0xe0, 0x8b, 0x97, 0xe5, 0x81, 0x96, 0xe0, 0x85, + 0x5a, 0xe5, 0x92, 0xc3, 0x80, 0xe5, 0x8f, 0xd8, + 0xe0, 0xca, 0x9b, 0xc9, 0x1b, 0xe0, 0x16, 0xfb, + 0x58, 0xe0, 0x78, 0xe6, 0x80, 0x68, 0xe0, 0xc0, + 0xbd, 0x88, 0xfd, 0xc0, 0xbf, 0x76, 0x20, 0xfd, + 0xc0, 0xbf, 0x76, 0x20, }; typedef enum { @@ -2787,6 +2863,7 @@ typedef enum { UNICODE_SCRIPT_Cuneiform, UNICODE_SCRIPT_Cypriot, UNICODE_SCRIPT_Cyrillic, + UNICODE_SCRIPT_Cypro_Minoan, UNICODE_SCRIPT_Deseret, UNICODE_SCRIPT_Devanagari, UNICODE_SCRIPT_Dives_Akuru, @@ -2819,6 +2896,7 @@ typedef enum { UNICODE_SCRIPT_Kaithi, UNICODE_SCRIPT_Kannada, UNICODE_SCRIPT_Katakana, + UNICODE_SCRIPT_Kawi, UNICODE_SCRIPT_Kayah_Li, UNICODE_SCRIPT_Kharoshthi, UNICODE_SCRIPT_Khmer, @@ -2853,6 +2931,7 @@ typedef enum { UNICODE_SCRIPT_Multani, UNICODE_SCRIPT_Myanmar, UNICODE_SCRIPT_Nabataean, + UNICODE_SCRIPT_Nag_Mundari, UNICODE_SCRIPT_Nandinagari, UNICODE_SCRIPT_New_Tai_Lue, UNICODE_SCRIPT_Newa, @@ -2869,6 +2948,7 @@ typedef enum { UNICODE_SCRIPT_Old_Sogdian, UNICODE_SCRIPT_Old_South_Arabian, UNICODE_SCRIPT_Old_Turkic, + UNICODE_SCRIPT_Old_Uyghur, UNICODE_SCRIPT_Oriya, UNICODE_SCRIPT_Osage, UNICODE_SCRIPT_Osmanya, @@ -2907,8 +2987,11 @@ typedef enum { UNICODE_SCRIPT_Tibetan, UNICODE_SCRIPT_Tifinagh, UNICODE_SCRIPT_Tirhuta, + UNICODE_SCRIPT_Tangsa, + UNICODE_SCRIPT_Toto, UNICODE_SCRIPT_Ugaritic, UNICODE_SCRIPT_Vai, + UNICODE_SCRIPT_Vithkuqi, UNICODE_SCRIPT_Wancho, UNICODE_SCRIPT_Warang_Citi, UNICODE_SCRIPT_Yezidi, @@ -2947,6 +3030,7 @@ static const char unicode_script_name_table[] = "Cuneiform,Xsux" "\0" "Cypriot,Cprt" "\0" "Cyrillic,Cyrl" "\0" + "Cypro_Minoan,Cpmn" "\0" "Deseret,Dsrt" "\0" "Devanagari,Deva" "\0" "Dives_Akuru,Diak" "\0" @@ -2979,6 +3063,7 @@ static const char unicode_script_name_table[] = "Kaithi,Kthi" "\0" "Kannada,Knda" "\0" "Katakana,Kana" "\0" + "Kawi,Kawi" "\0" "Kayah_Li,Kali" "\0" "Kharoshthi,Khar" "\0" "Khmer,Khmr" "\0" @@ -3013,6 +3098,7 @@ static const char unicode_script_name_table[] = "Multani,Mult" "\0" "Myanmar,Mymr" "\0" "Nabataean,Nbat" "\0" + "Nag_Mundari,Nagm" "\0" "Nandinagari,Nand" "\0" "New_Tai_Lue,Talu" "\0" "Newa,Newa" "\0" @@ -3029,6 +3115,7 @@ static const char unicode_script_name_table[] = "Old_Sogdian,Sogo" "\0" "Old_South_Arabian,Sarb" "\0" "Old_Turkic,Orkh" "\0" + "Old_Uyghur,Ougr" "\0" "Oriya,Orya" "\0" "Osage,Osge" "\0" "Osmanya,Osma" "\0" @@ -3067,8 +3154,11 @@ static const char unicode_script_name_table[] = "Tibetan,Tibt" "\0" "Tifinagh,Tfng" "\0" "Tirhuta,Tirh" "\0" + "Tangsa,Tnsa" "\0" + "Toto,Toto" "\0" "Ugaritic,Ugar" "\0" "Vai,Vaii" "\0" + "Vithkuqi,Vith" "\0" "Wancho,Wcho" "\0" "Warang_Citi,Wara" "\0" "Yezidi,Yezi" "\0" @@ -3076,437 +3166,454 @@ static const char unicode_script_name_table[] = "Zanabazar_Square,Zanb" "\0" ; -static const uint8_t unicode_script_table[2609] = { - 0xc0, 0x19, 0x99, 0x45, 0x85, 0x19, 0x99, 0x45, - 0xae, 0x19, 0x80, 0x45, 0x8e, 0x19, 0x80, 0x45, - 0x84, 0x19, 0x96, 0x45, 0x80, 0x19, 0x9e, 0x45, - 0x80, 0x19, 0xe1, 0x60, 0x45, 0xa6, 0x19, 0x84, - 0x45, 0x84, 0x19, 0x81, 0x0d, 0x93, 0x19, 0xe0, - 0x0f, 0x37, 0x83, 0x2b, 0x80, 0x19, 0x82, 0x2b, - 0x01, 0x83, 0x2b, 0x80, 0x19, 0x80, 0x2b, 0x03, - 0x80, 0x2b, 0x80, 0x19, 0x80, 0x2b, 0x80, 0x19, - 0x82, 0x2b, 0x00, 0x80, 0x2b, 0x00, 0x93, 0x2b, - 0x00, 0xbe, 0x2b, 0x8d, 0x1a, 0x8f, 0x2b, 0xe0, - 0x24, 0x1d, 0x81, 0x37, 0xe0, 0x48, 0x1d, 0x00, +static const uint8_t unicode_script_table[2720] = { + 0xc0, 0x19, 0x99, 0x47, 0x85, 0x19, 0x99, 0x47, + 0xae, 0x19, 0x80, 0x47, 0x8e, 0x19, 0x80, 0x47, + 0x84, 0x19, 0x96, 0x47, 0x80, 0x19, 0x9e, 0x47, + 0x80, 0x19, 0xe1, 0x60, 0x47, 0xa6, 0x19, 0x84, + 0x47, 0x84, 0x19, 0x81, 0x0d, 0x93, 0x19, 0xe0, + 0x0f, 0x38, 0x83, 0x2c, 0x80, 0x19, 0x82, 0x2c, + 0x01, 0x83, 0x2c, 0x80, 0x19, 0x80, 0x2c, 0x03, + 0x80, 0x2c, 0x80, 0x19, 0x80, 0x2c, 0x80, 0x19, + 0x82, 0x2c, 0x00, 0x80, 0x2c, 0x00, 0x93, 0x2c, + 0x00, 0xbe, 0x2c, 0x8d, 0x1a, 0x8f, 0x2c, 0xe0, + 0x24, 0x1d, 0x81, 0x38, 0xe0, 0x48, 0x1d, 0x00, 0xa5, 0x05, 0x01, 0xb1, 0x05, 0x01, 0x82, 0x05, - 0x00, 0xb6, 0x34, 0x07, 0x9a, 0x34, 0x03, 0x85, - 0x34, 0x0a, 0x84, 0x04, 0x80, 0x19, 0x85, 0x04, - 0x80, 0x19, 0x8d, 0x04, 0x80, 0x19, 0x80, 0x04, - 0x00, 0x80, 0x04, 0x80, 0x19, 0x9f, 0x04, 0x80, - 0x19, 0x89, 0x04, 0x8a, 0x37, 0x99, 0x04, 0x80, - 0x37, 0xe0, 0x0b, 0x04, 0x80, 0x19, 0xa1, 0x04, - 0x8d, 0x87, 0x00, 0xbb, 0x87, 0x01, 0x82, 0x87, - 0xaf, 0x04, 0xb1, 0x91, 0x0d, 0xba, 0x63, 0x01, - 0x82, 0x63, 0xad, 0x7b, 0x01, 0x8e, 0x7b, 0x00, - 0x9b, 0x50, 0x01, 0x80, 0x50, 0x00, 0x8a, 0x87, - 0x34, 0x94, 0x04, 0x00, 0x91, 0x04, 0x0a, 0x8e, - 0x04, 0x80, 0x19, 0x9c, 0x04, 0xd0, 0x1f, 0x83, - 0x37, 0x8e, 0x1f, 0x81, 0x19, 0x99, 0x1f, 0x83, - 0x0b, 0x00, 0x87, 0x0b, 0x01, 0x81, 0x0b, 0x01, - 0x95, 0x0b, 0x00, 0x86, 0x0b, 0x00, 0x80, 0x0b, - 0x02, 0x83, 0x0b, 0x01, 0x88, 0x0b, 0x01, 0x81, - 0x0b, 0x01, 0x83, 0x0b, 0x07, 0x80, 0x0b, 0x03, - 0x81, 0x0b, 0x00, 0x84, 0x0b, 0x01, 0x98, 0x0b, - 0x01, 0x82, 0x2e, 0x00, 0x85, 0x2e, 0x03, 0x81, - 0x2e, 0x01, 0x95, 0x2e, 0x00, 0x86, 0x2e, 0x00, - 0x81, 0x2e, 0x00, 0x81, 0x2e, 0x00, 0x81, 0x2e, - 0x01, 0x80, 0x2e, 0x00, 0x84, 0x2e, 0x03, 0x81, - 0x2e, 0x01, 0x82, 0x2e, 0x02, 0x80, 0x2e, 0x06, - 0x83, 0x2e, 0x00, 0x80, 0x2e, 0x06, 0x90, 0x2e, - 0x09, 0x82, 0x2c, 0x00, 0x88, 0x2c, 0x00, 0x82, - 0x2c, 0x00, 0x95, 0x2c, 0x00, 0x86, 0x2c, 0x00, - 0x81, 0x2c, 0x00, 0x84, 0x2c, 0x01, 0x89, 0x2c, - 0x00, 0x82, 0x2c, 0x00, 0x82, 0x2c, 0x01, 0x80, - 0x2c, 0x0e, 0x83, 0x2c, 0x01, 0x8b, 0x2c, 0x06, - 0x86, 0x2c, 0x00, 0x82, 0x70, 0x00, 0x87, 0x70, - 0x01, 0x81, 0x70, 0x01, 0x95, 0x70, 0x00, 0x86, - 0x70, 0x00, 0x81, 0x70, 0x00, 0x84, 0x70, 0x01, - 0x88, 0x70, 0x01, 0x81, 0x70, 0x01, 0x82, 0x70, - 0x06, 0x82, 0x70, 0x03, 0x81, 0x70, 0x00, 0x84, - 0x70, 0x01, 0x91, 0x70, 0x09, 0x81, 0x8e, 0x00, - 0x85, 0x8e, 0x02, 0x82, 0x8e, 0x00, 0x83, 0x8e, - 0x02, 0x81, 0x8e, 0x00, 0x80, 0x8e, 0x00, 0x81, - 0x8e, 0x02, 0x81, 0x8e, 0x02, 0x82, 0x8e, 0x02, - 0x8b, 0x8e, 0x03, 0x84, 0x8e, 0x02, 0x82, 0x8e, - 0x00, 0x83, 0x8e, 0x01, 0x80, 0x8e, 0x05, 0x80, - 0x8e, 0x0d, 0x94, 0x8e, 0x04, 0x8c, 0x90, 0x00, - 0x82, 0x90, 0x00, 0x96, 0x90, 0x00, 0x8f, 0x90, - 0x02, 0x87, 0x90, 0x00, 0x82, 0x90, 0x00, 0x83, - 0x90, 0x06, 0x81, 0x90, 0x00, 0x82, 0x90, 0x04, - 0x83, 0x90, 0x01, 0x89, 0x90, 0x06, 0x88, 0x90, - 0x8c, 0x3c, 0x00, 0x82, 0x3c, 0x00, 0x96, 0x3c, - 0x00, 0x89, 0x3c, 0x00, 0x84, 0x3c, 0x01, 0x88, - 0x3c, 0x00, 0x82, 0x3c, 0x00, 0x83, 0x3c, 0x06, - 0x81, 0x3c, 0x06, 0x80, 0x3c, 0x00, 0x83, 0x3c, - 0x01, 0x89, 0x3c, 0x00, 0x81, 0x3c, 0x0c, 0x8c, - 0x4f, 0x00, 0x82, 0x4f, 0x00, 0xb2, 0x4f, 0x00, - 0x82, 0x4f, 0x00, 0x85, 0x4f, 0x03, 0x8f, 0x4f, - 0x01, 0x99, 0x4f, 0x00, 0x82, 0x81, 0x00, 0x91, - 0x81, 0x02, 0x97, 0x81, 0x00, 0x88, 0x81, 0x00, - 0x80, 0x81, 0x01, 0x86, 0x81, 0x02, 0x80, 0x81, - 0x03, 0x85, 0x81, 0x00, 0x80, 0x81, 0x00, 0x87, - 0x81, 0x05, 0x89, 0x81, 0x01, 0x82, 0x81, 0x0b, - 0xb9, 0x92, 0x03, 0x80, 0x19, 0x9b, 0x92, 0x24, - 0x81, 0x44, 0x00, 0x80, 0x44, 0x00, 0x84, 0x44, - 0x00, 0x97, 0x44, 0x00, 0x80, 0x44, 0x00, 0x96, - 0x44, 0x01, 0x84, 0x44, 0x00, 0x80, 0x44, 0x00, - 0x85, 0x44, 0x01, 0x89, 0x44, 0x01, 0x83, 0x44, - 0x1f, 0xc7, 0x93, 0x00, 0xa3, 0x93, 0x03, 0xa6, - 0x93, 0x00, 0xa3, 0x93, 0x00, 0x8e, 0x93, 0x00, - 0x86, 0x93, 0x83, 0x19, 0x81, 0x93, 0x24, 0xe0, - 0x3f, 0x5e, 0xa5, 0x27, 0x00, 0x80, 0x27, 0x04, - 0x80, 0x27, 0x01, 0xaa, 0x27, 0x80, 0x19, 0x83, - 0x27, 0xe0, 0x9f, 0x30, 0xc8, 0x26, 0x00, 0x83, - 0x26, 0x01, 0x86, 0x26, 0x00, 0x80, 0x26, 0x00, - 0x83, 0x26, 0x01, 0xa8, 0x26, 0x00, 0x83, 0x26, - 0x01, 0xa0, 0x26, 0x00, 0x83, 0x26, 0x01, 0x86, - 0x26, 0x00, 0x80, 0x26, 0x00, 0x83, 0x26, 0x01, - 0x8e, 0x26, 0x00, 0xb8, 0x26, 0x00, 0x83, 0x26, - 0x01, 0xc2, 0x26, 0x01, 0x9f, 0x26, 0x02, 0x99, - 0x26, 0x05, 0xd5, 0x17, 0x01, 0x85, 0x17, 0x01, - 0xe2, 0x1f, 0x12, 0x9c, 0x66, 0x02, 0xca, 0x7a, - 0x82, 0x19, 0x8a, 0x7a, 0x06, 0x8c, 0x88, 0x00, - 0x86, 0x88, 0x0a, 0x94, 0x32, 0x81, 0x19, 0x08, - 0x93, 0x11, 0x0b, 0x8c, 0x89, 0x00, 0x82, 0x89, - 0x00, 0x81, 0x89, 0x0b, 0xdd, 0x40, 0x01, 0x89, - 0x40, 0x05, 0x89, 0x40, 0x05, 0x81, 0x5b, 0x81, - 0x19, 0x80, 0x5b, 0x80, 0x19, 0x88, 0x5b, 0x00, - 0x89, 0x5b, 0x05, 0xd8, 0x5b, 0x06, 0xaa, 0x5b, - 0x04, 0xc5, 0x12, 0x09, 0x9e, 0x47, 0x00, 0x8b, - 0x47, 0x03, 0x8b, 0x47, 0x03, 0x80, 0x47, 0x02, - 0x8b, 0x47, 0x9d, 0x8a, 0x01, 0x84, 0x8a, 0x0a, - 0xab, 0x61, 0x03, 0x99, 0x61, 0x05, 0x8a, 0x61, - 0x02, 0x81, 0x61, 0x9f, 0x40, 0x9b, 0x10, 0x01, - 0x81, 0x10, 0xbe, 0x8b, 0x00, 0x9c, 0x8b, 0x01, - 0x8a, 0x8b, 0x05, 0x89, 0x8b, 0x05, 0x8d, 0x8b, - 0x01, 0x90, 0x37, 0x3e, 0xcb, 0x07, 0x03, 0xac, - 0x07, 0x02, 0xbf, 0x85, 0xb3, 0x0a, 0x07, 0x83, - 0x0a, 0xb7, 0x46, 0x02, 0x8e, 0x46, 0x02, 0x82, - 0x46, 0xaf, 0x67, 0x88, 0x1d, 0x06, 0xaa, 0x27, - 0x01, 0x82, 0x27, 0x87, 0x85, 0x07, 0x82, 0x37, - 0x80, 0x19, 0x8c, 0x37, 0x80, 0x19, 0x86, 0x37, - 0x83, 0x19, 0x80, 0x37, 0x85, 0x19, 0x80, 0x37, - 0x82, 0x19, 0x81, 0x37, 0x80, 0x19, 0x04, 0xa5, - 0x45, 0x84, 0x2b, 0x80, 0x1d, 0xb0, 0x45, 0x84, - 0x2b, 0x83, 0x45, 0x84, 0x2b, 0x8c, 0x45, 0x80, - 0x1d, 0xc5, 0x45, 0x80, 0x2b, 0xb9, 0x37, 0x00, - 0x84, 0x37, 0xe0, 0x9f, 0x45, 0x95, 0x2b, 0x01, - 0x85, 0x2b, 0x01, 0xa5, 0x2b, 0x01, 0x85, 0x2b, - 0x01, 0x87, 0x2b, 0x00, 0x80, 0x2b, 0x00, 0x80, - 0x2b, 0x00, 0x80, 0x2b, 0x00, 0x9e, 0x2b, 0x01, - 0xb4, 0x2b, 0x00, 0x8e, 0x2b, 0x00, 0x8d, 0x2b, - 0x01, 0x85, 0x2b, 0x00, 0x92, 0x2b, 0x01, 0x82, - 0x2b, 0x00, 0x88, 0x2b, 0x00, 0x8b, 0x19, 0x81, - 0x37, 0xd6, 0x19, 0x00, 0x8a, 0x19, 0x80, 0x45, - 0x01, 0x8a, 0x19, 0x80, 0x45, 0x8e, 0x19, 0x00, - 0x8c, 0x45, 0x02, 0x9f, 0x19, 0x0f, 0xa0, 0x37, - 0x0e, 0xa5, 0x19, 0x80, 0x2b, 0x82, 0x19, 0x81, - 0x45, 0x85, 0x19, 0x80, 0x45, 0x9a, 0x19, 0x80, - 0x45, 0x90, 0x19, 0xa8, 0x45, 0x82, 0x19, 0x03, - 0xe2, 0x36, 0x19, 0x18, 0x8a, 0x19, 0x14, 0xe3, - 0x3f, 0x19, 0xe0, 0x9f, 0x0f, 0xe2, 0x13, 0x19, - 0x01, 0x9f, 0x19, 0x00, 0xe0, 0x08, 0x19, 0xae, - 0x28, 0x00, 0xae, 0x28, 0x00, 0x9f, 0x45, 0xe0, - 0x13, 0x1a, 0x04, 0x86, 0x1a, 0xa5, 0x27, 0x00, - 0x80, 0x27, 0x04, 0x80, 0x27, 0x01, 0xb7, 0x94, - 0x06, 0x81, 0x94, 0x0d, 0x80, 0x94, 0x96, 0x26, - 0x08, 0x86, 0x26, 0x00, 0x86, 0x26, 0x00, 0x86, - 0x26, 0x00, 0x86, 0x26, 0x00, 0x86, 0x26, 0x00, - 0x86, 0x26, 0x00, 0x86, 0x26, 0x00, 0x86, 0x26, - 0x00, 0x9f, 0x1d, 0xd2, 0x19, 0x2c, 0x99, 0x2f, - 0x00, 0xd8, 0x2f, 0x0b, 0xe0, 0x75, 0x2f, 0x19, - 0x8b, 0x19, 0x03, 0x84, 0x19, 0x80, 0x2f, 0x80, - 0x19, 0x80, 0x2f, 0x98, 0x19, 0x88, 0x2f, 0x83, - 0x37, 0x81, 0x30, 0x87, 0x19, 0x83, 0x2f, 0x83, - 0x19, 0x00, 0xd5, 0x35, 0x01, 0x81, 0x37, 0x81, - 0x19, 0x82, 0x35, 0x80, 0x19, 0xd9, 0x3d, 0x81, - 0x19, 0x82, 0x3d, 0x04, 0xaa, 0x0d, 0x00, 0xdd, - 0x30, 0x00, 0x8f, 0x19, 0x9f, 0x0d, 0xa3, 0x19, - 0x0b, 0x8f, 0x3d, 0x9e, 0x30, 0x00, 0xbf, 0x19, - 0x9e, 0x30, 0xd0, 0x19, 0xae, 0x3d, 0x80, 0x19, - 0xd7, 0x3d, 0xe0, 0x47, 0x19, 0xf0, 0x09, 0x5f, - 0x2f, 0xbf, 0x19, 0xf0, 0x41, 0x9c, 0x2f, 0x02, - 0xe4, 0x2c, 0x9b, 0x02, 0xb6, 0x9b, 0x08, 0xaf, - 0x4a, 0xe0, 0xcb, 0x97, 0x13, 0xdf, 0x1d, 0xd7, - 0x08, 0x07, 0xa1, 0x19, 0xe0, 0x05, 0x45, 0x82, - 0x19, 0xb4, 0x45, 0x01, 0x88, 0x45, 0x29, 0x8a, - 0x45, 0xac, 0x86, 0x02, 0x89, 0x19, 0x05, 0xb7, - 0x76, 0x07, 0xc5, 0x7c, 0x07, 0x8b, 0x7c, 0x05, - 0x9f, 0x1f, 0xad, 0x3e, 0x80, 0x19, 0x80, 0x3e, - 0xa3, 0x79, 0x0a, 0x80, 0x79, 0x9c, 0x30, 0x02, - 0xcd, 0x3a, 0x00, 0x80, 0x19, 0x89, 0x3a, 0x03, - 0x81, 0x3a, 0x9e, 0x5e, 0x00, 0xb6, 0x16, 0x08, - 0x8d, 0x16, 0x01, 0x89, 0x16, 0x01, 0x83, 0x16, - 0x9f, 0x5e, 0xc2, 0x8c, 0x17, 0x84, 0x8c, 0x96, - 0x55, 0x09, 0x85, 0x26, 0x01, 0x85, 0x26, 0x01, - 0x85, 0x26, 0x08, 0x86, 0x26, 0x00, 0x86, 0x26, - 0x00, 0xaa, 0x45, 0x80, 0x19, 0x88, 0x45, 0x80, - 0x2b, 0x83, 0x45, 0x81, 0x19, 0x03, 0xcf, 0x17, - 0xad, 0x55, 0x01, 0x89, 0x55, 0x05, 0xf0, 0x1b, - 0x43, 0x30, 0x0b, 0x96, 0x30, 0x03, 0xb0, 0x30, - 0x70, 0x10, 0xa3, 0xe1, 0x0d, 0x2f, 0x01, 0xe0, - 0x09, 0x2f, 0x25, 0x86, 0x45, 0x0b, 0x84, 0x05, - 0x04, 0x99, 0x34, 0x00, 0x84, 0x34, 0x00, 0x80, - 0x34, 0x00, 0x81, 0x34, 0x00, 0x81, 0x34, 0x00, - 0x89, 0x34, 0xe0, 0x11, 0x04, 0x10, 0xe1, 0x0a, - 0x04, 0x81, 0x19, 0x0f, 0xbf, 0x04, 0x01, 0xb5, - 0x04, 0x27, 0x8d, 0x04, 0x01, 0x8f, 0x37, 0x89, - 0x19, 0x05, 0x8d, 0x37, 0x81, 0x1d, 0xa2, 0x19, - 0x00, 0x92, 0x19, 0x00, 0x83, 0x19, 0x03, 0x84, - 0x04, 0x00, 0xe0, 0x26, 0x04, 0x01, 0x80, 0x19, - 0x00, 0x9f, 0x19, 0x99, 0x45, 0x85, 0x19, 0x99, - 0x45, 0x8a, 0x19, 0x89, 0x3d, 0x80, 0x19, 0xac, - 0x3d, 0x81, 0x19, 0x9e, 0x30, 0x02, 0x85, 0x30, - 0x01, 0x85, 0x30, 0x01, 0x85, 0x30, 0x01, 0x82, - 0x30, 0x02, 0x86, 0x19, 0x00, 0x86, 0x19, 0x09, - 0x84, 0x19, 0x01, 0x8b, 0x49, 0x00, 0x99, 0x49, - 0x00, 0x92, 0x49, 0x00, 0x81, 0x49, 0x00, 0x8e, - 0x49, 0x01, 0x8d, 0x49, 0x21, 0xe0, 0x1a, 0x49, - 0x04, 0x82, 0x19, 0x03, 0xac, 0x19, 0x02, 0x88, - 0x19, 0xce, 0x2b, 0x00, 0x8c, 0x19, 0x02, 0x80, - 0x2b, 0x2e, 0xac, 0x19, 0x80, 0x37, 0x60, 0x21, - 0x9c, 0x4b, 0x02, 0xb0, 0x13, 0x0e, 0x80, 0x37, - 0x9a, 0x19, 0x03, 0xa3, 0x69, 0x08, 0x82, 0x69, - 0x9a, 0x29, 0x04, 0xaa, 0x6b, 0x04, 0x9d, 0x96, - 0x00, 0x80, 0x96, 0xa3, 0x6c, 0x03, 0x8d, 0x6c, - 0x29, 0xcf, 0x1e, 0xaf, 0x7e, 0x9d, 0x72, 0x01, - 0x89, 0x72, 0x05, 0xa3, 0x71, 0x03, 0xa3, 0x71, - 0x03, 0xa7, 0x24, 0x07, 0xb3, 0x14, 0x0a, 0x80, - 0x14, 0x60, 0x2f, 0xe0, 0xd6, 0x48, 0x08, 0x95, - 0x48, 0x09, 0x87, 0x48, 0x60, 0x37, 0x85, 0x1c, - 0x01, 0x80, 0x1c, 0x00, 0xab, 0x1c, 0x00, 0x81, - 0x1c, 0x02, 0x80, 0x1c, 0x01, 0x80, 0x1c, 0x95, - 0x36, 0x00, 0x88, 0x36, 0x9f, 0x74, 0x9e, 0x5f, - 0x07, 0x88, 0x5f, 0x2f, 0x92, 0x33, 0x00, 0x81, - 0x33, 0x04, 0x84, 0x33, 0x9b, 0x77, 0x02, 0x80, - 0x77, 0x99, 0x4c, 0x04, 0x80, 0x4c, 0x3f, 0x9f, - 0x58, 0x97, 0x57, 0x03, 0x93, 0x57, 0x01, 0xad, - 0x57, 0x83, 0x3f, 0x00, 0x81, 0x3f, 0x04, 0x87, - 0x3f, 0x00, 0x82, 0x3f, 0x00, 0x9c, 0x3f, 0x01, - 0x82, 0x3f, 0x03, 0x89, 0x3f, 0x06, 0x88, 0x3f, - 0x06, 0x9f, 0x6e, 0x9f, 0x6a, 0x1f, 0xa6, 0x51, - 0x03, 0x8b, 0x51, 0x08, 0xb5, 0x06, 0x02, 0x86, - 0x06, 0x95, 0x39, 0x01, 0x87, 0x39, 0x92, 0x38, - 0x04, 0x87, 0x38, 0x91, 0x78, 0x06, 0x83, 0x78, - 0x0b, 0x86, 0x78, 0x4f, 0xc8, 0x6f, 0x36, 0xb2, - 0x68, 0x0c, 0xb2, 0x68, 0x06, 0x85, 0x68, 0xa7, - 0x31, 0x07, 0x89, 0x31, 0x60, 0xc5, 0x9e, 0x04, - 0x00, 0xa9, 0x9a, 0x00, 0x82, 0x9a, 0x01, 0x81, - 0x9a, 0x4d, 0xa7, 0x6d, 0x07, 0xa9, 0x82, 0x55, - 0x9b, 0x18, 0x13, 0x96, 0x25, 0x08, 0xcd, 0x0e, - 0x03, 0x9d, 0x0e, 0x0e, 0x80, 0x0e, 0xc1, 0x3b, - 0x0a, 0x80, 0x3b, 0x01, 0x98, 0x83, 0x06, 0x89, - 0x83, 0x05, 0xb4, 0x15, 0x00, 0x91, 0x15, 0x07, - 0xa6, 0x4e, 0x08, 0xdf, 0x7d, 0x00, 0x93, 0x81, - 0x0a, 0x91, 0x41, 0x00, 0xab, 0x41, 0x40, 0x86, - 0x5d, 0x00, 0x80, 0x5d, 0x00, 0x83, 0x5d, 0x00, - 0x8e, 0x5d, 0x00, 0x8a, 0x5d, 0x05, 0xba, 0x43, - 0x04, 0x89, 0x43, 0x05, 0x83, 0x2a, 0x00, 0x87, - 0x2a, 0x01, 0x81, 0x2a, 0x01, 0x95, 0x2a, 0x00, - 0x86, 0x2a, 0x00, 0x81, 0x2a, 0x00, 0x84, 0x2a, - 0x00, 0x80, 0x37, 0x88, 0x2a, 0x01, 0x81, 0x2a, - 0x01, 0x82, 0x2a, 0x01, 0x80, 0x2a, 0x05, 0x80, - 0x2a, 0x04, 0x86, 0x2a, 0x01, 0x86, 0x2a, 0x02, - 0x84, 0x2a, 0x60, 0x2a, 0xdb, 0x62, 0x00, 0x84, - 0x62, 0x1d, 0xc7, 0x95, 0x07, 0x89, 0x95, 0x60, - 0x45, 0xb5, 0x7f, 0x01, 0xa5, 0x7f, 0x21, 0xc4, - 0x5a, 0x0a, 0x89, 0x5a, 0x05, 0x8c, 0x5b, 0x12, - 0xb8, 0x8d, 0x06, 0x89, 0x8d, 0x35, 0x9a, 0x02, - 0x01, 0x8e, 0x02, 0x03, 0x8f, 0x02, 0x60, 0x5f, - 0xbb, 0x21, 0x60, 0x03, 0xd2, 0x99, 0x0b, 0x80, - 0x99, 0x86, 0x20, 0x01, 0x80, 0x20, 0x01, 0x87, - 0x20, 0x00, 0x81, 0x20, 0x00, 0x9d, 0x20, 0x00, - 0x81, 0x20, 0x01, 0x8b, 0x20, 0x08, 0x89, 0x20, - 0x45, 0x87, 0x60, 0x01, 0xad, 0x60, 0x01, 0x8a, - 0x60, 0x1a, 0xc7, 0x9c, 0x07, 0xd2, 0x84, 0x1c, - 0xb8, 0x75, 0x60, 0xa6, 0x88, 0x0c, 0x00, 0xac, - 0x0c, 0x00, 0x8d, 0x0c, 0x09, 0x9c, 0x0c, 0x02, - 0x9f, 0x52, 0x01, 0x95, 0x52, 0x00, 0x8d, 0x52, - 0x48, 0x86, 0x53, 0x00, 0x81, 0x53, 0x00, 0xab, - 0x53, 0x02, 0x80, 0x53, 0x00, 0x81, 0x53, 0x00, - 0x88, 0x53, 0x07, 0x89, 0x53, 0x05, 0x85, 0x2d, - 0x00, 0x81, 0x2d, 0x00, 0xa4, 0x2d, 0x00, 0x81, - 0x2d, 0x00, 0x85, 0x2d, 0x06, 0x89, 0x2d, 0x60, - 0xd5, 0x98, 0x4d, 0x60, 0x56, 0x80, 0x4a, 0x0e, - 0xb1, 0x8e, 0x0c, 0x80, 0x8e, 0xe3, 0x39, 0x1b, - 0x60, 0x05, 0xe0, 0x0e, 0x1b, 0x00, 0x84, 0x1b, - 0x0a, 0xe0, 0x63, 0x1b, 0x6a, 0x5b, 0xe3, 0xce, - 0x23, 0x00, 0x88, 0x23, 0x6f, 0x66, 0xe1, 0xe6, - 0x03, 0x70, 0x11, 0x58, 0xe1, 0xd8, 0x08, 0x06, - 0x9e, 0x5c, 0x00, 0x89, 0x5c, 0x03, 0x81, 0x5c, - 0x5f, 0x9d, 0x09, 0x01, 0x85, 0x09, 0x09, 0xc5, - 0x73, 0x09, 0x89, 0x73, 0x00, 0x86, 0x73, 0x00, - 0x94, 0x73, 0x04, 0x92, 0x73, 0x62, 0x4f, 0xda, - 0x54, 0x60, 0x04, 0xca, 0x59, 0x03, 0xb8, 0x59, - 0x06, 0x90, 0x59, 0x3f, 0x80, 0x8f, 0x80, 0x64, - 0x81, 0x19, 0x80, 0x42, 0x0a, 0x81, 0x2f, 0x0d, - 0xf0, 0x07, 0x97, 0x8f, 0x07, 0xe2, 0x9f, 0x8f, - 0xe1, 0x75, 0x42, 0x29, 0x88, 0x8f, 0x70, 0x12, - 0x96, 0x80, 0x3d, 0xe0, 0xbd, 0x35, 0x30, 0x82, - 0x35, 0x10, 0x83, 0x3d, 0x07, 0xe1, 0x2b, 0x64, - 0x68, 0xa3, 0xe0, 0x0a, 0x22, 0x04, 0x8c, 0x22, - 0x02, 0x88, 0x22, 0x06, 0x89, 0x22, 0x01, 0x83, - 0x22, 0x83, 0x19, 0x70, 0x02, 0xfb, 0xe0, 0x95, - 0x19, 0x09, 0xa6, 0x19, 0x01, 0xbd, 0x19, 0x82, - 0x37, 0x90, 0x19, 0x87, 0x37, 0x81, 0x19, 0x86, - 0x37, 0x9d, 0x19, 0x83, 0x37, 0xba, 0x19, 0x16, - 0xc5, 0x2b, 0x60, 0x39, 0x93, 0x19, 0x0b, 0xd6, - 0x19, 0x08, 0x98, 0x19, 0x60, 0x26, 0xd4, 0x19, - 0x00, 0xc6, 0x19, 0x00, 0x81, 0x19, 0x01, 0x80, - 0x19, 0x01, 0x81, 0x19, 0x01, 0x83, 0x19, 0x00, - 0x8b, 0x19, 0x00, 0x80, 0x19, 0x00, 0x86, 0x19, - 0x00, 0xc0, 0x19, 0x00, 0x83, 0x19, 0x01, 0x87, - 0x19, 0x00, 0x86, 0x19, 0x00, 0x9b, 0x19, 0x00, - 0x83, 0x19, 0x00, 0x84, 0x19, 0x00, 0x80, 0x19, - 0x02, 0x86, 0x19, 0x00, 0xe0, 0xf3, 0x19, 0x01, - 0xe0, 0xc3, 0x19, 0x01, 0xb1, 0x19, 0xe2, 0x2b, - 0x80, 0x0e, 0x84, 0x80, 0x00, 0x8e, 0x80, 0x64, - 0xef, 0x86, 0x28, 0x00, 0x90, 0x28, 0x01, 0x86, - 0x28, 0x00, 0x81, 0x28, 0x00, 0x84, 0x28, 0x60, - 0x74, 0xac, 0x65, 0x02, 0x8d, 0x65, 0x01, 0x89, - 0x65, 0x03, 0x81, 0x65, 0x61, 0x0f, 0xb9, 0x98, - 0x04, 0x80, 0x98, 0x64, 0x9f, 0xe0, 0x64, 0x56, - 0x01, 0x8f, 0x56, 0x28, 0xcb, 0x01, 0x03, 0x89, - 0x01, 0x03, 0x81, 0x01, 0x62, 0xb0, 0xc3, 0x19, - 0x4b, 0xbc, 0x19, 0x60, 0x61, 0x83, 0x04, 0x00, - 0x9a, 0x04, 0x00, 0x81, 0x04, 0x00, 0x80, 0x04, - 0x01, 0x80, 0x04, 0x00, 0x89, 0x04, 0x00, 0x83, - 0x04, 0x00, 0x80, 0x04, 0x00, 0x80, 0x04, 0x05, - 0x80, 0x04, 0x03, 0x80, 0x04, 0x00, 0x80, 0x04, - 0x00, 0x80, 0x04, 0x00, 0x82, 0x04, 0x00, 0x81, - 0x04, 0x00, 0x80, 0x04, 0x01, 0x80, 0x04, 0x00, - 0x80, 0x04, 0x00, 0x80, 0x04, 0x00, 0x80, 0x04, - 0x00, 0x80, 0x04, 0x00, 0x81, 0x04, 0x00, 0x80, - 0x04, 0x01, 0x83, 0x04, 0x00, 0x86, 0x04, 0x00, - 0x83, 0x04, 0x00, 0x83, 0x04, 0x00, 0x80, 0x04, - 0x00, 0x89, 0x04, 0x00, 0x90, 0x04, 0x04, 0x82, - 0x04, 0x00, 0x84, 0x04, 0x00, 0x90, 0x04, 0x33, - 0x81, 0x04, 0x60, 0xad, 0xab, 0x19, 0x03, 0xe0, - 0x03, 0x19, 0x0b, 0x8e, 0x19, 0x01, 0x8e, 0x19, - 0x00, 0x8e, 0x19, 0x00, 0xa4, 0x19, 0x09, 0xe0, - 0x4d, 0x19, 0x37, 0x99, 0x19, 0x80, 0x35, 0x81, - 0x19, 0x0c, 0xab, 0x19, 0x03, 0x88, 0x19, 0x06, - 0x81, 0x19, 0x0d, 0x85, 0x19, 0x60, 0x39, 0xe3, - 0x77, 0x19, 0x07, 0x8c, 0x19, 0x02, 0x8c, 0x19, - 0x02, 0xe0, 0x13, 0x19, 0x0b, 0xd8, 0x19, 0x06, - 0x8b, 0x19, 0x13, 0x8b, 0x19, 0x03, 0xb7, 0x19, - 0x07, 0x89, 0x19, 0x05, 0xa7, 0x19, 0x07, 0x9d, - 0x19, 0x01, 0x81, 0x19, 0x4d, 0xe0, 0x18, 0x19, - 0x00, 0xd1, 0x19, 0x00, 0xe0, 0x26, 0x19, 0x0b, - 0x8d, 0x19, 0x01, 0x84, 0x19, 0x02, 0x82, 0x19, - 0x04, 0x86, 0x19, 0x08, 0x98, 0x19, 0x06, 0x86, - 0x19, 0x08, 0x82, 0x19, 0x0c, 0x86, 0x19, 0x28, - 0xe0, 0x32, 0x19, 0x00, 0xb6, 0x19, 0x24, 0x89, - 0x19, 0x63, 0xa5, 0xf0, 0x96, 0x7d, 0x2f, 0x21, - 0xef, 0xd4, 0x2f, 0x0a, 0xe0, 0x7d, 0x2f, 0x01, - 0xf0, 0x06, 0x21, 0x2f, 0x0d, 0xf0, 0x0c, 0xd0, - 0x2f, 0x6b, 0xbe, 0xe1, 0xbd, 0x2f, 0x65, 0x81, - 0xf0, 0x02, 0xea, 0x2f, 0x7a, 0xdc, 0x55, 0x80, - 0x19, 0x1d, 0xdf, 0x19, 0x60, 0x1f, 0xe0, 0x8f, - 0x37, + 0x00, 0xb6, 0x35, 0x07, 0x9a, 0x35, 0x03, 0x85, + 0x35, 0x0a, 0x84, 0x04, 0x80, 0x19, 0x85, 0x04, + 0x80, 0x19, 0x8d, 0x04, 0x80, 0x19, 0x82, 0x04, + 0x80, 0x19, 0x9f, 0x04, 0x80, 0x19, 0x89, 0x04, + 0x8a, 0x38, 0x99, 0x04, 0x80, 0x38, 0xe0, 0x0b, + 0x04, 0x80, 0x19, 0xa1, 0x04, 0x8d, 0x8b, 0x00, + 0xbb, 0x8b, 0x01, 0x82, 0x8b, 0xaf, 0x04, 0xb1, + 0x95, 0x0d, 0xba, 0x66, 0x01, 0x82, 0x66, 0xad, + 0x7f, 0x01, 0x8e, 0x7f, 0x00, 0x9b, 0x52, 0x01, + 0x80, 0x52, 0x00, 0x8a, 0x8b, 0x04, 0x9e, 0x04, + 0x00, 0x81, 0x04, 0x05, 0xc9, 0x04, 0x80, 0x19, + 0x9c, 0x04, 0xd0, 0x20, 0x83, 0x38, 0x8e, 0x20, + 0x81, 0x19, 0x99, 0x20, 0x83, 0x0b, 0x00, 0x87, + 0x0b, 0x01, 0x81, 0x0b, 0x01, 0x95, 0x0b, 0x00, + 0x86, 0x0b, 0x00, 0x80, 0x0b, 0x02, 0x83, 0x0b, + 0x01, 0x88, 0x0b, 0x01, 0x81, 0x0b, 0x01, 0x83, + 0x0b, 0x07, 0x80, 0x0b, 0x03, 0x81, 0x0b, 0x00, + 0x84, 0x0b, 0x01, 0x98, 0x0b, 0x01, 0x82, 0x2f, + 0x00, 0x85, 0x2f, 0x03, 0x81, 0x2f, 0x01, 0x95, + 0x2f, 0x00, 0x86, 0x2f, 0x00, 0x81, 0x2f, 0x00, + 0x81, 0x2f, 0x00, 0x81, 0x2f, 0x01, 0x80, 0x2f, + 0x00, 0x84, 0x2f, 0x03, 0x81, 0x2f, 0x01, 0x82, + 0x2f, 0x02, 0x80, 0x2f, 0x06, 0x83, 0x2f, 0x00, + 0x80, 0x2f, 0x06, 0x90, 0x2f, 0x09, 0x82, 0x2d, + 0x00, 0x88, 0x2d, 0x00, 0x82, 0x2d, 0x00, 0x95, + 0x2d, 0x00, 0x86, 0x2d, 0x00, 0x81, 0x2d, 0x00, + 0x84, 0x2d, 0x01, 0x89, 0x2d, 0x00, 0x82, 0x2d, + 0x00, 0x82, 0x2d, 0x01, 0x80, 0x2d, 0x0e, 0x83, + 0x2d, 0x01, 0x8b, 0x2d, 0x06, 0x86, 0x2d, 0x00, + 0x82, 0x74, 0x00, 0x87, 0x74, 0x01, 0x81, 0x74, + 0x01, 0x95, 0x74, 0x00, 0x86, 0x74, 0x00, 0x81, + 0x74, 0x00, 0x84, 0x74, 0x01, 0x88, 0x74, 0x01, + 0x81, 0x74, 0x01, 0x82, 0x74, 0x06, 0x82, 0x74, + 0x03, 0x81, 0x74, 0x00, 0x84, 0x74, 0x01, 0x91, + 0x74, 0x09, 0x81, 0x92, 0x00, 0x85, 0x92, 0x02, + 0x82, 0x92, 0x00, 0x83, 0x92, 0x02, 0x81, 0x92, + 0x00, 0x80, 0x92, 0x00, 0x81, 0x92, 0x02, 0x81, + 0x92, 0x02, 0x82, 0x92, 0x02, 0x8b, 0x92, 0x03, + 0x84, 0x92, 0x02, 0x82, 0x92, 0x00, 0x83, 0x92, + 0x01, 0x80, 0x92, 0x05, 0x80, 0x92, 0x0d, 0x94, + 0x92, 0x04, 0x8c, 0x94, 0x00, 0x82, 0x94, 0x00, + 0x96, 0x94, 0x00, 0x8f, 0x94, 0x01, 0x88, 0x94, + 0x00, 0x82, 0x94, 0x00, 0x83, 0x94, 0x06, 0x81, + 0x94, 0x00, 0x82, 0x94, 0x01, 0x80, 0x94, 0x01, + 0x83, 0x94, 0x01, 0x89, 0x94, 0x06, 0x88, 0x94, + 0x8c, 0x3d, 0x00, 0x82, 0x3d, 0x00, 0x96, 0x3d, + 0x00, 0x89, 0x3d, 0x00, 0x84, 0x3d, 0x01, 0x88, + 0x3d, 0x00, 0x82, 0x3d, 0x00, 0x83, 0x3d, 0x06, + 0x81, 0x3d, 0x05, 0x81, 0x3d, 0x00, 0x83, 0x3d, + 0x01, 0x89, 0x3d, 0x00, 0x82, 0x3d, 0x0b, 0x8c, + 0x51, 0x00, 0x82, 0x51, 0x00, 0xb2, 0x51, 0x00, + 0x82, 0x51, 0x00, 0x85, 0x51, 0x03, 0x8f, 0x51, + 0x01, 0x99, 0x51, 0x00, 0x82, 0x85, 0x00, 0x91, + 0x85, 0x02, 0x97, 0x85, 0x00, 0x88, 0x85, 0x00, + 0x80, 0x85, 0x01, 0x86, 0x85, 0x02, 0x80, 0x85, + 0x03, 0x85, 0x85, 0x00, 0x80, 0x85, 0x00, 0x87, + 0x85, 0x05, 0x89, 0x85, 0x01, 0x82, 0x85, 0x0b, + 0xb9, 0x96, 0x03, 0x80, 0x19, 0x9b, 0x96, 0x24, + 0x81, 0x46, 0x00, 0x80, 0x46, 0x00, 0x84, 0x46, + 0x00, 0x97, 0x46, 0x00, 0x80, 0x46, 0x00, 0x96, + 0x46, 0x01, 0x84, 0x46, 0x00, 0x80, 0x46, 0x00, + 0x86, 0x46, 0x00, 0x89, 0x46, 0x01, 0x83, 0x46, + 0x1f, 0xc7, 0x97, 0x00, 0xa3, 0x97, 0x03, 0xa6, + 0x97, 0x00, 0xa3, 0x97, 0x00, 0x8e, 0x97, 0x00, + 0x86, 0x97, 0x83, 0x19, 0x81, 0x97, 0x24, 0xe0, + 0x3f, 0x60, 0xa5, 0x28, 0x00, 0x80, 0x28, 0x04, + 0x80, 0x28, 0x01, 0xaa, 0x28, 0x80, 0x19, 0x83, + 0x28, 0xe0, 0x9f, 0x31, 0xc8, 0x27, 0x00, 0x83, + 0x27, 0x01, 0x86, 0x27, 0x00, 0x80, 0x27, 0x00, + 0x83, 0x27, 0x01, 0xa8, 0x27, 0x00, 0x83, 0x27, + 0x01, 0xa0, 0x27, 0x00, 0x83, 0x27, 0x01, 0x86, + 0x27, 0x00, 0x80, 0x27, 0x00, 0x83, 0x27, 0x01, + 0x8e, 0x27, 0x00, 0xb8, 0x27, 0x00, 0x83, 0x27, + 0x01, 0xc2, 0x27, 0x01, 0x9f, 0x27, 0x02, 0x99, + 0x27, 0x05, 0xd5, 0x17, 0x01, 0x85, 0x17, 0x01, + 0xe2, 0x1f, 0x12, 0x9c, 0x69, 0x02, 0xca, 0x7e, + 0x82, 0x19, 0x8a, 0x7e, 0x06, 0x95, 0x8c, 0x08, + 0x80, 0x8c, 0x94, 0x33, 0x81, 0x19, 0x08, 0x93, + 0x11, 0x0b, 0x8c, 0x8d, 0x00, 0x82, 0x8d, 0x00, + 0x81, 0x8d, 0x0b, 0xdd, 0x42, 0x01, 0x89, 0x42, + 0x05, 0x89, 0x42, 0x05, 0x81, 0x5d, 0x81, 0x19, + 0x80, 0x5d, 0x80, 0x19, 0x93, 0x5d, 0x05, 0xd8, + 0x5d, 0x06, 0xaa, 0x5d, 0x04, 0xc5, 0x12, 0x09, + 0x9e, 0x49, 0x00, 0x8b, 0x49, 0x03, 0x8b, 0x49, + 0x03, 0x80, 0x49, 0x02, 0x8b, 0x49, 0x9d, 0x8e, + 0x01, 0x84, 0x8e, 0x0a, 0xab, 0x64, 0x03, 0x99, + 0x64, 0x05, 0x8a, 0x64, 0x02, 0x81, 0x64, 0x9f, + 0x42, 0x9b, 0x10, 0x01, 0x81, 0x10, 0xbe, 0x8f, + 0x00, 0x9c, 0x8f, 0x01, 0x8a, 0x8f, 0x05, 0x89, + 0x8f, 0x05, 0x8d, 0x8f, 0x01, 0x9e, 0x38, 0x30, + 0xcc, 0x07, 0x02, 0xae, 0x07, 0x00, 0xbf, 0x89, + 0xb3, 0x0a, 0x07, 0x83, 0x0a, 0xb7, 0x48, 0x02, + 0x8e, 0x48, 0x02, 0x82, 0x48, 0xaf, 0x6a, 0x88, + 0x1d, 0x06, 0xaa, 0x28, 0x01, 0x82, 0x28, 0x87, + 0x89, 0x07, 0x82, 0x38, 0x80, 0x19, 0x8c, 0x38, + 0x80, 0x19, 0x86, 0x38, 0x83, 0x19, 0x80, 0x38, + 0x85, 0x19, 0x80, 0x38, 0x82, 0x19, 0x81, 0x38, + 0x80, 0x19, 0x04, 0xa5, 0x47, 0x84, 0x2c, 0x80, + 0x1d, 0xb0, 0x47, 0x84, 0x2c, 0x83, 0x47, 0x84, + 0x2c, 0x8c, 0x47, 0x80, 0x1d, 0xc5, 0x47, 0x80, + 0x2c, 0xbf, 0x38, 0xe0, 0x9f, 0x47, 0x95, 0x2c, + 0x01, 0x85, 0x2c, 0x01, 0xa5, 0x2c, 0x01, 0x85, + 0x2c, 0x01, 0x87, 0x2c, 0x00, 0x80, 0x2c, 0x00, + 0x80, 0x2c, 0x00, 0x80, 0x2c, 0x00, 0x9e, 0x2c, + 0x01, 0xb4, 0x2c, 0x00, 0x8e, 0x2c, 0x00, 0x8d, + 0x2c, 0x01, 0x85, 0x2c, 0x00, 0x92, 0x2c, 0x01, + 0x82, 0x2c, 0x00, 0x88, 0x2c, 0x00, 0x8b, 0x19, + 0x81, 0x38, 0xd6, 0x19, 0x00, 0x8a, 0x19, 0x80, + 0x47, 0x01, 0x8a, 0x19, 0x80, 0x47, 0x8e, 0x19, + 0x00, 0x8c, 0x47, 0x02, 0xa0, 0x19, 0x0e, 0xa0, + 0x38, 0x0e, 0xa5, 0x19, 0x80, 0x2c, 0x82, 0x19, + 0x81, 0x47, 0x85, 0x19, 0x80, 0x47, 0x9a, 0x19, + 0x80, 0x47, 0x90, 0x19, 0xa8, 0x47, 0x82, 0x19, + 0x03, 0xe2, 0x36, 0x19, 0x18, 0x8a, 0x19, 0x14, + 0xe3, 0x3f, 0x19, 0xe0, 0x9f, 0x0f, 0xe2, 0x13, + 0x19, 0x01, 0x9f, 0x19, 0x00, 0xe0, 0x08, 0x19, + 0xdf, 0x29, 0x9f, 0x47, 0xe0, 0x13, 0x1a, 0x04, + 0x86, 0x1a, 0xa5, 0x28, 0x00, 0x80, 0x28, 0x04, + 0x80, 0x28, 0x01, 0xb7, 0x98, 0x06, 0x81, 0x98, + 0x0d, 0x80, 0x98, 0x96, 0x27, 0x08, 0x86, 0x27, + 0x00, 0x86, 0x27, 0x00, 0x86, 0x27, 0x00, 0x86, + 0x27, 0x00, 0x86, 0x27, 0x00, 0x86, 0x27, 0x00, + 0x86, 0x27, 0x00, 0x86, 0x27, 0x00, 0x9f, 0x1d, + 0xdd, 0x19, 0x21, 0x99, 0x30, 0x00, 0xd8, 0x30, + 0x0b, 0xe0, 0x75, 0x30, 0x19, 0x8b, 0x19, 0x03, + 0x84, 0x19, 0x80, 0x30, 0x80, 0x19, 0x80, 0x30, + 0x98, 0x19, 0x88, 0x30, 0x83, 0x38, 0x81, 0x31, + 0x87, 0x19, 0x83, 0x30, 0x83, 0x19, 0x00, 0xd5, + 0x36, 0x01, 0x81, 0x38, 0x81, 0x19, 0x82, 0x36, + 0x80, 0x19, 0xd9, 0x3e, 0x81, 0x19, 0x82, 0x3e, + 0x04, 0xaa, 0x0d, 0x00, 0xdd, 0x31, 0x00, 0x8f, + 0x19, 0x9f, 0x0d, 0xa3, 0x19, 0x0b, 0x8f, 0x3e, + 0x9e, 0x31, 0x00, 0xbf, 0x19, 0x9e, 0x31, 0xd0, + 0x19, 0xae, 0x3e, 0x80, 0x19, 0xd7, 0x3e, 0xe0, + 0x47, 0x19, 0xf0, 0x09, 0x5f, 0x30, 0xbf, 0x19, + 0xf0, 0x41, 0x9f, 0x30, 0xe4, 0x2c, 0xa2, 0x02, + 0xb6, 0xa2, 0x08, 0xaf, 0x4c, 0xe0, 0xcb, 0x9d, + 0x13, 0xdf, 0x1d, 0xd7, 0x08, 0x07, 0xa1, 0x19, + 0xe0, 0x05, 0x47, 0x82, 0x19, 0xbf, 0x47, 0x04, + 0x81, 0x47, 0x00, 0x80, 0x47, 0x00, 0x84, 0x47, + 0x17, 0x8d, 0x47, 0xac, 0x8a, 0x02, 0x89, 0x19, + 0x05, 0xb7, 0x7a, 0x07, 0xc5, 0x80, 0x07, 0x8b, + 0x80, 0x05, 0x9f, 0x20, 0xad, 0x40, 0x80, 0x19, + 0x80, 0x40, 0xa3, 0x7d, 0x0a, 0x80, 0x7d, 0x9c, + 0x31, 0x02, 0xcd, 0x3b, 0x00, 0x80, 0x19, 0x89, + 0x3b, 0x03, 0x81, 0x3b, 0x9e, 0x60, 0x00, 0xb6, + 0x16, 0x08, 0x8d, 0x16, 0x01, 0x89, 0x16, 0x01, + 0x83, 0x16, 0x9f, 0x60, 0xc2, 0x90, 0x17, 0x84, + 0x90, 0x96, 0x57, 0x09, 0x85, 0x27, 0x01, 0x85, + 0x27, 0x01, 0x85, 0x27, 0x08, 0x86, 0x27, 0x00, + 0x86, 0x27, 0x00, 0xaa, 0x47, 0x80, 0x19, 0x88, + 0x47, 0x80, 0x2c, 0x83, 0x47, 0x81, 0x19, 0x03, + 0xcf, 0x17, 0xad, 0x57, 0x01, 0x89, 0x57, 0x05, + 0xf0, 0x1b, 0x43, 0x31, 0x0b, 0x96, 0x31, 0x03, + 0xb0, 0x31, 0x70, 0x10, 0xa3, 0xe1, 0x0d, 0x30, + 0x01, 0xe0, 0x09, 0x30, 0x25, 0x86, 0x47, 0x0b, + 0x84, 0x05, 0x04, 0x99, 0x35, 0x00, 0x84, 0x35, + 0x00, 0x80, 0x35, 0x00, 0x81, 0x35, 0x00, 0x81, + 0x35, 0x00, 0x89, 0x35, 0xe0, 0x12, 0x04, 0x0f, + 0xe1, 0x0a, 0x04, 0x81, 0x19, 0xcf, 0x04, 0x01, + 0xb5, 0x04, 0x06, 0x80, 0x04, 0x1f, 0x8f, 0x04, + 0x8f, 0x38, 0x89, 0x19, 0x05, 0x8d, 0x38, 0x81, + 0x1d, 0xa2, 0x19, 0x00, 0x92, 0x19, 0x00, 0x83, + 0x19, 0x03, 0x84, 0x04, 0x00, 0xe0, 0x26, 0x04, + 0x01, 0x80, 0x19, 0x00, 0x9f, 0x19, 0x99, 0x47, + 0x85, 0x19, 0x99, 0x47, 0x8a, 0x19, 0x89, 0x3e, + 0x80, 0x19, 0xac, 0x3e, 0x81, 0x19, 0x9e, 0x31, + 0x02, 0x85, 0x31, 0x01, 0x85, 0x31, 0x01, 0x85, + 0x31, 0x01, 0x82, 0x31, 0x02, 0x86, 0x19, 0x00, + 0x86, 0x19, 0x09, 0x84, 0x19, 0x01, 0x8b, 0x4b, + 0x00, 0x99, 0x4b, 0x00, 0x92, 0x4b, 0x00, 0x81, + 0x4b, 0x00, 0x8e, 0x4b, 0x01, 0x8d, 0x4b, 0x21, + 0xe0, 0x1a, 0x4b, 0x04, 0x82, 0x19, 0x03, 0xac, + 0x19, 0x02, 0x88, 0x19, 0xce, 0x2c, 0x00, 0x8c, + 0x19, 0x02, 0x80, 0x2c, 0x2e, 0xac, 0x19, 0x80, + 0x38, 0x60, 0x21, 0x9c, 0x4d, 0x02, 0xb0, 0x13, + 0x0e, 0x80, 0x38, 0x9a, 0x19, 0x03, 0xa3, 0x6c, + 0x08, 0x82, 0x6c, 0x9a, 0x2a, 0x04, 0xaa, 0x6e, + 0x04, 0x9d, 0x9c, 0x00, 0x80, 0x9c, 0xa3, 0x6f, + 0x03, 0x8d, 0x6f, 0x29, 0xcf, 0x1f, 0xaf, 0x82, + 0x9d, 0x76, 0x01, 0x89, 0x76, 0x05, 0xa3, 0x75, + 0x03, 0xa3, 0x75, 0x03, 0xa7, 0x25, 0x07, 0xb3, + 0x14, 0x0a, 0x80, 0x14, 0x8a, 0x9e, 0x00, 0x8e, + 0x9e, 0x00, 0x86, 0x9e, 0x00, 0x81, 0x9e, 0x00, + 0x8a, 0x9e, 0x00, 0x8e, 0x9e, 0x00, 0x86, 0x9e, + 0x00, 0x81, 0x9e, 0x42, 0xe0, 0xd6, 0x4a, 0x08, + 0x95, 0x4a, 0x09, 0x87, 0x4a, 0x17, 0x85, 0x47, + 0x00, 0xa9, 0x47, 0x00, 0x88, 0x47, 0x44, 0x85, + 0x1c, 0x01, 0x80, 0x1c, 0x00, 0xab, 0x1c, 0x00, + 0x81, 0x1c, 0x02, 0x80, 0x1c, 0x01, 0x80, 0x1c, + 0x95, 0x37, 0x00, 0x88, 0x37, 0x9f, 0x78, 0x9e, + 0x61, 0x07, 0x88, 0x61, 0x2f, 0x92, 0x34, 0x00, + 0x81, 0x34, 0x04, 0x84, 0x34, 0x9b, 0x7b, 0x02, + 0x80, 0x7b, 0x99, 0x4e, 0x04, 0x80, 0x4e, 0x3f, + 0x9f, 0x5a, 0x97, 0x59, 0x03, 0x93, 0x59, 0x01, + 0xad, 0x59, 0x83, 0x41, 0x00, 0x81, 0x41, 0x04, + 0x87, 0x41, 0x00, 0x82, 0x41, 0x00, 0x9c, 0x41, + 0x01, 0x82, 0x41, 0x03, 0x89, 0x41, 0x06, 0x88, + 0x41, 0x06, 0x9f, 0x71, 0x9f, 0x6d, 0x1f, 0xa6, + 0x53, 0x03, 0x8b, 0x53, 0x08, 0xb5, 0x06, 0x02, + 0x86, 0x06, 0x95, 0x3a, 0x01, 0x87, 0x3a, 0x92, + 0x39, 0x04, 0x87, 0x39, 0x91, 0x7c, 0x06, 0x83, + 0x7c, 0x0b, 0x86, 0x7c, 0x4f, 0xc8, 0x72, 0x36, + 0xb2, 0x6b, 0x0c, 0xb2, 0x6b, 0x06, 0x85, 0x6b, + 0xa7, 0x32, 0x07, 0x89, 0x32, 0x60, 0xc5, 0x9e, + 0x04, 0x00, 0xa9, 0xa1, 0x00, 0x82, 0xa1, 0x01, + 0x81, 0xa1, 0x4a, 0x82, 0x04, 0xa7, 0x70, 0x07, + 0xa9, 0x86, 0x15, 0x99, 0x73, 0x25, 0x9b, 0x18, + 0x13, 0x96, 0x26, 0x08, 0xcd, 0x0e, 0x03, 0xa3, + 0x0e, 0x08, 0x80, 0x0e, 0xc2, 0x3c, 0x09, 0x80, + 0x3c, 0x01, 0x98, 0x87, 0x06, 0x89, 0x87, 0x05, + 0xb4, 0x15, 0x00, 0x91, 0x15, 0x07, 0xa6, 0x50, + 0x08, 0xdf, 0x81, 0x00, 0x93, 0x85, 0x0a, 0x91, + 0x43, 0x00, 0xae, 0x43, 0x3d, 0x86, 0x5f, 0x00, + 0x80, 0x5f, 0x00, 0x83, 0x5f, 0x00, 0x8e, 0x5f, + 0x00, 0x8a, 0x5f, 0x05, 0xba, 0x45, 0x04, 0x89, + 0x45, 0x05, 0x83, 0x2b, 0x00, 0x87, 0x2b, 0x01, + 0x81, 0x2b, 0x01, 0x95, 0x2b, 0x00, 0x86, 0x2b, + 0x00, 0x81, 0x2b, 0x00, 0x84, 0x2b, 0x00, 0x80, + 0x38, 0x88, 0x2b, 0x01, 0x81, 0x2b, 0x01, 0x82, + 0x2b, 0x01, 0x80, 0x2b, 0x05, 0x80, 0x2b, 0x04, + 0x86, 0x2b, 0x01, 0x86, 0x2b, 0x02, 0x84, 0x2b, + 0x60, 0x2a, 0xdb, 0x65, 0x00, 0x84, 0x65, 0x1d, + 0xc7, 0x99, 0x07, 0x89, 0x99, 0x60, 0x45, 0xb5, + 0x83, 0x01, 0xa5, 0x83, 0x21, 0xc4, 0x5c, 0x0a, + 0x89, 0x5c, 0x05, 0x8c, 0x5d, 0x12, 0xb9, 0x91, + 0x05, 0x89, 0x91, 0x35, 0x9a, 0x02, 0x01, 0x8e, + 0x02, 0x03, 0x96, 0x02, 0x60, 0x58, 0xbb, 0x22, + 0x60, 0x03, 0xd2, 0xa0, 0x0b, 0x80, 0xa0, 0x86, + 0x21, 0x01, 0x80, 0x21, 0x01, 0x87, 0x21, 0x00, + 0x81, 0x21, 0x00, 0x9d, 0x21, 0x00, 0x81, 0x21, + 0x01, 0x8b, 0x21, 0x08, 0x89, 0x21, 0x45, 0x87, + 0x63, 0x01, 0xad, 0x63, 0x01, 0x8a, 0x63, 0x1a, + 0xc7, 0xa3, 0x07, 0xd2, 0x88, 0x0c, 0x8f, 0x12, + 0xb8, 0x79, 0x06, 0x89, 0x20, 0x60, 0x95, 0x88, + 0x0c, 0x00, 0xac, 0x0c, 0x00, 0x8d, 0x0c, 0x09, + 0x9c, 0x0c, 0x02, 0x9f, 0x54, 0x01, 0x95, 0x54, + 0x00, 0x8d, 0x54, 0x48, 0x86, 0x55, 0x00, 0x81, + 0x55, 0x00, 0xab, 0x55, 0x02, 0x80, 0x55, 0x00, + 0x81, 0x55, 0x00, 0x88, 0x55, 0x07, 0x89, 0x55, + 0x05, 0x85, 0x2e, 0x00, 0x81, 0x2e, 0x00, 0xa4, + 0x2e, 0x00, 0x81, 0x2e, 0x00, 0x85, 0x2e, 0x06, + 0x89, 0x2e, 0x60, 0xd5, 0x98, 0x4f, 0x06, 0x90, + 0x3f, 0x00, 0xa8, 0x3f, 0x02, 0x9b, 0x3f, 0x55, + 0x80, 0x4c, 0x0e, 0xb1, 0x92, 0x0c, 0x80, 0x92, + 0xe3, 0x39, 0x1b, 0x60, 0x05, 0xe0, 0x0e, 0x1b, + 0x00, 0x84, 0x1b, 0x0a, 0xe0, 0x63, 0x1b, 0x69, + 0xeb, 0xe0, 0x02, 0x1e, 0x0c, 0xe3, 0xf5, 0x24, + 0x6f, 0x49, 0xe1, 0xe6, 0x03, 0x70, 0x11, 0x58, + 0xe1, 0xd8, 0x08, 0x06, 0x9e, 0x5e, 0x00, 0x89, + 0x5e, 0x03, 0x81, 0x5e, 0xce, 0x9a, 0x00, 0x89, + 0x9a, 0x05, 0x9d, 0x09, 0x01, 0x85, 0x09, 0x09, + 0xc5, 0x77, 0x09, 0x89, 0x77, 0x00, 0x86, 0x77, + 0x00, 0x94, 0x77, 0x04, 0x92, 0x77, 0x62, 0x4f, + 0xda, 0x56, 0x60, 0x04, 0xca, 0x5b, 0x03, 0xb8, + 0x5b, 0x06, 0x90, 0x5b, 0x3f, 0x80, 0x93, 0x80, + 0x67, 0x81, 0x30, 0x80, 0x44, 0x0a, 0x81, 0x30, + 0x0d, 0xf0, 0x07, 0x97, 0x93, 0x07, 0xe2, 0x9f, + 0x93, 0xe1, 0x75, 0x44, 0x29, 0x88, 0x93, 0x70, + 0x12, 0x86, 0x83, 0x3e, 0x00, 0x86, 0x3e, 0x00, + 0x81, 0x3e, 0x00, 0x80, 0x3e, 0xe0, 0xbe, 0x36, + 0x82, 0x3e, 0x0e, 0x80, 0x36, 0x1c, 0x82, 0x36, + 0x01, 0x80, 0x3e, 0x0d, 0x83, 0x3e, 0x07, 0xe1, + 0x2b, 0x67, 0x68, 0xa3, 0xe0, 0x0a, 0x23, 0x04, + 0x8c, 0x23, 0x02, 0x88, 0x23, 0x06, 0x89, 0x23, + 0x01, 0x83, 0x23, 0x83, 0x19, 0x70, 0x01, 0xfb, + 0xad, 0x38, 0x01, 0x96, 0x38, 0x08, 0xe0, 0x13, + 0x19, 0x3b, 0xe0, 0x95, 0x19, 0x09, 0xa6, 0x19, + 0x01, 0xbd, 0x19, 0x82, 0x38, 0x90, 0x19, 0x87, + 0x38, 0x81, 0x19, 0x86, 0x38, 0x9d, 0x19, 0x83, + 0x38, 0xbc, 0x19, 0x14, 0xc5, 0x2c, 0x60, 0x19, + 0x93, 0x19, 0x0b, 0x93, 0x19, 0x0b, 0xd6, 0x19, + 0x08, 0x98, 0x19, 0x60, 0x26, 0xd4, 0x19, 0x00, + 0xc6, 0x19, 0x00, 0x81, 0x19, 0x01, 0x80, 0x19, + 0x01, 0x81, 0x19, 0x01, 0x83, 0x19, 0x00, 0x8b, + 0x19, 0x00, 0x80, 0x19, 0x00, 0x86, 0x19, 0x00, + 0xc0, 0x19, 0x00, 0x83, 0x19, 0x01, 0x87, 0x19, + 0x00, 0x86, 0x19, 0x00, 0x9b, 0x19, 0x00, 0x83, + 0x19, 0x00, 0x84, 0x19, 0x00, 0x80, 0x19, 0x02, + 0x86, 0x19, 0x00, 0xe0, 0xf3, 0x19, 0x01, 0xe0, + 0xc3, 0x19, 0x01, 0xb1, 0x19, 0xe2, 0x2b, 0x84, + 0x0e, 0x84, 0x84, 0x00, 0x8e, 0x84, 0x63, 0xef, + 0x9e, 0x47, 0x05, 0x85, 0x47, 0x60, 0x74, 0x86, + 0x29, 0x00, 0x90, 0x29, 0x01, 0x86, 0x29, 0x00, + 0x81, 0x29, 0x00, 0x84, 0x29, 0x04, 0xbd, 0x1d, + 0x20, 0x80, 0x1d, 0x60, 0x0f, 0xac, 0x68, 0x02, + 0x8d, 0x68, 0x01, 0x89, 0x68, 0x03, 0x81, 0x68, + 0x60, 0xdf, 0x9e, 0x9b, 0x10, 0xb9, 0x9f, 0x04, + 0x80, 0x9f, 0x61, 0x6f, 0xa9, 0x62, 0x62, 0x85, + 0x86, 0x27, 0x00, 0x83, 0x27, 0x00, 0x81, 0x27, + 0x00, 0x8e, 0x27, 0x00, 0xe0, 0x64, 0x58, 0x01, + 0x8f, 0x58, 0x28, 0xcb, 0x01, 0x03, 0x89, 0x01, + 0x03, 0x81, 0x01, 0x62, 0xb0, 0xc3, 0x19, 0x4b, + 0xbc, 0x19, 0x60, 0x61, 0x83, 0x04, 0x00, 0x9a, + 0x04, 0x00, 0x81, 0x04, 0x00, 0x80, 0x04, 0x01, + 0x80, 0x04, 0x00, 0x89, 0x04, 0x00, 0x83, 0x04, + 0x00, 0x80, 0x04, 0x00, 0x80, 0x04, 0x05, 0x80, + 0x04, 0x03, 0x80, 0x04, 0x00, 0x80, 0x04, 0x00, + 0x80, 0x04, 0x00, 0x82, 0x04, 0x00, 0x81, 0x04, + 0x00, 0x80, 0x04, 0x01, 0x80, 0x04, 0x00, 0x80, + 0x04, 0x00, 0x80, 0x04, 0x00, 0x80, 0x04, 0x00, + 0x80, 0x04, 0x00, 0x81, 0x04, 0x00, 0x80, 0x04, + 0x01, 0x83, 0x04, 0x00, 0x86, 0x04, 0x00, 0x83, + 0x04, 0x00, 0x83, 0x04, 0x00, 0x80, 0x04, 0x00, + 0x89, 0x04, 0x00, 0x90, 0x04, 0x04, 0x82, 0x04, + 0x00, 0x84, 0x04, 0x00, 0x90, 0x04, 0x33, 0x81, + 0x04, 0x60, 0xad, 0xab, 0x19, 0x03, 0xe0, 0x03, + 0x19, 0x0b, 0x8e, 0x19, 0x01, 0x8e, 0x19, 0x00, + 0x8e, 0x19, 0x00, 0xa4, 0x19, 0x09, 0xe0, 0x4d, + 0x19, 0x37, 0x99, 0x19, 0x80, 0x36, 0x81, 0x19, + 0x0c, 0xab, 0x19, 0x03, 0x88, 0x19, 0x06, 0x81, + 0x19, 0x0d, 0x85, 0x19, 0x60, 0x39, 0xe3, 0x77, + 0x19, 0x03, 0x90, 0x19, 0x02, 0x8c, 0x19, 0x02, + 0xe0, 0x16, 0x19, 0x03, 0xde, 0x19, 0x05, 0x8b, + 0x19, 0x03, 0x80, 0x19, 0x0e, 0x8b, 0x19, 0x03, + 0xb7, 0x19, 0x07, 0x89, 0x19, 0x05, 0xa7, 0x19, + 0x07, 0x9d, 0x19, 0x01, 0x81, 0x19, 0x4d, 0xe0, + 0xf3, 0x19, 0x0b, 0x8d, 0x19, 0x01, 0x8c, 0x19, + 0x02, 0x88, 0x19, 0x06, 0xad, 0x19, 0x00, 0x86, + 0x19, 0x07, 0x8d, 0x19, 0x03, 0x88, 0x19, 0x06, + 0x88, 0x19, 0x06, 0xe0, 0x32, 0x19, 0x00, 0xb6, + 0x19, 0x24, 0x89, 0x19, 0x63, 0xa5, 0xf0, 0x96, + 0x7f, 0x30, 0x1f, 0xef, 0xd9, 0x30, 0x05, 0xe0, + 0x7d, 0x30, 0x01, 0xf0, 0x06, 0x21, 0x30, 0x0d, + 0xf0, 0x0c, 0xd0, 0x30, 0x6b, 0xbe, 0xe1, 0xbd, + 0x30, 0x65, 0x81, 0xf0, 0x02, 0xea, 0x30, 0x04, + 0xef, 0xff, 0x30, 0x7a, 0xcb, 0xf0, 0x80, 0x19, + 0x1d, 0xdf, 0x19, 0x60, 0x1f, 0xe0, 0x8f, 0x38, }; -static const uint8_t unicode_script_ext_table[799] = { - 0x82, 0xc1, 0x00, 0x00, 0x01, 0x2b, 0x01, 0x00, - 0x00, 0x01, 0x2b, 0x1c, 0x00, 0x0c, 0x01, 0x45, - 0x80, 0x92, 0x00, 0x00, 0x02, 0x1d, 0x6b, 0x00, - 0x02, 0x1d, 0x28, 0x01, 0x02, 0x1d, 0x45, 0x00, - 0x02, 0x1d, 0x28, 0x81, 0x03, 0x00, 0x00, 0x05, - 0x04, 0x31, 0x87, 0x91, 0x9a, 0x0d, 0x00, 0x00, - 0x05, 0x04, 0x31, 0x87, 0x91, 0x9a, 0x00, 0x03, - 0x04, 0x87, 0x91, 0x01, 0x00, 0x00, 0x05, 0x04, - 0x31, 0x87, 0x91, 0x9a, 0x1f, 0x00, 0x00, 0x08, - 0x01, 0x04, 0x50, 0x51, 0x78, 0x31, 0x82, 0x87, - 0x09, 0x00, 0x0a, 0x02, 0x04, 0x87, 0x09, 0x00, - 0x09, 0x03, 0x04, 0x91, 0x9a, 0x05, 0x00, 0x00, - 0x02, 0x04, 0x87, 0x62, 0x00, 0x00, 0x02, 0x04, - 0x31, 0x81, 0xfb, 0x00, 0x00, 0x0d, 0x0b, 0x1f, - 0x2a, 0x2c, 0x2e, 0x3c, 0x45, 0x4f, 0x70, 0x7d, - 0x8e, 0x90, 0x95, 0x00, 0x0c, 0x0b, 0x1f, 0x2a, - 0x2c, 0x2e, 0x3c, 0x45, 0x4f, 0x70, 0x8e, 0x90, - 0x95, 0x10, 0x00, 0x00, 0x14, 0x0b, 0x1f, 0x21, - 0x2d, 0x53, 0x2a, 0x2c, 0x2e, 0x3c, 0x4e, 0x4f, - 0x60, 0x70, 0x43, 0x81, 0x86, 0x8d, 0x8e, 0x90, - 0x95, 0x00, 0x15, 0x0b, 0x1f, 0x21, 0x2d, 0x53, - 0x2a, 0x2c, 0x2e, 0x3c, 0x47, 0x4e, 0x4f, 0x60, - 0x70, 0x43, 0x81, 0x86, 0x8d, 0x8e, 0x90, 0x95, - 0x09, 0x04, 0x1f, 0x21, 0x3b, 0x4e, 0x75, 0x00, - 0x09, 0x03, 0x0b, 0x15, 0x86, 0x75, 0x00, 0x09, - 0x02, 0x2e, 0x5d, 0x75, 0x00, 0x09, 0x02, 0x2c, - 0x41, 0x80, 0x75, 0x00, 0x0d, 0x02, 0x2a, 0x8e, - 0x80, 0x71, 0x00, 0x09, 0x02, 0x3c, 0x60, 0x82, - 0xcf, 0x00, 0x09, 0x03, 0x15, 0x5e, 0x8a, 0x80, - 0x30, 0x00, 0x00, 0x02, 0x27, 0x45, 0x85, 0xb8, - 0x00, 0x01, 0x04, 0x11, 0x32, 0x89, 0x88, 0x80, - 0x4a, 0x00, 0x01, 0x02, 0x5b, 0x76, 0x00, 0x00, - 0x00, 0x02, 0x5b, 0x76, 0x84, 0x49, 0x00, 0x00, - 0x04, 0x0b, 0x1f, 0x2a, 0x3c, 0x00, 0x01, 0x1f, - 0x00, 0x04, 0x0b, 0x1f, 0x2a, 0x3c, 0x00, 0x02, - 0x1f, 0x2a, 0x00, 0x01, 0x1f, 0x01, 0x02, 0x0b, - 0x1f, 0x00, 0x02, 0x1f, 0x7d, 0x00, 0x02, 0x0b, - 0x1f, 0x00, 0x02, 0x1f, 0x7d, 0x00, 0x06, 0x1f, - 0x3c, 0x4f, 0x70, 0x8e, 0x90, 0x00, 0x01, 0x1f, - 0x01, 0x02, 0x1f, 0x7d, 0x01, 0x01, 0x1f, 0x00, - 0x02, 0x1f, 0x7d, 0x00, 0x02, 0x0b, 0x1f, 0x06, - 0x01, 0x1f, 0x00, 0x02, 0x1f, 0x60, 0x00, 0x02, - 0x0b, 0x1f, 0x01, 0x01, 0x1f, 0x00, 0x02, 0x0b, - 0x1f, 0x03, 0x01, 0x1f, 0x00, 0x08, 0x0b, 0x1f, - 0x2a, 0x3c, 0x60, 0x70, 0x90, 0x95, 0x00, 0x02, - 0x1f, 0x2a, 0x00, 0x03, 0x1f, 0x2a, 0x3c, 0x01, - 0x02, 0x0b, 0x1f, 0x00, 0x01, 0x0b, 0x01, 0x02, - 0x1f, 0x2a, 0x00, 0x01, 0x60, 0x80, 0x44, 0x00, - 0x01, 0x01, 0x2b, 0x35, 0x00, 0x00, 0x02, 0x1d, - 0x87, 0x81, 0xb5, 0x00, 0x00, 0x02, 0x45, 0x5b, - 0x80, 0x3f, 0x00, 0x00, 0x03, 0x1f, 0x2a, 0x45, - 0x8c, 0xd1, 0x00, 0x00, 0x02, 0x1d, 0x28, 0x81, - 0x3c, 0x00, 0x01, 0x06, 0x0d, 0x30, 0x2f, 0x35, - 0x3d, 0x9b, 0x00, 0x05, 0x0d, 0x30, 0x2f, 0x35, - 0x3d, 0x01, 0x00, 0x00, 0x01, 0x2f, 0x00, 0x00, - 0x09, 0x06, 0x0d, 0x30, 0x2f, 0x35, 0x3d, 0x9b, - 0x00, 0x00, 0x00, 0x05, 0x0d, 0x30, 0x2f, 0x35, - 0x3d, 0x07, 0x06, 0x0d, 0x30, 0x2f, 0x35, 0x3d, - 0x9b, 0x03, 0x05, 0x0d, 0x30, 0x2f, 0x35, 0x3d, - 0x09, 0x00, 0x03, 0x02, 0x0d, 0x2f, 0x01, 0x00, - 0x00, 0x05, 0x0d, 0x30, 0x2f, 0x35, 0x3d, 0x04, - 0x02, 0x35, 0x3d, 0x00, 0x00, 0x00, 0x05, 0x0d, - 0x30, 0x2f, 0x35, 0x3d, 0x03, 0x00, 0x01, 0x03, - 0x2f, 0x35, 0x3d, 0x01, 0x01, 0x2f, 0x58, 0x00, - 0x03, 0x02, 0x35, 0x3d, 0x02, 0x00, 0x00, 0x02, - 0x35, 0x3d, 0x59, 0x00, 0x00, 0x06, 0x0d, 0x30, - 0x2f, 0x35, 0x3d, 0x9b, 0x00, 0x02, 0x35, 0x3d, - 0x80, 0x12, 0x00, 0x0f, 0x01, 0x2f, 0x1f, 0x00, - 0x23, 0x01, 0x2f, 0x3b, 0x00, 0x27, 0x01, 0x2f, - 0x37, 0x00, 0x30, 0x01, 0x2f, 0x0e, 0x00, 0x0b, - 0x01, 0x2f, 0x32, 0x00, 0x00, 0x01, 0x2f, 0x57, - 0x00, 0x18, 0x01, 0x2f, 0x09, 0x00, 0x04, 0x01, - 0x2f, 0x5f, 0x00, 0x1e, 0x01, 0x2f, 0xc0, 0x31, - 0xef, 0x00, 0x00, 0x02, 0x1d, 0x28, 0x80, 0x0f, - 0x00, 0x07, 0x02, 0x2f, 0x45, 0x80, 0xa7, 0x00, - 0x02, 0x0e, 0x1f, 0x21, 0x2c, 0x2e, 0x41, 0x3c, - 0x3b, 0x4e, 0x4f, 0x5a, 0x60, 0x43, 0x8d, 0x95, - 0x02, 0x0d, 0x1f, 0x21, 0x2c, 0x2e, 0x41, 0x3c, - 0x3b, 0x4e, 0x5a, 0x60, 0x43, 0x8d, 0x95, 0x03, - 0x0b, 0x1f, 0x21, 0x2c, 0x2e, 0x41, 0x3b, 0x4e, - 0x5a, 0x43, 0x8d, 0x95, 0x80, 0x36, 0x00, 0x00, - 0x02, 0x0b, 0x1f, 0x00, 0x00, 0x00, 0x02, 0x1f, - 0x8e, 0x39, 0x00, 0x00, 0x03, 0x3e, 0x45, 0x5e, - 0x80, 0x1f, 0x00, 0x00, 0x02, 0x10, 0x3a, 0xc0, - 0x13, 0xa1, 0x00, 0x00, 0x02, 0x04, 0x91, 0x09, - 0x00, 0x00, 0x02, 0x04, 0x91, 0x46, 0x00, 0x01, - 0x05, 0x0d, 0x30, 0x2f, 0x35, 0x3d, 0x80, 0x99, - 0x00, 0x04, 0x06, 0x0d, 0x30, 0x2f, 0x35, 0x3d, - 0x9b, 0x09, 0x00, 0x00, 0x02, 0x35, 0x3d, 0x2c, - 0x00, 0x01, 0x02, 0x35, 0x3d, 0x80, 0xdf, 0x00, - 0x02, 0x02, 0x1c, 0x49, 0x03, 0x00, 0x2c, 0x03, - 0x1c, 0x48, 0x49, 0x02, 0x00, 0x08, 0x02, 0x1c, - 0x49, 0x81, 0x1f, 0x00, 0x1b, 0x02, 0x04, 0x1a, - 0x8f, 0x84, 0x00, 0x00, 0x02, 0x2a, 0x8e, 0x00, - 0x00, 0x00, 0x02, 0x2a, 0x8e, 0x36, 0x00, 0x01, - 0x02, 0x2a, 0x8e, 0x8c, 0x12, 0x00, 0x01, 0x02, - 0x2a, 0x8e, 0x00, 0x00, 0x00, 0x02, 0x2a, 0x8e, - 0xc0, 0x5c, 0x4b, 0x00, 0x03, 0x01, 0x22, 0x96, - 0x3b, 0x00, 0x11, 0x01, 0x2f, 0x9e, 0x5d, 0x00, - 0x01, 0x01, 0x2f, 0xce, 0xcd, 0x2d, 0x00, +static const uint8_t unicode_script_ext_table[828] = { + 0x82, 0xc1, 0x00, 0x00, 0x01, 0x2c, 0x01, 0x00, + 0x00, 0x01, 0x2c, 0x1c, 0x00, 0x0c, 0x01, 0x47, + 0x80, 0x92, 0x00, 0x00, 0x02, 0x1d, 0x6e, 0x00, + 0x02, 0x1d, 0x29, 0x01, 0x02, 0x1d, 0x47, 0x00, + 0x02, 0x1d, 0x29, 0x81, 0x03, 0x00, 0x00, 0x06, + 0x04, 0x66, 0x32, 0x8b, 0x95, 0xa1, 0x0d, 0x00, + 0x00, 0x06, 0x04, 0x66, 0x32, 0x8b, 0x95, 0xa1, + 0x00, 0x03, 0x04, 0x8b, 0x95, 0x01, 0x00, 0x00, + 0x07, 0x01, 0x04, 0x66, 0x32, 0x8b, 0x95, 0xa1, + 0x1f, 0x00, 0x00, 0x09, 0x01, 0x04, 0x52, 0x53, + 0x73, 0x7c, 0x32, 0x86, 0x8b, 0x09, 0x00, 0x0a, + 0x02, 0x04, 0x8b, 0x09, 0x00, 0x09, 0x03, 0x04, + 0x95, 0xa1, 0x05, 0x00, 0x00, 0x02, 0x04, 0x8b, + 0x62, 0x00, 0x00, 0x02, 0x04, 0x32, 0x81, 0xfb, + 0x00, 0x00, 0x0d, 0x0b, 0x20, 0x2b, 0x2d, 0x2f, + 0x3d, 0x47, 0x51, 0x74, 0x81, 0x92, 0x94, 0x99, + 0x00, 0x0c, 0x0b, 0x20, 0x2b, 0x2d, 0x2f, 0x3d, + 0x47, 0x51, 0x74, 0x92, 0x94, 0x99, 0x10, 0x00, + 0x00, 0x14, 0x0b, 0x20, 0x22, 0x2e, 0x55, 0x2b, + 0x2d, 0x2f, 0x3d, 0x50, 0x51, 0x63, 0x74, 0x45, + 0x85, 0x8a, 0x91, 0x92, 0x94, 0x99, 0x00, 0x15, + 0x0b, 0x20, 0x22, 0x2e, 0x55, 0x2b, 0x2d, 0x2f, + 0x3d, 0x49, 0x50, 0x51, 0x63, 0x74, 0x45, 0x85, + 0x8a, 0x91, 0x92, 0x94, 0x99, 0x09, 0x04, 0x20, + 0x22, 0x3c, 0x50, 0x75, 0x00, 0x09, 0x03, 0x0b, + 0x15, 0x8a, 0x75, 0x00, 0x09, 0x02, 0x2f, 0x5f, + 0x75, 0x00, 0x09, 0x02, 0x2d, 0x43, 0x80, 0x75, + 0x00, 0x0d, 0x02, 0x2b, 0x92, 0x80, 0x71, 0x00, + 0x09, 0x02, 0x3d, 0x63, 0x82, 0xcf, 0x00, 0x09, + 0x03, 0x15, 0x60, 0x8e, 0x80, 0x30, 0x00, 0x00, + 0x02, 0x28, 0x47, 0x85, 0xb8, 0x00, 0x01, 0x04, + 0x11, 0x33, 0x8d, 0x8c, 0x80, 0x4a, 0x00, 0x01, + 0x02, 0x5d, 0x7a, 0x00, 0x00, 0x00, 0x02, 0x5d, + 0x7a, 0x84, 0x49, 0x00, 0x00, 0x04, 0x0b, 0x20, + 0x2b, 0x3d, 0x00, 0x01, 0x20, 0x00, 0x04, 0x0b, + 0x20, 0x2b, 0x3d, 0x00, 0x02, 0x20, 0x2b, 0x00, + 0x01, 0x20, 0x01, 0x02, 0x0b, 0x20, 0x00, 0x02, + 0x20, 0x81, 0x00, 0x02, 0x0b, 0x20, 0x00, 0x02, + 0x20, 0x81, 0x00, 0x06, 0x20, 0x3d, 0x51, 0x74, + 0x92, 0x94, 0x00, 0x01, 0x20, 0x01, 0x02, 0x20, + 0x81, 0x01, 0x01, 0x20, 0x00, 0x02, 0x20, 0x81, + 0x00, 0x02, 0x0b, 0x20, 0x06, 0x01, 0x20, 0x00, + 0x02, 0x20, 0x63, 0x00, 0x02, 0x0b, 0x20, 0x01, + 0x01, 0x20, 0x00, 0x02, 0x0b, 0x20, 0x03, 0x01, + 0x20, 0x00, 0x08, 0x0b, 0x20, 0x2b, 0x3d, 0x63, + 0x74, 0x94, 0x99, 0x00, 0x02, 0x20, 0x2b, 0x00, + 0x03, 0x20, 0x2b, 0x3d, 0x01, 0x02, 0x0b, 0x20, + 0x00, 0x01, 0x0b, 0x01, 0x02, 0x20, 0x2b, 0x00, + 0x01, 0x63, 0x80, 0x44, 0x00, 0x01, 0x01, 0x2c, + 0x35, 0x00, 0x00, 0x02, 0x1d, 0x8b, 0x00, 0x00, + 0x00, 0x01, 0x8b, 0x81, 0xb3, 0x00, 0x00, 0x02, + 0x47, 0x5d, 0x80, 0x3f, 0x00, 0x00, 0x03, 0x20, + 0x2b, 0x47, 0x8c, 0xd1, 0x00, 0x00, 0x02, 0x1d, + 0x29, 0x81, 0x3c, 0x00, 0x01, 0x06, 0x0d, 0x31, + 0x30, 0x36, 0x3e, 0xa2, 0x00, 0x05, 0x0d, 0x31, + 0x30, 0x36, 0x3e, 0x01, 0x00, 0x00, 0x01, 0x30, + 0x00, 0x00, 0x09, 0x06, 0x0d, 0x31, 0x30, 0x36, + 0x3e, 0xa2, 0x00, 0x00, 0x00, 0x05, 0x0d, 0x31, + 0x30, 0x36, 0x3e, 0x07, 0x06, 0x0d, 0x31, 0x30, + 0x36, 0x3e, 0xa2, 0x03, 0x05, 0x0d, 0x31, 0x30, + 0x36, 0x3e, 0x09, 0x00, 0x03, 0x02, 0x0d, 0x30, + 0x01, 0x00, 0x00, 0x05, 0x0d, 0x31, 0x30, 0x36, + 0x3e, 0x04, 0x02, 0x36, 0x3e, 0x00, 0x00, 0x00, + 0x05, 0x0d, 0x31, 0x30, 0x36, 0x3e, 0x03, 0x00, + 0x01, 0x03, 0x30, 0x36, 0x3e, 0x01, 0x01, 0x30, + 0x58, 0x00, 0x03, 0x02, 0x36, 0x3e, 0x02, 0x00, + 0x00, 0x02, 0x36, 0x3e, 0x59, 0x00, 0x00, 0x06, + 0x0d, 0x31, 0x30, 0x36, 0x3e, 0xa2, 0x00, 0x02, + 0x36, 0x3e, 0x80, 0x12, 0x00, 0x0f, 0x01, 0x30, + 0x1f, 0x00, 0x23, 0x01, 0x30, 0x3b, 0x00, 0x27, + 0x01, 0x30, 0x37, 0x00, 0x30, 0x01, 0x30, 0x0e, + 0x00, 0x0b, 0x01, 0x30, 0x32, 0x00, 0x00, 0x01, + 0x30, 0x57, 0x00, 0x18, 0x01, 0x30, 0x09, 0x00, + 0x04, 0x01, 0x30, 0x5f, 0x00, 0x1e, 0x01, 0x30, + 0xc0, 0x31, 0xef, 0x00, 0x00, 0x02, 0x1d, 0x29, + 0x80, 0x0f, 0x00, 0x07, 0x02, 0x30, 0x47, 0x80, + 0xa7, 0x00, 0x02, 0x0e, 0x20, 0x22, 0x2d, 0x2f, + 0x43, 0x3d, 0x3c, 0x50, 0x51, 0x5c, 0x63, 0x45, + 0x91, 0x99, 0x02, 0x0d, 0x20, 0x22, 0x2d, 0x2f, + 0x43, 0x3d, 0x3c, 0x50, 0x5c, 0x63, 0x45, 0x91, + 0x99, 0x03, 0x0b, 0x20, 0x22, 0x2d, 0x2f, 0x43, + 0x3c, 0x50, 0x5c, 0x45, 0x91, 0x99, 0x80, 0x36, + 0x00, 0x00, 0x02, 0x0b, 0x20, 0x00, 0x00, 0x00, + 0x02, 0x20, 0x92, 0x39, 0x00, 0x00, 0x03, 0x40, + 0x47, 0x60, 0x80, 0x1f, 0x00, 0x00, 0x02, 0x10, + 0x3b, 0xc0, 0x12, 0xed, 0x00, 0x01, 0x02, 0x04, + 0x66, 0x80, 0x31, 0x00, 0x00, 0x02, 0x04, 0x95, + 0x09, 0x00, 0x00, 0x02, 0x04, 0x95, 0x46, 0x00, + 0x01, 0x05, 0x0d, 0x31, 0x30, 0x36, 0x3e, 0x80, + 0x99, 0x00, 0x04, 0x06, 0x0d, 0x31, 0x30, 0x36, + 0x3e, 0xa2, 0x09, 0x00, 0x00, 0x02, 0x36, 0x3e, + 0x2c, 0x00, 0x01, 0x02, 0x36, 0x3e, 0x80, 0xdf, + 0x00, 0x01, 0x03, 0x1e, 0x1c, 0x4b, 0x00, 0x02, + 0x1c, 0x4b, 0x03, 0x00, 0x2c, 0x03, 0x1c, 0x4a, + 0x4b, 0x02, 0x00, 0x08, 0x02, 0x1c, 0x4b, 0x81, + 0x1f, 0x00, 0x1b, 0x02, 0x04, 0x1a, 0x87, 0x75, + 0x00, 0x00, 0x02, 0x53, 0x73, 0x87, 0x8d, 0x00, + 0x00, 0x02, 0x2b, 0x92, 0x00, 0x00, 0x00, 0x02, + 0x2b, 0x92, 0x36, 0x00, 0x01, 0x02, 0x2b, 0x92, + 0x8c, 0x12, 0x00, 0x01, 0x02, 0x2b, 0x92, 0x00, + 0x00, 0x00, 0x02, 0x2b, 0x92, 0xc0, 0x5c, 0x4b, + 0x00, 0x03, 0x01, 0x23, 0x96, 0x3b, 0x00, 0x11, + 0x01, 0x30, 0x9e, 0x5d, 0x00, 0x01, 0x01, 0x30, + 0xce, 0xcd, 0x2d, 0x00, }; static const uint8_t unicode_prop_Hyphen_table[28] = { @@ -3544,7 +3651,7 @@ static const uint8_t unicode_prop_Other_Math_table[200] = { 0x80, 0x89, 0x80, 0x90, 0x22, 0x04, 0x80, 0x90, }; -static const uint8_t unicode_prop_Other_Alphabetic_table[411] = { +static const uint8_t unicode_prop_Other_Alphabetic_table[428] = { 0x43, 0x44, 0x80, 0x42, 0x69, 0x8d, 0x00, 0x01, 0x01, 0x00, 0xc7, 0x8a, 0xaf, 0x8c, 0x06, 0x8f, 0x80, 0xe4, 0x33, 0x19, 0x0b, 0x80, 0xa2, 0x80, @@ -3556,57 +3663,61 @@ static const uint8_t unicode_prop_Other_Alphabetic_table[411] = { 0x0a, 0x80, 0x8a, 0x82, 0xb9, 0x38, 0x10, 0x81, 0x94, 0x81, 0x95, 0x13, 0x82, 0xb9, 0x31, 0x09, 0x81, 0x88, 0x81, 0x89, 0x81, 0x9d, 0x80, 0xba, - 0x22, 0x10, 0x82, 0x89, 0x80, 0xa7, 0x83, 0xb9, + 0x22, 0x10, 0x82, 0x89, 0x80, 0xa7, 0x84, 0xb8, 0x30, 0x10, 0x17, 0x81, 0x8a, 0x81, 0x9c, 0x82, - 0xb9, 0x30, 0x10, 0x17, 0x81, 0x8a, 0x81, 0x9b, - 0x83, 0xb9, 0x30, 0x10, 0x82, 0x89, 0x80, 0x89, - 0x81, 0x9c, 0x82, 0xca, 0x28, 0x00, 0x87, 0x91, - 0x81, 0xbc, 0x01, 0x86, 0x91, 0x80, 0xe2, 0x01, - 0x28, 0x81, 0x8f, 0x80, 0x40, 0xa2, 0x90, 0x8a, - 0x8a, 0x80, 0xa3, 0xed, 0x8b, 0x00, 0x0b, 0x96, - 0x1b, 0x10, 0x11, 0x32, 0x83, 0x8c, 0x8b, 0x00, - 0x89, 0x83, 0x46, 0x73, 0x81, 0x9d, 0x81, 0x9d, - 0x81, 0x9d, 0x81, 0xc1, 0x92, 0x40, 0xbb, 0x81, - 0xa1, 0x80, 0xf5, 0x8b, 0x83, 0x88, 0x40, 0xdd, - 0x84, 0xb8, 0x89, 0x81, 0x93, 0xc9, 0x81, 0xbe, - 0x84, 0xaf, 0x8e, 0xbb, 0x82, 0x9d, 0x88, 0x09, - 0xb8, 0x8a, 0xb1, 0x92, 0x41, 0xaf, 0x8d, 0x46, - 0xc0, 0xb3, 0x48, 0xf5, 0x9f, 0x60, 0x78, 0x73, - 0x87, 0xa1, 0x81, 0x41, 0x61, 0x07, 0x80, 0x96, - 0x84, 0xd7, 0x81, 0xb1, 0x8f, 0x00, 0xb8, 0x80, - 0xa5, 0x84, 0x9b, 0x8b, 0xac, 0x83, 0xaf, 0x8b, - 0xa4, 0x80, 0xc2, 0x8d, 0x8b, 0x07, 0x81, 0xac, - 0x82, 0xb1, 0x00, 0x11, 0x0c, 0x80, 0xab, 0x24, - 0x80, 0x40, 0xec, 0x87, 0x60, 0x4f, 0x32, 0x80, - 0x48, 0x56, 0x84, 0x46, 0x85, 0x10, 0x0c, 0x83, - 0x43, 0x13, 0x83, 0x41, 0x82, 0x81, 0x41, 0x52, - 0x82, 0xb4, 0x8d, 0xbb, 0x80, 0xac, 0x88, 0xc6, + 0xb9, 0x30, 0x10, 0x17, 0x81, 0x8a, 0x81, 0x8e, + 0x80, 0x8b, 0x83, 0xb9, 0x30, 0x10, 0x82, 0x89, + 0x80, 0x89, 0x81, 0x9c, 0x82, 0xca, 0x28, 0x00, + 0x87, 0x91, 0x81, 0xbc, 0x01, 0x86, 0x91, 0x80, + 0xe2, 0x01, 0x28, 0x81, 0x8f, 0x80, 0x40, 0xa2, + 0x92, 0x88, 0x8a, 0x80, 0xa3, 0xed, 0x8b, 0x00, + 0x0b, 0x96, 0x1b, 0x10, 0x11, 0x32, 0x83, 0x8c, + 0x8b, 0x00, 0x89, 0x83, 0x46, 0x73, 0x81, 0x9d, + 0x81, 0x9d, 0x81, 0x9d, 0x81, 0xc1, 0x92, 0x40, + 0xbb, 0x81, 0xa1, 0x80, 0xf5, 0x8b, 0x83, 0x88, + 0x40, 0xdd, 0x84, 0xb8, 0x89, 0x81, 0x93, 0xc9, + 0x81, 0x8a, 0x82, 0xb0, 0x84, 0xaf, 0x8e, 0xbb, + 0x82, 0x9d, 0x88, 0x09, 0xb8, 0x8a, 0xb1, 0x92, + 0x41, 0xaf, 0x8d, 0x46, 0xc0, 0xb3, 0x48, 0xf5, + 0x9f, 0x60, 0x78, 0x73, 0x87, 0xa1, 0x81, 0x41, + 0x61, 0x07, 0x80, 0x96, 0x84, 0xd7, 0x81, 0xb1, + 0x8f, 0x00, 0xb8, 0x80, 0xa5, 0x84, 0x9b, 0x8b, + 0xac, 0x83, 0xaf, 0x8b, 0xa4, 0x80, 0xc2, 0x8d, + 0x8b, 0x07, 0x81, 0xac, 0x82, 0xb1, 0x00, 0x11, + 0x0c, 0x80, 0xab, 0x24, 0x80, 0x40, 0xec, 0x87, + 0x60, 0x4f, 0x32, 0x80, 0x48, 0x56, 0x84, 0x46, + 0x85, 0x10, 0x0c, 0x83, 0x43, 0x13, 0x83, 0x41, + 0x82, 0x81, 0x41, 0x52, 0x82, 0xb4, 0x8d, 0xac, + 0x81, 0x8a, 0x82, 0xac, 0x88, 0x88, 0x80, 0xbc, 0x82, 0xa3, 0x8b, 0x91, 0x81, 0xb8, 0x82, 0xaf, - 0x8c, 0x8d, 0x81, 0xdb, 0x88, 0x08, 0x28, 0x40, - 0x9f, 0x89, 0x96, 0x83, 0xb9, 0x31, 0x09, 0x81, - 0x89, 0x80, 0x89, 0x81, 0x40, 0xd0, 0x8c, 0x02, - 0xe9, 0x91, 0x40, 0xec, 0x31, 0x86, 0x9c, 0x81, - 0xd1, 0x8e, 0x00, 0xe9, 0x8a, 0xe6, 0x8d, 0x41, - 0x00, 0x8c, 0x40, 0xf6, 0x28, 0x09, 0x0a, 0x00, - 0x80, 0x40, 0x8d, 0x31, 0x2b, 0x80, 0x9b, 0x89, - 0xa9, 0x20, 0x83, 0x91, 0x8a, 0xad, 0x8d, 0x41, - 0x96, 0x38, 0x86, 0xd2, 0x95, 0x80, 0x8d, 0xf9, - 0x2a, 0x00, 0x08, 0x10, 0x02, 0x80, 0xc1, 0x20, - 0x08, 0x83, 0x41, 0x5b, 0x83, 0x60, 0x50, 0x57, - 0x00, 0xb6, 0x33, 0xdc, 0x81, 0x60, 0x4c, 0xab, - 0x80, 0x60, 0x23, 0x60, 0x30, 0x90, 0x0e, 0x01, - 0x04, 0x49, 0x1b, 0x80, 0x47, 0xe7, 0x99, 0x85, - 0x99, 0x85, 0x99, + 0x8c, 0x8d, 0x81, 0xdb, 0x88, 0x08, 0x28, 0x08, + 0x40, 0x9c, 0x89, 0x96, 0x83, 0xb9, 0x31, 0x09, + 0x81, 0x89, 0x80, 0x89, 0x81, 0x40, 0xd0, 0x8c, + 0x02, 0xe9, 0x91, 0x40, 0xec, 0x31, 0x86, 0x9c, + 0x81, 0xd1, 0x8e, 0x00, 0xe9, 0x8a, 0xe6, 0x8d, + 0x41, 0x00, 0x8c, 0x40, 0xf6, 0x28, 0x09, 0x0a, + 0x00, 0x80, 0x40, 0x8d, 0x31, 0x2b, 0x80, 0x9b, + 0x89, 0xa9, 0x20, 0x83, 0x91, 0x8a, 0xad, 0x8d, + 0x41, 0x96, 0x38, 0x86, 0xd2, 0x95, 0x80, 0x8d, + 0xf9, 0x2a, 0x00, 0x08, 0x10, 0x02, 0x80, 0xc1, + 0x20, 0x08, 0x83, 0x41, 0x5b, 0x83, 0x88, 0x08, + 0x80, 0xaf, 0x32, 0x82, 0x60, 0x50, 0x0d, 0x00, + 0xb6, 0x33, 0xdc, 0x81, 0x60, 0x4c, 0xab, 0x80, + 0x60, 0x23, 0x60, 0x30, 0x90, 0x0e, 0x01, 0x04, + 0xe3, 0x80, 0x48, 0xb6, 0x80, 0x47, 0xe7, 0x99, + 0x85, 0x99, 0x85, 0x99, }; -static const uint8_t unicode_prop_Other_Lowercase_table[51] = { +static const uint8_t unicode_prop_Other_Lowercase_table[69] = { 0x40, 0xa9, 0x80, 0x8e, 0x80, 0x41, 0xf4, 0x88, - 0x31, 0x9d, 0x84, 0xdf, 0x80, 0xb3, 0x80, 0x59, - 0xb0, 0xbe, 0x8c, 0x80, 0xa1, 0xa4, 0x42, 0xb0, - 0x80, 0x8c, 0x80, 0x8f, 0x8c, 0x40, 0xd2, 0x8f, - 0x43, 0x4f, 0x99, 0x47, 0x91, 0x81, 0x60, 0x7a, - 0x1d, 0x81, 0x40, 0xd1, 0x80, 0x40, 0x86, 0x81, - 0x43, 0x61, 0x83, + 0x31, 0x9d, 0x84, 0xdf, 0x80, 0xb3, 0x80, 0x4d, + 0x80, 0x80, 0x4c, 0x2e, 0xbe, 0x8c, 0x80, 0xa1, + 0xa4, 0x42, 0xb0, 0x80, 0x8c, 0x80, 0x8f, 0x8c, + 0x40, 0xd2, 0x8f, 0x43, 0x4f, 0x99, 0x47, 0x91, + 0x81, 0x60, 0x7a, 0x1d, 0x81, 0x40, 0xd1, 0x80, + 0x40, 0x80, 0x12, 0x81, 0x43, 0x61, 0x83, 0x88, + 0x80, 0x60, 0x5c, 0x15, 0x01, 0x10, 0xa9, 0x80, + 0x88, 0x60, 0xd8, 0x74, 0xbd, }; static const uint8_t unicode_prop_Other_Uppercase_table[15] = { @@ -3643,10 +3754,10 @@ static const uint8_t unicode_prop_Other_ID_Continue_table[12] = { 0x88, 0x46, 0x67, 0x80, }; -static const uint8_t unicode_prop_Prepended_Concatenation_Mark_table[17] = { +static const uint8_t unicode_prop_Prepended_Concatenation_Mark_table[19] = { 0x45, 0xff, 0x85, 0x40, 0xd6, 0x80, 0xb0, 0x80, - 0x41, 0xd1, 0x80, 0x61, 0x07, 0xd9, 0x80, 0x8e, - 0x80, + 0x41, 0x7f, 0x81, 0xcf, 0x80, 0x61, 0x07, 0xd9, + 0x80, 0x8e, 0x80, }; static const uint8_t unicode_prop_XID_Start1_table[31] = { @@ -3668,71 +3779,70 @@ static const uint8_t unicode_prop_Changes_When_Titlecased1_table[22] = { 0x8b, 0x80, 0x8e, 0x80, 0xae, 0x80, }; -static const uint8_t unicode_prop_Changes_When_Casefolded1_table[33] = { - 0x40, 0xde, 0x80, 0xcf, 0x80, 0x97, 0x80, 0x44, - 0x3c, 0x80, 0x59, 0x11, 0x80, 0x40, 0xe4, 0x3f, - 0x3f, 0x87, 0x89, 0x11, 0x05, 0x02, 0x11, 0x80, - 0xa9, 0x11, 0x80, 0x60, 0xdb, 0x07, 0x86, 0x8b, - 0x84, +static const uint8_t unicode_prop_Changes_When_Casefolded1_table[29] = { + 0x41, 0xef, 0x80, 0x41, 0x9e, 0x80, 0x9e, 0x80, + 0x5a, 0xe4, 0x83, 0x40, 0xb5, 0x00, 0x00, 0x00, + 0x80, 0xde, 0x06, 0x06, 0x80, 0x8a, 0x09, 0x81, + 0x89, 0x10, 0x81, 0x8d, 0x80, }; -static const uint8_t unicode_prop_Changes_When_NFKC_Casefolded1_table[441] = { +static const uint8_t unicode_prop_Changes_When_NFKC_Casefolded1_table[447] = { 0x40, 0x9f, 0x06, 0x00, 0x01, 0x00, 0x01, 0x12, - 0x10, 0x82, 0x9f, 0x80, 0xcf, 0x01, 0x80, 0x8b, - 0x07, 0x80, 0xfb, 0x01, 0x01, 0x80, 0xa5, 0x80, - 0x40, 0xbb, 0x88, 0x9e, 0x29, 0x84, 0xda, 0x08, - 0x81, 0x89, 0x80, 0xa3, 0x04, 0x02, 0x04, 0x08, - 0x80, 0xc9, 0x82, 0x9c, 0x80, 0x41, 0x93, 0x80, - 0x40, 0x93, 0x80, 0xd7, 0x83, 0x42, 0xde, 0x87, - 0xfb, 0x08, 0x80, 0xd2, 0x01, 0x80, 0xa1, 0x11, - 0x80, 0x40, 0xfc, 0x81, 0x42, 0xd4, 0x80, 0xfe, - 0x80, 0xa7, 0x81, 0xad, 0x80, 0xb5, 0x80, 0x88, - 0x03, 0x03, 0x03, 0x80, 0x8b, 0x80, 0x88, 0x00, - 0x26, 0x80, 0x90, 0x80, 0x88, 0x03, 0x03, 0x03, - 0x80, 0x8b, 0x80, 0x41, 0x41, 0x80, 0xe1, 0x81, - 0x46, 0x52, 0x81, 0xd4, 0x83, 0x45, 0x1c, 0x10, - 0x8a, 0x80, 0x91, 0x80, 0x9b, 0x8c, 0x80, 0xa1, - 0xa4, 0x40, 0xd9, 0x80, 0x40, 0xd5, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x3f, 0x3f, 0x87, - 0x89, 0x11, 0x04, 0x00, 0x29, 0x04, 0x12, 0x80, - 0x88, 0x12, 0x80, 0x88, 0x11, 0x11, 0x04, 0x08, - 0x8f, 0x00, 0x20, 0x8b, 0x12, 0x2a, 0x08, 0x0b, - 0x00, 0x07, 0x82, 0x8c, 0x06, 0x92, 0x81, 0x9a, - 0x80, 0x8c, 0x8a, 0x80, 0xd6, 0x18, 0x10, 0x8a, - 0x01, 0x0c, 0x0a, 0x00, 0x10, 0x11, 0x02, 0x06, - 0x05, 0x1c, 0x85, 0x8f, 0x8f, 0x8f, 0x88, 0x80, - 0x40, 0xa1, 0x08, 0x81, 0x40, 0xf7, 0x81, 0x41, - 0x34, 0xd5, 0x99, 0x9a, 0x45, 0x20, 0x80, 0xe6, - 0x82, 0xe4, 0x80, 0x41, 0x9e, 0x81, 0x40, 0xf0, - 0x80, 0x41, 0x2e, 0x80, 0xd2, 0x80, 0x8b, 0x40, - 0xd5, 0xa9, 0x80, 0xb4, 0x00, 0x82, 0xdf, 0x09, - 0x80, 0xde, 0x80, 0xb0, 0xdd, 0x82, 0x8d, 0xdf, - 0x9e, 0x80, 0xa7, 0x87, 0xae, 0x80, 0x41, 0x7f, - 0x60, 0x72, 0x9b, 0x81, 0x40, 0xd1, 0x80, 0x40, - 0x86, 0x81, 0x43, 0x61, 0x83, 0x88, 0x80, 0x60, + 0x10, 0x82, 0xf3, 0x80, 0x8b, 0x80, 0x40, 0x84, + 0x01, 0x01, 0x80, 0xa2, 0x01, 0x80, 0x40, 0xbb, + 0x88, 0x9e, 0x29, 0x84, 0xda, 0x08, 0x81, 0x89, + 0x80, 0xa3, 0x04, 0x02, 0x04, 0x08, 0x07, 0x80, + 0x9e, 0x80, 0xa0, 0x82, 0x9c, 0x80, 0x42, 0x28, + 0x80, 0xd7, 0x83, 0x42, 0xde, 0x87, 0xfb, 0x08, + 0x80, 0xd2, 0x01, 0x80, 0xa1, 0x11, 0x80, 0x40, + 0xfc, 0x81, 0x42, 0xd4, 0x80, 0xfe, 0x80, 0xa7, + 0x81, 0xad, 0x80, 0xb5, 0x80, 0x88, 0x03, 0x03, + 0x03, 0x80, 0x8b, 0x80, 0x88, 0x00, 0x26, 0x80, + 0x90, 0x80, 0x88, 0x03, 0x03, 0x03, 0x80, 0x8b, + 0x80, 0x41, 0x41, 0x80, 0xe1, 0x81, 0x46, 0x52, + 0x81, 0xd4, 0x84, 0x45, 0x1b, 0x10, 0x8a, 0x80, + 0x91, 0x80, 0x9b, 0x8c, 0x80, 0xa1, 0xa4, 0x40, + 0xd5, 0x83, 0x40, 0xb5, 0x00, 0x00, 0x00, 0x80, + 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0xb7, 0x05, 0x00, 0x13, 0x05, 0x11, 0x02, 0x0c, + 0x11, 0x00, 0x00, 0x0c, 0x15, 0x05, 0x08, 0x8f, + 0x00, 0x20, 0x8b, 0x12, 0x2a, 0x08, 0x0b, 0x00, + 0x07, 0x82, 0x8c, 0x06, 0x92, 0x81, 0x9a, 0x80, + 0x8c, 0x8a, 0x80, 0xd6, 0x18, 0x10, 0x8a, 0x01, + 0x0c, 0x0a, 0x00, 0x10, 0x11, 0x02, 0x06, 0x05, + 0x1c, 0x85, 0x8f, 0x8f, 0x8f, 0x88, 0x80, 0x40, + 0xa1, 0x08, 0x81, 0x40, 0xf7, 0x81, 0x41, 0x34, + 0xd5, 0x99, 0x9a, 0x45, 0x20, 0x80, 0xe6, 0x82, + 0xe4, 0x80, 0x41, 0x9e, 0x81, 0x40, 0xf0, 0x80, + 0x41, 0x2e, 0x80, 0xd2, 0x80, 0x8b, 0x40, 0xd5, + 0xa9, 0x80, 0xb4, 0x00, 0x82, 0xdf, 0x09, 0x80, + 0xde, 0x80, 0xb0, 0xdd, 0x82, 0x8d, 0xdf, 0x9e, + 0x80, 0xa7, 0x87, 0xae, 0x80, 0x41, 0x7f, 0x60, + 0x72, 0x9b, 0x81, 0x40, 0xd1, 0x80, 0x40, 0x80, + 0x12, 0x81, 0x43, 0x61, 0x83, 0x88, 0x80, 0x60, 0x4d, 0x95, 0x41, 0x0d, 0x08, 0x00, 0x81, 0x89, - 0x00, 0x00, 0x09, 0x82, 0xc3, 0x81, 0xe9, 0xa5, - 0x86, 0x8b, 0x24, 0x00, 0x97, 0x04, 0x00, 0x01, - 0x01, 0x80, 0xeb, 0xa0, 0x41, 0x6a, 0x91, 0xbf, - 0x81, 0xb5, 0xa7, 0x8c, 0x82, 0x99, 0x95, 0x94, - 0x81, 0x8b, 0x80, 0x92, 0x03, 0x1a, 0x00, 0x80, - 0x40, 0x86, 0x08, 0x80, 0x9f, 0x99, 0x40, 0x83, - 0x15, 0x0d, 0x0d, 0x0a, 0x16, 0x06, 0x80, 0x88, - 0x60, 0xbc, 0xa6, 0x83, 0x54, 0xb9, 0x86, 0x8d, - 0x87, 0xbf, 0x85, 0x42, 0x3e, 0xd4, 0x80, 0xc6, - 0x01, 0x08, 0x09, 0x0b, 0x80, 0x8b, 0x00, 0x06, - 0x80, 0xc0, 0x03, 0x0f, 0x06, 0x80, 0x9b, 0x03, - 0x04, 0x00, 0x16, 0x80, 0x41, 0x53, 0x81, 0x41, - 0x23, 0x81, 0xb1, 0x55, 0xff, 0x18, 0x9a, 0x01, - 0x00, 0x08, 0x80, 0x89, 0x03, 0x00, 0x00, 0x28, - 0x18, 0x00, 0x00, 0x02, 0x01, 0x00, 0x08, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x0b, 0x06, 0x03, - 0x03, 0x00, 0x80, 0x89, 0x80, 0x90, 0x22, 0x04, - 0x80, 0x90, 0x42, 0x43, 0x8a, 0x84, 0x9e, 0x80, - 0x9f, 0x99, 0x82, 0xa2, 0x80, 0xee, 0x82, 0x8c, - 0xab, 0x83, 0x88, 0x31, 0x49, 0x9d, 0x89, 0x60, - 0xfc, 0x05, 0x42, 0x1d, 0x6b, 0x05, 0xe1, 0x4f, - 0xff, + 0x00, 0x00, 0x09, 0x82, 0xc3, 0x81, 0xe9, 0xc2, + 0x00, 0x97, 0x04, 0x00, 0x01, 0x01, 0x80, 0xeb, + 0xa0, 0x41, 0x6a, 0x91, 0xbf, 0x81, 0xb5, 0xa7, + 0x8c, 0x82, 0x99, 0x95, 0x94, 0x81, 0x8b, 0x80, + 0x92, 0x03, 0x1a, 0x00, 0x80, 0x40, 0x86, 0x08, + 0x80, 0x9f, 0x99, 0x40, 0x83, 0x15, 0x0d, 0x0d, + 0x0a, 0x16, 0x06, 0x80, 0x88, 0x47, 0x87, 0x20, + 0xa9, 0x80, 0x88, 0x60, 0xb4, 0xe4, 0x83, 0x54, + 0xb9, 0x86, 0x8d, 0x87, 0xbf, 0x85, 0x42, 0x3e, + 0xd4, 0x80, 0xc6, 0x01, 0x08, 0x09, 0x0b, 0x80, + 0x8b, 0x00, 0x06, 0x80, 0xc0, 0x03, 0x0f, 0x06, + 0x80, 0x9b, 0x03, 0x04, 0x00, 0x16, 0x80, 0x41, + 0x53, 0x81, 0x41, 0x23, 0x81, 0xb1, 0x48, 0x2f, + 0xbd, 0x4d, 0x91, 0x18, 0x9a, 0x01, 0x00, 0x08, + 0x80, 0x89, 0x03, 0x00, 0x00, 0x28, 0x18, 0x00, + 0x00, 0x02, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x0b, 0x06, 0x03, 0x03, 0x00, + 0x80, 0x89, 0x80, 0x90, 0x22, 0x04, 0x80, 0x90, + 0x42, 0x43, 0x8a, 0x84, 0x9e, 0x80, 0x9f, 0x99, + 0x82, 0xa2, 0x80, 0xee, 0x82, 0x8c, 0xab, 0x83, + 0x88, 0x31, 0x49, 0x9d, 0x89, 0x60, 0xfc, 0x05, + 0x42, 0x1d, 0x6b, 0x05, 0xe1, 0x4f, 0xff, }; static const uint8_t unicode_prop_ASCII_Hex_Digit_table[5] = { @@ -3744,14 +3854,14 @@ static const uint8_t unicode_prop_Bidi_Control_table[10] = { 0xb6, 0x83, }; -static const uint8_t unicode_prop_Dash_table[53] = { +static const uint8_t unicode_prop_Dash_table[55] = { 0xac, 0x80, 0x45, 0x5b, 0x80, 0xb2, 0x80, 0x4e, 0x40, 0x80, 0x44, 0x04, 0x80, 0x48, 0x08, 0x85, 0xbc, 0x80, 0xa6, 0x80, 0x8e, 0x80, 0x41, 0x85, 0x80, 0x4c, 0x03, 0x01, 0x80, 0x9e, 0x0b, 0x80, - 0x41, 0xda, 0x80, 0x92, 0x80, 0xee, 0x80, 0x60, - 0xcd, 0x8f, 0x81, 0xa4, 0x80, 0x89, 0x80, 0x40, - 0xa8, 0x80, 0x4f, 0x9e, 0x80, + 0x9b, 0x80, 0x41, 0xbd, 0x80, 0x92, 0x80, 0xee, + 0x80, 0x60, 0xcd, 0x8f, 0x81, 0xa4, 0x80, 0x89, + 0x80, 0x40, 0xa8, 0x80, 0x4f, 0x9e, 0x80, }; static const uint8_t unicode_prop_Deprecated_table[23] = { @@ -3760,55 +3870,60 @@ static const uint8_t unicode_prop_Deprecated_table[23] = { 0x42, 0xb8, 0x81, 0x6d, 0xdc, 0xd5, 0x80, }; -static const uint8_t unicode_prop_Diacritic_table[358] = { +static const uint8_t unicode_prop_Diacritic_table[399] = { 0xdd, 0x00, 0x80, 0xc6, 0x05, 0x03, 0x01, 0x81, 0x41, 0xf6, 0x40, 0x9e, 0x07, 0x25, 0x90, 0x0b, 0x80, 0x88, 0x81, 0x40, 0xfc, 0x84, 0x40, 0xd0, 0x80, 0xb6, 0x90, 0x80, 0x9a, 0x00, 0x01, 0x00, 0x40, 0x85, 0x3b, 0x81, 0x40, 0x85, 0x0b, 0x0a, 0x82, 0xc2, 0x9a, 0xda, 0x8a, 0xb9, 0x8a, 0xa1, - 0x81, 0x40, 0xc8, 0x9b, 0xbc, 0x80, 0x8f, 0x02, - 0x83, 0x9b, 0x80, 0xc9, 0x80, 0x8f, 0x80, 0xed, - 0x80, 0x8f, 0x80, 0xed, 0x80, 0x8f, 0x80, 0xae, - 0x82, 0xbb, 0x80, 0x8f, 0x06, 0x80, 0xf6, 0x80, - 0xfe, 0x80, 0xed, 0x80, 0x8f, 0x80, 0xec, 0x81, - 0x8f, 0x80, 0xfb, 0x80, 0xfb, 0x28, 0x80, 0xea, - 0x80, 0x8c, 0x84, 0xca, 0x81, 0x9a, 0x00, 0x00, - 0x03, 0x81, 0xc1, 0x10, 0x81, 0xbd, 0x80, 0xef, - 0x00, 0x81, 0xa7, 0x0b, 0x84, 0x98, 0x30, 0x80, - 0x89, 0x81, 0x42, 0xc0, 0x82, 0x44, 0x68, 0x8a, + 0x81, 0xfd, 0x87, 0xa8, 0x89, 0x8f, 0x9b, 0xbc, + 0x80, 0x8f, 0x02, 0x83, 0x9b, 0x80, 0xc9, 0x80, + 0x8f, 0x80, 0xed, 0x80, 0x8f, 0x80, 0xed, 0x80, + 0x8f, 0x80, 0xae, 0x82, 0xbb, 0x80, 0x8f, 0x06, + 0x80, 0xf6, 0x80, 0xed, 0x80, 0x8f, 0x80, 0xed, + 0x80, 0x8f, 0x80, 0xec, 0x81, 0x8f, 0x80, 0xfb, + 0x80, 0xfb, 0x28, 0x80, 0xea, 0x80, 0x8c, 0x84, + 0xca, 0x81, 0x9a, 0x00, 0x00, 0x03, 0x81, 0xc1, + 0x10, 0x81, 0xbd, 0x80, 0xef, 0x00, 0x81, 0xa7, + 0x0b, 0x84, 0x98, 0x30, 0x80, 0x89, 0x81, 0x42, + 0xc0, 0x82, 0x43, 0xb3, 0x81, 0x40, 0xb2, 0x8a, 0x88, 0x80, 0x41, 0x5a, 0x82, 0x41, 0x38, 0x39, - 0x80, 0xaf, 0x8d, 0xf5, 0x80, 0x8e, 0x80, 0xa5, - 0x88, 0xb5, 0x81, 0x40, 0x89, 0x81, 0xbf, 0x85, - 0xd1, 0x98, 0x18, 0x28, 0x0a, 0xb1, 0xbe, 0xd8, - 0x8b, 0xa4, 0x22, 0x82, 0x41, 0xbc, 0x00, 0x82, - 0x8a, 0x82, 0x8c, 0x82, 0x8c, 0x82, 0x8c, 0x81, - 0x4c, 0xef, 0x82, 0x41, 0x3c, 0x80, 0x41, 0xf9, - 0x85, 0xe8, 0x83, 0xde, 0x80, 0x60, 0x75, 0x71, - 0x80, 0x8b, 0x08, 0x80, 0x9b, 0x81, 0xd1, 0x81, - 0x8d, 0xa1, 0xe5, 0x82, 0xec, 0x81, 0x40, 0xc9, - 0x80, 0x9a, 0x91, 0xb8, 0x83, 0xa3, 0x80, 0xde, - 0x80, 0x8b, 0x80, 0xa3, 0x80, 0x40, 0x94, 0x82, - 0xc0, 0x83, 0xb2, 0x80, 0xe3, 0x84, 0x88, 0x82, - 0xff, 0x81, 0x60, 0x4f, 0x2f, 0x80, 0x43, 0x00, - 0x8f, 0x41, 0x0d, 0x00, 0x80, 0xae, 0x80, 0xac, - 0x81, 0xc2, 0x80, 0x42, 0xfb, 0x80, 0x48, 0x03, - 0x81, 0x42, 0x3a, 0x85, 0x42, 0x1d, 0x8a, 0x41, - 0x67, 0x81, 0xf7, 0x81, 0xbd, 0x80, 0xcb, 0x80, - 0x88, 0x82, 0xe7, 0x81, 0x40, 0xb1, 0x81, 0xd0, - 0x80, 0x8f, 0x80, 0x97, 0x32, 0x84, 0x40, 0xcc, - 0x02, 0x80, 0xfa, 0x81, 0x40, 0xfa, 0x81, 0xfd, - 0x80, 0xf5, 0x81, 0xf2, 0x80, 0x41, 0x0c, 0x81, - 0x41, 0x01, 0x0b, 0x80, 0x40, 0x9b, 0x80, 0xd2, - 0x80, 0x91, 0x80, 0xd0, 0x80, 0x41, 0xa4, 0x80, - 0x41, 0x01, 0x00, 0x81, 0xd0, 0x80, 0x60, 0x4d, - 0x57, 0x84, 0xba, 0x86, 0x44, 0x57, 0x90, 0xcf, - 0x81, 0x60, 0x61, 0x74, 0x12, 0x2f, 0x39, 0x86, - 0x9d, 0x83, 0x4f, 0x81, 0x86, 0x41, 0xb4, 0x83, - 0x45, 0xdf, 0x86, 0xec, 0x10, 0x82, + 0x80, 0xaf, 0x8e, 0x81, 0x8a, 0xe7, 0x80, 0x8e, + 0x80, 0xa5, 0x88, 0xb5, 0x81, 0x40, 0x89, 0x81, + 0xbf, 0x85, 0xd1, 0x98, 0x18, 0x28, 0x0a, 0xb1, + 0xbe, 0xd8, 0x8b, 0xa4, 0x8a, 0x41, 0xbc, 0x00, + 0x82, 0x8a, 0x82, 0x8c, 0x82, 0x8c, 0x82, 0x8c, + 0x81, 0x4c, 0xef, 0x82, 0x41, 0x3c, 0x80, 0x41, + 0xf9, 0x85, 0xe8, 0x83, 0xde, 0x80, 0x60, 0x75, + 0x71, 0x80, 0x8b, 0x08, 0x80, 0x9b, 0x81, 0xd1, + 0x81, 0x8d, 0xa1, 0xe5, 0x82, 0xec, 0x81, 0x40, + 0xc9, 0x80, 0x9a, 0x91, 0xb8, 0x83, 0xa3, 0x80, + 0xde, 0x80, 0x8b, 0x80, 0xa3, 0x80, 0x40, 0x94, + 0x82, 0xc0, 0x83, 0xb2, 0x80, 0xe3, 0x84, 0x88, + 0x82, 0xff, 0x81, 0x60, 0x4f, 0x2f, 0x80, 0x43, + 0x00, 0x8f, 0x41, 0x0d, 0x00, 0x80, 0xae, 0x80, + 0xac, 0x81, 0xc2, 0x80, 0x42, 0xfb, 0x80, 0x44, + 0x9e, 0x28, 0xa9, 0x80, 0x88, 0x43, 0x29, 0x81, + 0x42, 0x3a, 0x85, 0x41, 0xd4, 0x82, 0xc5, 0x8a, + 0xb0, 0x83, 0x40, 0xbf, 0x80, 0xa8, 0x80, 0xc7, + 0x81, 0xf7, 0x81, 0xbd, 0x80, 0xcb, 0x80, 0x88, + 0x82, 0xe7, 0x81, 0x40, 0xb1, 0x81, 0xd0, 0x80, + 0x8f, 0x80, 0x97, 0x32, 0x84, 0x40, 0xcc, 0x02, + 0x80, 0xfa, 0x81, 0x40, 0xfa, 0x81, 0xfd, 0x80, + 0xf5, 0x81, 0xf2, 0x80, 0x41, 0x0c, 0x81, 0x41, + 0x01, 0x0b, 0x80, 0x40, 0x9b, 0x80, 0xd2, 0x80, + 0x91, 0x80, 0xd0, 0x80, 0x41, 0xa4, 0x80, 0x41, + 0x01, 0x00, 0x81, 0xd0, 0x80, 0x56, 0xae, 0x8e, + 0x60, 0x36, 0x99, 0x84, 0xba, 0x86, 0x44, 0x57, + 0x90, 0xcf, 0x81, 0x60, 0x3f, 0xfd, 0x18, 0x30, + 0x81, 0x5f, 0x00, 0xad, 0x81, 0x96, 0x42, 0x1f, + 0x12, 0x2f, 0x39, 0x86, 0x9d, 0x83, 0x4e, 0x81, + 0xbd, 0x40, 0xc1, 0x86, 0x41, 0x76, 0x80, 0xbc, + 0x83, 0x45, 0xdf, 0x86, 0xec, 0x10, 0x82, }; -static const uint8_t unicode_prop_Extender_table[89] = { +static const uint8_t unicode_prop_Extender_table[92] = { 0x40, 0xb6, 0x80, 0x42, 0x17, 0x81, 0x43, 0x6d, 0x80, 0x41, 0xb8, 0x80, 0x43, 0x59, 0x80, 0x42, 0xef, 0x80, 0xfe, 0x80, 0x49, 0x42, 0x80, 0xb7, @@ -3817,10 +3932,10 @@ static const uint8_t unicode_prop_Extender_table[89] = { 0xdc, 0x82, 0x60, 0x6f, 0x15, 0x80, 0x45, 0xf5, 0x80, 0x43, 0xc1, 0x80, 0x95, 0x80, 0x40, 0x88, 0x80, 0xeb, 0x80, 0x94, 0x81, 0x60, 0x54, 0x7a, - 0x80, 0x53, 0xeb, 0x80, 0x42, 0x67, 0x82, 0x44, - 0xce, 0x80, 0x60, 0x50, 0xa8, 0x81, 0x44, 0x9b, - 0x08, 0x80, 0x60, 0x71, 0x57, 0x81, 0x48, 0x05, - 0x82, + 0x80, 0x48, 0x0f, 0x81, 0x4b, 0xd9, 0x80, 0x42, + 0x67, 0x82, 0x44, 0xce, 0x80, 0x60, 0x50, 0xa8, + 0x81, 0x44, 0x9b, 0x08, 0x80, 0x60, 0x71, 0x57, + 0x81, 0x48, 0x05, 0x82, }; static const uint8_t unicode_prop_Hex_Digit_table[12] = { @@ -3836,16 +3951,16 @@ static const uint8_t unicode_prop_IDS_Trinary_Operator_table[4] = { 0x60, 0x2f, 0xf1, 0x81, }; -static const uint8_t unicode_prop_Ideographic_table[66] = { +static const uint8_t unicode_prop_Ideographic_table[69] = { 0x60, 0x30, 0x05, 0x81, 0x98, 0x88, 0x8d, 0x82, - 0x43, 0xc4, 0x59, 0xbf, 0xbf, 0x60, 0x51, 0xfc, - 0x60, 0x59, 0x02, 0x41, 0x6d, 0x81, 0xe9, 0x60, + 0x43, 0xc4, 0x59, 0xbf, 0xbf, 0x60, 0x51, 0xff, + 0x60, 0x58, 0xff, 0x41, 0x6d, 0x81, 0xe9, 0x60, 0x75, 0x09, 0x80, 0x9a, 0x57, 0xf7, 0x87, 0x44, 0xd5, 0xa9, 0x88, 0x60, 0x24, 0x66, 0x41, 0x8b, - 0x60, 0x4d, 0x03, 0x60, 0xa6, 0xdd, 0xa1, 0x50, - 0x34, 0x8a, 0x40, 0xdd, 0x81, 0x56, 0x81, 0x8d, + 0x60, 0x4d, 0x03, 0x60, 0xa6, 0xdf, 0x9f, 0x50, + 0x39, 0x85, 0x40, 0xdd, 0x81, 0x56, 0x81, 0x8d, 0x5d, 0x30, 0x4c, 0x1e, 0x42, 0x1d, 0x45, 0xe1, - 0x53, 0x4a, + 0x53, 0x4a, 0x84, 0x50, 0x5f, }; static const uint8_t unicode_prop_Join_Control_table[4] = { @@ -3901,34 +4016,35 @@ static const uint8_t unicode_prop_Regional_Indicator_table[4] = { 0x61, 0xf1, 0xe5, 0x99, }; -static const uint8_t unicode_prop_Sentence_Terminal_table[188] = { +static const uint8_t unicode_prop_Sentence_Terminal_table[196] = { 0xa0, 0x80, 0x8b, 0x80, 0x8f, 0x80, 0x45, 0x48, - 0x80, 0x40, 0x93, 0x81, 0x40, 0xb3, 0x80, 0xaa, + 0x80, 0x40, 0x92, 0x82, 0x40, 0xb3, 0x80, 0xaa, 0x82, 0x40, 0xf5, 0x80, 0xbc, 0x00, 0x02, 0x81, 0x41, 0x24, 0x81, 0x46, 0xe3, 0x81, 0x43, 0x15, 0x03, 0x81, 0x43, 0x04, 0x80, 0x40, 0xc5, 0x81, 0x40, 0xcb, 0x04, 0x80, 0x41, 0x39, 0x81, 0x41, - 0x61, 0x83, 0x40, 0xad, 0x09, 0x81, 0x40, 0xda, - 0x81, 0xc0, 0x81, 0x43, 0xbb, 0x81, 0x88, 0x82, - 0x4d, 0xe3, 0x80, 0x8c, 0x80, 0x41, 0xc4, 0x80, - 0x60, 0x74, 0xfb, 0x80, 0x41, 0x0d, 0x81, 0x40, - 0xe2, 0x02, 0x80, 0x41, 0x7d, 0x81, 0xd5, 0x81, - 0xde, 0x80, 0x40, 0x97, 0x81, 0x40, 0x92, 0x82, - 0x40, 0x8f, 0x81, 0x40, 0xf8, 0x80, 0x60, 0x52, - 0x65, 0x02, 0x81, 0x40, 0xa8, 0x80, 0x8b, 0x80, - 0x8f, 0x80, 0xc0, 0x80, 0x4a, 0xf3, 0x81, 0x44, - 0xfc, 0x84, 0x40, 0xec, 0x81, 0xf4, 0x83, 0xfe, - 0x82, 0x40, 0x80, 0x0d, 0x80, 0x8f, 0x81, 0xd7, - 0x08, 0x81, 0xeb, 0x80, 0x41, 0xa0, 0x81, 0x41, - 0x74, 0x0c, 0x8e, 0xe8, 0x81, 0x40, 0xf8, 0x82, - 0x42, 0x04, 0x00, 0x80, 0x40, 0xfa, 0x81, 0xd6, - 0x81, 0x41, 0xa3, 0x81, 0x42, 0xb3, 0x81, 0x60, - 0x4b, 0x74, 0x81, 0x40, 0x84, 0x80, 0xc0, 0x81, + 0x61, 0x83, 0x40, 0xad, 0x09, 0x81, 0x9c, 0x81, + 0x40, 0xbb, 0x81, 0xc0, 0x81, 0x43, 0xbb, 0x81, + 0x88, 0x82, 0x4d, 0xe3, 0x80, 0x8c, 0x80, 0x95, + 0x81, 0x41, 0xac, 0x80, 0x60, 0x74, 0xfb, 0x80, + 0x41, 0x0d, 0x81, 0x40, 0xe2, 0x02, 0x80, 0x41, + 0x7d, 0x81, 0xd5, 0x81, 0xde, 0x80, 0x40, 0x97, + 0x81, 0x40, 0x92, 0x82, 0x40, 0x8f, 0x81, 0x40, + 0xf8, 0x80, 0x60, 0x52, 0x65, 0x02, 0x81, 0x40, + 0xa8, 0x80, 0x8b, 0x80, 0x8f, 0x80, 0xc0, 0x80, + 0x4a, 0xf3, 0x81, 0x44, 0xfc, 0x84, 0xab, 0x83, + 0x40, 0xbc, 0x81, 0xf4, 0x83, 0xfe, 0x82, 0x40, + 0x80, 0x0d, 0x80, 0x8f, 0x81, 0xd7, 0x08, 0x81, + 0xeb, 0x80, 0x41, 0xa0, 0x81, 0x41, 0x74, 0x0c, + 0x8e, 0xe8, 0x81, 0x40, 0xf8, 0x82, 0x42, 0x04, + 0x00, 0x80, 0x40, 0xfa, 0x81, 0xd6, 0x81, 0x41, + 0xa3, 0x81, 0x42, 0xb3, 0x81, 0xc9, 0x81, 0x60, + 0x4b, 0x28, 0x81, 0x40, 0x84, 0x80, 0xc0, 0x81, 0x8a, 0x80, 0x43, 0x52, 0x80, 0x60, 0x4e, 0x05, 0x80, 0x5d, 0xe7, 0x80, }; -static const uint8_t unicode_prop_Soft_Dotted_table[71] = { +static const uint8_t unicode_prop_Soft_Dotted_table[79] = { 0xe8, 0x81, 0x40, 0xc3, 0x80, 0x41, 0x18, 0x80, 0x9d, 0x80, 0xb3, 0x80, 0x93, 0x80, 0x41, 0x3f, 0x80, 0xe1, 0x00, 0x80, 0x59, 0x08, 0x80, 0xb2, @@ -3937,55 +4053,56 @@ static const uint8_t unicode_prop_Soft_Dotted_table[71] = { 0x4b, 0x31, 0x80, 0x61, 0xa7, 0xa4, 0x81, 0xb1, 0x81, 0xb1, 0x81, 0xb1, 0x81, 0xb1, 0x81, 0xb1, 0x81, 0xb1, 0x81, 0xb1, 0x81, 0xb1, 0x81, 0xb1, - 0x81, 0xb1, 0x81, 0xb1, 0x81, 0xb1, 0x81, + 0x81, 0xb1, 0x81, 0xb1, 0x81, 0xb1, 0x81, 0x48, + 0x85, 0x80, 0x41, 0x30, 0x81, 0x99, 0x80, }; -static const uint8_t unicode_prop_Terminal_Punctuation_table[241] = { +static const uint8_t unicode_prop_Terminal_Punctuation_table[248] = { 0xa0, 0x80, 0x89, 0x00, 0x80, 0x8a, 0x0a, 0x80, 0x43, 0x3d, 0x07, 0x80, 0x42, 0x00, 0x80, 0xb8, - 0x80, 0xc7, 0x80, 0x8d, 0x01, 0x81, 0x40, 0xb3, + 0x80, 0xc7, 0x80, 0x8d, 0x00, 0x82, 0x40, 0xb3, 0x80, 0xaa, 0x8a, 0x00, 0x40, 0xea, 0x81, 0xb5, 0x8e, 0x9e, 0x80, 0x41, 0x04, 0x81, 0x44, 0xf3, 0x81, 0x40, 0xab, 0x03, 0x85, 0x41, 0x36, 0x81, 0x43, 0x14, 0x87, 0x43, 0x04, 0x80, 0xfb, 0x82, 0xc6, 0x81, 0x40, 0x9c, 0x12, 0x80, 0xa6, 0x19, 0x81, 0x41, 0x39, 0x81, 0x41, 0x61, 0x83, 0x40, - 0xad, 0x08, 0x82, 0x40, 0xda, 0x84, 0xbd, 0x81, - 0x43, 0xbb, 0x81, 0x88, 0x82, 0x4d, 0xe3, 0x80, - 0x8c, 0x03, 0x80, 0x89, 0x00, 0x81, 0x41, 0xb0, - 0x81, 0x60, 0x74, 0xfa, 0x81, 0x41, 0x0c, 0x82, - 0x40, 0xe2, 0x84, 0x41, 0x7d, 0x81, 0xd5, 0x81, - 0xde, 0x80, 0x40, 0x96, 0x82, 0x40, 0x92, 0x82, - 0xfe, 0x80, 0x8f, 0x81, 0x40, 0xf8, 0x80, 0x60, - 0x52, 0x63, 0x10, 0x83, 0x40, 0xa8, 0x80, 0x89, - 0x00, 0x80, 0x8a, 0x0a, 0x80, 0xc0, 0x01, 0x80, - 0x44, 0x39, 0x80, 0xaf, 0x80, 0x44, 0x85, 0x80, - 0x40, 0xc6, 0x80, 0x41, 0x35, 0x81, 0x40, 0x97, - 0x85, 0xc3, 0x85, 0xd8, 0x83, 0x43, 0xb7, 0x84, - 0x40, 0xec, 0x86, 0xef, 0x83, 0xfe, 0x82, 0x40, - 0x80, 0x0d, 0x80, 0x8f, 0x81, 0xd7, 0x84, 0xeb, - 0x80, 0x41, 0xa0, 0x82, 0x8b, 0x81, 0x41, 0x65, - 0x1a, 0x8e, 0xe8, 0x81, 0x40, 0xf8, 0x82, 0x42, - 0x04, 0x00, 0x80, 0x40, 0xfa, 0x81, 0xd6, 0x0b, - 0x81, 0x41, 0x9d, 0x82, 0xac, 0x80, 0x42, 0x84, - 0x81, 0x45, 0x76, 0x84, 0x60, 0x45, 0xf8, 0x81, - 0x40, 0x84, 0x80, 0xc0, 0x82, 0x89, 0x80, 0x43, - 0x51, 0x81, 0x60, 0x4e, 0x05, 0x80, 0x5d, 0xe6, - 0x83, + 0xad, 0x08, 0x82, 0x9c, 0x81, 0x40, 0xbb, 0x84, + 0xbd, 0x81, 0x43, 0xbb, 0x81, 0x88, 0x82, 0x4d, + 0xe3, 0x80, 0x8c, 0x03, 0x80, 0x89, 0x00, 0x0a, + 0x81, 0x41, 0xab, 0x81, 0x60, 0x74, 0xfa, 0x81, + 0x41, 0x0c, 0x82, 0x40, 0xe2, 0x84, 0x41, 0x7d, + 0x81, 0xd5, 0x81, 0xde, 0x80, 0x40, 0x96, 0x82, + 0x40, 0x92, 0x82, 0xfe, 0x80, 0x8f, 0x81, 0x40, + 0xf8, 0x80, 0x60, 0x52, 0x63, 0x10, 0x83, 0x40, + 0xa8, 0x80, 0x89, 0x00, 0x80, 0x8a, 0x0a, 0x80, + 0xc0, 0x01, 0x80, 0x44, 0x39, 0x80, 0xaf, 0x80, + 0x44, 0x85, 0x80, 0x40, 0xc6, 0x80, 0x41, 0x35, + 0x81, 0x40, 0x97, 0x85, 0xc3, 0x85, 0xd8, 0x83, + 0x43, 0xb7, 0x84, 0xab, 0x83, 0x40, 0xbc, 0x86, + 0xef, 0x83, 0xfe, 0x82, 0x40, 0x80, 0x0d, 0x80, + 0x8f, 0x81, 0xd7, 0x84, 0xeb, 0x80, 0x41, 0xa0, + 0x82, 0x8b, 0x81, 0x41, 0x65, 0x1a, 0x8e, 0xe8, + 0x81, 0x40, 0xf8, 0x82, 0x42, 0x04, 0x00, 0x80, + 0x40, 0xfa, 0x81, 0xd6, 0x0b, 0x81, 0x41, 0x9d, + 0x82, 0xac, 0x80, 0x42, 0x84, 0x81, 0xc9, 0x81, + 0x45, 0x2a, 0x84, 0x60, 0x45, 0xf8, 0x81, 0x40, + 0x84, 0x80, 0xc0, 0x82, 0x89, 0x80, 0x43, 0x51, + 0x81, 0x60, 0x4e, 0x05, 0x80, 0x5d, 0xe6, 0x83, }; -static const uint8_t unicode_prop_Unified_Ideograph_table[42] = { +static const uint8_t unicode_prop_Unified_Ideograph_table[45] = { 0x60, 0x33, 0xff, 0x59, 0xbf, 0xbf, 0x60, 0x51, - 0xfc, 0x60, 0x5a, 0x10, 0x08, 0x00, 0x81, 0x89, + 0xff, 0x60, 0x5a, 0x0d, 0x08, 0x00, 0x81, 0x89, 0x00, 0x00, 0x09, 0x82, 0x61, 0x05, 0xd5, 0x60, - 0xa6, 0xdd, 0xa1, 0x50, 0x34, 0x8a, 0x40, 0xdd, + 0xa6, 0xdf, 0x9f, 0x50, 0x39, 0x85, 0x40, 0xdd, 0x81, 0x56, 0x81, 0x8d, 0x5d, 0x30, 0x54, 0x1e, - 0x53, 0x4a, + 0x53, 0x4a, 0x84, 0x50, 0x5f, }; -static const uint8_t unicode_prop_Variation_Selector_table[12] = { - 0x58, 0x0a, 0x82, 0x60, 0xe5, 0xf1, 0x8f, 0x6d, - 0x02, 0xef, 0x40, 0xef, +static const uint8_t unicode_prop_Variation_Selector_table[13] = { + 0x58, 0x0a, 0x10, 0x80, 0x60, 0xe5, 0xef, 0x8f, + 0x6d, 0x02, 0xef, 0x40, 0xef, }; static const uint8_t unicode_prop_White_Space_table[22] = { @@ -3994,7 +4111,7 @@ static const uint8_t unicode_prop_White_Space_table[22] = { 0x80, 0xae, 0x80, 0x4f, 0x9f, 0x80, }; -static const uint8_t unicode_prop_Bidi_Mirrored_table[171] = { +static const uint8_t unicode_prop_Bidi_Mirrored_table[173] = { 0xa7, 0x81, 0x91, 0x00, 0x80, 0x9b, 0x00, 0x80, 0x9c, 0x00, 0x80, 0xac, 0x80, 0x8e, 0x80, 0x4e, 0x7d, 0x83, 0x47, 0x5c, 0x81, 0x49, 0x9b, 0x81, @@ -4012,14 +4129,14 @@ static const uint8_t unicode_prop_Bidi_Mirrored_table[171] = { 0x09, 0x0b, 0xaa, 0x0f, 0x80, 0xa7, 0x20, 0x00, 0x14, 0x22, 0x18, 0x14, 0x00, 0x40, 0xff, 0x80, 0x42, 0x02, 0x1a, 0x08, 0x81, 0x8d, 0x09, 0x89, - 0x41, 0xdd, 0x89, 0x0f, 0x60, 0xce, 0x3c, 0x2c, - 0x81, 0x40, 0xa1, 0x81, 0x91, 0x00, 0x80, 0x9b, - 0x00, 0x80, 0x9c, 0x00, 0x00, 0x08, 0x81, 0x60, - 0xd7, 0x76, 0x80, 0xb8, 0x80, 0xb8, 0x80, 0xb8, - 0x80, 0xb8, 0x80, + 0xaa, 0x87, 0x41, 0xaa, 0x89, 0x0f, 0x60, 0xce, + 0x3c, 0x2c, 0x81, 0x40, 0xa1, 0x81, 0x91, 0x00, + 0x80, 0x9b, 0x00, 0x80, 0x9c, 0x00, 0x00, 0x08, + 0x81, 0x60, 0xd7, 0x76, 0x80, 0xb8, 0x80, 0xb8, + 0x80, 0xb8, 0x80, 0xb8, 0x80, }; -static const uint8_t unicode_prop_Emoji_table[238] = { +static const uint8_t unicode_prop_Emoji_table[239] = { 0xa2, 0x05, 0x04, 0x89, 0xee, 0x03, 0x80, 0x5f, 0x8c, 0x80, 0x8b, 0x80, 0x40, 0xd7, 0x80, 0x95, 0x80, 0xd9, 0x85, 0x8e, 0x81, 0x41, 0x6e, 0x81, @@ -4045,11 +4162,11 @@ static const uint8_t unicode_prop_Emoji_table[238] = { 0xbe, 0x8a, 0x28, 0x97, 0x31, 0x0f, 0x8b, 0x01, 0x19, 0x03, 0x81, 0x8c, 0x09, 0x07, 0x81, 0x88, 0x04, 0x82, 0x8b, 0x17, 0x11, 0x00, 0x03, 0x05, - 0x02, 0x05, 0xd5, 0xaf, 0xc5, 0x27, 0x0a, 0x3d, - 0x10, 0x01, 0x10, 0x81, 0x89, 0x40, 0xe2, 0x8b, - 0x41, 0x1f, 0xae, 0x80, 0x89, 0x80, 0xb1, 0x80, - 0xd1, 0x80, 0xb2, 0xef, 0x22, 0x14, 0x86, 0x88, - 0x98, 0x36, 0x88, 0x82, 0x8c, 0x86, + 0x02, 0x05, 0xd5, 0xaf, 0xc5, 0x27, 0x0a, 0x83, + 0x89, 0x10, 0x01, 0x10, 0x81, 0x89, 0x40, 0xe2, + 0x8b, 0x18, 0x41, 0x1a, 0xae, 0x80, 0x89, 0x80, + 0x40, 0xb8, 0xef, 0x8c, 0x82, 0x88, 0x86, 0xad, + 0x06, 0x87, 0x8d, 0x83, 0x88, 0x86, 0x88, }; static const uint8_t unicode_prop_Emoji_Component_table[28] = { @@ -4063,7 +4180,7 @@ static const uint8_t unicode_prop_Emoji_Modifier_table[4] = { 0x61, 0xf3, 0xfa, 0x84, }; -static const uint8_t unicode_prop_Emoji_Modifier_Base_table[66] = { +static const uint8_t unicode_prop_Emoji_Modifier_Base_table[71] = { 0x60, 0x26, 0x1c, 0x80, 0x40, 0xda, 0x80, 0x8f, 0x83, 0x61, 0xcc, 0x76, 0x80, 0xbb, 0x11, 0x01, 0x82, 0xf4, 0x09, 0x8a, 0x94, 0x92, 0x10, 0x1a, @@ -4072,10 +4189,10 @@ static const uint8_t unicode_prop_Emoji_Modifier_Base_table[66] = { 0xd2, 0x80, 0x8f, 0x82, 0x88, 0x80, 0x8a, 0x80, 0x42, 0x3e, 0x01, 0x07, 0x3d, 0x80, 0x88, 0x89, 0x0a, 0xb7, 0x80, 0xbc, 0x08, 0x08, 0x80, 0x90, - 0x10, 0x8c, + 0x10, 0x8c, 0x40, 0xe4, 0x82, 0xa9, 0x88, }; -static const uint8_t unicode_prop_Emoji_Presentation_table[144] = { +static const uint8_t unicode_prop_Emoji_Presentation_table[145] = { 0x60, 0x23, 0x19, 0x81, 0x40, 0xcc, 0x1a, 0x01, 0x80, 0x42, 0x08, 0x81, 0x94, 0x81, 0xb1, 0x8b, 0xaa, 0x80, 0x92, 0x80, 0x8c, 0x07, 0x81, 0x90, @@ -4090,10 +4207,11 @@ static const uint8_t unicode_prop_Emoji_Presentation_table[144] = { 0x1c, 0x8b, 0x90, 0x10, 0x82, 0xc6, 0x00, 0x80, 0x40, 0xba, 0x81, 0xbe, 0x8c, 0x18, 0x97, 0x91, 0x80, 0x99, 0x81, 0x8c, 0x80, 0xd5, 0xd4, 0xaf, - 0xc5, 0x28, 0x12, 0x0a, 0x92, 0x0e, 0x88, 0x40, - 0xe2, 0x8b, 0x41, 0x1f, 0xae, 0x80, 0x89, 0x80, - 0xb1, 0x80, 0xd1, 0x80, 0xb2, 0xef, 0x22, 0x14, - 0x86, 0x88, 0x98, 0x36, 0x88, 0x82, 0x8c, 0x86, + 0xc5, 0x28, 0x12, 0x0a, 0x1b, 0x8a, 0x0e, 0x88, + 0x40, 0xe2, 0x8b, 0x18, 0x41, 0x1a, 0xae, 0x80, + 0x89, 0x80, 0x40, 0xb8, 0xef, 0x8c, 0x82, 0x88, + 0x86, 0xad, 0x06, 0x87, 0x8d, 0x83, 0x88, 0x86, + 0x88, }; static const uint8_t unicode_prop_Extended_Pictographic_table[156] = { @@ -4122,7 +4240,7 @@ static const uint8_t unicode_prop_Extended_Pictographic_table[156] = { static const uint8_t unicode_prop_Default_Ignorable_Code_Point_table[51] = { 0x40, 0xac, 0x80, 0x42, 0xa0, 0x80, 0x42, 0xcb, 0x80, 0x4b, 0x41, 0x81, 0x46, 0x52, 0x81, 0xd4, - 0x83, 0x47, 0xfb, 0x84, 0x99, 0x84, 0xb0, 0x8f, + 0x84, 0x47, 0xfa, 0x84, 0x99, 0x84, 0xb0, 0x8f, 0x50, 0xf3, 0x80, 0x60, 0xcc, 0x9a, 0x8f, 0x40, 0xee, 0x80, 0x40, 0x9f, 0x80, 0xce, 0x88, 0x60, 0xbc, 0xa6, 0x83, 0x54, 0xce, 0x87, 0x6c, 0x2e, diff --git a/libquickjs-sys/embed/quickjs/libunicode.c b/libquickjs-sys/embed/quickjs/libunicode.c index 63c12a0..0712a6c 100644 --- a/libquickjs-sys/embed/quickjs/libunicode.c +++ b/libquickjs-sys/embed/quickjs/libunicode.c @@ -43,11 +43,111 @@ enum { RUN_TYPE_UF_D1_EXT, RUN_TYPE_U_EXT, RUN_TYPE_LF_EXT, - RUN_TYPE_U_EXT2, - RUN_TYPE_L_EXT2, - RUN_TYPE_U_EXT3, + RUN_TYPE_UF_EXT2, + RUN_TYPE_LF_EXT2, + RUN_TYPE_UF_EXT3, }; +static int lre_case_conv1(uint32_t c, int conv_type) +{ + uint32_t res[LRE_CC_RES_LEN_MAX]; + lre_case_conv(res, c, conv_type); + return res[0]; +} + +/* case conversion using the table entry 'idx' with value 'v' */ +static int lre_case_conv_entry(uint32_t *res, uint32_t c, int conv_type, uint32_t idx, uint32_t v) +{ + uint32_t code, data, type, a, is_lower; + is_lower = (conv_type != 0); + type = (v >> (32 - 17 - 7 - 4)) & 0xf; + data = ((v & 0xf) << 8) | case_conv_table2[idx]; + code = v >> (32 - 17); + switch(type) { + case RUN_TYPE_U: + case RUN_TYPE_L: + case RUN_TYPE_UF: + case RUN_TYPE_LF: + if (conv_type == (type & 1) || + (type >= RUN_TYPE_UF && conv_type == 2)) { + c = c - code + (case_conv_table1[data] >> (32 - 17)); + } + break; + case RUN_TYPE_UL: + a = c - code; + if ((a & 1) != (1 - is_lower)) + break; + c = (a ^ 1) + code; + break; + case RUN_TYPE_LSU: + a = c - code; + if (a == 1) { + c += 2 * is_lower - 1; + } else if (a == (1 - is_lower) * 2) { + c += (2 * is_lower - 1) * 2; + } + break; + case RUN_TYPE_U2L_399_EXT2: + if (!is_lower) { + res[0] = c - code + case_conv_ext[data >> 6]; + res[1] = 0x399; + return 2; + } else { + c = c - code + case_conv_ext[data & 0x3f]; + } + break; + case RUN_TYPE_UF_D20: + if (conv_type == 1) + break; + c = data + (conv_type == 2) * 0x20; + break; + case RUN_TYPE_UF_D1_EXT: + if (conv_type == 1) + break; + c = case_conv_ext[data] + (conv_type == 2); + break; + case RUN_TYPE_U_EXT: + case RUN_TYPE_LF_EXT: + if (is_lower != (type - RUN_TYPE_U_EXT)) + break; + c = case_conv_ext[data]; + break; + case RUN_TYPE_LF_EXT2: + if (!is_lower) + break; + res[0] = c - code + case_conv_ext[data >> 6]; + res[1] = case_conv_ext[data & 0x3f]; + return 2; + case RUN_TYPE_UF_EXT2: + if (conv_type == 1) + break; + res[0] = c - code + case_conv_ext[data >> 6]; + res[1] = case_conv_ext[data & 0x3f]; + if (conv_type == 2) { + /* convert to lower */ + res[0] = lre_case_conv1(res[0], 1); + res[1] = lre_case_conv1(res[1], 1); + } + return 2; + default: + case RUN_TYPE_UF_EXT3: + if (conv_type == 1) + break; + res[0] = case_conv_ext[data >> 8]; + res[1] = case_conv_ext[(data >> 4) & 0xf]; + res[2] = case_conv_ext[data & 0xf]; + if (conv_type == 2) { + /* convert to lower */ + res[0] = lre_case_conv1(res[0], 1); + res[1] = lre_case_conv1(res[1], 1); + res[2] = lre_case_conv1(res[2], 1); + } + return 3; + } + res[0] = c; + return 1; +} + /* conv_type: 0 = to upper 1 = to lower @@ -66,10 +166,9 @@ int lre_case_conv(uint32_t *res, uint32_t c, int conv_type) } } } else { - uint32_t v, code, data, type, len, a, is_lower; + uint32_t v, code, len; int idx, idx_min, idx_max; - is_lower = (conv_type != 0); idx_min = 0; idx_max = countof(case_conv_table1) - 1; while (idx_min <= idx_max) { @@ -82,74 +181,7 @@ int lre_case_conv(uint32_t *res, uint32_t c, int conv_type) } else if (c >= code + len) { idx_min = idx + 1; } else { - type = (v >> (32 - 17 - 7 - 4)) & 0xf; - data = ((v & 0xf) << 8) | case_conv_table2[idx]; - switch(type) { - case RUN_TYPE_U: - case RUN_TYPE_L: - case RUN_TYPE_UF: - case RUN_TYPE_LF: - if (conv_type == (type & 1) || - (type >= RUN_TYPE_UF && conv_type == 2)) { - c = c - code + (case_conv_table1[data] >> (32 - 17)); - } - break; - case RUN_TYPE_UL: - a = c - code; - if ((a & 1) != (1 - is_lower)) - break; - c = (a ^ 1) + code; - break; - case RUN_TYPE_LSU: - a = c - code; - if (a == 1) { - c += 2 * is_lower - 1; - } else if (a == (1 - is_lower) * 2) { - c += (2 * is_lower - 1) * 2; - } - break; - case RUN_TYPE_U2L_399_EXT2: - if (!is_lower) { - res[0] = c - code + case_conv_ext[data >> 6]; - res[1] = 0x399; - return 2; - } else { - c = c - code + case_conv_ext[data & 0x3f]; - } - break; - case RUN_TYPE_UF_D20: - if (conv_type == 1) - break; - c = data + (conv_type == 2) * 0x20; - break; - case RUN_TYPE_UF_D1_EXT: - if (conv_type == 1) - break; - c = case_conv_ext[data] + (conv_type == 2); - break; - case RUN_TYPE_U_EXT: - case RUN_TYPE_LF_EXT: - if (is_lower != (type - RUN_TYPE_U_EXT)) - break; - c = case_conv_ext[data]; - break; - case RUN_TYPE_U_EXT2: - case RUN_TYPE_L_EXT2: - if (conv_type != (type - RUN_TYPE_U_EXT2)) - break; - res[0] = c - code + case_conv_ext[data >> 6]; - res[1] = case_conv_ext[data & 0x3f]; - return 2; - default: - case RUN_TYPE_U_EXT3: - if (conv_type != 0) - break; - res[0] = case_conv_ext[data >> 8]; - res[1] = case_conv_ext[(data >> 4) & 0xf]; - res[2] = case_conv_ext[data & 0xf]; - return 3; - } - break; + return lre_case_conv_entry(res, c, conv_type, idx, v); } } } @@ -157,6 +189,77 @@ int lre_case_conv(uint32_t *res, uint32_t c, int conv_type) return 1; } +static int lre_case_folding_entry(uint32_t c, uint32_t idx, uint32_t v, BOOL is_unicode) +{ + uint32_t res[LRE_CC_RES_LEN_MAX]; + int len; + + if (is_unicode) { + len = lre_case_conv_entry(res, c, 2, idx, v); + if (len == 1) { + c = res[0]; + } else { + /* handle the few specific multi-character cases (see + unicode_gen.c:dump_case_folding_special_cases()) */ + if (c == 0xfb06) { + c = 0xfb05; + } else if (c == 0x01fd3) { + c = 0x390; + } else if (c == 0x01fe3) { + c = 0x3b0; + } + } + } else { + if (likely(c < 128)) { + if (c >= 'a' && c <= 'z') + c = c - 'a' + 'A'; + } else { + /* legacy regexp: to upper case if single char >= 128 */ + len = lre_case_conv_entry(res, c, FALSE, idx, v); + if (len == 1 && res[0] >= 128) + c = res[0]; + } + } + return c; +} + +/* JS regexp specific rules for case folding */ +int lre_canonicalize(uint32_t c, BOOL is_unicode) +{ + if (c < 128) { + /* fast case */ + if (is_unicode) { + if (c >= 'A' && c <= 'Z') { + c = c - 'A' + 'a'; + } + } else { + if (c >= 'a' && c <= 'z') { + c = c - 'a' + 'A'; + } + } + } else { + uint32_t v, code, len; + int idx, idx_min, idx_max; + + idx_min = 0; + idx_max = countof(case_conv_table1) - 1; + while (idx_min <= idx_max) { + idx = (unsigned)(idx_max + idx_min) / 2; + v = case_conv_table1[idx]; + code = v >> (32 - 17); + len = (v >> (32 - 17 - 7)) & 0x7f; + if (c < code) { + idx_max = idx - 1; + } else if (c >= code + len) { + idx_min = idx + 1; + } else { + return lre_case_folding_entry(c, idx, v, is_unicode); + } + } + } + return c; +} + static uint32_t get_le24(const uint8_t *ptr) { #if defined(__x86__) || defined(__x86_64__) @@ -1179,11 +1282,11 @@ static int unicode_case1(CharRange *cr, int case_mask) #define MR(x) (1 << RUN_TYPE_ ## x) const uint32_t tab_run_mask[3] = { MR(U) | MR(UF) | MR(UL) | MR(LSU) | MR(U2L_399_EXT2) | MR(UF_D20) | - MR(UF_D1_EXT) | MR(U_EXT) | MR(U_EXT2) | MR(U_EXT3), + MR(UF_D1_EXT) | MR(U_EXT) | MR(UF_EXT2) | MR(UF_EXT3), - MR(L) | MR(LF) | MR(UL) | MR(LSU) | MR(U2L_399_EXT2) | MR(LF_EXT) | MR(L_EXT2), + MR(L) | MR(LF) | MR(UL) | MR(LSU) | MR(U2L_399_EXT2) | MR(LF_EXT) | MR(LF_EXT2), - MR(UF) | MR(LF) | MR(UL) | MR(LSU) | MR(U2L_399_EXT2) | MR(LF_EXT) | MR(UF_D20) | MR(UF_D1_EXT) | MR(LF_EXT), + MR(UF) | MR(LF) | MR(UL) | MR(LSU) | MR(U2L_399_EXT2) | MR(LF_EXT) | MR(LF_EXT2) | MR(UF_D20) | MR(UF_D1_EXT) | MR(LF_EXT) | MR(UF_EXT2) | MR(UF_EXT3), }; #undef MR uint32_t mask, v, code, type, len, i, idx; @@ -1236,7 +1339,136 @@ static int unicode_case1(CharRange *cr, int case_mask) } return 0; } - + +static int point_cmp(const void *p1, const void *p2, void *arg) +{ + uint32_t v1 = *(uint32_t *)p1; + uint32_t v2 = *(uint32_t *)p2; + return (v1 > v2) - (v1 < v2); +} + +static void cr_sort_and_remove_overlap(CharRange *cr) +{ + uint32_t start, end, start1, end1, i, j; + + /* the resulting ranges are not necessarily sorted and may overlap */ + rqsort(cr->points, cr->len / 2, sizeof(cr->points[0]) * 2, point_cmp, NULL); + j = 0; + for(i = 0; i < cr->len; ) { + start = cr->points[i]; + end = cr->points[i + 1]; + i += 2; + while (i < cr->len) { + start1 = cr->points[i]; + end1 = cr->points[i + 1]; + if (start1 > end) { + /* |------| + * |-------| */ + break; + } else if (end1 <= end) { + /* |------| + * |--| */ + i += 2; + } else { + /* |------| + * |-------| */ + end = end1; + i += 2; + } + } + cr->points[j] = start; + cr->points[j + 1] = end; + j += 2; + } + cr->len = j; +} + +/* canonicalize a character set using the JS regex case folding rules + (see lre_canonicalize()) */ +int cr_regexp_canonicalize(CharRange *cr, BOOL is_unicode) +{ + CharRange cr_inter, cr_mask, cr_result, cr_sub; + uint32_t v, code, len, i, idx, start, end, c, d_start, d_end, d; + + cr_init(&cr_mask, cr->mem_opaque, cr->realloc_func); + cr_init(&cr_inter, cr->mem_opaque, cr->realloc_func); + cr_init(&cr_result, cr->mem_opaque, cr->realloc_func); + cr_init(&cr_sub, cr->mem_opaque, cr->realloc_func); + + if (unicode_case1(&cr_mask, is_unicode ? CASE_F : CASE_U)) + goto fail; + if (cr_op(&cr_inter, cr_mask.points, cr_mask.len, cr->points, cr->len, CR_OP_INTER)) + goto fail; + + if (cr_invert(&cr_mask)) + goto fail; + if (cr_op(&cr_sub, cr_mask.points, cr_mask.len, cr->points, cr->len, CR_OP_INTER)) + goto fail; + + /* cr_inter = cr & cr_mask */ + /* cr_sub = cr & ~cr_mask */ + + /* use the case conversion table to compute the result */ + d_start = -1; + d_end = -1; + idx = 0; + v = case_conv_table1[idx]; + code = v >> (32 - 17); + len = (v >> (32 - 17 - 7)) & 0x7f; + for(i = 0; i < cr_inter.len; i += 2) { + start = cr_inter.points[i]; + end = cr_inter.points[i + 1]; + + for(c = start; c < end; c++) { + for(;;) { + if (c >= code && c < code + len) + break; + idx++; + assert(idx < countof(case_conv_table1)); + v = case_conv_table1[idx]; + code = v >> (32 - 17); + len = (v >> (32 - 17 - 7)) & 0x7f; + } + d = lre_case_folding_entry(c, idx, v, is_unicode); + /* try to merge with the current interval */ + if (d_start == -1) { + d_start = d; + d_end = d + 1; + } else if (d_end == d) { + d_end++; + } else { + cr_add_interval(&cr_result, d_start, d_end); + d_start = d; + d_end = d + 1; + } + } + } + if (d_start != -1) { + if (cr_add_interval(&cr_result, d_start, d_end)) + goto fail; + } + + /* the resulting ranges are not necessarily sorted and may overlap */ + cr_sort_and_remove_overlap(&cr_result); + + /* or with the character not affected by the case folding */ + cr->len = 0; + if (cr_op(cr, cr_result.points, cr_result.len, cr_sub.points, cr_sub.len, CR_OP_UNION)) + goto fail; + + cr_free(&cr_inter); + cr_free(&cr_mask); + cr_free(&cr_result); + cr_free(&cr_sub); + return 0; + fail: + cr_free(&cr_inter); + cr_free(&cr_mask); + cr_free(&cr_result); + cr_free(&cr_sub); + return -1; +} + typedef enum { POP_GC, POP_PROP, diff --git a/libquickjs-sys/embed/quickjs/libunicode.h b/libquickjs-sys/embed/quickjs/libunicode.h index cfa600a..8abacb0 100644 --- a/libquickjs-sys/embed/quickjs/libunicode.h +++ b/libquickjs-sys/embed/quickjs/libunicode.h @@ -41,6 +41,7 @@ typedef enum { } UnicodeNormalizationEnum; int lre_case_conv(uint32_t *res, uint32_t c, int conv_type); +int lre_canonicalize(uint32_t c, BOOL is_unicode); LRE_BOOL lre_is_cased(uint32_t c); LRE_BOOL lre_is_case_ignorable(uint32_t c); @@ -101,6 +102,8 @@ int cr_op(CharRange *cr, const uint32_t *a_pt, int a_len, int cr_invert(CharRange *cr); +int cr_regexp_canonicalize(CharRange *cr, BOOL is_unicode); + #ifdef CONFIG_ALL_UNICODE LRE_BOOL lre_is_id_start(uint32_t c); diff --git a/libquickjs-sys/embed/quickjs/list.h b/libquickjs-sys/embed/quickjs/list.h index 0a1bc5a..5c18234 100644 --- a/libquickjs-sys/embed/quickjs/list.h +++ b/libquickjs-sys/embed/quickjs/list.h @@ -36,8 +36,7 @@ struct list_head { #define LIST_HEAD_INIT(el) { &(el), &(el) } /* return the pointer of type 'type *' containing 'el' as field 'member' */ -#define list_entry(el, type, member) \ - ((type *)((uint8_t *)(el) - offsetof(type, member))) +#define list_entry(el, type, member) container_of(el, type, member) static inline void init_list_head(struct list_head *head) { diff --git a/libquickjs-sys/embed/quickjs/qjs.c b/libquickjs-sys/embed/quickjs/qjs.c index d56b843..77b5cfb 100644 --- a/libquickjs-sys/embed/quickjs/qjs.c +++ b/libquickjs-sys/embed/quickjs/qjs.c @@ -140,19 +140,19 @@ static inline unsigned long long js_trace_malloc_ptr_offset(uint8_t *ptr, } /* default memory allocation functions with memory limitation */ -static inline size_t js_trace_malloc_usable_size(void *ptr) +static size_t js_trace_malloc_usable_size(const void *ptr) { #if defined(__APPLE__) return malloc_size(ptr); #elif defined(_WIN32) - return _msize(ptr); + return _msize((void *)ptr); #elif defined(EMSCRIPTEN) return 0; #elif defined(__linux__) - return malloc_usable_size(ptr); + return malloc_usable_size((void *)ptr); #else /* change this to `return 0;` if compilation fails */ - return malloc_usable_size(ptr); + return malloc_usable_size((void *)ptr); #endif } @@ -264,18 +264,7 @@ static const JSMallocFunctions trace_mf = { js_trace_malloc, js_trace_free, js_trace_realloc, -#if defined(__APPLE__) - malloc_size, -#elif defined(_WIN32) - (size_t (*)(const void *))_msize, -#elif defined(EMSCRIPTEN) - NULL, -#elif defined(__linux__) - (size_t (*)(const void *))malloc_usable_size, -#else - /* change this to `NULL,` if compilation fails */ - malloc_usable_size, -#endif + js_trace_malloc_usable_size, }; #define PROG_NAME "qjs" @@ -454,8 +443,10 @@ int main(int argc, char **argv) } } +#ifdef CONFIG_BIGNUM if (load_jscalc) bignum_ext = 1; +#endif if (trace_memory) { js_trace_malloc_init(&trace_data); diff --git a/libquickjs-sys/embed/quickjs/qjsc.c b/libquickjs-sys/embed/quickjs/qjsc.c index b9f1e4c..f8e60b3 100644 --- a/libquickjs-sys/embed/quickjs/qjsc.c +++ b/libquickjs-sys/embed/quickjs/qjsc.c @@ -76,9 +76,7 @@ static const FeatureEntry feature_list[] = { { "promise", "Promise" }, #define FE_MODULE_LOADER 9 { "module-loader", NULL }, -#ifdef CONFIG_BIGNUM { "bigint", "BigInt" }, -#endif }; void namelist_add(namelist_t *lp, const char *name, const char *short_name, @@ -332,6 +330,7 @@ static const char main_c_template1[] = static const char main_c_template2[] = " js_std_loop(ctx);\n" + " js_std_free_handlers(rt);\n" " JS_FreeContext(ctx);\n" " JS_FreeRuntime(rt);\n" " return 0;\n" @@ -345,8 +344,8 @@ void help(void) "usage: " PROG_NAME " [options] [files]\n" "\n" "options are:\n" - "-c only output bytecode in a C file\n" - "-e output main() and bytecode in a C file (default = executable output)\n" + "-c only output bytecode to a C file\n" + "-e output main() and bytecode to a C file (default = executable output)\n" "-o output set the output filename\n" "-N cname set the C name of the generated data\n" "-m compile as Javascript module (default=autodetect)\n" diff --git a/libquickjs-sys/embed/quickjs/quickjs-atom.h b/libquickjs-sys/embed/quickjs/quickjs-atom.h index 4c22794..f62a7c4 100644 --- a/libquickjs-sys/embed/quickjs/quickjs-atom.h +++ b/libquickjs-sys/embed/quickjs/quickjs-atom.h @@ -82,6 +82,7 @@ DEF(length, "length") DEF(fileName, "fileName") DEF(lineNumber, "lineNumber") DEF(message, "message") +DEF(cause, "cause") DEF(errors, "errors") DEF(stack, "stack") DEF(name, "name") @@ -166,22 +167,23 @@ DEF(revoke, "revoke") DEF(async, "async") DEF(exec, "exec") DEF(groups, "groups") +DEF(indices, "indices") DEF(status, "status") DEF(reason, "reason") DEF(globalThis, "globalThis") -#ifdef CONFIG_BIGNUM DEF(bigint, "bigint") +#ifdef CONFIG_BIGNUM DEF(bigfloat, "bigfloat") DEF(bigdecimal, "bigdecimal") DEF(roundingMode, "roundingMode") DEF(maximumSignificantDigits, "maximumSignificantDigits") DEF(maximumFractionDigits, "maximumFractionDigits") #endif -#ifdef CONFIG_ATOMICS +/* the following 3 atoms are only used with CONFIG_ATOMICS */ DEF(not_equal, "not-equal") DEF(timed_out, "timed-out") DEF(ok, "ok") -#endif +/* */ DEF(toJSON, "toJSON") /* class names */ DEF(Object, "Object") @@ -209,15 +211,13 @@ DEF(Int16Array, "Int16Array") DEF(Uint16Array, "Uint16Array") DEF(Int32Array, "Int32Array") DEF(Uint32Array, "Uint32Array") -#ifdef CONFIG_BIGNUM DEF(BigInt64Array, "BigInt64Array") DEF(BigUint64Array, "BigUint64Array") -#endif DEF(Float32Array, "Float32Array") DEF(Float64Array, "Float64Array") DEF(DataView, "DataView") -#ifdef CONFIG_BIGNUM DEF(BigInt, "BigInt") +#ifdef CONFIG_BIGNUM DEF(BigFloat, "BigFloat") DEF(BigFloatEnv, "BigFloatEnv") DEF(BigDecimal, "BigDecimal") diff --git a/libquickjs-sys/embed/quickjs/quickjs-libc.c b/libquickjs-sys/embed/quickjs/quickjs-libc.c index e180dd0..d4f4d67 100644 --- a/libquickjs-sys/embed/quickjs/quickjs-libc.c +++ b/libquickjs-sys/embed/quickjs/quickjs-libc.c @@ -751,6 +751,7 @@ static JSValue js_evalScript(JSContext *ctx, JSValueConst this_val, JSValue ret; JSValueConst options_obj; BOOL backtrace_barrier = FALSE; + BOOL is_async = FALSE; int flags; if (argc >= 2) { @@ -758,6 +759,9 @@ static JSValue js_evalScript(JSContext *ctx, JSValueConst this_val, if (get_bool_option(ctx, &backtrace_barrier, options_obj, "backtrace_barrier")) return JS_EXCEPTION; + if (get_bool_option(ctx, &is_async, options_obj, + "async")) + return JS_EXCEPTION; } str = JS_ToCStringLen(ctx, &len, argv[0]); @@ -770,6 +774,8 @@ static JSValue js_evalScript(JSContext *ctx, JSValueConst this_val, flags = JS_EVAL_TYPE_GLOBAL; if (backtrace_barrier) flags |= JS_EVAL_FLAG_BACKTRACE_BARRIER; + if (is_async) + flags |= JS_EVAL_FLAG_ASYNC; ret = JS_Eval(ctx, str, len, "", flags); JS_FreeCString(ctx, str); if (!ts->recv_pipe && --ts->eval_script_recurse == 0) { @@ -1970,6 +1976,13 @@ static int64_t get_time_ms(void) clock_gettime(CLOCK_MONOTONIC, &ts); return (uint64_t)ts.tv_sec * 1000 + (ts.tv_nsec / 1000000); } + +static int64_t get_time_ns(void) +{ + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return (uint64_t)ts.tv_sec * 1000000000 + ts.tv_nsec; +} #else /* more portable, but does not work if the date is updated */ static int64_t get_time_ms(void) @@ -1978,8 +1991,21 @@ static int64_t get_time_ms(void) gettimeofday(&tv, NULL); return (int64_t)tv.tv_sec * 1000 + (tv.tv_usec / 1000); } + +static int64_t get_time_ns(void) +{ + struct timeval tv; + gettimeofday(&tv, NULL); + return (int64_t)tv.tv_sec * 1000000000 + (tv.tv_usec * 1000); +} #endif +static JSValue js_os_now(JSContext *ctx, JSValue this_val, + int argc, JSValue *argv) +{ + return JS_NewFloat64(ctx, (double)get_time_ns() / 1e6); +} + static void unlink_timer(JSRuntime *rt, JSOSTimer *th) { if (th->link.prev) { @@ -2062,6 +2088,38 @@ static JSClassDef js_os_timer_class = { .gc_mark = js_os_timer_mark, }; +/* return a promise */ +static JSValue js_os_sleepAsync(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + JSRuntime *rt = JS_GetRuntime(ctx); + JSThreadState *ts = JS_GetRuntimeOpaque(rt); + int64_t delay; + JSOSTimer *th; + JSValue promise, resolving_funcs[2]; + + if (JS_ToInt64(ctx, &delay, argv[0])) + return JS_EXCEPTION; + promise = JS_NewPromiseCapability(ctx, resolving_funcs); + if (JS_IsException(promise)) + return JS_EXCEPTION; + + th = js_mallocz(ctx, sizeof(*th)); + if (!th) { + JS_FreeValue(ctx, promise); + JS_FreeValue(ctx, resolving_funcs[0]); + JS_FreeValue(ctx, resolving_funcs[1]); + return JS_EXCEPTION; + } + th->has_object = FALSE; + th->timeout = get_time_ms() + delay; + th->func = JS_DupValue(ctx, resolving_funcs[0]); + list_add_tail(&th->link, &ts->os_timers); + JS_FreeValue(ctx, resolving_funcs[0]); + JS_FreeValue(ctx, resolving_funcs[1]); + return promise; +} + static void call_handler(JSContext *ctx, JSValueConst func) { JSValue ret, func1; @@ -3030,6 +3088,13 @@ static JSValue js_os_exec(JSContext *ctx, JSValueConst this_val, goto done; } +/* getpid() -> pid */ +static JSValue js_os_getpid(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + return JS_NewInt32(ctx, getpid()); +} + /* waitpid(pid, block) -> [pid, status] */ static JSValue js_os_waitpid(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) @@ -3274,6 +3339,7 @@ static void *worker_func(void *opaque) JSRuntime *rt; JSThreadState *ts; JSContext *ctx; + JSValue promise; rt = JS_NewRuntime(); if (rt == NULL) { @@ -3300,8 +3366,11 @@ static void *worker_func(void *opaque) js_std_add_helpers(ctx, -1, NULL); - if (!JS_RunModule(ctx, args->basename, args->filename)) + promise = JS_LoadModule(ctx, args->basename, args->filename); + if (JS_IsException(promise)) js_std_dump_error(ctx); + /* XXX: check */ + JS_FreeValue(ctx, promise); free(args->filename); free(args->basename); free(args); @@ -3621,8 +3690,10 @@ static const JSCFunctionListEntry js_os_funcs[] = { OS_FLAG(SIGTTIN), OS_FLAG(SIGTTOU), #endif + JS_CFUNC_DEF("now", 0, js_os_now ), JS_CFUNC_DEF("setTimeout", 2, js_os_setTimeout ), JS_CFUNC_DEF("clearTimeout", 1, js_os_clearTimeout ), + JS_CFUNC_DEF("sleepAsync", 1, js_os_sleepAsync ), JS_PROP_STRING_DEF("platform", OS_PLATFORM, 0 ), JS_CFUNC_DEF("getcwd", 0, js_os_getcwd ), JS_CFUNC_DEF("chdir", 0, js_os_chdir ), @@ -3650,6 +3721,7 @@ static const JSCFunctionListEntry js_os_funcs[] = { JS_CFUNC_DEF("symlink", 2, js_os_symlink ), JS_CFUNC_DEF("readlink", 1, js_os_readlink ), JS_CFUNC_DEF("exec", 1, js_os_exec ), + JS_CFUNC_DEF("getpid", 0, js_os_getpid ), JS_CFUNC_DEF("waitpid", 2, js_os_waitpid ), OS_FLAG(WNOHANG), JS_CFUNC_DEF("pipe", 0, js_os_pipe ), diff --git a/libquickjs-sys/embed/quickjs/quickjs-opcode.h b/libquickjs-sys/embed/quickjs/quickjs-opcode.h index c731a14..6d2d6e9 100644 --- a/libquickjs-sys/embed/quickjs/quickjs-opcode.h +++ b/libquickjs-sys/embed/quickjs/quickjs-opcode.h @@ -172,6 +172,7 @@ DEF(set_loc_uninitialized, 3, 0, 0, loc) DEF( get_loc_check, 3, 0, 1, loc) DEF( put_loc_check, 3, 1, 0, loc) /* must come after get_loc_check */ DEF( put_loc_check_init, 3, 1, 0, loc) +DEF(get_loc_checkthis, 3, 0, 1, loc) DEF(get_var_ref_check, 3, 0, 1, var_ref) DEF(put_var_ref_check, 3, 1, 0, var_ref) /* must come after get_var_ref_check */ DEF(put_var_ref_check_init, 3, 1, 0, var_ref) @@ -182,6 +183,7 @@ DEF( goto, 5, 0, 0, label) /* must come after if_true */ DEF( catch, 5, 0, 1, label) DEF( gosub, 5, 0, 0, label) /* used to execute the finally block */ DEF( ret, 1, 1, 0, none) /* used to return from the finally block */ +DEF( nip_catch, 1, 2, 1, none) /* catch ... a -> a */ DEF( to_object, 1, 1, 1, none) //DEF( to_string, 1, 1, 1, none) @@ -208,7 +210,6 @@ DEF( for_of_next, 2, 3, 5, u8) DEF(iterator_check_object, 1, 1, 1, none) DEF(iterator_get_value_done, 1, 1, 2, none) DEF( iterator_close, 1, 3, 0, none) -DEF(iterator_close_return, 1, 4, 4, none) DEF( iterator_next, 1, 4, 4, none) DEF( iterator_call, 2, 4, 5, u8) DEF( initial_yield, 1, 0, 0, none) @@ -256,6 +257,7 @@ DEF( and, 1, 2, 1, none) DEF( xor, 1, 2, 1, none) DEF( or, 1, 2, 1, none) DEF(is_undefined_or_null, 1, 1, 1, none) +DEF( private_in, 1, 2, 1, none) #ifdef CONFIG_BIGNUM DEF( mul_pow10, 1, 2, 1, none) DEF( math_mod, 1, 2, 1, none) @@ -270,6 +272,8 @@ def( leave_scope, 3, 0, 0, u16) /* emitted in phase 1, removed in phase 2 */ def( label, 5, 0, 0, label) /* emitted in phase 1, removed in phase 3 */ +/* the following opcodes must be in the same order as the 'with_x' and + get_var_undef, get_var and put_var opcodes */ def(scope_get_var_undef, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase 2 */ def( scope_get_var, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase 2 */ def( scope_put_var, 7, 1, 0, atom_u16) /* emitted in phase 1, removed in phase 2 */ @@ -277,10 +281,13 @@ def(scope_delete_var, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase def( scope_make_ref, 11, 0, 2, atom_label_u16) /* emitted in phase 1, removed in phase 2 */ def( scope_get_ref, 7, 0, 2, atom_u16) /* emitted in phase 1, removed in phase 2 */ def(scope_put_var_init, 7, 0, 2, atom_u16) /* emitted in phase 1, removed in phase 2 */ +def(scope_get_var_checkthis, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase 2, only used to return 'this' in derived class constructors */ def(scope_get_private_field, 7, 1, 1, atom_u16) /* obj -> value, emitted in phase 1, removed in phase 2 */ def(scope_get_private_field2, 7, 1, 2, atom_u16) /* obj -> obj value, emitted in phase 1, removed in phase 2 */ -def(scope_put_private_field, 7, 1, 1, atom_u16) /* obj value ->, emitted in phase 1, removed in phase 2 */ - +def(scope_put_private_field, 7, 2, 0, atom_u16) /* obj value ->, emitted in phase 1, removed in phase 2 */ +def(scope_in_private_field, 7, 1, 1, atom_u16) /* obj -> res emitted in phase 1, removed in phase 2 */ +def(get_field_opt_chain, 5, 1, 1, atom) /* emitted in phase 1, removed in phase 2 */ +def(get_array_el_opt_chain, 1, 2, 1, none) /* emitted in phase 1, removed in phase 2 */ def( set_class_name, 5, 1, 1, u32) /* emitted in phase 1, removed in phase 2 */ def( line_num, 5, 0, 0, u32) /* emitted in phase 1, removed in phase 3 */ diff --git a/libquickjs-sys/embed/quickjs/quickjs.c b/libquickjs-sys/embed/quickjs/quickjs.c index 48aeffc..4e58a98 100644 --- a/libquickjs-sys/embed/quickjs/quickjs.c +++ b/libquickjs-sys/embed/quickjs/quickjs.c @@ -44,9 +44,7 @@ #include "list.h" #include "quickjs.h" #include "libregexp.h" -#ifdef CONFIG_BIGNUM #include "libbf.h" -#endif #define OPTIMIZE 1 #define SHORT_OPCODES 1 @@ -89,6 +87,7 @@ 8: dump stdlib functions 16: dump bytecode in hex 32: dump line number table + 64: dump compute_stack_size */ //#define DUMP_BYTECODE (1) /* dump the occurence of the automatic GC */ @@ -144,15 +143,13 @@ enum { JS_CLASS_UINT16_ARRAY, /* u.array (typed_array) */ JS_CLASS_INT32_ARRAY, /* u.array (typed_array) */ JS_CLASS_UINT32_ARRAY, /* u.array (typed_array) */ -#ifdef CONFIG_BIGNUM JS_CLASS_BIG_INT64_ARRAY, /* u.array (typed_array) */ JS_CLASS_BIG_UINT64_ARRAY, /* u.array (typed_array) */ -#endif JS_CLASS_FLOAT32_ARRAY, /* u.array (typed_array) */ JS_CLASS_FLOAT64_ARRAY, /* u.array (typed_array) */ JS_CLASS_DATAVIEW, /* u.typed_array */ -#ifdef CONFIG_BIGNUM JS_CLASS_BIG_INT, /* u.object_data */ +#ifdef CONFIG_BIGNUM JS_CLASS_BIG_FLOAT, /* u.object_data */ JS_CLASS_FLOAT_ENV, /* u.float_env */ JS_CLASS_BIG_DECIMAL, /* u.object_data */ @@ -200,7 +197,7 @@ typedef enum JSErrorEnum { JS_NATIVE_ERROR_COUNT, /* number of different NativeError objects */ } JSErrorEnum; -#define JS_MAX_LOCAL_VARS 65536 +#define JS_MAX_LOCAL_VARS 65535 #define JS_STACK_SIZE_MAX 65534 #define JS_STRING_LEN_MAX ((1 << 30) - 1) @@ -218,7 +215,6 @@ typedef enum { typedef enum OPCodeEnum OPCodeEnum; -#ifdef CONFIG_BIGNUM /* function pointers are used for numeric operations so that it is possible to remove some numeric types */ typedef struct { @@ -236,7 +232,6 @@ typedef struct { int64_t exponent); int (*mul_pow10)(JSContext *ctx, JSValue *sp); } JSNumericOperations; -#endif struct JSRuntime { JSMallocFunctions mf; @@ -288,7 +283,9 @@ struct JSRuntime { JSModuleNormalizeFunc *module_normalize_func; JSModuleLoaderFunc *module_loader_func; void *module_loader_opaque; - + /* timestamp for internal use in module evaluation */ + int64_t module_async_evaluation_next_timestamp; + BOOL can_block : 8; /* TRUE if Atomics.wait can block */ /* used to allocate, free and clone SharedArrayBuffers */ JSSharedArrayBufferFunctions sab_funcs; @@ -298,9 +295,9 @@ struct JSRuntime { int shape_hash_size; int shape_hash_count; /* number of hashed shapes */ JSShape **shape_hash; -#ifdef CONFIG_BIGNUM bf_context_t bf_ctx; JSNumericOperations bigint_ops; +#ifdef CONFIG_BIGNUM JSNumericOperations bigfloat_ops; JSNumericOperations bigdecimal_ops; uint32_t operator_count; @@ -321,17 +318,18 @@ struct JSClass { #define JS_MODE_STRICT (1 << 0) #define JS_MODE_STRIP (1 << 1) #define JS_MODE_MATH (1 << 2) +#define JS_MODE_ASYNC (1 << 3) /* async function */ typedef struct JSStackFrame { struct JSStackFrame *prev_frame; /* NULL if first stack frame */ JSValue cur_func; /* current function, JS_UNDEFINED if the frame is detached */ JSValue *arg_buf; /* arguments */ JSValue *var_buf; /* variables */ - struct list_head var_ref_list; /* list of JSVarRef.link */ + struct list_head var_ref_list; /* list of JSVarRef.var_ref_link */ const uint8_t *cur_pc; /* only used in bytecode functions : PC of the instruction after the call */ int arg_count; - int js_mode; /* 0 or JS_MODE_MATH for C functions */ + int js_mode; /* for C functions, only JS_MODE_MATH may be set */ /* only used in generators. Current stack pointer value. NULL if the function is running. */ JSValue *cur_sp; @@ -364,11 +362,6 @@ typedef struct JSVarRef { struct { int __gc_ref_count; /* corresponds to header.ref_count */ uint8_t __gc_mark; /* corresponds to header.mark/gc_obj_type */ - - /* 0 : the JSVarRef is on the stack. header.link is an element - of JSStackFrame.var_ref_list. - 1 : the JSVarRef is detached. header.link has the normal meanning - */ uint8_t is_detached : 1; uint8_t is_arg : 1; uint16_t var_idx; /* index of the corresponding function variable on @@ -377,16 +370,15 @@ typedef struct JSVarRef { }; JSValue *pvalue; /* pointer to the value, either on the stack or to 'value' */ - JSValue value; /* used when the variable is no longer on the stack */ + union { + JSValue value; /* used when is_detached = TRUE */ + struct { + struct list_head var_ref_link; /* JSStackFrame.var_ref_list list */ + struct JSAsyncFunctionState *async_func; /* != NULL if async stack frame */ + }; /* used when is_detached = FALSE */ + }; } JSVarRef; -#ifdef CONFIG_BIGNUM -typedef struct JSFloatEnv { - limb_t prec; - bf_flags_t flags; - unsigned int status; -} JSFloatEnv; - /* the same structure is used for big integers and big floats. Big integers are never infinite or NaNs */ typedef struct JSBigFloat { @@ -394,6 +386,13 @@ typedef struct JSBigFloat { bf_t num; } JSBigFloat; +#ifdef CONFIG_BIGNUM +typedef struct JSFloatEnv { + limb_t prec; + bf_flags_t flags; + unsigned int status; +} JSFloatEnv; + typedef struct JSBigDecimal { JSRefCountHeader header; /* must come first, 32-bit */ bfdec_t num; @@ -437,15 +436,14 @@ struct JSContext { JSValue global_var_obj; /* contains the global let/const definitions */ uint64_t random_state; -#ifdef CONFIG_BIGNUM bf_context_t *bf_ctx; /* points to rt->bf_ctx, shared by all contexts */ +#ifdef CONFIG_BIGNUM JSFloatEnv fp_env; /* global FP environment */ BOOL bignum_ext : 8; /* enable math mode */ BOOL allow_operator_overloading : 8; #endif /* when the counter reaches zero, JSRutime.interrupt_handler is called */ int interrupt_counter; - BOOL is_error_property_enabled; struct list_head loaded_modules; /* list of JSModuleDef.link */ @@ -558,6 +556,7 @@ typedef struct JSVarDef { uint8_t is_const : 1; uint8_t is_lexical : 1; uint8_t is_captured : 1; + uint8_t is_static_private : 1; /* only used during private class field parsing */ uint8_t var_kind : 4; /* see JSVarKindEnum */ /* only used during compilation: function pool index for lexical variables with var_kind = @@ -598,6 +597,7 @@ typedef struct JSFunctionBytecode { uint8_t has_debug : 1; uint8_t backtrace_barrier : 1; /* stop backtrace on this function */ uint8_t read_only_bytecode : 1; + uint8_t is_direct_or_indirect_eval : 1; /* used by JS_GetScriptOrModuleName() */ /* XXX: 4 bits available */ uint8_t *byte_code_buf; /* (self pointer) */ int byte_code_len; @@ -638,9 +638,11 @@ typedef enum JSIteratorKindEnum { typedef struct JSForInIterator { JSValue obj; - BOOL is_array; - uint32_t array_length; uint32_t idx; + uint32_t atom_count; + uint8_t in_prototype_chain; + uint8_t is_array; + JSPropertyEnum *tab_atom; /* is_array = FALSE */ } JSForInIterator; typedef struct JSRegExp { @@ -674,21 +676,16 @@ typedef struct JSTypedArray { } JSTypedArray; typedef struct JSAsyncFunctionState { - JSValue this_val; /* 'this' generator argument */ + JSGCObjectHeader header; + JSValue this_val; /* 'this' argument */ int argc; /* number of function arguments */ BOOL throw_flag; /* used to throw an exception in JS_CallInternal() */ + BOOL is_completed; /* TRUE if the function has returned. The stack + frame is no longer valid */ + JSValue resolving_funcs[2]; /* only used in JS async functions */ JSStackFrame frame; } JSAsyncFunctionState; -/* XXX: could use an object instead to avoid the - JS_TAG_ASYNC_FUNCTION tag for the GC */ -typedef struct JSAsyncFunctionData { - JSGCObjectHeader header; /* must come first */ - JSValue resolving_funcs[2]; - BOOL is_active; /* true if the async function state is valid */ - JSAsyncFunctionState func_state; -} JSAsyncFunctionData; - typedef enum { /* binary operators */ JS_OVOP_ADD, @@ -770,6 +767,15 @@ typedef struct JSImportEntry { int req_module_idx; /* in req_module_entries */ } JSImportEntry; +typedef enum { + JS_MODULE_STATUS_UNLINKED, + JS_MODULE_STATUS_LINKING, + JS_MODULE_STATUS_LINKED, + JS_MODULE_STATUS_EVALUATING, + JS_MODULE_STATUS_EVALUATING_ASYNC, + JS_MODULE_STATUS_EVALUATED, +} JSModuleStatus; + struct JSModuleDef { JSRefCountHeader header; /* must come first, 32-bit */ JSAtom module_name; @@ -794,11 +800,24 @@ struct JSModuleDef { JSValue module_ns; JSValue func_obj; /* only used for JS modules */ JSModuleInitFunc *init_func; /* only used for C modules */ + BOOL has_tla : 8; /* true if func_obj contains await */ BOOL resolved : 8; BOOL func_created : 8; - BOOL instantiated : 8; - BOOL evaluated : 8; - BOOL eval_mark : 8; /* temporary use during js_evaluate_module() */ + JSModuleStatus status : 8; + /* temp use during js_module_link() & js_module_evaluate() */ + int dfs_index, dfs_ancestor_index; + JSModuleDef *stack_prev; + /* temp use during js_module_evaluate() */ + JSModuleDef **async_parent_modules; + int async_parent_modules_count; + int async_parent_modules_size; + int pending_async_dependencies; + BOOL async_evaluation; + int64_t async_evaluation_timestamp; + JSModuleDef *cycle_root; + JSValue promise; /* corresponds to spec field: capability */ + JSValue resolving_funcs[2]; /* corresponds to spec field: capability */ + /* true if evaluation yielded an exception. It is saved in eval_exception */ BOOL eval_has_exception : 8; @@ -906,7 +925,7 @@ struct JSObject { struct JSProxyData *proxy_data; /* JS_CLASS_PROXY */ struct JSPromiseData *promise_data; /* JS_CLASS_PROMISE */ struct JSPromiseFunctionData *promise_function_data; /* JS_CLASS_PROMISE_RESOLVE_FUNCTION, JS_CLASS_PROMISE_REJECT_FUNCTION */ - struct JSAsyncFunctionData *async_function_data; /* JS_CLASS_ASYNC_FUNCTION_RESOLVE, JS_CLASS_ASYNC_FUNCTION_REJECT */ + struct JSAsyncFunctionState *async_function_data; /* JS_CLASS_ASYNC_FUNCTION_RESOLVE, JS_CLASS_ASYNC_FUNCTION_REJECT */ struct JSAsyncFromSyncIteratorData *async_from_sync_iterator_data; /* JS_CLASS_ASYNC_FROM_SYNC_ITERATOR */ struct JSAsyncGeneratorData *async_generator_data; /* JS_CLASS_ASYNC_GENERATOR */ struct { /* JS_CLASS_BYTECODE_FUNCTION: 12/24 bytes */ @@ -1117,6 +1136,18 @@ static JSValue JS_ToObject(JSContext *ctx, JSValueConst val); static JSValue JS_ToObjectFree(JSContext *ctx, JSValue val); static JSProperty *add_property(JSContext *ctx, JSObject *p, JSAtom prop, int prop_flags); +static JSValue JS_NewBigInt(JSContext *ctx); +static inline bf_t *JS_GetBigInt(JSValueConst val) +{ + JSBigFloat *p = JS_VALUE_GET_PTR(val); + return &p->num; +} +static JSValue JS_CompactBigInt1(JSContext *ctx, JSValue val, + BOOL convert_to_safe_integer); +static JSValue JS_CompactBigInt(JSContext *ctx, JSValue val); +static int JS_ToBigInt64Free(JSContext *ctx, int64_t *pres, JSValue val); +static bf_t *JS_ToBigInt(JSContext *ctx, bf_t *buf, JSValueConst val); +static void JS_FreeBigInt(JSContext *ctx, bf_t *a, bf_t *buf); #ifdef CONFIG_BIGNUM static void js_float_env_finalizer(JSRuntime *rt, JSValue val); static JSValue JS_NewBigFloat(JSContext *ctx); @@ -1131,18 +1162,6 @@ static inline bfdec_t *JS_GetBigDecimal(JSValueConst val) JSBigDecimal *p = JS_VALUE_GET_PTR(val); return &p->num; } -static JSValue JS_NewBigInt(JSContext *ctx); -static inline bf_t *JS_GetBigInt(JSValueConst val) -{ - JSBigFloat *p = JS_VALUE_GET_PTR(val); - return &p->num; -} -static JSValue JS_CompactBigInt1(JSContext *ctx, JSValue val, - BOOL convert_to_safe_integer); -static JSValue JS_CompactBigInt(JSContext *ctx, JSValue val); -static int JS_ToBigInt64Free(JSContext *ctx, int64_t *pres, JSValue val); -static bf_t *JS_ToBigInt(JSContext *ctx, bf_t *buf, JSValueConst val); -static void JS_FreeBigInt(JSContext *ctx, bf_t *a, bf_t *buf); static bf_t *JS_ToBigFloat(JSContext *ctx, bf_t *buf, JSValueConst val); static JSValue JS_ToBigDecimalFree(JSContext *ctx, JSValue val, BOOL allow_null_or_undefined); @@ -1173,11 +1192,17 @@ static JSValue js_typed_array_constructor(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int classid); +static JSValue js_typed_array_constructor_ta(JSContext *ctx, + JSValueConst new_target, + JSValueConst src_obj, + int classid); static BOOL typed_array_is_detached(JSContext *ctx, JSObject *p); static uint32_t typed_array_get_length(JSContext *ctx, JSObject *p); static JSValue JS_ThrowTypeErrorDetachedArrayBuffer(JSContext *ctx); static JSVarRef *get_var_ref(JSContext *ctx, JSStackFrame *sf, int var_idx, BOOL is_arg); +static void __async_func_free(JSRuntime *rt, JSAsyncFunctionState *s); +static void async_func_free(JSRuntime *rt, JSAsyncFunctionState *s); static JSValue js_generator_function_call(JSContext *ctx, JSValueConst func_obj, JSValueConst this_obj, int argc, JSValueConst *argv, @@ -1203,6 +1228,8 @@ static __exception int perform_promise_then(JSContext *ctx, JSValueConst *cap_resolving_funcs); static JSValue js_promise_resolve(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic); +static JSValue js_promise_then(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv); static int js_string_compare(JSContext *ctx, const JSString *p1, const JSString *p2); static JSValue JS_ToNumber(JSContext *ctx, JSValueConst val); @@ -1214,8 +1241,6 @@ static JSValue JS_ToNumberFree(JSContext *ctx, JSValue val); static int JS_GetOwnPropertyInternal(JSContext *ctx, JSPropertyDescriptor *desc, JSObject *p, JSAtom prop); static void js_free_desc(JSContext *ctx, JSPropertyDescriptor *desc); -static void async_func_mark(JSRuntime *rt, JSAsyncFunctionState *s, - JS_MarkFunc *mark_func); static void JS_AddIntrinsicBasicObjects(JSContext *ctx); static void js_free_shape(JSRuntime *rt, JSShape *sh); static void js_free_shape_null(JSRuntime *rt, JSShape *sh); @@ -1243,13 +1268,14 @@ static JSAtom js_symbol_to_atom(JSContext *ctx, JSValue val); static void add_gc_object(JSRuntime *rt, JSGCObjectHeader *h, JSGCObjectTypeEnum type); static void remove_gc_object(JSGCObjectHeader *h); -static void js_async_function_free0(JSRuntime *rt, JSAsyncFunctionData *s); static JSValue js_instantiate_prototype(JSContext *ctx, JSObject *p, JSAtom atom, void *opaque); static JSValue js_module_ns_autoinit(JSContext *ctx, JSObject *p, JSAtom atom, void *opaque); static JSValue JS_InstantiateFunctionListItem2(JSContext *ctx, JSObject *p, JSAtom atom, void *opaque); void JS_SetUncatchableError(JSContext *ctx, JSValueConst val, BOOL flag); +static JSValue js_object_groupBy(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv, int is_map); static const JSClassExoticMethods js_arguments_exotic_methods; static const JSClassExoticMethods js_string_exotic_methods; @@ -1311,14 +1337,12 @@ void *js_mallocz_rt(JSRuntime *rt, size_t size) return memset(ptr, 0, size); } -#ifdef CONFIG_BIGNUM /* called by libbf */ static void *js_bf_realloc(void *opaque, void *ptr, size_t size) { JSRuntime *rt = opaque; return js_realloc_rt(rt, ptr, size); } -#endif /* CONFIG_BIGNUM */ /* Throw out of memory in case of error */ void *js_malloc(JSContext *ctx, size_t size) @@ -1469,15 +1493,13 @@ static JSClassShortDef const js_std_class_def[] = { { JS_ATOM_Uint16Array, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_UINT16_ARRAY */ { JS_ATOM_Int32Array, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_INT32_ARRAY */ { JS_ATOM_Uint32Array, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_UINT32_ARRAY */ -#ifdef CONFIG_BIGNUM { JS_ATOM_BigInt64Array, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_BIG_INT64_ARRAY */ { JS_ATOM_BigUint64Array, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_BIG_UINT64_ARRAY */ -#endif { JS_ATOM_Float32Array, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_FLOAT32_ARRAY */ { JS_ATOM_Float64Array, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_FLOAT64_ARRAY */ { JS_ATOM_DataView, js_typed_array_finalizer, js_typed_array_mark }, /* JS_CLASS_DATAVIEW */ -#ifdef CONFIG_BIGNUM { JS_ATOM_BigInt, js_object_data_finalizer, js_object_data_mark }, /* JS_CLASS_BIG_INT */ +#ifdef CONFIG_BIGNUM { JS_ATOM_BigFloat, js_object_data_finalizer, js_object_data_mark }, /* JS_CLASS_BIG_FLOAT */ { JS_ATOM_BigFloatEnv, js_float_env_finalizer, NULL }, /* JS_CLASS_FLOAT_ENV */ { JS_ATOM_BigDecimal, js_object_data_finalizer, js_object_data_mark }, /* JS_CLASS_BIG_DECIMAL */ @@ -1512,7 +1534,6 @@ static int init_class_range(JSRuntime *rt, JSClassShortDef const *tab, return 0; } -#ifdef CONFIG_BIGNUM static JSValue JS_ThrowUnsupportedOperation(JSContext *ctx) { return JS_ThrowTypeError(ctx, "unsupported operation"); @@ -1568,8 +1589,6 @@ static void set_dummy_numeric_ops(JSNumericOperations *ops) ops->mul_pow10 = invalid_mul_pow10; } -#endif /* CONFIG_BIGNUM */ - #if !defined(CONFIG_STACK_CHECK) /* no stack limitation */ static inline uintptr_t js_get_stack_pointer(void) @@ -1617,9 +1636,9 @@ JSRuntime *JS_NewRuntime2(const JSMallocFunctions *mf, void *opaque) rt->malloc_state = ms; rt->malloc_gc_threshold = 256 * 1024; -#ifdef CONFIG_BIGNUM bf_context_init(&rt->bf_ctx, js_bf_realloc, rt); set_dummy_numeric_ops(&rt->bigint_ops); +#ifdef CONFIG_BIGNUM set_dummy_numeric_ops(&rt->bigfloat_ops); set_dummy_numeric_ops(&rt->bigdecimal_ops); #endif @@ -1674,19 +1693,19 @@ void JS_SetRuntimeOpaque(JSRuntime *rt, void *opaque) } /* default memory allocation functions with memory limitation */ -static inline size_t js_def_malloc_usable_size(void *ptr) +static size_t js_def_malloc_usable_size(const void *ptr) { #if defined(__APPLE__) return malloc_size(ptr); #elif defined(_WIN32) - return _msize(ptr); + return _msize((void *)ptr); #elif defined(EMSCRIPTEN) return 0; #elif defined(__linux__) - return malloc_usable_size(ptr); + return malloc_usable_size((void *)ptr); #else /* change this to `return 0;` if compilation fails */ - return malloc_usable_size(ptr); + return malloc_usable_size((void *)ptr); #endif } @@ -1750,18 +1769,7 @@ static const JSMallocFunctions def_malloc_funcs = { js_def_malloc, js_def_free, js_def_realloc, -#if defined(__APPLE__) - malloc_size, -#elif defined(_WIN32) - (size_t (*)(const void *))_msize, -#elif defined(EMSCRIPTEN) - NULL, -#elif defined(__linux__) - (size_t (*)(const void *))malloc_usable_size, -#else - /* change this to `NULL,` if compilation fails */ - malloc_usable_size, -#endif + js_def_malloc_usable_size, }; JSRuntime *JS_NewRuntime(void) @@ -1991,9 +1999,7 @@ void JS_FreeRuntime(JSRuntime *rt) } js_free_rt(rt, rt->class_array); -#ifdef CONFIG_BIGNUM bf_context_end(&rt->bf_ctx); -#endif #ifdef DUMP_LEAKS /* only the atoms defined in JS_InitAtoms() should be left */ @@ -2131,8 +2137,8 @@ JSContext *JS_NewContextRaw(JSRuntime *rt) } ctx->rt = rt; list_add_tail(&ctx->link, &rt->context_list); -#ifdef CONFIG_BIGNUM ctx->bf_ctx = &rt->bf_ctx; +#ifdef CONFIG_BIGNUM ctx->fp_env.prec = 113; ctx->fp_env.flags = bf_set_exp_bits(15) | BF_RNDN | BF_FLAG_SUBNORMAL; #endif @@ -2165,9 +2171,7 @@ JSContext *JS_NewContext(JSRuntime *rt) JS_AddIntrinsicMapSet(ctx); JS_AddIntrinsicTypedArrays(ctx); JS_AddIntrinsicPromise(ctx); -#ifdef CONFIG_BIGNUM JS_AddIntrinsicBigInt(ctx); -#endif return ctx; } @@ -2208,7 +2212,6 @@ JSValue JS_GetClassProto(JSContext *ctx, JSClassID class_id) typedef enum JSFreeModuleEnum { JS_FREE_MODULE_ALL, JS_FREE_MODULE_NOT_RESOLVED, - JS_FREE_MODULE_NOT_EVALUATED, } JSFreeModuleEnum; /* XXX: would be more efficient with separate module lists */ @@ -2218,8 +2221,7 @@ static void js_free_modules(JSContext *ctx, JSFreeModuleEnum flag) list_for_each_safe(el, el1, &ctx->loaded_modules) { JSModuleDef *m = list_entry(el, JSModuleDef, link); if (flag == JS_FREE_MODULE_ALL || - (flag == JS_FREE_MODULE_NOT_RESOLVED && !m->resolved) || - (flag == JS_FREE_MODULE_NOT_EVALUATED && !m->evaluated)) { + (flag == JS_FREE_MODULE_NOT_RESOLVED && !m->resolved)) { js_free_module_def(ctx, m); } } @@ -2375,6 +2377,11 @@ static inline BOOL is_math_mode(JSContext *ctx) JSStackFrame *sf = ctx->rt->current_stack_frame; return (sf && (sf->js_mode & JS_MODE_MATH)); } +#else +static inline BOOL is_math_mode(JSContext *ctx) +{ + return FALSE; +} #endif /* JSAtom support */ @@ -3369,16 +3376,25 @@ static inline BOOL JS_IsEmptyString(JSValueConst v) /* JSClass support */ +#ifdef CONFIG_ATOMICS +static pthread_mutex_t js_class_id_mutex = PTHREAD_MUTEX_INITIALIZER; +#endif + /* a new class ID is allocated if *pclass_id != 0 */ JSClassID JS_NewClassID(JSClassID *pclass_id) { JSClassID class_id; - /* XXX: make it thread safe */ +#ifdef CONFIG_ATOMICS + pthread_mutex_lock(&js_class_id_mutex); +#endif class_id = *pclass_id; if (class_id == 0) { class_id = js_class_id_alloc++; *pclass_id = class_id; } +#ifdef CONFIG_ATOMICS + pthread_mutex_unlock(&js_class_id_mutex); +#endif return class_id; } @@ -4074,7 +4090,7 @@ void JS_FreeCString(JSContext *ctx, const char *ptr) if (!ptr) return; /* purposely removing constness */ - p = (JSString *)(void *)(ptr - offsetof(JSString, u)); + p = container_of(ptr, JSString, u); JS_FreeValue(ctx, JS_MKPTR(JS_TAG_STRING, p)); } @@ -4453,6 +4469,7 @@ static no_inline int resize_properties(JSContext *ctx, JSShape **psh, JSShapeProperty *pr; void *sh_alloc; intptr_t h; + JSShape *old_sh; sh = *psh; new_size = max_int(count, sh->prop_size * 3 / 2); @@ -4468,19 +4485,21 @@ static no_inline int resize_properties(JSContext *ctx, JSShape **psh, new_hash_size = sh->prop_hash_mask + 1; while (new_hash_size < new_size) new_hash_size = 2 * new_hash_size; + /* resize the property shapes. Using js_realloc() is not possible in + case the GC runs during the allocation */ + old_sh = sh; + sh_alloc = js_malloc(ctx, get_shape_size(new_hash_size, new_size)); + if (!sh_alloc) + return -1; + sh = get_shape_from_alloc(sh_alloc, new_hash_size); + list_del(&old_sh->header.link); + /* copy all the shape properties */ + memcpy(sh, old_sh, + sizeof(JSShape) + sizeof(sh->prop[0]) * old_sh->prop_count); + list_add_tail(&sh->header.link, &ctx->rt->gc_obj_list); + if (new_hash_size != (sh->prop_hash_mask + 1)) { - JSShape *old_sh; /* resize the hash table and the properties */ - old_sh = sh; - sh_alloc = js_malloc(ctx, get_shape_size(new_hash_size, new_size)); - if (!sh_alloc) - return -1; - sh = get_shape_from_alloc(sh_alloc, new_hash_size); - list_del(&old_sh->header.link); - /* copy all the fields and the properties */ - memcpy(sh, old_sh, - sizeof(JSShape) + sizeof(sh->prop[0]) * old_sh->prop_count); - list_add_tail(&sh->header.link, &ctx->rt->gc_obj_list); new_hash_mask = new_hash_size - 1; sh->prop_hash_mask = new_hash_mask; memset(prop_hash_end(sh) - new_hash_size, 0, @@ -4492,20 +4511,12 @@ static no_inline int resize_properties(JSContext *ctx, JSShape **psh, prop_hash_end(sh)[-h - 1] = i + 1; } } - js_free(ctx, get_alloc_from_shape(old_sh)); } else { - /* only resize the properties */ - list_del(&sh->header.link); - sh_alloc = js_realloc(ctx, get_alloc_from_shape(sh), - get_shape_size(new_hash_size, new_size)); - if (unlikely(!sh_alloc)) { - /* insert again in the GC list */ - list_add_tail(&sh->header.link, &ctx->rt->gc_obj_list); - return -1; - } - sh = get_shape_from_alloc(sh_alloc, new_hash_size); - list_add_tail(&sh->header.link, &ctx->rt->gc_obj_list); + /* just copy the previous hash table */ + memcpy(prop_hash_end(sh) - new_hash_size, prop_hash_end(old_sh) - new_hash_size, + sizeof(prop_hash_end(sh)[0]) * new_hash_size); } + js_free(ctx, get_alloc_from_shape(old_sh)); *psh = sh; sh->prop_size = new_size; return 0; @@ -4782,10 +4793,8 @@ static JSValue JS_NewObjectFromShape(JSContext *ctx, JSShape *sh, JSClassID clas case JS_CLASS_UINT16_ARRAY: case JS_CLASS_INT32_ARRAY: case JS_CLASS_UINT32_ARRAY: -#ifdef CONFIG_BIGNUM case JS_CLASS_BIG_INT64_ARRAY: case JS_CLASS_BIG_UINT64_ARRAY: -#endif case JS_CLASS_FLOAT32_ARRAY: case JS_CLASS_FLOAT64_ARRAY: p->is_exotic = 1; @@ -4802,8 +4811,8 @@ static JSValue JS_NewObjectFromShape(JSContext *ctx, JSShape *sh, JSClassID clas case JS_CLASS_BOOLEAN: case JS_CLASS_SYMBOL: case JS_CLASS_DATE: -#ifdef CONFIG_BIGNUM case JS_CLASS_BIG_INT: +#ifdef CONFIG_BIGNUM case JS_CLASS_BIG_FLOAT: case JS_CLASS_BIG_DECIMAL: #endif @@ -4865,8 +4874,8 @@ static JSValue JS_GetObjectData(JSContext *ctx, JSValueConst obj) case JS_CLASS_BOOLEAN: case JS_CLASS_SYMBOL: case JS_CLASS_DATE: -#ifdef CONFIG_BIGNUM case JS_CLASS_BIG_INT: +#ifdef CONFIG_BIGNUM case JS_CLASS_BIG_FLOAT: case JS_CLASS_BIG_DECIMAL: #endif @@ -4889,8 +4898,8 @@ static int JS_SetObjectData(JSContext *ctx, JSValueConst obj, JSValue val) case JS_CLASS_BOOLEAN: case JS_CLASS_SYMBOL: case JS_CLASS_DATE: -#ifdef CONFIG_BIGNUM case JS_CLASS_BIG_INT: +#ifdef CONFIG_BIGNUM case JS_CLASS_BIG_FLOAT: case JS_CLASS_BIG_DECIMAL: #endif @@ -5237,10 +5246,12 @@ static void free_var_ref(JSRuntime *rt, JSVarRef *var_ref) if (--var_ref->header.ref_count == 0) { if (var_ref->is_detached) { JS_FreeValueRT(rt, var_ref->value); - remove_gc_object(&var_ref->header); } else { - list_del(&var_ref->header.link); /* still on the stack */ + list_del(&var_ref->var_ref_link); /* still on the stack */ + if (var_ref->async_func) + async_func_free(rt, var_ref->async_func); } + remove_gc_object(&var_ref->header); js_free_rt(rt, var_ref); } } @@ -5338,7 +5349,7 @@ static void js_bytecode_function_mark(JSRuntime *rt, JSValueConst val, if (var_refs) { for(i = 0; i < b->closure_var_count; i++) { JSVarRef *var_ref = var_refs[i]; - if (var_ref && var_ref->is_detached) { + if (var_ref) { mark_func(rt, &var_ref->header); } } @@ -5380,7 +5391,15 @@ static void js_for_in_iterator_finalizer(JSRuntime *rt, JSValue val) { JSObject *p = JS_VALUE_GET_OBJ(val); JSForInIterator *it = p->u.for_in_iterator; + int i; + JS_FreeValueRT(rt, it->obj); + if (!it->is_array) { + for(i = 0; i < it->atom_count; i++) { + JS_FreeAtomRT(rt, it->tab_atom[i].atom); + } + js_free_rt(rt, it->tab_atom); + } js_free_rt(rt, it); } @@ -5448,6 +5467,9 @@ static void free_gc_object(JSRuntime *rt, JSGCObjectHeader *gp) case JS_GC_OBJ_TYPE_FUNCTION_BYTECODE: free_function_bytecode(rt, (JSFunctionBytecode *)gp); break; + case JS_GC_OBJ_TYPE_ASYNC_FUNCTION: + __async_func_free(rt, (JSAsyncFunctionState *)gp); + break; default: abort(); } @@ -5517,15 +5539,17 @@ void __JS_FreeValueRT(JSRuntime *rt, JSValue v) case JS_TAG_MODULE: abort(); /* never freed here */ break; -#ifdef CONFIG_BIGNUM case JS_TAG_BIG_INT: +#ifdef CONFIG_BIGNUM case JS_TAG_BIG_FLOAT: +#endif { JSBigFloat *bf = JS_VALUE_GET_PTR(v); bf_delete(&bf->num); js_free_rt(rt, bf); } break; +#ifdef CONFIG_BIGNUM case JS_TAG_BIG_DECIMAL: { JSBigDecimal *bf = JS_VALUE_GET_PTR(v); @@ -5604,11 +5628,9 @@ static void mark_children(JSRuntime *rt, JSGCObjectHeader *gp, if (pr->u.getset.setter) mark_func(rt, &pr->u.getset.setter->header); } else if ((prs->flags & JS_PROP_TMASK) == JS_PROP_VARREF) { - if (pr->u.var_ref->is_detached) { - /* Note: the tag does not matter - provided it is a GC object */ - mark_func(rt, &pr->u.var_ref->header); - } + /* Note: the tag does not matter + provided it is a GC object */ + mark_func(rt, &pr->u.var_ref->header); } else if ((prs->flags & JS_PROP_TMASK) == JS_PROP_AUTOINIT) { js_autoinit_mark(rt, pr, mark_func); } @@ -5642,16 +5664,32 @@ static void mark_children(JSRuntime *rt, JSGCObjectHeader *gp, case JS_GC_OBJ_TYPE_VAR_REF: { JSVarRef *var_ref = (JSVarRef *)gp; - /* only detached variable referenced are taken into account */ - assert(var_ref->is_detached); - JS_MarkValue(rt, *var_ref->pvalue, mark_func); + if (var_ref->is_detached) { + JS_MarkValue(rt, *var_ref->pvalue, mark_func); + } else if (var_ref->async_func) { + mark_func(rt, &var_ref->async_func->header); + } } break; case JS_GC_OBJ_TYPE_ASYNC_FUNCTION: { - JSAsyncFunctionData *s = (JSAsyncFunctionData *)gp; - if (s->is_active) - async_func_mark(rt, &s->func_state, mark_func); + JSAsyncFunctionState *s = (JSAsyncFunctionState *)gp; + JSStackFrame *sf = &s->frame; + JSValue *sp; + + if (!s->is_completed) { + JS_MarkValue(rt, sf->cur_func, mark_func); + JS_MarkValue(rt, s->this_val, mark_func); + /* sf->cur_sp = NULL if the function is running */ + if (sf->cur_sp) { + /* if the function is running, cur_sp is not known so we + cannot mark the stack. Marking the variables is not needed + because a running function cannot be part of a removable + cycle */ + for(sp = sf->arg_buf; sp < sf->cur_sp; sp++) + JS_MarkValue(rt, *sp, mark_func); + } + } JS_MarkValue(rt, s->resolving_funcs[0], mark_func); JS_MarkValue(rt, s->resolving_funcs[1], mark_func); } @@ -5759,12 +5797,13 @@ static void gc_free_cycles(JSRuntime *rt) if (el == &rt->tmp_obj_list) break; p = list_entry(el, JSGCObjectHeader, link); - /* Only need to free the GC object associated with JS - values. The rest will be automatically removed because they - must be referenced by them. */ + /* Only need to free the GC object associated with JS values + or async functions. The rest will be automatically removed + because they must be referenced by them. */ switch(p->gc_obj_type) { case JS_GC_OBJ_TYPE_JS_OBJECT: case JS_GC_OBJ_TYPE_FUNCTION_BYTECODE: + case JS_GC_OBJ_TYPE_ASYNC_FUNCTION: #ifdef DUMP_GC_FREE if (!header_done) { printf("Freeing cycles:\n"); @@ -5786,7 +5825,8 @@ static void gc_free_cycles(JSRuntime *rt) list_for_each_safe(el, el1, &rt->gc_zero_ref_count_list) { p = list_entry(el, JSGCObjectHeader, link); assert(p->gc_obj_type == JS_GC_OBJ_TYPE_JS_OBJECT || - p->gc_obj_type == JS_GC_OBJ_TYPE_FUNCTION_BYTECODE); + p->gc_obj_type == JS_GC_OBJ_TYPE_FUNCTION_BYTECODE || + p->gc_obj_type == JS_GC_OBJ_TYPE_ASYNC_FUNCTION); js_free_rt(rt, p); } @@ -5888,13 +5928,13 @@ static void compute_value_size(JSValueConst val, JSMemoryUsage_helper *hp) case JS_TAG_STRING: compute_jsstring_size(JS_VALUE_GET_STRING(val), hp); break; -#ifdef CONFIG_BIGNUM case JS_TAG_BIG_INT: +#ifdef CONFIG_BIGNUM case JS_TAG_BIG_FLOAT: case JS_TAG_BIG_DECIMAL: +#endif /* should track JSBigFloat usage */ break; -#endif } } @@ -6018,8 +6058,8 @@ void JS_ComputeMemoryUsage(JSRuntime *rt, JSMemoryUsage *s) case JS_CLASS_BOOLEAN: /* u.object_data */ case JS_CLASS_SYMBOL: /* u.object_data */ case JS_CLASS_DATE: /* u.object_data */ -#ifdef CONFIG_BIGNUM case JS_CLASS_BIG_INT: /* u.object_data */ +#ifdef CONFIG_BIGNUM case JS_CLASS_BIG_FLOAT: /* u.object_data */ case JS_CLASS_BIG_DECIMAL: /* u.object_data */ #endif @@ -6111,10 +6151,8 @@ void JS_ComputeMemoryUsage(JSRuntime *rt, JSMemoryUsage *s) case JS_CLASS_UINT16_ARRAY: /* u.typed_array / u.array */ case JS_CLASS_INT32_ARRAY: /* u.typed_array / u.array */ case JS_CLASS_UINT32_ARRAY: /* u.typed_array / u.array */ -#ifdef CONFIG_BIGNUM case JS_CLASS_BIG_INT64_ARRAY: /* u.typed_array / u.array */ case JS_CLASS_BIG_UINT64_ARRAY: /* u.typed_array / u.array */ -#endif case JS_CLASS_FLOAT32_ARRAY: /* u.typed_array / u.array */ case JS_CLASS_FLOAT64_ARRAY: /* u.typed_array / u.array */ case JS_CLASS_DATAVIEW: /* u.typed_array */ @@ -6241,10 +6279,10 @@ void JS_DumpMemoryUsage(FILE *fp, const JSMemoryUsage *s, JSRuntime *rt) if (obj_classes[0]) fprintf(fp, " %5d %2.0d %s\n", obj_classes[0], 0, "none"); for (class_id = 1; class_id < JS_CLASS_INIT_COUNT; class_id++) { - if (obj_classes[class_id]) { + if (obj_classes[class_id] && class_id < rt->class_count) { char buf[ATOM_GET_STR_BUF_SIZE]; fprintf(fp, " %5d %2.0d %s\n", obj_classes[class_id], class_id, - JS_AtomGetStrRT(rt, buf, sizeof(buf), js_std_class_def[class_id - 1].class_name)); + JS_AtomGetStrRT(rt, buf, sizeof(buf), rt->class_array[class_id].class_name)); } } if (obj_classes[JS_CLASS_INIT_COUNT]) @@ -6875,10 +6913,10 @@ int JS_SetPrototype(JSContext *ctx, JSValueConst obj, JSValueConst proto_val) static JSValueConst JS_GetPrototypePrimitive(JSContext *ctx, JSValueConst val) { switch(JS_VALUE_GET_NORM_TAG(val)) { -#ifdef CONFIG_BIGNUM case JS_TAG_BIG_INT: val = ctx->class_proto[JS_CLASS_BIG_INT]; break; +#ifdef CONFIG_BIGNUM case JS_TAG_BIG_FLOAT: val = ctx->class_proto[JS_CLASS_BIG_FLOAT]; break; @@ -7313,6 +7351,8 @@ static int JS_SetPrivateField(JSContext *ctx, JSValueConst obj, return 0; } +/* add a private brand field to 'home_obj' if not already present and + if obj is != null add a private brand to it */ static int JS_AddBrand(JSContext *ctx, JSValueConst obj, JSValueConst home_obj) { JSObject *p, *p1; @@ -7328,10 +7368,10 @@ static int JS_AddBrand(JSContext *ctx, JSValueConst obj, JSValueConst home_obj) p = JS_VALUE_GET_OBJ(home_obj); prs = find_own_property(&pr, p, JS_ATOM_Private_brand); if (!prs) { + /* if the brand is not present, add it */ brand = JS_NewSymbolFromAtom(ctx, JS_ATOM_brand, JS_ATOM_TYPE_PRIVATE); if (JS_IsException(brand)) return -1; - /* if the brand is not present, add it */ pr = add_property(ctx, p, JS_ATOM_Private_brand, JS_PROP_C_W_E); if (!pr) { JS_FreeValue(ctx, brand); @@ -7343,20 +7383,27 @@ static int JS_AddBrand(JSContext *ctx, JSValueConst obj, JSValueConst home_obj) } brand_atom = js_symbol_to_atom(ctx, brand); - if (unlikely(JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT)) { - JS_ThrowTypeErrorNotAnObject(ctx); + if (JS_IsObject(obj)) { + p1 = JS_VALUE_GET_OBJ(obj); + prs = find_own_property(&pr, p1, brand_atom); + if (unlikely(prs)) { + JS_FreeAtom(ctx, brand_atom); + JS_ThrowTypeError(ctx, "private method is already present"); + return -1; + } + pr = add_property(ctx, p1, brand_atom, JS_PROP_C_W_E); + JS_FreeAtom(ctx, brand_atom); + if (!pr) + return -1; + pr->u.value = JS_UNDEFINED; + } else { JS_FreeAtom(ctx, brand_atom); - return -1; } - p1 = JS_VALUE_GET_OBJ(obj); - pr = add_property(ctx, p1, brand_atom, JS_PROP_C_W_E); - JS_FreeAtom(ctx, brand_atom); - if (!pr) - return -1; - pr->u.value = JS_UNDEFINED; return 0; } +/* return a boolean telling if the brand of the home object of 'func' + is present on 'obj' or -1 in case of exception */ static int JS_CheckBrand(JSContext *ctx, JSValueConst obj, JSValueConst func) { JSObject *p, *p1, *home_obj; @@ -7365,11 +7412,8 @@ static int JS_CheckBrand(JSContext *ctx, JSValueConst obj, JSValueConst func) JSValueConst brand; /* get the home object of 'func' */ - if (unlikely(JS_VALUE_GET_TAG(func) != JS_TAG_OBJECT)) { - not_obj: - JS_ThrowTypeErrorNotAnObject(ctx); - return -1; - } + if (unlikely(JS_VALUE_GET_TAG(func) != JS_TAG_OBJECT)) + goto not_obj; p1 = JS_VALUE_GET_OBJ(func); if (!js_class_has_bytecode(p1->class_id)) goto not_obj; @@ -7387,15 +7431,14 @@ static int JS_CheckBrand(JSContext *ctx, JSValueConst obj, JSValueConst func) goto not_obj; /* get the brand array of 'obj' */ - if (unlikely(JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT)) - goto not_obj; - p = JS_VALUE_GET_OBJ(obj); - prs = find_own_property(&pr, p, js_symbol_to_atom(ctx, (JSValue)brand)); - if (!prs) { - JS_ThrowTypeError(ctx, "invalid brand on object"); + if (unlikely(JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT)) { + not_obj: + JS_ThrowTypeErrorNotAnObject(ctx); return -1; } - return 0; + p = JS_VALUE_GET_OBJ(obj); + prs = find_own_property(&pr, p, js_symbol_to_atom(ctx, (JSValue)brand)); + return (prs != NULL); } static uint32_t js_string_obj_get_length(JSContext *ctx, @@ -7852,39 +7895,45 @@ static JSValue JS_GetPropertyValue(JSContext *ctx, JSValueConst this_obj, if (likely(JS_VALUE_GET_TAG(this_obj) == JS_TAG_OBJECT && JS_VALUE_GET_TAG(prop) == JS_TAG_INT)) { JSObject *p; - uint32_t idx, len; + uint32_t idx; /* fast path for array access */ p = JS_VALUE_GET_OBJ(this_obj); idx = JS_VALUE_GET_INT(prop); - len = (uint32_t)p->u.array.count; - if (unlikely(idx >= len)) - goto slow_path; switch(p->class_id) { case JS_CLASS_ARRAY: case JS_CLASS_ARGUMENTS: + if (unlikely(idx >= p->u.array.count)) goto slow_path; return JS_DupValue(ctx, p->u.array.u.values[idx]); case JS_CLASS_INT8_ARRAY: + if (unlikely(idx >= p->u.array.count)) goto slow_path; return JS_NewInt32(ctx, p->u.array.u.int8_ptr[idx]); case JS_CLASS_UINT8C_ARRAY: case JS_CLASS_UINT8_ARRAY: + if (unlikely(idx >= p->u.array.count)) goto slow_path; return JS_NewInt32(ctx, p->u.array.u.uint8_ptr[idx]); case JS_CLASS_INT16_ARRAY: + if (unlikely(idx >= p->u.array.count)) goto slow_path; return JS_NewInt32(ctx, p->u.array.u.int16_ptr[idx]); case JS_CLASS_UINT16_ARRAY: + if (unlikely(idx >= p->u.array.count)) goto slow_path; return JS_NewInt32(ctx, p->u.array.u.uint16_ptr[idx]); case JS_CLASS_INT32_ARRAY: + if (unlikely(idx >= p->u.array.count)) goto slow_path; return JS_NewInt32(ctx, p->u.array.u.int32_ptr[idx]); case JS_CLASS_UINT32_ARRAY: + if (unlikely(idx >= p->u.array.count)) goto slow_path; return JS_NewUint32(ctx, p->u.array.u.uint32_ptr[idx]); -#ifdef CONFIG_BIGNUM case JS_CLASS_BIG_INT64_ARRAY: + if (unlikely(idx >= p->u.array.count)) goto slow_path; return JS_NewBigInt64(ctx, p->u.array.u.int64_ptr[idx]); case JS_CLASS_BIG_UINT64_ARRAY: + if (unlikely(idx >= p->u.array.count)) goto slow_path; return JS_NewBigUint64(ctx, p->u.array.u.uint64_ptr[idx]); -#endif case JS_CLASS_FLOAT32_ARRAY: + if (unlikely(idx >= p->u.array.count)) goto slow_path; return __JS_NewFloat64(ctx, p->u.array.u.float_ptr[idx]); case JS_CLASS_FLOAT64_ARRAY: + if (unlikely(idx >= p->u.array.count)) goto slow_path; return __JS_NewFloat64(ctx, p->u.array.u.double_ptr[idx]); default: goto slow_path; @@ -8302,6 +8351,30 @@ static int add_fast_array_element(JSContext *ctx, JSObject *p, return TRUE; } +/* Allocate a new fast array. Its 'length' property is set to zero. It + maximum size is 2^31-1 elements. For convenience, 'len' is a 64 bit + integer. WARNING: the content of the array is not initialized. */ +static JSValue js_allocate_fast_array(JSContext *ctx, int64_t len) +{ + JSValue arr; + JSObject *p; + + if (len > INT32_MAX) + return JS_ThrowRangeError(ctx, "invalid array length"); + arr = JS_NewArray(ctx); + if (JS_IsException(arr)) + return arr; + if (len > 0) { + p = JS_VALUE_GET_OBJ(arr); + if (expand_fast_array(ctx, p, len) < 0) { + JS_FreeValue(ctx, arr); + return JS_EXCEPTION; + } + p->u.array.count = len; + } + return arr; +} + static void js_free_desc(JSContext *ctx, JSPropertyDescriptor *desc) { JS_FreeValue(ctx, desc->getter); @@ -8309,119 +8382,14 @@ static void js_free_desc(JSContext *ctx, JSPropertyDescriptor *desc) JS_FreeValue(ctx, desc->value); } -/* generic (and slower) version of JS_SetProperty() for - * Reflect.set(). 'obj' must be an object. */ -static int JS_SetPropertyGeneric(JSContext *ctx, - JSValueConst obj, JSAtom prop, - JSValue val, JSValueConst this_obj, - int flags) -{ - int ret; - JSPropertyDescriptor desc; - JSValue obj1; - JSObject *p; - - obj1 = JS_DupValue(ctx, obj); - for(;;) { - p = JS_VALUE_GET_OBJ(obj1); - if (p->is_exotic) { - const JSClassExoticMethods *em = ctx->rt->class_array[p->class_id].exotic; - if (em && em->set_property) { - ret = em->set_property(ctx, obj1, prop, - val, this_obj, flags); - JS_FreeValue(ctx, obj1); - JS_FreeValue(ctx, val); - return ret; - } - } - - ret = JS_GetOwnPropertyInternal(ctx, &desc, p, prop); - if (ret < 0) { - JS_FreeValue(ctx, obj1); - JS_FreeValue(ctx, val); - return ret; - } - if (ret) { - if (desc.flags & JS_PROP_GETSET) { - JSObject *setter; - if (JS_IsUndefined(desc.setter)) - setter = NULL; - else - setter = JS_VALUE_GET_OBJ(desc.setter); - ret = call_setter(ctx, setter, this_obj, val, flags); - JS_FreeValue(ctx, desc.getter); - JS_FreeValue(ctx, desc.setter); - JS_FreeValue(ctx, obj1); - return ret; - } else { - JS_FreeValue(ctx, desc.value); - if (!(desc.flags & JS_PROP_WRITABLE)) { - JS_FreeValue(ctx, obj1); - goto read_only_error; - } - } - break; - } - /* Note: at this point 'obj1' cannot be a proxy. XXX: may have - to check recursion */ - obj1 = JS_GetPrototypeFree(ctx, obj1); - if (JS_IsNull(obj1)) - break; - } - JS_FreeValue(ctx, obj1); - - if (!JS_IsObject(this_obj)) { - JS_FreeValue(ctx, val); - return JS_ThrowTypeErrorOrFalse(ctx, flags, "receiver is not an object"); - } - - p = JS_VALUE_GET_OBJ(this_obj); - - /* modify the property in this_obj if it already exists */ - ret = JS_GetOwnPropertyInternal(ctx, &desc, p, prop); - if (ret < 0) { - JS_FreeValue(ctx, val); - return ret; - } - if (ret) { - if (desc.flags & JS_PROP_GETSET) { - JS_FreeValue(ctx, desc.getter); - JS_FreeValue(ctx, desc.setter); - JS_FreeValue(ctx, val); - return JS_ThrowTypeErrorOrFalse(ctx, flags, "setter is forbidden"); - } else { - JS_FreeValue(ctx, desc.value); - if (!(desc.flags & JS_PROP_WRITABLE) || - p->class_id == JS_CLASS_MODULE_NS) { - read_only_error: - JS_FreeValue(ctx, val); - return JS_ThrowTypeErrorReadOnly(ctx, flags, prop); - } - } - ret = JS_DefineProperty(ctx, this_obj, prop, val, - JS_UNDEFINED, JS_UNDEFINED, - JS_PROP_HAS_VALUE); - JS_FreeValue(ctx, val); - return ret; - } - - ret = JS_CreateProperty(ctx, p, prop, val, JS_UNDEFINED, JS_UNDEFINED, - flags | - JS_PROP_HAS_VALUE | - JS_PROP_HAS_ENUMERABLE | - JS_PROP_HAS_WRITABLE | - JS_PROP_HAS_CONFIGURABLE | - JS_PROP_C_W_E); - JS_FreeValue(ctx, val); - return ret; -} - /* return -1 in case of exception or TRUE or FALSE. Warning: 'val' is freed by the function. 'flags' is a bitmask of JS_PROP_NO_ADD, JS_PROP_THROW or JS_PROP_THROW_STRICT. If JS_PROP_NO_ADD is set, - the new property is not added and an error is raised. */ -int JS_SetPropertyInternal(JSContext *ctx, JSValueConst this_obj, - JSAtom prop, JSValue val, int flags) + the new property is not added and an error is raised. 'this_obj' is + the receiver. If obj != this_obj, then obj must be an object + (Reflect.set case). */ +int JS_SetPropertyInternal(JSContext *ctx, JSValueConst obj, + JSAtom prop, JSValue val, JSValueConst this_obj, int flags) { JSObject *p, *p1; JSShapeProperty *prs; @@ -8434,25 +8402,37 @@ int JS_SetPropertyInternal(JSContext *ctx, JSValueConst this_obj, #endif tag = JS_VALUE_GET_TAG(this_obj); if (unlikely(tag != JS_TAG_OBJECT)) { - switch(tag) { - case JS_TAG_NULL: - JS_FreeValue(ctx, val); - JS_ThrowTypeErrorAtom(ctx, "cannot set property '%s' of null", prop); - return -1; - case JS_TAG_UNDEFINED: - JS_FreeValue(ctx, val); - JS_ThrowTypeErrorAtom(ctx, "cannot set property '%s' of undefined", prop); - return -1; - default: - /* even on a primitive type we can have setters on the prototype */ + if (JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT) { p = NULL; - p1 = JS_VALUE_GET_OBJ(JS_GetPrototypePrimitive(ctx, this_obj)); + p1 = JS_VALUE_GET_OBJ(obj); goto prototype_lookup; + } else { + switch(tag) { + case JS_TAG_NULL: + JS_FreeValue(ctx, val); + JS_ThrowTypeErrorAtom(ctx, "cannot set property '%s' of null", prop); + return -1; + case JS_TAG_UNDEFINED: + JS_FreeValue(ctx, val); + JS_ThrowTypeErrorAtom(ctx, "cannot set property '%s' of undefined", prop); + return -1; + default: + /* even on a primitive type we can have setters on the prototype */ + p = NULL; + p1 = JS_VALUE_GET_OBJ(JS_GetPrototypePrimitive(ctx, obj)); + goto prototype_lookup; + } } + } else { + p = JS_VALUE_GET_OBJ(this_obj); + p1 = JS_VALUE_GET_OBJ(obj); + if (unlikely(p != p1)) + goto retry2; } - p = JS_VALUE_GET_OBJ(this_obj); -retry: - prs = find_own_property(&pr, p, prop); + + /* fast path if obj == this_obj */ + retry: + prs = find_own_property(&pr, p1, prop); if (prs) { if (likely((prs->flags & (JS_PROP_TMASK | JS_PROP_WRITABLE | JS_PROP_LENGTH)) == JS_PROP_WRITABLE)) { @@ -8484,8 +8464,7 @@ retry: goto read_only_prop; } } - - p1 = p; + for(;;) { if (p1->is_exotic) { if (p1->fast_array) { @@ -8509,11 +8488,19 @@ retry: return -1; } typed_array_oob: - val = JS_ToNumberFree(ctx, val); - JS_FreeValue(ctx, val); - if (JS_IsException(val)) - return -1; - return JS_ThrowTypeErrorOrFalse(ctx, flags, "out-of-bound numeric index"); + /* must convert the argument even if out of bound access */ + if (p1->class_id == JS_CLASS_BIG_INT64_ARRAY || + p1->class_id == JS_CLASS_BIG_UINT64_ARRAY) { + int64_t v; + if (JS_ToBigInt64Free(ctx, &v, val)) + return -1; + } else { + val = JS_ToNumberFree(ctx, val); + JS_FreeValue(ctx, val); + if (JS_IsException(val)) + return -1; + } + return TRUE; } } } else { @@ -8585,9 +8572,7 @@ retry: return -1; goto retry2; } else if (!(prs->flags & JS_PROP_WRITABLE)) { - read_only_prop: - JS_FreeValue(ctx, val); - return JS_ThrowTypeErrorReadOnly(ctx, flags, prop); + goto read_only_prop; } } } @@ -8608,16 +8593,56 @@ retry: return JS_ThrowTypeErrorOrFalse(ctx, flags, "object is not extensible"); } - if (p->is_exotic) { - if (p->class_id == JS_CLASS_ARRAY && p->fast_array && - __JS_AtomIsTaggedInt(prop)) { - uint32_t idx = __JS_AtomToUInt32(prop); - if (idx == p->u.array.count) { - /* fast case */ - return add_fast_array_element(ctx, p, val, flags); + if (likely(p == JS_VALUE_GET_OBJ(obj))) { + if (p->is_exotic) { + if (p->class_id == JS_CLASS_ARRAY && p->fast_array && + __JS_AtomIsTaggedInt(prop)) { + uint32_t idx = __JS_AtomToUInt32(prop); + if (idx == p->u.array.count) { + /* fast case */ + return add_fast_array_element(ctx, p, val, flags); + } else { + goto generic_create_prop; + } } else { goto generic_create_prop; } + } else { + pr = add_property(ctx, p, prop, JS_PROP_C_W_E); + if (unlikely(!pr)) { + JS_FreeValue(ctx, val); + return -1; + } + pr->u.value = val; + return TRUE; + } + } else { + /* generic case: modify the property in this_obj if it already exists */ + ret = JS_GetOwnPropertyInternal(ctx, &desc, p, prop); + if (ret < 0) { + JS_FreeValue(ctx, val); + return ret; + } + if (ret) { + if (desc.flags & JS_PROP_GETSET) { + JS_FreeValue(ctx, desc.getter); + JS_FreeValue(ctx, desc.setter); + JS_FreeValue(ctx, val); + return JS_ThrowTypeErrorOrFalse(ctx, flags, "setter is forbidden"); + } else { + JS_FreeValue(ctx, desc.value); + if (!(desc.flags & JS_PROP_WRITABLE) || + p->class_id == JS_CLASS_MODULE_NS) { + read_only_prop: + JS_FreeValue(ctx, val); + return JS_ThrowTypeErrorReadOnly(ctx, flags, prop); + } + } + ret = JS_DefineProperty(ctx, this_obj, prop, val, + JS_UNDEFINED, JS_UNDEFINED, + JS_PROP_HAS_VALUE); + JS_FreeValue(ctx, val); + return ret; } else { generic_create_prop: ret = JS_CreateProperty(ctx, p, prop, val, JS_UNDEFINED, JS_UNDEFINED, @@ -8631,14 +8656,6 @@ retry: return ret; } } - - pr = add_property(ctx, p, prop, JS_PROP_C_W_E); - if (unlikely(!pr)) { - JS_FreeValue(ctx, val); - return -1; - } - pr->u.value = val; - return TRUE; } /* flags can be JS_PROP_THROW or JS_PROP_THROW_STRICT */ @@ -8723,7 +8740,6 @@ static int JS_SetPropertyValue(JSContext *ctx, JSValueConst this_obj, goto ta_out_of_bound; p->u.array.u.uint32_ptr[idx] = v; break; -#ifdef CONFIG_BIGNUM case JS_CLASS_BIG_INT64_ARRAY: case JS_CLASS_BIG_UINT64_ARRAY: /* XXX: need specific conversion function */ @@ -8736,7 +8752,6 @@ static int JS_SetPropertyValue(JSContext *ctx, JSValueConst this_obj, p->u.array.u.uint64_ptr[idx] = v; } break; -#endif case JS_CLASS_FLOAT32_ARRAY: if (JS_ToFloat64Free(ctx, &d, val)) return -1; @@ -8749,7 +8764,7 @@ static int JS_SetPropertyValue(JSContext *ctx, JSValueConst this_obj, return -1; if (unlikely(idx >= (uint32_t)p->u.array.count)) { ta_out_of_bound: - return JS_ThrowTypeErrorOrFalse(ctx, flags, "out-of-bound numeric index"); + return TRUE; } p->u.array.u.double_ptr[idx] = d; break; @@ -8767,7 +8782,7 @@ static int JS_SetPropertyValue(JSContext *ctx, JSValueConst this_obj, JS_FreeValue(ctx, val); return -1; } - ret = JS_SetPropertyInternal(ctx, this_obj, atom, val, flags); + ret = JS_SetPropertyInternal(ctx, this_obj, atom, val, this_obj, flags); JS_FreeAtom(ctx, atom); return ret; } @@ -8807,7 +8822,7 @@ int JS_SetPropertyStr(JSContext *ctx, JSValueConst this_obj, JSAtom atom; int ret; atom = JS_NewAtom(ctx, prop); - ret = JS_SetPropertyInternal(ctx, this_obj, atom, val, JS_PROP_THROW); + ret = JS_SetPropertyInternal(ctx, this_obj, atom, val, this_obj, JS_PROP_THROW); JS_FreeAtom(ctx, atom); return ret; } @@ -9147,15 +9162,19 @@ int JS_DefineProperty(JSContext *ctx, JSValueConst this_obj, spaces. */ if (!js_same_value(ctx, val, *pr->u.var_ref->pvalue)) goto not_configurable; + } else { + /* update the reference */ + set_value(ctx, pr->u.var_ref->pvalue, + JS_DupValue(ctx, val)); } - /* update the reference */ - set_value(ctx, pr->u.var_ref->pvalue, - JS_DupValue(ctx, val)); } /* if writable is set to false, no longer a reference (for mapped arguments) */ if ((flags & (JS_PROP_HAS_WRITABLE | JS_PROP_WRITABLE)) == JS_PROP_HAS_WRITABLE) { JSValue val1; + if (p->class_id == JS_CLASS_MODULE_NS) { + return JS_ThrowTypeErrorOrFalse(ctx, flags, "module namespace properties have writable = false"); + } if (js_shape_prepare_update(ctx, p, &prs)) return -1; val1 = JS_DupValue(ctx, *pr->u.var_ref->pvalue); @@ -9264,7 +9283,7 @@ int JS_DefineProperty(JSContext *ctx, JSValueConst this_obj, } idx = __JS_AtomToUInt32(prop); /* if the typed array is detached, p->u.array.count = 0 */ - if (idx >= typed_array_get_length(ctx, p)) { + if (idx >= p->u.array.count) { typed_array_oob: return JS_ThrowTypeErrorOrFalse(ctx, flags, "out-of-bound index in typed array"); } @@ -9658,7 +9677,7 @@ static int JS_SetGlobalVar(JSContext *ctx, JSAtom prop, JSValue val, flags = JS_PROP_THROW_STRICT; if (is_strict_mode(ctx)) flags |= JS_PROP_NO_ADD; - return JS_SetPropertyInternal(ctx, ctx->global_obj, prop, val, flags); + return JS_SetPropertyInternal(ctx, ctx->global_obj, prop, val, ctx->global_obj, flags); } /* return -1, FALSE or TRUE. return FALSE if not configurable or @@ -9935,9 +9954,10 @@ static int JS_ToBoolFree(JSContext *ctx, JSValue val) JS_FreeValue(ctx, val); return ret; } -#ifdef CONFIG_BIGNUM case JS_TAG_BIG_INT: +#ifdef CONFIG_BIGNUM case JS_TAG_BIG_FLOAT: +#endif { JSBigFloat *p = JS_VALUE_GET_PTR(val); BOOL ret; @@ -9945,6 +9965,7 @@ static int JS_ToBoolFree(JSContext *ctx, JSValue val) JS_FreeValue(ctx, val); return ret; } +#ifdef CONFIG_BIGNUM case JS_TAG_BIG_DECIMAL: { JSBigDecimal *p = JS_VALUE_GET_PTR(val); @@ -10014,12 +10035,13 @@ static inline int to_digit(int c) } /* XXX: remove */ -static double js_strtod(const char *p, int radix, BOOL is_float) +static double js_strtod(const char *str, int radix, BOOL is_float) { double d; int c; if (!is_float || radix != 10) { + const char *p = str; uint64_t n_max, n; int int_exp, is_neg; @@ -10046,6 +10068,8 @@ static double js_strtod(const char *p, int radix, BOOL is_float) if (n <= n_max) { n = n * radix + c; } else { + if (radix == 10) + goto strtod_case; int_exp++; } p++; @@ -10057,7 +10081,8 @@ static double js_strtod(const char *p, int radix, BOOL is_float) if (is_neg) d = -d; } else { - d = strtod(p, NULL); + strtod_case: + d = strtod(str, NULL); } return d; } @@ -10075,15 +10100,16 @@ static double js_strtod(const char *p, int radix, BOOL is_float) #define ATOD_TYPE_MASK (3 << 7) #define ATOD_TYPE_FLOAT64 (0 << 7) #define ATOD_TYPE_BIG_INT (1 << 7) +#ifdef CONFIG_BIGNUM #define ATOD_TYPE_BIG_FLOAT (2 << 7) #define ATOD_TYPE_BIG_DECIMAL (3 << 7) /* assume bigint mode: floats are parsed as integers if no decimal point nor exponent */ #define ATOD_MODE_BIGINT (1 << 9) +#endif /* accept -0x1 */ #define ATOD_ACCEPT_PREFIX_AFTER_SIGN (1 << 10) -#ifdef CONFIG_BIGNUM static JSValue js_string_to_bigint(JSContext *ctx, const char *buf, int radix, int flags, slimb_t *pexponent) { @@ -10099,10 +10125,15 @@ static JSValue js_string_to_bigint(JSContext *ctx, const char *buf, JS_FreeValue(ctx, val); return JS_ThrowOutOfMemory(ctx); } +#ifdef CONFIG_BIGNUM val = JS_CompactBigInt1(ctx, val, (flags & ATOD_MODE_BIGINT) != 0); +#else + val = JS_CompactBigInt1(ctx, val, FALSE); +#endif return val; } +#ifdef CONFIG_BIGNUM static JSValue js_string_to_bigfloat(JSContext *ctx, const char *buf, int radix, int flags, slimb_t *pexponent) { @@ -10148,7 +10179,6 @@ static JSValue js_string_to_bigdecimal(JSContext *ctx, const char *buf, } return val; } - #endif /* return an exception in case of memory error. Return JS_NAN if @@ -10223,8 +10253,11 @@ static JSValue js_atof(JSContext *ctx, const char *str, const char **pp, } else { no_radix_prefix: if (!(flags & ATOD_INT_ONLY) && - (atod_type == ATOD_TYPE_FLOAT64 || - atod_type == ATOD_TYPE_BIG_FLOAT) && + (atod_type == ATOD_TYPE_FLOAT64 +#ifdef CONFIG_BIGNUM + || atod_type == ATOD_TYPE_BIG_FLOAT +#endif + ) && strstart(p, "Infinity", &p)) { #ifdef CONFIG_BIGNUM if (atod_type == ATOD_TYPE_BIG_FLOAT) { @@ -10304,36 +10337,40 @@ static JSValue js_atof(JSContext *ctx, const char *str, const char **pp, } buf[j] = '\0'; -#ifdef CONFIG_BIGNUM if (flags & ATOD_ACCEPT_SUFFIX) { if (*p == 'n') { p++; atod_type = ATOD_TYPE_BIG_INT; - } else if (*p == 'l') { + } else +#ifdef CONFIG_BIGNUM + if (*p == 'l') { p++; atod_type = ATOD_TYPE_BIG_FLOAT; } else if (*p == 'm') { p++; atod_type = ATOD_TYPE_BIG_DECIMAL; - } else { - if (flags & ATOD_MODE_BIGINT) { - if (!is_float) - atod_type = ATOD_TYPE_BIG_INT; - if (has_legacy_octal) - goto fail; - } else { - if (is_float && radix != 10) - goto fail; - } + } else if (flags & ATOD_MODE_BIGINT) { + if (!is_float) + atod_type = ATOD_TYPE_BIG_INT; + if (has_legacy_octal) + goto fail; + } else +#endif + { + if (is_float && radix != 10) + goto fail; } } else { if (atod_type == ATOD_TYPE_FLOAT64) { +#ifdef CONFIG_BIGNUM if (flags & ATOD_MODE_BIGINT) { if (!is_float) atod_type = ATOD_TYPE_BIG_INT; if (has_legacy_octal) goto fail; - } else { + } else +#endif + { if (is_float && radix != 10) goto fail; } @@ -10354,6 +10391,7 @@ static JSValue js_atof(JSContext *ctx, const char *str, const char **pp, goto fail; val = ctx->rt->bigint_ops.from_string(ctx, buf, radix, flags, NULL); break; +#ifdef CONFIG_BIGNUM case ATOD_TYPE_BIG_FLOAT: if (has_legacy_octal) goto fail; @@ -10365,19 +10403,10 @@ static JSValue js_atof(JSContext *ctx, const char *str, const char **pp, goto fail; val = ctx->rt->bigdecimal_ops.from_string(ctx, buf, radix, flags, NULL); break; +#endif default: abort(); } -#else - { - double d; - (void)has_legacy_octal; - if (is_float && radix != 10) - goto fail; - d = js_strtod(buf, radix, is_float); - val = JS_NewFloat64(ctx, d); - } -#endif done: if (buf_allocated) @@ -10415,6 +10444,13 @@ static JSValue JS_ToNumberHintFree(JSContext *ctx, JSValue val, redo: tag = JS_VALUE_GET_NORM_TAG(val); switch(tag) { + case JS_TAG_BIG_INT: + if (flag != TON_FLAG_NUMERIC) { + JS_FreeValue(ctx, val); + return JS_ThrowTypeError(ctx, "cannot convert bigint to number"); + } + ret = val; + break; #ifdef CONFIG_BIGNUM case JS_TAG_BIG_DECIMAL: if (flag != TON_FLAG_NUMERIC) { @@ -10423,13 +10459,6 @@ static JSValue JS_ToNumberHintFree(JSContext *ctx, JSValue val, } ret = val; break; - case JS_TAG_BIG_INT: - if (flag != TON_FLAG_NUMERIC) { - JS_FreeValue(ctx, val); - return JS_ThrowTypeError(ctx, "cannot convert bigint to number"); - } - ret = val; - break; case JS_TAG_BIG_FLOAT: if (flag != TON_FLAG_NUMERIC) { JS_FreeValue(ctx, val); @@ -10528,9 +10557,10 @@ static __exception int __JS_ToFloat64Free(JSContext *ctx, double *pres, case JS_TAG_FLOAT64: d = JS_VALUE_GET_FLOAT64(val); break; -#ifdef CONFIG_BIGNUM case JS_TAG_BIG_INT: +#ifdef CONFIG_BIGNUM case JS_TAG_BIG_FLOAT: +#endif { JSBigFloat *p = JS_VALUE_GET_PTR(val); /* XXX: there can be a double rounding issue with some @@ -10540,7 +10570,6 @@ static __exception int __JS_ToFloat64Free(JSContext *ctx, double *pres, JS_FreeValue(ctx, val); } break; -#endif default: abort(); } @@ -10608,6 +10637,10 @@ static __maybe_unused JSValue JS_ToIntegerFree(JSContext *ctx, JSValue val) BOOL is_nan; a = JS_ToBigFloat(ctx, &a_s, val); + if (!a) { + JS_FreeValue(ctx, val); + return JS_EXCEPTION; + } if (!bf_is_finite(a)) { is_nan = bf_is_nan(a); if (is_nan) @@ -11008,9 +11041,10 @@ static __exception int JS_ToArrayLengthFree(JSContext *ctx, uint32_t *plen, len = v; } break; -#ifdef CONFIG_BIGNUM case JS_TAG_BIG_INT: +#ifdef CONFIG_BIGNUM case JS_TAG_BIG_FLOAT: +#endif { JSBigFloat *p = JS_VALUE_GET_PTR(val); bf_t a; @@ -11025,7 +11059,6 @@ static __exception int JS_ToArrayLengthFree(JSContext *ctx, uint32_t *plen, goto fail; } break; -#endif default: if (JS_TAG_IS_FLOAT64(tag)) { double d; @@ -11129,13 +11162,13 @@ static BOOL JS_NumberIsNegativeOrMinusZero(JSContext *ctx, JSValueConst val) u.d = JS_VALUE_GET_FLOAT64(val); return (u.u64 >> 63); } -#ifdef CONFIG_BIGNUM case JS_TAG_BIG_INT: { JSBigFloat *p = JS_VALUE_GET_PTR(val); /* Note: integer zeros are not necessarily positive */ return p->num.sign && !bf_is_zero(&p->num); } +#ifdef CONFIG_BIGNUM case JS_TAG_BIG_FLOAT: { JSBigFloat *p = JS_VALUE_GET_PTR(val); @@ -11154,8 +11187,6 @@ static BOOL JS_NumberIsNegativeOrMinusZero(JSContext *ctx, JSValueConst val) } } -#ifdef CONFIG_BIGNUM - static JSValue js_bigint_to_string1(JSContext *ctx, JSValueConst val, int radix) { JSValue ret; @@ -11185,6 +11216,8 @@ static JSValue js_bigint_to_string(JSContext *ctx, JSValueConst val) return js_bigint_to_string1(ctx, val, 10); } +#ifdef CONFIG_BIGNUM + static JSValue js_ftoa(JSContext *ctx, JSValueConst val1, int radix, limb_t prec, bf_flags_t flags) { @@ -11197,6 +11230,10 @@ static JSValue js_ftoa(JSContext *ctx, JSValueConst val1, int radix, if (JS_IsException(val)) return val; a = JS_ToBigFloat(ctx, &a_s, val); + if (!a) { + JS_FreeValue(ctx, val); + return JS_EXCEPTION; + } saved_sign = a->sign; if (a->expn == BF_EXP_ZERO) a->sign = 0; @@ -11253,6 +11290,8 @@ static JSValue js_bigdecimal_to_string1(JSContext *ctx, JSValueConst val, int saved_sign; a = JS_ToBigDecimal(ctx, val); + if (!a) + return JS_EXCEPTION; saved_sign = a->sign; if (a->expn == BF_EXP_ZERO) a->sign = 0; @@ -11585,9 +11624,9 @@ JSValue JS_ToStringInternal(JSContext *ctx, JSValueConst val, BOOL is_ToProperty case JS_TAG_FLOAT64: return js_dtoa(ctx, JS_VALUE_GET_FLOAT64(val), 10, 0, JS_DTOA_VAR_FORMAT); -#ifdef CONFIG_BIGNUM case JS_TAG_BIG_INT: return ctx->rt->bigint_ops.to_string(ctx, val); +#ifdef CONFIG_BIGNUM case JS_TAG_BIG_FLOAT: return ctx->rt->bigfloat_ops.to_string(ctx, val); case JS_TAG_BIG_DECIMAL: @@ -11748,10 +11787,8 @@ static __maybe_unused void JS_DumpObject(JSRuntime *rt, JSObject *p) case JS_CLASS_UINT16_ARRAY: case JS_CLASS_INT32_ARRAY: case JS_CLASS_UINT32_ARRAY: -#ifdef CONFIG_BIGNUM case JS_CLASS_BIG_INT64_ARRAY: case JS_CLASS_BIG_UINT64_ARRAY: -#endif case JS_CLASS_FLOAT32_ARRAY: case JS_CLASS_FLOAT64_ARRAY: { @@ -11878,7 +11915,6 @@ static __maybe_unused void JS_DumpValueShort(JSRuntime *rt, case JS_TAG_FLOAT64: printf("%.14g", JS_VALUE_GET_FLOAT64(val)); break; -#ifdef CONFIG_BIGNUM case JS_TAG_BIG_INT: { JSBigFloat *p = JS_VALUE_GET_PTR(val); @@ -11889,6 +11925,7 @@ static __maybe_unused void JS_DumpValueShort(JSRuntime *rt, bf_realloc(&rt->bf_ctx, str, 0); } break; +#ifdef CONFIG_BIGNUM case JS_TAG_BIG_FLOAT: { JSBigFloat *p = JS_VALUE_GET_PTR(val); @@ -11990,8 +12027,6 @@ static double js_pow(double a, double b) } } -#ifdef CONFIG_BIGNUM - JSValue JS_NewBigInt64_1(JSContext *ctx, int64_t v) { JSValue val; @@ -12036,70 +12071,6 @@ JSValue JS_NewBigUint64(JSContext *ctx, uint64_t v) return val; } -/* if the returned bigfloat is allocated it is equal to - 'buf'. Otherwise it is a pointer to the bigfloat in 'val'. Return - NULL in case of error. */ -static bf_t *JS_ToBigFloat(JSContext *ctx, bf_t *buf, JSValueConst val) -{ - uint32_t tag; - bf_t *r; - JSBigFloat *p; - - tag = JS_VALUE_GET_NORM_TAG(val); - switch(tag) { - case JS_TAG_INT: - case JS_TAG_BOOL: - case JS_TAG_NULL: - r = buf; - bf_init(ctx->bf_ctx, r); - if (bf_set_si(r, JS_VALUE_GET_INT(val))) - goto fail; - break; - case JS_TAG_FLOAT64: - r = buf; - bf_init(ctx->bf_ctx, r); - if (bf_set_float64(r, JS_VALUE_GET_FLOAT64(val))) { - fail: - bf_delete(r); - return NULL; - } - break; - case JS_TAG_BIG_INT: - case JS_TAG_BIG_FLOAT: - p = JS_VALUE_GET_PTR(val); - r = &p->num; - break; - case JS_TAG_UNDEFINED: - default: - r = buf; - bf_init(ctx->bf_ctx, r); - bf_set_nan(r); - break; - } - return r; -} - -/* return NULL if invalid type */ -static bfdec_t *JS_ToBigDecimal(JSContext *ctx, JSValueConst val) -{ - uint32_t tag; - JSBigDecimal *p; - bfdec_t *r; - - tag = JS_VALUE_GET_NORM_TAG(val); - switch(tag) { - case JS_TAG_BIG_DECIMAL: - p = JS_VALUE_GET_PTR(val); - r = &p->num; - break; - default: - JS_ThrowTypeError(ctx, "bigdecimal expected"); - r = NULL; - break; - } - return r; -} - /* return NaN if bad bigint literal */ static JSValue JS_StringToBigInt(JSContext *ctx, JSValue val) { @@ -12117,8 +12088,10 @@ static JSValue JS_StringToBigInt(JSContext *ctx, JSValue val) val = JS_NewBigInt64(ctx, 0); } else { flags = ATOD_INT_ONLY | ATOD_ACCEPT_BIN_OCT | ATOD_TYPE_BIG_INT; +#ifdef CONFIG_BIGNUM if (is_math_mode(ctx)) flags |= ATOD_MODE_BIGINT; +#endif val = js_atof(ctx, p, &p, 0, flags); p += skip_spaces(p); if (!JS_IsException(val)) { @@ -12179,6 +12152,7 @@ static bf_t *JS_ToBigIntFree(JSContext *ctx, bf_t *buf, JSValue val) p = JS_VALUE_GET_PTR(val); r = &p->num; break; +#ifdef CONFIG_BIGNUM case JS_TAG_BIG_FLOAT: if (!is_math_mode(ctx)) goto fail; @@ -12191,6 +12165,7 @@ static bf_t *JS_ToBigIntFree(JSContext *ctx, bf_t *buf, JSValue val) bf_rint(r, BF_RNDZ); JS_FreeValue(ctx, val); break; +#endif case JS_TAG_STRING: val = JS_StringToBigIntErr(ctx, val); if (JS_IsException(val)) @@ -12251,7 +12226,7 @@ static void JS_FreeBigInt(JSContext *ctx, bf_t *a, bf_t *buf) } else { JSBigFloat *p = (JSBigFloat *)((uint8_t *)a - offsetof(JSBigFloat, num)); - JS_FreeValue(ctx, JS_MKPTR(JS_TAG_BIG_FLOAT, p)); + JS_FreeValue(ctx, JS_MKPTR(JS_TAG_BIG_INT, p)); } } @@ -12286,28 +12261,6 @@ static JSBigFloat *js_new_bf(JSContext *ctx) return p; } -static JSValue JS_NewBigFloat(JSContext *ctx) -{ - JSBigFloat *p; - p = js_malloc(ctx, sizeof(*p)); - if (!p) - return JS_EXCEPTION; - p->header.ref_count = 1; - bf_init(ctx->bf_ctx, &p->num); - return JS_MKPTR(JS_TAG_BIG_FLOAT, p); -} - -static JSValue JS_NewBigDecimal(JSContext *ctx) -{ - JSBigDecimal *p; - p = js_malloc(ctx, sizeof(*p)); - if (!p) - return JS_EXCEPTION; - p->header.ref_count = 1; - bfdec_init(ctx->bf_ctx, &p->num); - return JS_MKPTR(JS_TAG_BIG_DECIMAL, p); -} - static JSValue JS_NewBigInt(JSContext *ctx) { JSBigFloat *p; @@ -12349,6 +12302,110 @@ static JSValue JS_CompactBigInt(JSContext *ctx, JSValue val) return JS_CompactBigInt1(ctx, val, is_math_mode(ctx)); } +static JSValue throw_bf_exception(JSContext *ctx, int status) +{ + const char *str; + if (status & BF_ST_MEM_ERROR) + return JS_ThrowOutOfMemory(ctx); + if (status & BF_ST_DIVIDE_ZERO) { + str = "division by zero"; + } else if (status & BF_ST_INVALID_OP) { + str = "invalid operation"; + } else { + str = "integer overflow"; + } + return JS_ThrowRangeError(ctx, "%s", str); +} + +/* if the returned bigfloat is allocated it is equal to + 'buf'. Otherwise it is a pointer to the bigfloat in 'val'. Return + NULL in case of error. */ +static bf_t *JS_ToBigFloat(JSContext *ctx, bf_t *buf, JSValueConst val) +{ + uint32_t tag; + bf_t *r; + JSBigFloat *p; + + tag = JS_VALUE_GET_NORM_TAG(val); + switch(tag) { + case JS_TAG_INT: + case JS_TAG_BOOL: + case JS_TAG_NULL: + r = buf; + bf_init(ctx->bf_ctx, r); + if (bf_set_si(r, JS_VALUE_GET_INT(val))) + goto fail; + break; + case JS_TAG_FLOAT64: + r = buf; + bf_init(ctx->bf_ctx, r); + if (bf_set_float64(r, JS_VALUE_GET_FLOAT64(val))) { + fail: + bf_delete(r); + return NULL; + } + break; + case JS_TAG_BIG_INT: +#ifdef CONFIG_BIGNUM + case JS_TAG_BIG_FLOAT: +#endif + p = JS_VALUE_GET_PTR(val); + r = &p->num; + break; + case JS_TAG_UNDEFINED: + default: + r = buf; + bf_init(ctx->bf_ctx, r); + bf_set_nan(r); + break; + } + return r; +} + +#ifdef CONFIG_BIGNUM +/* return NULL if invalid type */ +static bfdec_t *JS_ToBigDecimal(JSContext *ctx, JSValueConst val) +{ + uint32_t tag; + JSBigDecimal *p; + bfdec_t *r; + + tag = JS_VALUE_GET_NORM_TAG(val); + switch(tag) { + case JS_TAG_BIG_DECIMAL: + p = JS_VALUE_GET_PTR(val); + r = &p->num; + break; + default: + JS_ThrowTypeError(ctx, "bigdecimal expected"); + r = NULL; + break; + } + return r; +} + +static JSValue JS_NewBigFloat(JSContext *ctx) +{ + JSBigFloat *p; + p = js_malloc(ctx, sizeof(*p)); + if (!p) + return JS_EXCEPTION; + p->header.ref_count = 1; + bf_init(ctx->bf_ctx, &p->num); + return JS_MKPTR(JS_TAG_BIG_FLOAT, p); +} + +static JSValue JS_NewBigDecimal(JSContext *ctx) +{ + JSBigDecimal *p; + p = js_malloc(ctx, sizeof(*p)); + if (!p) + return JS_EXCEPTION; + p->header.ref_count = 1; + bfdec_init(ctx->bf_ctx, &p->num); + return JS_MKPTR(JS_TAG_BIG_DECIMAL, p); +} + /* must be kept in sync with JSOverloadableOperatorEnum */ /* XXX: use atoms ? */ static const char js_overloadable_operator_names[JS_OVOP_COUNT][4] = { @@ -12672,73 +12729,6 @@ static __exception int js_call_unary_op_fallback(JSContext *ctx, return -1; } -static JSValue throw_bf_exception(JSContext *ctx, int status) -{ - const char *str; - if (status & BF_ST_MEM_ERROR) - return JS_ThrowOutOfMemory(ctx); - if (status & BF_ST_DIVIDE_ZERO) { - str = "division by zero"; - } else if (status & BF_ST_INVALID_OP) { - str = "invalid operation"; - } else { - str = "integer overflow"; - } - return JS_ThrowRangeError(ctx, "%s", str); -} - -static int js_unary_arith_bigint(JSContext *ctx, - JSValue *pres, OPCodeEnum op, JSValue op1) -{ - bf_t a_s, *r, *a; - int ret, v; - JSValue res; - - if (op == OP_plus && !is_math_mode(ctx)) { - JS_ThrowTypeError(ctx, "bigint argument with unary +"); - JS_FreeValue(ctx, op1); - return -1; - } - res = JS_NewBigInt(ctx); - if (JS_IsException(res)) { - JS_FreeValue(ctx, op1); - return -1; - } - r = JS_GetBigInt(res); - a = JS_ToBigInt(ctx, &a_s, op1); - ret = 0; - switch(op) { - case OP_inc: - case OP_dec: - v = 2 * (op - OP_dec) - 1; - ret = bf_add_si(r, a, v, BF_PREC_INF, BF_RNDZ); - break; - case OP_plus: - ret = bf_set(r, a); - break; - case OP_neg: - ret = bf_set(r, a); - bf_neg(r); - break; - case OP_not: - ret = bf_add_si(r, a, 1, BF_PREC_INF, BF_RNDZ); - bf_neg(r); - break; - default: - abort(); - } - JS_FreeBigInt(ctx, a, &a_s); - JS_FreeValue(ctx, op1); - if (unlikely(ret)) { - JS_FreeValue(ctx, res); - throw_bf_exception(ctx, ret); - return -1; - } - res = JS_CompactBigInt(ctx, res); - *pres = res; - return 0; -} - static int js_unary_arith_bigfloat(JSContext *ctx, JSValue *pres, OPCodeEnum op, JSValue op1) { @@ -12759,6 +12749,11 @@ static int js_unary_arith_bigfloat(JSContext *ctx, } r = JS_GetBigFloat(res); a = JS_ToBigFloat(ctx, &a_s, op1); + if (!a) { + JS_FreeValue(ctx, res); + JS_FreeValue(ctx, op1); + return -1; + } ret = 0; switch(op) { case OP_inc: @@ -12808,6 +12803,11 @@ static int js_unary_arith_bigdecimal(JSContext *ctx, } r = JS_GetBigDecimal(res); a = JS_ToBigDecimal(ctx, op1); + if (!a) { + JS_FreeValue(ctx, res); + JS_FreeValue(ctx, op1); + return -1; + } ret = 0; switch(op) { case OP_inc: @@ -12835,20 +12835,81 @@ static int js_unary_arith_bigdecimal(JSContext *ctx, return 0; } +#endif /* CONFIG_BIGNUM */ + +static int js_unary_arith_bigint(JSContext *ctx, + JSValue *pres, OPCodeEnum op, JSValue op1) +{ + bf_t a_s, *r, *a; + int ret, v; + JSValue res; + + if (op == OP_plus && !is_math_mode(ctx)) { + JS_ThrowTypeError(ctx, "bigint argument with unary +"); + JS_FreeValue(ctx, op1); + return -1; + } + res = JS_NewBigInt(ctx); + if (JS_IsException(res)) { + JS_FreeValue(ctx, op1); + return -1; + } + r = JS_GetBigInt(res); + a = JS_ToBigInt(ctx, &a_s, op1); + if (!a) { + JS_FreeValue(ctx, res); + JS_FreeValue(ctx, op1); + return -1; + } + ret = 0; + switch(op) { + case OP_inc: + case OP_dec: + v = 2 * (op - OP_dec) - 1; + ret = bf_add_si(r, a, v, BF_PREC_INF, BF_RNDZ); + break; + case OP_plus: + ret = bf_set(r, a); + break; + case OP_neg: + ret = bf_set(r, a); + bf_neg(r); + break; + case OP_not: + ret = bf_add_si(r, a, 1, BF_PREC_INF, BF_RNDZ); + bf_neg(r); + break; + default: + abort(); + } + JS_FreeBigInt(ctx, a, &a_s); + JS_FreeValue(ctx, op1); + if (unlikely(ret)) { + JS_FreeValue(ctx, res); + throw_bf_exception(ctx, ret); + return -1; + } + res = JS_CompactBigInt(ctx, res); + *pres = res; + return 0; +} + static no_inline __exception int js_unary_arith_slow(JSContext *ctx, JSValue *sp, OPCodeEnum op) { - JSValue op1, val; - int v, ret; + JSValue op1; + int v; uint32_t tag; op1 = sp[-1]; /* fast path for float64 */ if (JS_TAG_IS_FLOAT64(JS_VALUE_GET_TAG(op1))) goto handle_float64; +#ifdef CONFIG_BIGNUM if (JS_IsObject(op1)) { - ret = js_call_unary_op_fallback(ctx, &val, op1, op); + JSValue val; + int ret = js_call_unary_op_fallback(ctx, &val, op1, op); if (ret < 0) return -1; if (ret) { @@ -12857,7 +12918,7 @@ static no_inline __exception int js_unary_arith_slow(JSContext *ctx, return 0; } } - +#endif op1 = JS_ToNumericFree(ctx, op1); if (JS_IsException(op1)) goto exception; @@ -12894,6 +12955,7 @@ static no_inline __exception int js_unary_arith_slow(JSContext *ctx, if (ctx->rt->bigint_ops.unary_arith(ctx, sp - 1, op, op1)) goto exception; break; +#ifdef CONFIG_BIGNUM case JS_TAG_BIG_FLOAT: if (ctx->rt->bigfloat_ops.unary_arith(ctx, sp - 1, op, op1)) goto exception; @@ -12902,6 +12964,7 @@ static no_inline __exception int js_unary_arith_slow(JSContext *ctx, if (ctx->rt->bigdecimal_ops.unary_arith(ctx, sp - 1, op, op1)) goto exception; break; +#endif default: handle_float64: { @@ -12952,12 +13015,13 @@ static __exception int js_post_inc_slow(JSContext *ctx, static no_inline int js_not_slow(JSContext *ctx, JSValue *sp) { - JSValue op1, val; - int ret; + JSValue op1; op1 = sp[-1]; +#ifdef CONFIG_BIGNUM if (JS_IsObject(op1)) { - ret = js_call_unary_op_fallback(ctx, &val, op1, OP_not); + JSValue val; + int ret = js_call_unary_op_fallback(ctx, &val, op1, OP_not); if (ret < 0) return -1; if (ret) { @@ -12966,7 +13030,7 @@ static no_inline int js_not_slow(JSContext *ctx, JSValue *sp) return 0; } } - +#endif op1 = JS_ToNumericFree(ctx, op1); if (JS_IsException(op1)) goto exception; @@ -12985,67 +13049,6 @@ static no_inline int js_not_slow(JSContext *ctx, JSValue *sp) return -1; } -static int js_binary_arith_bigfloat(JSContext *ctx, OPCodeEnum op, - JSValue *pres, JSValue op1, JSValue op2) -{ - bf_t a_s, b_s, *r, *a, *b; - int ret; - JSValue res; - - res = JS_NewBigFloat(ctx); - if (JS_IsException(res)) { - JS_FreeValue(ctx, op1); - JS_FreeValue(ctx, op2); - return -1; - } - r = JS_GetBigFloat(res); - a = JS_ToBigFloat(ctx, &a_s, op1); - b = JS_ToBigFloat(ctx, &b_s, op2); - bf_init(ctx->bf_ctx, r); - switch(op) { - case OP_add: - ret = bf_add(r, a, b, ctx->fp_env.prec, ctx->fp_env.flags); - break; - case OP_sub: - ret = bf_sub(r, a, b, ctx->fp_env.prec, ctx->fp_env.flags); - break; - case OP_mul: - ret = bf_mul(r, a, b, ctx->fp_env.prec, ctx->fp_env.flags); - break; - case OP_div: - ret = bf_div(r, a, b, ctx->fp_env.prec, ctx->fp_env.flags); - break; - case OP_math_mod: - /* Euclidian remainder */ - ret = bf_rem(r, a, b, ctx->fp_env.prec, ctx->fp_env.flags, - BF_DIVREM_EUCLIDIAN); - break; - case OP_mod: - ret = bf_rem(r, a, b, ctx->fp_env.prec, ctx->fp_env.flags, - BF_RNDZ); - break; - case OP_pow: - ret = bf_pow(r, a, b, ctx->fp_env.prec, - ctx->fp_env.flags | BF_POW_JS_QUIRKS); - break; - default: - abort(); - } - if (a == &a_s) - bf_delete(a); - if (b == &b_s) - bf_delete(b); - JS_FreeValue(ctx, op1); - JS_FreeValue(ctx, op2); - if (unlikely(ret & BF_ST_MEM_ERROR)) { - JS_FreeValue(ctx, res); - throw_bf_exception(ctx, ret); - return -1; - } - *pres = res; - return 0; -} - static int js_binary_arith_bigint(JSContext *ctx, OPCodeEnum op, JSValue *pres, JSValue op1, JSValue op2) { @@ -13087,11 +13090,13 @@ static int js_binary_arith_bigint(JSContext *ctx, OPCodeEnum op, goto math_mode_div_pow; } break; +#ifdef CONFIG_BIGNUM case OP_math_mod: /* Euclidian remainder */ ret = bf_rem(r, a, b, BF_PREC_INF, BF_RNDZ, BF_DIVREM_EUCLIDIAN) & BF_ST_INVALID_OP; break; +#endif case OP_mod: ret = bf_rem(r, a, b, BF_PREC_INF, BF_RNDZ, BF_RNDZ) & BF_ST_INVALID_OP; @@ -13102,6 +13107,7 @@ static int js_binary_arith_bigint(JSContext *ctx, OPCodeEnum op, ret = BF_ST_INVALID_OP; } else { math_mode_div_pow: +#ifdef CONFIG_BIGNUM JS_FreeValue(ctx, res); ret = js_call_binary_op_simple(ctx, &res, ctx->class_proto[JS_CLASS_BIG_INT], op1, op2, op); if (ret != 0) { @@ -13142,6 +13148,9 @@ static int js_binary_arith_bigint(JSContext *ctx, OPCodeEnum op, } *pres = res; return 0; +#else + abort(); +#endif } } else { ret = bf_pow(r, a, b, BF_PREC_INF, BF_RNDZ | BF_POW_JS_QUIRKS); @@ -13201,6 +13210,79 @@ static int js_binary_arith_bigint(JSContext *ctx, OPCodeEnum op, return -1; } +#ifdef CONFIG_BIGNUM +static int js_binary_arith_bigfloat(JSContext *ctx, OPCodeEnum op, + JSValue *pres, JSValue op1, JSValue op2) +{ + bf_t a_s, b_s, *r, *a, *b; + int ret; + JSValue res; + + res = JS_NewBigFloat(ctx); + if (JS_IsException(res)) + goto fail; + r = JS_GetBigFloat(res); + a = JS_ToBigFloat(ctx, &a_s, op1); + if (!a) { + JS_FreeValue(ctx, res); + goto fail; + } + b = JS_ToBigFloat(ctx, &b_s, op2); + if (!b) { + if (a == &a_s) + bf_delete(a); + JS_FreeValue(ctx, res); + goto fail; + } + bf_init(ctx->bf_ctx, r); + switch(op) { + case OP_add: + ret = bf_add(r, a, b, ctx->fp_env.prec, ctx->fp_env.flags); + break; + case OP_sub: + ret = bf_sub(r, a, b, ctx->fp_env.prec, ctx->fp_env.flags); + break; + case OP_mul: + ret = bf_mul(r, a, b, ctx->fp_env.prec, ctx->fp_env.flags); + break; + case OP_div: + ret = bf_div(r, a, b, ctx->fp_env.prec, ctx->fp_env.flags); + break; + case OP_math_mod: + /* Euclidian remainder */ + ret = bf_rem(r, a, b, ctx->fp_env.prec, ctx->fp_env.flags, + BF_DIVREM_EUCLIDIAN); + break; + case OP_mod: + ret = bf_rem(r, a, b, ctx->fp_env.prec, ctx->fp_env.flags, + BF_RNDZ); + break; + case OP_pow: + ret = bf_pow(r, a, b, ctx->fp_env.prec, + ctx->fp_env.flags | BF_POW_JS_QUIRKS); + break; + default: + abort(); + } + if (a == &a_s) + bf_delete(a); + if (b == &b_s) + bf_delete(b); + JS_FreeValue(ctx, op1); + JS_FreeValue(ctx, op2); + if (unlikely(ret & BF_ST_MEM_ERROR)) { + JS_FreeValue(ctx, res); + throw_bf_exception(ctx, ret); + return -1; + } + *pres = res; + return 0; + fail: + JS_FreeValue(ctx, op1); + JS_FreeValue(ctx, op2); + return -1; +} + /* b must be a positive integer */ static int js_bfdec_pow(bfdec_t *r, const bfdec_t *a, const bfdec_t *b) { @@ -13287,13 +13369,13 @@ static int js_binary_arith_bigdecimal(JSContext *ctx, OPCodeEnum op, JS_FreeValue(ctx, op2); return -1; } +#endif /* CONFIG_BIGNUM */ static no_inline __exception int js_binary_arith_slow(JSContext *ctx, JSValue *sp, OPCodeEnum op) { - JSValue op1, op2, res; + JSValue op1, op2; uint32_t tag1, tag2; - int ret; double d1, d2; op1 = sp[-2]; @@ -13307,12 +13389,14 @@ static no_inline __exception int js_binary_arith_slow(JSContext *ctx, JSValue *s goto handle_float64; } +#ifdef CONFIG_BIGNUM /* try to call an overloaded operator */ if ((tag1 == JS_TAG_OBJECT && (tag2 != JS_TAG_NULL && tag2 != JS_TAG_UNDEFINED)) || (tag2 == JS_TAG_OBJECT && (tag1 != JS_TAG_NULL && tag1 != JS_TAG_UNDEFINED))) { - ret = js_call_binary_op_fallback(ctx, &res, op1, op2, op, TRUE, 0); + JSValue res; + int ret = js_call_binary_op_fallback(ctx, &res, op1, op2, op, TRUE, 0); if (ret != 0) { JS_FreeValue(ctx, op1); JS_FreeValue(ctx, op2); @@ -13324,6 +13408,7 @@ static no_inline __exception int js_binary_arith_slow(JSContext *ctx, JSValue *s } } } +#endif op1 = JS_ToNumericFree(ctx, op1); if (JS_IsException(op1)) { @@ -13362,6 +13447,7 @@ static no_inline __exception int js_binary_arith_slow(JSContext *ctx, JSValue *s goto handle_bigint; sp[-2] = __JS_NewFloat64(ctx, (double)v1 / (double)v2); return 0; +#ifdef CONFIG_BIGNUM case OP_math_mod: if (unlikely(v2 == 0)) { throw_bf_exception(ctx, BF_ST_DIVIDE_ZERO); @@ -13375,6 +13461,7 @@ static no_inline __exception int js_binary_arith_slow(JSContext *ctx, JSValue *s v += v2; } break; +#endif case OP_mod: if (v1 < 0 || v2 <= 0) { sp[-2] = JS_NewFloat64(ctx, fmod(v1, v2)); @@ -13395,13 +13482,17 @@ static no_inline __exception int js_binary_arith_slow(JSContext *ctx, JSValue *s abort(); } sp[-2] = JS_NewInt64(ctx, v); - } else if (tag1 == JS_TAG_BIG_DECIMAL || tag2 == JS_TAG_BIG_DECIMAL) { + } else +#ifdef CONFIG_BIGNUM + if (tag1 == JS_TAG_BIG_DECIMAL || tag2 == JS_TAG_BIG_DECIMAL) { if (ctx->rt->bigdecimal_ops.binary_arith(ctx, op, sp - 2, op1, op2)) goto exception; } else if (tag1 == JS_TAG_BIG_FLOAT || tag2 == JS_TAG_BIG_FLOAT) { if (ctx->rt->bigfloat_ops.binary_arith(ctx, op, sp - 2, op1, op2)) goto exception; - } else if (tag1 == JS_TAG_BIG_INT || tag2 == JS_TAG_BIG_INT) { + } else +#endif + if (tag1 == JS_TAG_BIG_INT || tag2 == JS_TAG_BIG_INT) { handle_bigint: if (ctx->rt->bigint_ops.binary_arith(ctx, op, sp - 2, op1, op2)) goto exception; @@ -13430,6 +13521,7 @@ static no_inline __exception int js_binary_arith_slow(JSContext *ctx, JSValue *s case OP_mod: dr = fmod(d1, d2); break; +#ifdef CONFIG_BIGNUM case OP_math_mod: d2 = fabs(d2); dr = fmod(d1, d2); @@ -13437,6 +13529,7 @@ static no_inline __exception int js_binary_arith_slow(JSContext *ctx, JSValue *s if (dr < 0) dr += d2; break; +#endif case OP_pow: dr = js_pow(d1, d2); break; @@ -13454,9 +13547,8 @@ static no_inline __exception int js_binary_arith_slow(JSContext *ctx, JSValue *s static no_inline __exception int js_add_slow(JSContext *ctx, JSValue *sp) { - JSValue op1, op2, res; + JSValue op1, op2; uint32_t tag1, tag2; - int ret; op1 = sp[-2]; op2 = sp[-1]; @@ -13473,6 +13565,7 @@ static no_inline __exception int js_add_slow(JSContext *ctx, JSValue *sp) } if (tag1 == JS_TAG_OBJECT || tag2 == JS_TAG_OBJECT) { +#ifdef CONFIG_BIGNUM /* try to call an overloaded operator */ if ((tag1 == JS_TAG_OBJECT && (tag2 != JS_TAG_NULL && tag2 != JS_TAG_UNDEFINED && @@ -13480,8 +13573,9 @@ static no_inline __exception int js_add_slow(JSContext *ctx, JSValue *sp) (tag2 == JS_TAG_OBJECT && (tag1 != JS_TAG_NULL && tag1 != JS_TAG_UNDEFINED && tag1 != JS_TAG_STRING))) { - ret = js_call_binary_op_fallback(ctx, &res, op1, op2, OP_add, - FALSE, HINT_NONE); + JSValue res; + int ret = js_call_binary_op_fallback(ctx, &res, op1, op2, OP_add, + FALSE, HINT_NONE); if (ret != 0) { JS_FreeValue(ctx, op1); JS_FreeValue(ctx, op2); @@ -13493,7 +13587,7 @@ static no_inline __exception int js_add_slow(JSContext *ctx, JSValue *sp) } } } - +#endif op1 = JS_ToPrimitiveFree(ctx, op1, HINT_NONE); if (JS_IsException(op1)) { JS_FreeValue(ctx, op2); @@ -13536,13 +13630,17 @@ static no_inline __exception int js_add_slow(JSContext *ctx, JSValue *sp) v2 = JS_VALUE_GET_INT(op2); v = (int64_t)v1 + (int64_t)v2; sp[-2] = JS_NewInt64(ctx, v); - } else if (tag1 == JS_TAG_BIG_DECIMAL || tag2 == JS_TAG_BIG_DECIMAL) { + } else +#ifdef CONFIG_BIGNUM + if (tag1 == JS_TAG_BIG_DECIMAL || tag2 == JS_TAG_BIG_DECIMAL) { if (ctx->rt->bigdecimal_ops.binary_arith(ctx, OP_add, sp - 2, op1, op2)) goto exception; } else if (tag1 == JS_TAG_BIG_FLOAT || tag2 == JS_TAG_BIG_FLOAT) { if (ctx->rt->bigfloat_ops.binary_arith(ctx, OP_add, sp - 2, op1, op2)) goto exception; - } else if (tag1 == JS_TAG_BIG_INT || tag2 == JS_TAG_BIG_INT) { + } else +#endif + if (tag1 == JS_TAG_BIG_INT || tag2 == JS_TAG_BIG_INT) { handle_bigint: if (ctx->rt->bigint_ops.binary_arith(ctx, OP_add, sp - 2, op1, op2)) goto exception; @@ -13570,8 +13668,7 @@ static no_inline __exception int js_binary_logic_slow(JSContext *ctx, JSValue *sp, OPCodeEnum op) { - JSValue op1, op2, res; - int ret; + JSValue op1, op2; uint32_t tag1, tag2; uint32_t v1, v2, r; @@ -13580,12 +13677,14 @@ static no_inline __exception int js_binary_logic_slow(JSContext *ctx, tag1 = JS_VALUE_GET_NORM_TAG(op1); tag2 = JS_VALUE_GET_NORM_TAG(op2); +#ifdef CONFIG_BIGNUM /* try to call an overloaded operator */ if ((tag1 == JS_TAG_OBJECT && (tag2 != JS_TAG_NULL && tag2 != JS_TAG_UNDEFINED)) || (tag2 == JS_TAG_OBJECT && (tag1 != JS_TAG_NULL && tag1 != JS_TAG_UNDEFINED))) { - ret = js_call_binary_op_fallback(ctx, &res, op1, op2, op, TRUE, 0); + JSValue res; + int ret = js_call_binary_op_fallback(ctx, &res, op1, op2, op, TRUE, 0); if (ret != 0) { JS_FreeValue(ctx, op1); JS_FreeValue(ctx, op2); @@ -13597,6 +13696,7 @@ static no_inline __exception int js_binary_logic_slow(JSContext *ctx, } } } +#endif op1 = JS_ToNumericFree(ctx, op1); if (JS_IsException(op1)) { @@ -13707,6 +13807,7 @@ static int js_compare_bigfloat(JSContext *ctx, OPCodeEnum op, return res; } +#ifdef CONFIG_BIGNUM static int js_compare_bigdecimal(JSContext *ctx, OPCodeEnum op, JSValue op1, JSValue op2) { @@ -13726,8 +13827,8 @@ static int js_compare_bigdecimal(JSContext *ctx, OPCodeEnum op, JS_FreeValue(ctx, op1); return -1; } - a = JS_ToBigDecimal(ctx, op1); - b = JS_ToBigDecimal(ctx, op2); + a = JS_ToBigDecimal(ctx, op1); /* cannot fail */ + b = JS_ToBigDecimal(ctx, op2); /* cannot fail */ switch(op) { case OP_lt: @@ -13752,11 +13853,12 @@ static int js_compare_bigdecimal(JSContext *ctx, OPCodeEnum op, JS_FreeValue(ctx, op2); return res; } +#endif /* !CONFIG_BIGNUM */ static no_inline int js_relational_slow(JSContext *ctx, JSValue *sp, OPCodeEnum op) { - JSValue op1, op2, ret; + JSValue op1, op2; int res; uint32_t tag1, tag2; @@ -13764,11 +13866,13 @@ static no_inline int js_relational_slow(JSContext *ctx, JSValue *sp, op2 = sp[-1]; tag1 = JS_VALUE_GET_NORM_TAG(op1); tag2 = JS_VALUE_GET_NORM_TAG(op2); +#ifdef CONFIG_BIGNUM /* try to call an overloaded operator */ if ((tag1 == JS_TAG_OBJECT && (tag2 != JS_TAG_NULL && tag2 != JS_TAG_UNDEFINED)) || (tag2 == JS_TAG_OBJECT && (tag1 != JS_TAG_NULL && tag1 != JS_TAG_UNDEFINED))) { + JSValue ret; res = js_call_binary_op_fallback(ctx, &ret, op1, op2, op, FALSE, HINT_NUMBER); if (res != 0) { @@ -13782,6 +13886,7 @@ static no_inline int js_relational_slow(JSContext *ctx, JSValue *sp, } } } +#endif op1 = JS_ToPrimitiveFree(ctx, op1, HINT_NUMBER); if (JS_IsException(op1)) { JS_FreeValue(ctx, op2); @@ -13856,6 +13961,7 @@ static no_inline int js_relational_slow(JSContext *ctx, JSValue *sp, tag1 = JS_VALUE_GET_NORM_TAG(op1); tag2 = JS_VALUE_GET_NORM_TAG(op2); +#ifdef CONFIG_BIGNUM if (tag1 == JS_TAG_BIG_DECIMAL || tag2 == JS_TAG_BIG_DECIMAL) { res = ctx->rt->bigdecimal_ops.compare(ctx, op, op1, op2); if (res < 0) @@ -13864,7 +13970,9 @@ static no_inline int js_relational_slow(JSContext *ctx, JSValue *sp, res = ctx->rt->bigfloat_ops.compare(ctx, op, op1, op2); if (res < 0) goto exception; - } else if (tag1 == JS_TAG_BIG_INT || tag2 == JS_TAG_BIG_INT) { + } else +#endif + if (tag1 == JS_TAG_BIG_INT || tag2 == JS_TAG_BIG_INT) { res = ctx->rt->bigint_ops.compare(ctx, op, op1, op2); if (res < 0) goto exception; @@ -13912,14 +14020,20 @@ static no_inline int js_relational_slow(JSContext *ctx, JSValue *sp, static BOOL tag_is_number(uint32_t tag) { return (tag == JS_TAG_INT || tag == JS_TAG_BIG_INT || - tag == JS_TAG_FLOAT64 || tag == JS_TAG_BIG_FLOAT || - tag == JS_TAG_BIG_DECIMAL); + tag == JS_TAG_FLOAT64 +#ifdef CONFIG_BIGNUM + || tag == JS_TAG_BIG_FLOAT || tag == JS_TAG_BIG_DECIMAL +#endif + ); } static no_inline __exception int js_eq_slow(JSContext *ctx, JSValue *sp, BOOL is_neq) { - JSValue op1, op2, ret; + JSValue op1, op2; +#ifdef CONFIG_BIGNUM + JSValue ret; +#endif int res; uint32_t tag1, tag2; @@ -13947,7 +14061,9 @@ static no_inline __exception int js_eq_slow(JSContext *ctx, JSValue *sp, d2 = JS_VALUE_GET_INT(op2); } res = (d1 == d2); - } else if (tag1 == JS_TAG_BIG_DECIMAL || tag2 == JS_TAG_BIG_DECIMAL) { + } else +#ifdef CONFIG_BIGNUM + if (tag1 == JS_TAG_BIG_DECIMAL || tag2 == JS_TAG_BIG_DECIMAL) { res = ctx->rt->bigdecimal_ops.compare(ctx, OP_eq, op1, op2); if (res < 0) goto exception; @@ -13955,12 +14071,15 @@ static no_inline __exception int js_eq_slow(JSContext *ctx, JSValue *sp, res = ctx->rt->bigfloat_ops.compare(ctx, OP_eq, op1, op2); if (res < 0) goto exception; - } else { + } else +#endif + { res = ctx->rt->bigint_ops.compare(ctx, OP_eq, op1, op2); if (res < 0) goto exception; } } else if (tag1 == tag2) { +#ifdef CONFIG_BIGNUM if (tag1 == JS_TAG_OBJECT) { /* try the fallback operator */ res = js_call_binary_op_fallback(ctx, &ret, op1, op2, @@ -13977,6 +14096,7 @@ static no_inline __exception int js_eq_slow(JSContext *ctx, JSValue *sp, } } } +#endif res = js_strict_eq2(ctx, op1, op2, JS_EQ_STRICT); } else if ((tag1 == JS_TAG_NULL && tag2 == JS_TAG_UNDEFINED) || (tag2 == JS_TAG_NULL && tag1 == JS_TAG_UNDEFINED)) { @@ -14024,7 +14144,7 @@ static no_inline __exception int js_eq_slow(JSContext *ctx, JSValue *sp, (tag_is_number(tag2) || tag2 == JS_TAG_STRING || tag2 == JS_TAG_SYMBOL)) || (tag2 == JS_TAG_OBJECT && (tag_is_number(tag1) || tag1 == JS_TAG_STRING || tag1 == JS_TAG_SYMBOL))) { - +#ifdef CONFIG_BIGNUM /* try the fallback operator */ res = js_call_binary_op_fallback(ctx, &ret, op1, op2, is_neq ? OP_neq : OP_eq, @@ -14039,7 +14159,7 @@ static no_inline __exception int js_eq_slow(JSContext *ctx, JSValue *sp, return 0; } } - +#endif op1 = JS_ToPrimitiveFree(ctx, op1, HINT_NONE); if (JS_IsException(op1)) { JS_FreeValue(ctx, op2); @@ -14111,6 +14231,7 @@ static no_inline int js_shr_slow(JSContext *ctx, JSValue *sp) return -1; } +#ifdef CONFIG_BIGNUM static JSValue js_mul_pow10_to_float64(JSContext *ctx, const bf_t *a, int64_t exponent) { @@ -14145,8 +14266,10 @@ static no_inline int js_mul_pow10(JSContext *ctx, JSValue *sp) op1 = sp[-2]; op2 = sp[-1]; a = JS_ToBigFloat(ctx, &a_s, op1); - if (!a) + if (!a) { + JS_FreeValue(ctx, res); return -1; + } if (JS_IsBigInt(ctx, op2)) { ret = JS_ToBigInt64(ctx, &e, op2); } else { @@ -14167,395 +14290,7 @@ static no_inline int js_mul_pow10(JSContext *ctx, JSValue *sp) sp[-2] = res; return 0; } - -#else /* !CONFIG_BIGNUM */ - -static JSValue JS_ThrowUnsupportedBigint(JSContext *ctx) -{ - return JS_ThrowTypeError(ctx, "bigint is not supported"); -} - -JSValue JS_NewBigInt64(JSContext *ctx, int64_t v) -{ - return JS_ThrowUnsupportedBigint(ctx); -} - -JSValue JS_NewBigUint64(JSContext *ctx, uint64_t v) -{ - return JS_ThrowUnsupportedBigint(ctx); -} - -int JS_ToBigInt64(JSContext *ctx, int64_t *pres, JSValueConst val) -{ - JS_ThrowUnsupportedBigint(ctx); - *pres = 0; - return -1; -} - -static no_inline __exception int js_unary_arith_slow(JSContext *ctx, - JSValue *sp, - OPCodeEnum op) -{ - JSValue op1; - double d; - - op1 = sp[-1]; - if (unlikely(JS_ToFloat64Free(ctx, &d, op1))) { - sp[-1] = JS_UNDEFINED; - return -1; - } - switch(op) { - case OP_inc: - d++; - break; - case OP_dec: - d--; - break; - case OP_plus: - break; - case OP_neg: - d = -d; - break; - default: - abort(); - } - sp[-1] = JS_NewFloat64(ctx, d); - return 0; -} - -/* specific case necessary for correct return value semantics */ -static __exception int js_post_inc_slow(JSContext *ctx, - JSValue *sp, OPCodeEnum op) -{ - JSValue op1; - double d, r; - - op1 = sp[-1]; - if (unlikely(JS_ToFloat64Free(ctx, &d, op1))) { - sp[-1] = JS_UNDEFINED; - return -1; - } - r = d + 2 * (op - OP_post_dec) - 1; - sp[0] = JS_NewFloat64(ctx, r); - sp[-1] = JS_NewFloat64(ctx, d); - return 0; -} - -static no_inline __exception int js_binary_arith_slow(JSContext *ctx, JSValue *sp, - OPCodeEnum op) -{ - JSValue op1, op2; - double d1, d2, r; - - op1 = sp[-2]; - op2 = sp[-1]; - if (unlikely(JS_ToFloat64Free(ctx, &d1, op1))) { - JS_FreeValue(ctx, op2); - goto exception; - } - if (unlikely(JS_ToFloat64Free(ctx, &d2, op2))) { - goto exception; - } - switch(op) { - case OP_sub: - r = d1 - d2; - break; - case OP_mul: - r = d1 * d2; - break; - case OP_div: - r = d1 / d2; - break; - case OP_mod: - r = fmod(d1, d2); - break; - case OP_pow: - r = js_pow(d1, d2); - break; - default: - abort(); - } - sp[-2] = JS_NewFloat64(ctx, r); - return 0; - exception: - sp[-2] = JS_UNDEFINED; - sp[-1] = JS_UNDEFINED; - return -1; -} - -static no_inline __exception int js_add_slow(JSContext *ctx, JSValue *sp) -{ - JSValue op1, op2; - uint32_t tag1, tag2; - - op1 = sp[-2]; - op2 = sp[-1]; - tag1 = JS_VALUE_GET_TAG(op1); - tag2 = JS_VALUE_GET_TAG(op2); - if ((tag1 == JS_TAG_INT || JS_TAG_IS_FLOAT64(tag1)) && - (tag2 == JS_TAG_INT || JS_TAG_IS_FLOAT64(tag2))) { - goto add_numbers; - } else { - op1 = JS_ToPrimitiveFree(ctx, op1, HINT_NONE); - if (JS_IsException(op1)) { - JS_FreeValue(ctx, op2); - goto exception; - } - op2 = JS_ToPrimitiveFree(ctx, op2, HINT_NONE); - if (JS_IsException(op2)) { - JS_FreeValue(ctx, op1); - goto exception; - } - tag1 = JS_VALUE_GET_TAG(op1); - tag2 = JS_VALUE_GET_TAG(op2); - if (tag1 == JS_TAG_STRING || tag2 == JS_TAG_STRING) { - sp[-2] = JS_ConcatString(ctx, op1, op2); - if (JS_IsException(sp[-2])) - goto exception; - } else { - double d1, d2; - add_numbers: - if (JS_ToFloat64Free(ctx, &d1, op1)) { - JS_FreeValue(ctx, op2); - goto exception; - } - if (JS_ToFloat64Free(ctx, &d2, op2)) - goto exception; - sp[-2] = JS_NewFloat64(ctx, d1 + d2); - } - } - return 0; - exception: - sp[-2] = JS_UNDEFINED; - sp[-1] = JS_UNDEFINED; - return -1; -} - -static no_inline __exception int js_binary_logic_slow(JSContext *ctx, - JSValue *sp, - OPCodeEnum op) -{ - JSValue op1, op2; - uint32_t v1, v2, r; - - op1 = sp[-2]; - op2 = sp[-1]; - if (unlikely(JS_ToInt32Free(ctx, (int32_t *)&v1, op1))) { - JS_FreeValue(ctx, op2); - goto exception; - } - if (unlikely(JS_ToInt32Free(ctx, (int32_t *)&v2, op2))) - goto exception; - switch(op) { - case OP_shl: - r = v1 << (v2 & 0x1f); - break; - case OP_sar: - r = (int)v1 >> (v2 & 0x1f); - break; - case OP_and: - r = v1 & v2; - break; - case OP_or: - r = v1 | v2; - break; - case OP_xor: - r = v1 ^ v2; - break; - default: - abort(); - } - sp[-2] = JS_NewInt32(ctx, r); - return 0; - exception: - sp[-2] = JS_UNDEFINED; - sp[-1] = JS_UNDEFINED; - return -1; -} - -static no_inline int js_not_slow(JSContext *ctx, JSValue *sp) -{ - int32_t v1; - - if (unlikely(JS_ToInt32Free(ctx, &v1, sp[-1]))) { - sp[-1] = JS_UNDEFINED; - return -1; - } - sp[-1] = JS_NewInt32(ctx, ~v1); - return 0; -} - -static no_inline int js_relational_slow(JSContext *ctx, JSValue *sp, - OPCodeEnum op) -{ - JSValue op1, op2; - int res; - - op1 = sp[-2]; - op2 = sp[-1]; - op1 = JS_ToPrimitiveFree(ctx, op1, HINT_NUMBER); - if (JS_IsException(op1)) { - JS_FreeValue(ctx, op2); - goto exception; - } - op2 = JS_ToPrimitiveFree(ctx, op2, HINT_NUMBER); - if (JS_IsException(op2)) { - JS_FreeValue(ctx, op1); - goto exception; - } - if (JS_VALUE_GET_TAG(op1) == JS_TAG_STRING && - JS_VALUE_GET_TAG(op2) == JS_TAG_STRING) { - JSString *p1, *p2; - p1 = JS_VALUE_GET_STRING(op1); - p2 = JS_VALUE_GET_STRING(op2); - res = js_string_compare(ctx, p1, p2); - JS_FreeValue(ctx, op1); - JS_FreeValue(ctx, op2); - switch(op) { - case OP_lt: - res = (res < 0); - break; - case OP_lte: - res = (res <= 0); - break; - case OP_gt: - res = (res > 0); - break; - default: - case OP_gte: - res = (res >= 0); - break; - } - } else { - double d1, d2; - if (JS_ToFloat64Free(ctx, &d1, op1)) { - JS_FreeValue(ctx, op2); - goto exception; - } - if (JS_ToFloat64Free(ctx, &d2, op2)) - goto exception; - switch(op) { - case OP_lt: - res = (d1 < d2); /* if NaN return false */ - break; - case OP_lte: - res = (d1 <= d2); /* if NaN return false */ - break; - case OP_gt: - res = (d1 > d2); /* if NaN return false */ - break; - default: - case OP_gte: - res = (d1 >= d2); /* if NaN return false */ - break; - } - } - sp[-2] = JS_NewBool(ctx, res); - return 0; - exception: - sp[-2] = JS_UNDEFINED; - sp[-1] = JS_UNDEFINED; - return -1; -} - -static no_inline __exception int js_eq_slow(JSContext *ctx, JSValue *sp, - BOOL is_neq) -{ - JSValue op1, op2; - int tag1, tag2; - BOOL res; - - op1 = sp[-2]; - op2 = sp[-1]; - redo: - tag1 = JS_VALUE_GET_NORM_TAG(op1); - tag2 = JS_VALUE_GET_NORM_TAG(op2); - if (tag1 == tag2 || - (tag1 == JS_TAG_INT && tag2 == JS_TAG_FLOAT64) || - (tag2 == JS_TAG_INT && tag1 == JS_TAG_FLOAT64)) { - res = js_strict_eq(ctx, op1, op2); - } else if ((tag1 == JS_TAG_NULL && tag2 == JS_TAG_UNDEFINED) || - (tag2 == JS_TAG_NULL && tag1 == JS_TAG_UNDEFINED)) { - res = TRUE; - } else if ((tag1 == JS_TAG_STRING && (tag2 == JS_TAG_INT || - tag2 == JS_TAG_FLOAT64)) || - (tag2 == JS_TAG_STRING && (tag1 == JS_TAG_INT || - tag1 == JS_TAG_FLOAT64))) { - double d1; - double d2; - if (JS_ToFloat64Free(ctx, &d1, op1)) { - JS_FreeValue(ctx, op2); - goto exception; - } - if (JS_ToFloat64Free(ctx, &d2, op2)) - goto exception; - res = (d1 == d2); - } else if (tag1 == JS_TAG_BOOL) { - op1 = JS_NewInt32(ctx, JS_VALUE_GET_INT(op1)); - goto redo; - } else if (tag2 == JS_TAG_BOOL) { - op2 = JS_NewInt32(ctx, JS_VALUE_GET_INT(op2)); - goto redo; - } else if (tag1 == JS_TAG_OBJECT && - (tag2 == JS_TAG_INT || tag2 == JS_TAG_FLOAT64 || tag2 == JS_TAG_STRING || tag2 == JS_TAG_SYMBOL)) { - op1 = JS_ToPrimitiveFree(ctx, op1, HINT_NONE); - if (JS_IsException(op1)) { - JS_FreeValue(ctx, op2); - goto exception; - } - goto redo; - } else if (tag2 == JS_TAG_OBJECT && - (tag1 == JS_TAG_INT || tag1 == JS_TAG_FLOAT64 || tag1 == JS_TAG_STRING || tag1 == JS_TAG_SYMBOL)) { - op2 = JS_ToPrimitiveFree(ctx, op2, HINT_NONE); - if (JS_IsException(op2)) { - JS_FreeValue(ctx, op1); - goto exception; - } - goto redo; - } else { - /* IsHTMLDDA object is equivalent to undefined for '==' and '!=' */ - if ((JS_IsHTMLDDA(ctx, op1) && - (tag2 == JS_TAG_NULL || tag2 == JS_TAG_UNDEFINED)) || - (JS_IsHTMLDDA(ctx, op2) && - (tag1 == JS_TAG_NULL || tag1 == JS_TAG_UNDEFINED))) { - res = TRUE; - } else { - res = FALSE; - } - JS_FreeValue(ctx, op1); - JS_FreeValue(ctx, op2); - } - sp[-2] = JS_NewBool(ctx, res ^ is_neq); - return 0; - exception: - sp[-2] = JS_UNDEFINED; - sp[-1] = JS_UNDEFINED; - return -1; -} - -static no_inline int js_shr_slow(JSContext *ctx, JSValue *sp) -{ - JSValue op1, op2; - uint32_t v1, v2, r; - - op1 = sp[-2]; - op2 = sp[-1]; - if (unlikely(JS_ToUint32Free(ctx, &v1, op1))) { - JS_FreeValue(ctx, op2); - goto exception; - } - if (unlikely(JS_ToUint32Free(ctx, &v2, op2))) - goto exception; - r = v1 >> (v2 & 0x1f); - sp[-2] = JS_NewUint32(ctx, r); - return 0; - exception: - sp[-2] = JS_UNDEFINED; - sp[-1] = JS_UNDEFINED; - return -1; -} - -#endif /* !CONFIG_BIGNUM */ +#endif /* XXX: Should take JSValueConst arguments */ static BOOL js_strict_eq2(JSContext *ctx, JSValue op1, JSValue op2, @@ -14649,7 +14384,6 @@ static BOOL js_strict_eq2(JSContext *ctx, JSValue op1, JSValue op2, res = (d1 == d2); /* if NaN return false and +0 == -0 */ } goto done_no_free; -#ifdef CONFIG_BIGNUM case JS_TAG_BIG_INT: { bf_t a_s, *a, b_s, *b; @@ -14657,8 +14391,8 @@ static BOOL js_strict_eq2(JSContext *ctx, JSValue op1, JSValue op2, res = FALSE; break; } - a = JS_ToBigFloat(ctx, &a_s, op1); - b = JS_ToBigFloat(ctx, &b_s, op2); + a = JS_ToBigFloat(ctx, &a_s, op1); /* cannot fail */ + b = JS_ToBigFloat(ctx, &b_s, op2); /* cannot fail */ res = bf_cmp_eq(a, b); if (a == &a_s) bf_delete(a); @@ -14666,6 +14400,7 @@ static BOOL js_strict_eq2(JSContext *ctx, JSValue op1, JSValue op2, bf_delete(b); } break; +#ifdef CONFIG_BIGNUM case JS_TAG_BIG_FLOAT: { JSBigFloat *p1, *p2; @@ -14770,6 +14505,43 @@ static __exception int js_operator_in(JSContext *ctx, JSValue *sp) return 0; } +static __exception int js_operator_private_in(JSContext *ctx, JSValue *sp) +{ + JSValue op1, op2; + int ret; + + op1 = sp[-2]; /* object */ + op2 = sp[-1]; /* field name or method function */ + + if (JS_VALUE_GET_TAG(op1) != JS_TAG_OBJECT) { + JS_ThrowTypeError(ctx, "invalid 'in' operand"); + return -1; + } + if (JS_IsObject(op2)) { + /* method: use the brand */ + ret = JS_CheckBrand(ctx, op1, op2); + if (ret < 0) + return -1; + } else { + JSAtom atom; + JSObject *p; + JSShapeProperty *prs; + JSProperty *pr; + /* field */ + atom = JS_ValueToAtom(ctx, op2); + if (unlikely(atom == JS_ATOM_NULL)) + return -1; + p = JS_VALUE_GET_OBJ(op1); + prs = find_own_property(&pr, p, atom); + JS_FreeAtom(ctx, atom); + ret = (prs != NULL); + } + JS_FreeValue(ctx, op1); + JS_FreeValue(ctx, op2); + sp[-2] = JS_NewBool(ctx, ret); + return 0; +} + static __exception int js_has_unscopable(JSContext *ctx, JSValueConst obj, JSAtom atom) { @@ -14811,10 +14583,10 @@ static __exception int js_operator_typeof(JSContext *ctx, JSValueConst op1) tag = JS_VALUE_GET_NORM_TAG(op1); switch(tag) { -#ifdef CONFIG_BIGNUM case JS_TAG_BIG_INT: atom = JS_ATOM_bigint; break; +#ifdef CONFIG_BIGNUM case JS_TAG_BIG_FLOAT: atom = JS_ATOM_bigfloat; break; @@ -15068,10 +14840,10 @@ static JSValue js_build_rest(JSContext *ctx, int first, int argc, JSValueConst * static JSValue build_for_in_iterator(JSContext *ctx, JSValue obj) { - JSObject *p; + JSObject *p, *p1; JSPropertyEnum *tab_atom; int i; - JSValue enum_obj, obj1; + JSValue enum_obj; JSForInIterator *it; uint32_t tag, tab_atom_count; @@ -15094,14 +14866,65 @@ static JSValue build_for_in_iterator(JSContext *ctx, JSValue obj) it->is_array = FALSE; it->obj = obj; it->idx = 0; - p = JS_VALUE_GET_OBJ(enum_obj); - p->u.for_in_iterator = it; + it->tab_atom = NULL; + it->atom_count = 0; + it->in_prototype_chain = FALSE; + p1 = JS_VALUE_GET_OBJ(enum_obj); + p1->u.for_in_iterator = it; if (tag == JS_TAG_NULL || tag == JS_TAG_UNDEFINED) return enum_obj; - /* fast path: assume no enumerable properties in the prototype chain */ - obj1 = JS_DupValue(ctx, obj); + p = JS_VALUE_GET_OBJ(obj); + if (p->fast_array) { + JSShape *sh; + JSShapeProperty *prs; + /* check that there are no enumerable normal fields */ + sh = p->shape; + for(i = 0, prs = get_shape_prop(sh); i < sh->prop_count; i++, prs++) { + if (prs->flags & JS_PROP_ENUMERABLE) + goto normal_case; + } + /* for fast arrays, we only store the number of elements */ + it->is_array = TRUE; + it->atom_count = p->u.array.count; + } else { + normal_case: + if (JS_GetOwnPropertyNamesInternal(ctx, &tab_atom, &tab_atom_count, p, + JS_GPN_STRING_MASK | JS_GPN_SET_ENUM)) { + JS_FreeValue(ctx, enum_obj); + return JS_EXCEPTION; + } + it->tab_atom = tab_atom; + it->atom_count = tab_atom_count; + } + return enum_obj; +} + +/* obj -> enum_obj */ +static __exception int js_for_in_start(JSContext *ctx, JSValue *sp) +{ + sp[-1] = build_for_in_iterator(ctx, sp[-1]); + if (JS_IsException(sp[-1])) + return -1; + return 0; +} + +/* return -1 if exception, 0 if slow case, 1 if the enumeration is finished */ +static __exception int js_for_in_prepare_prototype_chain_enum(JSContext *ctx, + JSValueConst enum_obj) +{ + JSObject *p; + JSForInIterator *it; + JSPropertyEnum *tab_atom; + uint32_t tab_atom_count, i; + JSValue obj1; + + p = JS_VALUE_GET_OBJ(enum_obj); + it = p->u.for_in_iterator; + + /* check if there are enumerable properties in the prototype chain (fast path) */ + obj1 = JS_DupValue(ctx, it->obj); for(;;) { obj1 = JS_GetPrototypeFree(ctx, obj1); if (JS_IsNull(obj1)) @@ -15125,75 +14948,29 @@ static JSValue build_for_in_iterator(JSContext *ctx, JSValue obj) goto fail; } } - - p = JS_VALUE_GET_OBJ(obj); - - if (p->fast_array) { - JSShape *sh; - JSShapeProperty *prs; - /* check that there are no enumerable normal fields */ - sh = p->shape; - for(i = 0, prs = get_shape_prop(sh); i < sh->prop_count; i++, prs++) { - if (prs->flags & JS_PROP_ENUMERABLE) - goto normal_case; - } - /* for fast arrays, we only store the number of elements */ - it->is_array = TRUE; - it->array_length = p->u.array.count; - } else { - normal_case: - if (JS_GetOwnPropertyNamesInternal(ctx, &tab_atom, &tab_atom_count, p, - JS_GPN_STRING_MASK | JS_GPN_ENUM_ONLY)) - goto fail; - for(i = 0; i < tab_atom_count; i++) { - JS_SetPropertyInternal(ctx, enum_obj, tab_atom[i].atom, JS_NULL, 0); - } - js_free_prop_enum(ctx, tab_atom, tab_atom_count); - } - return enum_obj; + JS_FreeValue(ctx, obj1); + return 1; slow_path: - /* non enumerable properties hide the enumerables ones in the - prototype chain */ - obj1 = JS_DupValue(ctx, obj); - for(;;) { + /* add the visited properties, even if they are not enumerable */ + if (it->is_array) { if (JS_GetOwnPropertyNamesInternal(ctx, &tab_atom, &tab_atom_count, - JS_VALUE_GET_OBJ(obj1), + JS_VALUE_GET_OBJ(it->obj), JS_GPN_STRING_MASK | JS_GPN_SET_ENUM)) { - JS_FreeValue(ctx, obj1); - goto fail; - } - for(i = 0; i < tab_atom_count; i++) { - JS_DefinePropertyValue(ctx, enum_obj, tab_atom[i].atom, JS_NULL, - (tab_atom[i].is_enumerable ? - JS_PROP_ENUMERABLE : 0)); - } - js_free_prop_enum(ctx, tab_atom, tab_atom_count); - obj1 = JS_GetPrototypeFree(ctx, obj1); - if (JS_IsNull(obj1)) - break; - if (JS_IsException(obj1)) - goto fail; - /* must check for timeout to avoid infinite loop */ - if (js_poll_interrupts(ctx)) { - JS_FreeValue(ctx, obj1); goto fail; } + it->is_array = FALSE; + it->tab_atom = tab_atom; + it->atom_count = tab_atom_count; + } + + for(i = 0; i < it->atom_count; i++) { + if (JS_DefinePropertyValue(ctx, enum_obj, it->tab_atom[i].atom, JS_NULL, JS_PROP_ENUMERABLE) < 0) + goto fail; } - return enum_obj; - - fail: - JS_FreeValue(ctx, enum_obj); - return JS_EXCEPTION; -} - -/* obj -> enum_obj */ -static __exception int js_for_in_start(JSContext *ctx, JSValue *sp) -{ - sp[-1] = build_for_in_iterator(ctx, sp[-1]); - if (JS_IsException(sp[-1])) - return -1; return 0; + fail: + return -1; } /* enum_obj -> enum_obj value done */ @@ -15203,6 +14980,8 @@ static __exception int js_for_in_next(JSContext *ctx, JSValue *sp) JSObject *p; JSAtom prop; JSForInIterator *it; + JSPropertyEnum *tab_atom; + uint32_t tab_atom_count; int ret; enum_obj = sp[-1]; @@ -15215,28 +14994,68 @@ static __exception int js_for_in_next(JSContext *ctx, JSValue *sp) it = p->u.for_in_iterator; for(;;) { - if (it->is_array) { - if (it->idx >= it->array_length) - goto done; - prop = __JS_AtomFromUInt32(it->idx); - it->idx++; + if (it->idx >= it->atom_count) { + if (JS_IsNull(it->obj) || JS_IsUndefined(it->obj)) + goto done; /* not an object */ + /* no more property in the current object: look in the prototype */ + if (!it->in_prototype_chain) { + ret = js_for_in_prepare_prototype_chain_enum(ctx, enum_obj); + if (ret < 0) + return -1; + if (ret) + goto done; + it->in_prototype_chain = TRUE; + } + it->obj = JS_GetPrototypeFree(ctx, it->obj); + if (JS_IsException(it->obj)) + return -1; + if (JS_IsNull(it->obj)) + goto done; /* no more prototype */ + + /* must check for timeout to avoid infinite loop */ + if (js_poll_interrupts(ctx)) + return -1; + + if (JS_GetOwnPropertyNamesInternal(ctx, &tab_atom, &tab_atom_count, + JS_VALUE_GET_OBJ(it->obj), + JS_GPN_STRING_MASK | JS_GPN_SET_ENUM)) { + return -1; + } + js_free_prop_enum(ctx, it->tab_atom, it->atom_count); + it->tab_atom = tab_atom; + it->atom_count = tab_atom_count; + it->idx = 0; } else { - JSShape *sh = p->shape; - JSShapeProperty *prs; - if (it->idx >= sh->prop_count) - goto done; - prs = get_shape_prop(sh) + it->idx; - prop = prs->atom; - it->idx++; - if (prop == JS_ATOM_NULL || !(prs->flags & JS_PROP_ENUMERABLE)) - continue; + if (it->is_array) { + prop = __JS_AtomFromUInt32(it->idx); + it->idx++; + } else { + BOOL is_enumerable; + prop = it->tab_atom[it->idx].atom; + is_enumerable = it->tab_atom[it->idx].is_enumerable; + it->idx++; + if (it->in_prototype_chain) { + /* slow case: we are in the prototype chain */ + ret = JS_GetOwnPropertyInternal(ctx, NULL, JS_VALUE_GET_OBJ(enum_obj), prop); + if (ret < 0) + return ret; + if (ret) + continue; /* already visited */ + /* add to the visited property list */ + if (JS_DefinePropertyValue(ctx, enum_obj, prop, JS_NULL, + JS_PROP_ENUMERABLE) < 0) + return -1; + } + if (!is_enumerable) + continue; + } + /* check if the property was deleted */ + ret = JS_GetOwnPropertyInternal(ctx, NULL, JS_VALUE_GET_OBJ(it->obj), prop); + if (ret < 0) + return ret; + if (ret) + break; } - /* check if the property was deleted */ - ret = JS_HasProperty(ctx, it->obj, prop); - if (ret < 0) - return ret; - if (ret) - break; } /* return the property */ sp[0] = JS_AtomToValue(ctx, prop); @@ -15722,7 +15541,7 @@ static JSVarRef *get_var_ref(JSContext *ctx, JSStackFrame *sf, struct list_head *el; list_for_each(el, &sf->var_ref_list) { - var_ref = list_entry(el, JSVarRef, header.link); + var_ref = list_entry(el, JSVarRef, var_ref_link); if (var_ref->var_idx == var_idx && var_ref->is_arg == is_arg) { var_ref->header.ref_count++; return var_ref; @@ -15733,15 +15552,29 @@ static JSVarRef *get_var_ref(JSContext *ctx, JSStackFrame *sf, if (!var_ref) return NULL; var_ref->header.ref_count = 1; + add_gc_object(ctx->rt, &var_ref->header, JS_GC_OBJ_TYPE_VAR_REF); var_ref->is_detached = FALSE; var_ref->is_arg = is_arg; var_ref->var_idx = var_idx; - list_add_tail(&var_ref->header.link, &sf->var_ref_list); + list_add_tail(&var_ref->var_ref_link, &sf->var_ref_list); + if (sf->js_mode & JS_MODE_ASYNC) { + /* The stack frame is detached and may be destroyed at any + time so its reference count must be increased. Calling + close_var_refs() when destroying the stack frame is not + possible because it would change the graph between the GC + objects. Another solution could be to temporarily detach + the JSVarRef of async functions during the GC. It would + have the advantage of allowing the release of unused stack + frames in a cycle. */ + var_ref->async_func = container_of(sf, JSAsyncFunctionState, frame); + var_ref->async_func->header.ref_count++; + } else { + var_ref->async_func = NULL; + } if (is_arg) var_ref->pvalue = &sf->arg_buf[var_idx]; else var_ref->pvalue = &sf->var_buf[var_idx]; - var_ref->value = JS_UNDEFINED; return var_ref; } @@ -15972,7 +15805,10 @@ static void close_var_refs(JSRuntime *rt, JSStackFrame *sf) int var_idx; list_for_each_safe(el, el1, &sf->var_ref_list) { - var_ref = list_entry(el, JSVarRef, header.link); + var_ref = list_entry(el, JSVarRef, var_ref_link); + /* no need to unlink var_ref->var_ref_link as the list is never used afterwards */ + if (var_ref->async_func) + async_func_free(rt, var_ref->async_func); var_idx = var_ref->var_idx; if (var_ref->is_arg) var_ref->value = JS_DupValueRT(rt, sf->arg_buf[var_idx]); @@ -15981,7 +15817,6 @@ static void close_var_refs(JSRuntime *rt, JSStackFrame *sf) var_ref->pvalue = &var_ref->value; /* the reference is no longer to a local variable */ var_ref->is_detached = TRUE; - add_gc_object(rt, &var_ref->header, JS_GC_OBJ_TYPE_VAR_REF); } } @@ -15992,14 +15827,15 @@ static void close_lexical_var(JSContext *ctx, JSStackFrame *sf, int idx, int is_ int var_idx = idx; list_for_each_safe(el, el1, &sf->var_ref_list) { - var_ref = list_entry(el, JSVarRef, header.link); + var_ref = list_entry(el, JSVarRef, var_ref_link); if (var_idx == var_ref->var_idx && var_ref->is_arg == is_arg) { + list_del(&var_ref->var_ref_link); + if (var_ref->async_func) + async_func_free(ctx->rt, var_ref->async_func); var_ref->value = JS_DupValue(ctx, sf->var_buf[var_idx]); var_ref->pvalue = &var_ref->value; - list_del(&var_ref->header.link); /* the reference is no longer to a local variable */ var_ref->is_detached = TRUE; - add_gc_object(ctx->rt, &var_ref->header, JS_GC_OBJ_TYPE_VAR_REF); } } } @@ -16190,9 +16026,10 @@ typedef enum { OP_SPECIAL_OBJECT_IMPORT_META, } OPSpecialObjectEnum; -#define FUNC_RET_AWAIT 0 -#define FUNC_RET_YIELD 1 -#define FUNC_RET_YIELD_STAR 2 +#define FUNC_RET_AWAIT 0 +#define FUNC_RET_YIELD 1 +#define FUNC_RET_YIELD_STAR 2 +#define FUNC_RET_INITIAL_YIELD 3 /* argv[] is modified if (flags & JS_CALL_FLAG_COPY_ARGV) = 0. */ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, @@ -16754,8 +16591,15 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, } BREAK; CASE(OP_check_brand): - if (JS_CheckBrand(ctx, sp[-2], sp[-1]) < 0) - goto exception; + { + int ret = JS_CheckBrand(ctx, sp[-2], sp[-1]); + if (ret < 0) + goto exception; + if (!ret) { + JS_ThrowTypeError(ctx, "invalid brand on object"); + goto exception; + } + } BREAK; CASE(OP_add_brand): if (JS_AddBrand(ctx, sp[-2], sp[-1]) < 0) @@ -17177,6 +17021,19 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, sp++; } BREAK; + CASE(OP_get_loc_checkthis): + { + int idx; + idx = get_u16(pc); + pc += 2; + if (unlikely(JS_IsUninitialized(var_buf[idx]))) { + JS_ThrowReferenceErrorUninitialized2(caller_ctx, b, idx, FALSE); + goto exception; + } + sp[0] = JS_DupValue(ctx, var_buf[idx]); + sp++; + } + BREAK; CASE(OP_put_loc_check): { int idx; @@ -17446,26 +17303,21 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, } sp--; BREAK; - CASE(OP_iterator_close_return): + CASE(OP_nip_catch): { JSValue ret_val; - /* iter_obj next catch_offset ... ret_val -> - ret_eval iter_obj next catch_offset */ + /* catch_offset ... ret_val -> ret_eval */ ret_val = *--sp; while (sp > stack_buf && JS_VALUE_GET_TAG(sp[-1]) != JS_TAG_CATCH_OFFSET) { JS_FreeValue(ctx, *--sp); } - if (unlikely(sp < stack_buf + 3)) { - JS_ThrowInternalError(ctx, "iterator_close_return"); + if (unlikely(sp == stack_buf)) { + JS_ThrowInternalError(ctx, "nip_catch"); JS_FreeValue(ctx, ret_val); goto exception; } - sp[0] = sp[-1]; - sp[-1] = sp[-2]; - sp[-2] = sp[-3]; - sp[-3] = ret_val; - sp++; + sp[-1] = ret_val; } BREAK; @@ -17566,7 +17418,7 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, atom = get_u32(pc); pc += 4; - ret = JS_SetPropertyInternal(ctx, sp[-2], atom, sp[-1], + ret = JS_SetPropertyInternal(ctx, sp[-2], atom, sp[-1], sp[-2], JS_PROP_THROW_STRICT); JS_FreeValue(ctx, sp[-2]); sp -= 2; @@ -17865,8 +17717,8 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, atom = JS_ValueToAtom(ctx, sp[-2]); if (unlikely(atom == JS_ATOM_NULL)) goto exception; - ret = JS_SetPropertyGeneric(ctx, sp[-3], atom, sp[-1], sp[-4], - JS_PROP_THROW_STRICT); + ret = JS_SetPropertyInternal(ctx, sp[-3], atom, sp[-1], sp[-4], + JS_PROP_THROW_STRICT); JS_FreeAtom(ctx, atom); JS_FreeValue(ctx, sp[-4]); JS_FreeValue(ctx, sp[-3]); @@ -18415,6 +18267,11 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, goto exception; sp--; BREAK; + CASE(OP_private_in): + if (js_operator_private_in(ctx, sp)) + goto exception; + sp--; + BREAK; CASE(OP_instanceof): if (js_operator_instanceof(ctx, sp)) goto exception; @@ -18545,7 +18402,7 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, break; case OP_with_put_var: /* XXX: check if strict mode */ - ret = JS_SetPropertyInternal(ctx, obj, atom, sp[-2], + ret = JS_SetPropertyInternal(ctx, obj, atom, sp[-2], obj, JS_PROP_THROW_STRICT); JS_FreeValue(ctx, sp[-1]); sp -= 2; @@ -18601,9 +18458,11 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, ret_val = JS_NewInt32(ctx, FUNC_RET_YIELD_STAR); goto done_generator; CASE(OP_return_async): - CASE(OP_initial_yield): ret_val = JS_UNDEFINED; goto done_generator; + CASE(OP_initial_yield): + ret_val = JS_NewInt32(ctx, FUNC_RET_INITIAL_YIELD); + goto done_generator; CASE(OP_nop): BREAK; @@ -18885,26 +18744,35 @@ static JSValue JS_InvokeFree(JSContext *ctx, JSValue this_val, JSAtom atom, } /* JSAsyncFunctionState (used by generator and async functions) */ -static __exception int async_func_init(JSContext *ctx, JSAsyncFunctionState *s, - JSValueConst func_obj, JSValueConst this_obj, - int argc, JSValueConst *argv) +static JSAsyncFunctionState *async_func_init(JSContext *ctx, + JSValueConst func_obj, JSValueConst this_obj, + int argc, JSValueConst *argv) { + JSAsyncFunctionState *s; JSObject *p; JSFunctionBytecode *b; JSStackFrame *sf; int local_count, i, arg_buf_len, n; + s = js_mallocz(ctx, sizeof(*s)); + if (!s) + return NULL; + s->header.ref_count = 1; + add_gc_object(ctx->rt, &s->header, JS_GC_OBJ_TYPE_ASYNC_FUNCTION); + sf = &s->frame; init_list_head(&sf->var_ref_list); p = JS_VALUE_GET_OBJ(func_obj); b = p->u.func.function_bytecode; - sf->js_mode = b->js_mode; + sf->js_mode = b->js_mode | JS_MODE_ASYNC; sf->cur_pc = b->byte_code_buf; arg_buf_len = max_int(b->arg_count, argc); local_count = arg_buf_len + b->var_count + b->stack_size; sf->arg_buf = js_malloc(ctx, sizeof(JSValue) * max_int(local_count, 1)); - if (!sf->arg_buf) - return -1; + if (!sf->arg_buf) { + js_free(ctx, s); + return NULL; + } sf->cur_func = JS_DupValue(ctx, func_obj); s->this_val = JS_DupValue(ctx, this_obj); s->argc = argc; @@ -18916,38 +18784,17 @@ static __exception int async_func_init(JSContext *ctx, JSAsyncFunctionState *s, n = arg_buf_len + b->var_count; for(i = argc; i < n; i++) sf->arg_buf[i] = JS_UNDEFINED; - return 0; + s->resolving_funcs[0] = JS_UNDEFINED; + s->resolving_funcs[1] = JS_UNDEFINED; + s->is_completed = FALSE; + return s; } -static void async_func_mark(JSRuntime *rt, JSAsyncFunctionState *s, - JS_MarkFunc *mark_func) +static void async_func_free_frame(JSRuntime *rt, JSAsyncFunctionState *s) { - JSStackFrame *sf; + JSStackFrame *sf = &s->frame; JSValue *sp; - sf = &s->frame; - JS_MarkValue(rt, sf->cur_func, mark_func); - JS_MarkValue(rt, s->this_val, mark_func); - if (sf->cur_sp) { - /* if the function is running, cur_sp is not known so we - cannot mark the stack. Marking the variables is not needed - because a running function cannot be part of a removable - cycle */ - for(sp = sf->arg_buf; sp < sf->cur_sp; sp++) - JS_MarkValue(rt, *sp, mark_func); - } -} - -static void async_func_free(JSRuntime *rt, JSAsyncFunctionState *s) -{ - JSStackFrame *sf; - JSValue *sp; - - sf = &s->frame; - - /* close the closure variables. */ - close_var_refs(rt, sf); - if (sf->arg_buf) { /* cannot free the function if it is running */ assert(sf->cur_sp != NULL); @@ -18955,6 +18802,7 @@ static void async_func_free(JSRuntime *rt, JSAsyncFunctionState *s) JS_FreeValueRT(rt, *sp); } js_free_rt(rt, sf->arg_buf); + sf->arg_buf = NULL; } JS_FreeValueRT(rt, sf->cur_func); JS_FreeValueRT(rt, s->this_val); @@ -18962,17 +18810,66 @@ static void async_func_free(JSRuntime *rt, JSAsyncFunctionState *s) static JSValue async_func_resume(JSContext *ctx, JSAsyncFunctionState *s) { - JSValue func_obj; + JSRuntime *rt = ctx->rt; + JSStackFrame *sf = &s->frame; + JSValue func_obj, ret; - if (js_check_stack_overflow(ctx->rt, 0)) - return JS_ThrowStackOverflow(ctx); + assert(!s->is_completed); + if (js_check_stack_overflow(ctx->rt, 0)) { + ret = JS_ThrowStackOverflow(ctx); + } else { + /* the tag does not matter provided it is not an object */ + func_obj = JS_MKPTR(JS_TAG_INT, s); + ret = JS_CallInternal(ctx, func_obj, s->this_val, JS_UNDEFINED, + s->argc, sf->arg_buf, JS_CALL_FLAG_GENERATOR); + } + if (JS_IsException(ret) || JS_IsUndefined(ret)) { + if (JS_IsUndefined(ret)) { + ret = sf->cur_sp[-1]; + sf->cur_sp[-1] = JS_UNDEFINED; + } + /* end of execution */ + s->is_completed = TRUE; - /* the tag does not matter provided it is not an object */ - func_obj = JS_MKPTR(JS_TAG_INT, s); - return JS_CallInternal(ctx, func_obj, s->this_val, JS_UNDEFINED, - s->argc, s->frame.arg_buf, JS_CALL_FLAG_GENERATOR); + /* close the closure variables. */ + close_var_refs(rt, sf); + + async_func_free_frame(rt, s); + } + return ret; } +static void __async_func_free(JSRuntime *rt, JSAsyncFunctionState *s) +{ + /* cannot close the closure variables here because it would + potentially modify the object graph */ + if (!s->is_completed) { + async_func_free_frame(rt, s); + } + + JS_FreeValueRT(rt, s->resolving_funcs[0]); + JS_FreeValueRT(rt, s->resolving_funcs[1]); + + remove_gc_object(&s->header); + if (rt->gc_phase == JS_GC_PHASE_REMOVE_CYCLES && s->header.ref_count != 0) { + list_add_tail(&s->header.link, &rt->gc_zero_ref_count_list); + } else { + js_free_rt(rt, s); + } +} + +static void async_func_free(JSRuntime *rt, JSAsyncFunctionState *s) +{ + if (--s->header.ref_count == 0) { + if (rt->gc_phase != JS_GC_PHASE_REMOVE_CYCLES) { + list_del(&s->header.link); + list_add(&s->header.link, &rt->gc_zero_ref_count_list); + if (rt->gc_phase == JS_GC_PHASE_NONE) { + free_zero_refcount(rt); + } + } + } +} /* Generators */ @@ -18986,14 +18883,17 @@ typedef enum JSGeneratorStateEnum { typedef struct JSGeneratorData { JSGeneratorStateEnum state; - JSAsyncFunctionState func_state; + JSAsyncFunctionState *func_state; } JSGeneratorData; static void free_generator_stack_rt(JSRuntime *rt, JSGeneratorData *s) { if (s->state == JS_GENERATOR_STATE_COMPLETED) return; - async_func_free(rt, &s->func_state); + if (s->func_state) { + async_func_free(rt, s->func_state); + s->func_state = NULL; + } s->state = JS_GENERATOR_STATE_COMPLETED; } @@ -19018,9 +18918,9 @@ static void js_generator_mark(JSRuntime *rt, JSValueConst val, JSObject *p = JS_VALUE_GET_OBJ(val); JSGeneratorData *s = p->u.generator_data; - if (!s || s->state == JS_GENERATOR_STATE_COMPLETED) + if (!s || !s->func_state) return; - async_func_mark(rt, &s->func_state, mark_func); + mark_func(rt, &s->func_state->header); } /* XXX: use enum */ @@ -19039,7 +18939,7 @@ static JSValue js_generator_next(JSContext *ctx, JSValueConst this_val, *pdone = TRUE; if (!s) return JS_ThrowTypeError(ctx, "not a generator"); - sf = &s->func_state.frame; + sf = &s->func_state->frame; switch(s->state) { default: case JS_GENERATOR_STATE_SUSPENDED_START: @@ -19057,23 +18957,23 @@ static JSValue js_generator_next(JSContext *ctx, JSValueConst this_val, if (magic == GEN_MAGIC_THROW && s->state == JS_GENERATOR_STATE_SUSPENDED_YIELD) { JS_Throw(ctx, ret); - s->func_state.throw_flag = TRUE; + s->func_state->throw_flag = TRUE; } else { sf->cur_sp[-1] = ret; sf->cur_sp[0] = JS_NewInt32(ctx, magic); sf->cur_sp++; exec_no_arg: - s->func_state.throw_flag = FALSE; + s->func_state->throw_flag = FALSE; } s->state = JS_GENERATOR_STATE_EXECUTING; - func_ret = async_func_resume(ctx, &s->func_state); + func_ret = async_func_resume(ctx, s->func_state); s->state = JS_GENERATOR_STATE_SUSPENDED_YIELD; - if (JS_IsException(func_ret)) { - /* finalize the execution in case of exception */ + if (s->func_state->is_completed) { + /* finalize the execution in case of exception or normal return */ free_generator_stack(ctx, s); return func_ret; - } - if (JS_VALUE_GET_TAG(func_ret) == JS_TAG_INT) { + } else { + assert(JS_VALUE_GET_TAG(func_ret) == JS_TAG_INT); /* get the returned yield value at the top of the stack */ ret = sf->cur_sp[-1]; sf->cur_sp[-1] = JS_UNDEFINED; @@ -19084,12 +18984,6 @@ static JSValue js_generator_next(JSContext *ctx, JSValueConst this_val, } else { *pdone = FALSE; } - } else { - /* end of iterator */ - ret = sf->cur_sp[-1]; - sf->cur_sp[-1] = JS_UNDEFINED; - JS_FreeValue(ctx, func_ret); - free_generator_stack(ctx, s); } break; case JS_GENERATOR_STATE_COMPLETED: @@ -19127,13 +19021,14 @@ static JSValue js_generator_function_call(JSContext *ctx, JSValueConst func_obj, if (!s) return JS_EXCEPTION; s->state = JS_GENERATOR_STATE_SUSPENDED_START; - if (async_func_init(ctx, &s->func_state, func_obj, this_obj, argc, argv)) { + s->func_state = async_func_init(ctx, func_obj, this_obj, argc, argv); + if (!s->func_state) { s->state = JS_GENERATOR_STATE_COMPLETED; goto fail; } /* execute the function up to 'OP_initial_yield' */ - func_ret = async_func_resume(ctx, &s->func_state); + func_ret = async_func_resume(ctx, s->func_state); if (JS_IsException(func_ret)) goto fail; JS_FreeValue(ctx, func_ret); @@ -19151,36 +19046,12 @@ static JSValue js_generator_function_call(JSContext *ctx, JSValueConst func_obj, /* AsyncFunction */ -static void js_async_function_terminate(JSRuntime *rt, JSAsyncFunctionData *s) -{ - if (s->is_active) { - async_func_free(rt, &s->func_state); - s->is_active = FALSE; - } -} - -static void js_async_function_free0(JSRuntime *rt, JSAsyncFunctionData *s) -{ - js_async_function_terminate(rt, s); - JS_FreeValueRT(rt, s->resolving_funcs[0]); - JS_FreeValueRT(rt, s->resolving_funcs[1]); - remove_gc_object(&s->header); - js_free_rt(rt, s); -} - -static void js_async_function_free(JSRuntime *rt, JSAsyncFunctionData *s) -{ - if (--s->header.ref_count == 0) { - js_async_function_free0(rt, s); - } -} - static void js_async_function_resolve_finalizer(JSRuntime *rt, JSValue val) { JSObject *p = JS_VALUE_GET_OBJ(val); - JSAsyncFunctionData *s = p->u.async_function_data; + JSAsyncFunctionState *s = p->u.async_function_data; if (s) { - js_async_function_free(rt, s); + async_func_free(rt, s); } } @@ -19188,14 +19059,14 @@ static void js_async_function_resolve_mark(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func) { JSObject *p = JS_VALUE_GET_OBJ(val); - JSAsyncFunctionData *s = p->u.async_function_data; + JSAsyncFunctionState *s = p->u.async_function_data; if (s) { mark_func(rt, &s->header); } } static int js_async_function_resolve_create(JSContext *ctx, - JSAsyncFunctionData *s, + JSAsyncFunctionState *s, JSValue *resolving_funcs) { int i; @@ -19217,60 +19088,58 @@ static int js_async_function_resolve_create(JSContext *ctx, return 0; } -static void js_async_function_resume(JSContext *ctx, JSAsyncFunctionData *s) +static void js_async_function_resume(JSContext *ctx, JSAsyncFunctionState *s) { JSValue func_ret, ret2; - func_ret = async_func_resume(ctx, &s->func_state); - if (JS_IsException(func_ret)) { - JSValue error; - fail: - error = JS_GetException(ctx); - ret2 = JS_Call(ctx, s->resolving_funcs[1], JS_UNDEFINED, - 1, (JSValueConst *)&error); - JS_FreeValue(ctx, error); - js_async_function_terminate(ctx->rt, s); - JS_FreeValue(ctx, ret2); /* XXX: what to do if exception ? */ - } else { - JSValue value; - value = s->func_state.frame.cur_sp[-1]; - s->func_state.frame.cur_sp[-1] = JS_UNDEFINED; - if (JS_IsUndefined(func_ret)) { - /* function returned */ - ret2 = JS_Call(ctx, s->resolving_funcs[0], JS_UNDEFINED, - 1, (JSValueConst *)&value); + func_ret = async_func_resume(ctx, s); + if (s->is_completed) { + if (JS_IsException(func_ret)) { + JSValue error; + fail: + error = JS_GetException(ctx); + ret2 = JS_Call(ctx, s->resolving_funcs[1], JS_UNDEFINED, + 1, (JSValueConst *)&error); + JS_FreeValue(ctx, error); JS_FreeValue(ctx, ret2); /* XXX: what to do if exception ? */ - JS_FreeValue(ctx, value); - js_async_function_terminate(ctx->rt, s); } else { - JSValue promise, resolving_funcs[2], resolving_funcs1[2]; - int i, res; - - /* await */ - JS_FreeValue(ctx, func_ret); /* not used */ - promise = js_promise_resolve(ctx, ctx->promise_ctor, - 1, (JSValueConst *)&value, 0); - JS_FreeValue(ctx, value); - if (JS_IsException(promise)) - goto fail; - if (js_async_function_resolve_create(ctx, s, resolving_funcs)) { - JS_FreeValue(ctx, promise); - goto fail; - } - - /* Note: no need to create 'thrownawayCapability' as in - the spec */ - for(i = 0; i < 2; i++) - resolving_funcs1[i] = JS_UNDEFINED; - res = perform_promise_then(ctx, promise, - (JSValueConst *)resolving_funcs, - (JSValueConst *)resolving_funcs1); - JS_FreeValue(ctx, promise); - for(i = 0; i < 2; i++) - JS_FreeValue(ctx, resolving_funcs[i]); - if (res) - goto fail; + /* normal return */ + ret2 = JS_Call(ctx, s->resolving_funcs[0], JS_UNDEFINED, + 1, (JSValueConst *)&func_ret); + JS_FreeValue(ctx, func_ret); + JS_FreeValue(ctx, ret2); /* XXX: what to do if exception ? */ } + } else { + JSValue value, promise, resolving_funcs[2], resolving_funcs1[2]; + int i, res; + + value = s->frame.cur_sp[-1]; + s->frame.cur_sp[-1] = JS_UNDEFINED; + + /* await */ + JS_FreeValue(ctx, func_ret); /* not used */ + promise = js_promise_resolve(ctx, ctx->promise_ctor, + 1, (JSValueConst *)&value, 0); + JS_FreeValue(ctx, value); + if (JS_IsException(promise)) + goto fail; + if (js_async_function_resolve_create(ctx, s, resolving_funcs)) { + JS_FreeValue(ctx, promise); + goto fail; + } + + /* Note: no need to create 'thrownawayCapability' as in + the spec */ + for(i = 0; i < 2; i++) + resolving_funcs1[i] = JS_UNDEFINED; + res = perform_promise_then(ctx, promise, + (JSValueConst *)resolving_funcs, + (JSValueConst *)resolving_funcs1); + JS_FreeValue(ctx, promise); + for(i = 0; i < 2; i++) + JS_FreeValue(ctx, resolving_funcs[i]); + if (res) + goto fail; } } @@ -19281,7 +19150,7 @@ static JSValue js_async_function_resolve_call(JSContext *ctx, int flags) { JSObject *p = JS_VALUE_GET_OBJ(func_obj); - JSAsyncFunctionData *s = p->u.async_function_data; + JSAsyncFunctionState *s = p->u.async_function_data; BOOL is_reject = p->class_id - JS_CLASS_ASYNC_FUNCTION_RESOLVE; JSValueConst arg; @@ -19289,12 +19158,12 @@ static JSValue js_async_function_resolve_call(JSContext *ctx, arg = argv[0]; else arg = JS_UNDEFINED; - s->func_state.throw_flag = is_reject; + s->throw_flag = is_reject; if (is_reject) { JS_Throw(ctx, JS_DupValue(ctx, arg)); } else { /* return value of await */ - s->func_state.frame.cur_sp[-1] = JS_DupValue(ctx, arg); + s->frame.cur_sp[-1] = JS_DupValue(ctx, arg); } js_async_function_resume(ctx, s); return JS_UNDEFINED; @@ -19305,32 +19174,21 @@ static JSValue js_async_function_call(JSContext *ctx, JSValueConst func_obj, int argc, JSValueConst *argv, int flags) { JSValue promise; - JSAsyncFunctionData *s; + JSAsyncFunctionState *s; - s = js_mallocz(ctx, sizeof(*s)); + s = async_func_init(ctx, func_obj, this_obj, argc, argv); if (!s) return JS_EXCEPTION; - s->header.ref_count = 1; - add_gc_object(ctx->rt, &s->header, JS_GC_OBJ_TYPE_ASYNC_FUNCTION); - s->is_active = FALSE; - s->resolving_funcs[0] = JS_UNDEFINED; - s->resolving_funcs[1] = JS_UNDEFINED; promise = JS_NewPromiseCapability(ctx, s->resolving_funcs); - if (JS_IsException(promise)) - goto fail; - - if (async_func_init(ctx, &s->func_state, func_obj, this_obj, argc, argv)) { - fail: - JS_FreeValue(ctx, promise); - js_async_function_free(ctx->rt, s); + if (JS_IsException(promise)) { + async_func_free(ctx->rt, s); return JS_EXCEPTION; } - s->is_active = TRUE; js_async_function_resume(ctx, s); - - js_async_function_free(ctx->rt, s); + + async_func_free(ctx->rt, s); return promise; } @@ -19359,7 +19217,8 @@ typedef struct JSAsyncGeneratorRequest { typedef struct JSAsyncGeneratorData { JSObject *generator; /* back pointer to the object (const) */ JSAsyncGeneratorStateEnum state; - JSAsyncFunctionState func_state; + /* func_state is NULL is state AWAITING_RETURN and COMPLETED */ + JSAsyncFunctionState *func_state; struct list_head queue; /* list of JSAsyncGeneratorRequest.link */ } JSAsyncGeneratorData; @@ -19377,10 +19236,8 @@ static void js_async_generator_free(JSRuntime *rt, JS_FreeValueRT(rt, req->resolving_funcs[1]); js_free_rt(rt, req); } - if (s->state != JS_ASYNC_GENERATOR_STATE_COMPLETED && - s->state != JS_ASYNC_GENERATOR_STATE_AWAITING_RETURN) { - async_func_free(rt, &s->func_state); - } + if (s->func_state) + async_func_free(rt, s->func_state); js_free_rt(rt, s); } @@ -19407,9 +19264,8 @@ static void js_async_generator_mark(JSRuntime *rt, JSValueConst val, JS_MarkValue(rt, req->resolving_funcs[0], mark_func); JS_MarkValue(rt, req->resolving_funcs[1], mark_func); } - if (s->state != JS_ASYNC_GENERATOR_STATE_COMPLETED && - s->state != JS_ASYNC_GENERATOR_STATE_AWAITING_RETURN) { - async_func_mark(rt, &s->func_state, mark_func); + if (s->func_state) { + mark_func(rt, &s->func_state->header); } } } @@ -19519,7 +19375,8 @@ static void js_async_generator_complete(JSContext *ctx, { if (s->state != JS_ASYNC_GENERATOR_STATE_COMPLETED) { s->state = JS_ASYNC_GENERATOR_STATE_COMPLETED; - async_func_free(ctx->rt, &s->func_state); + async_func_free(ctx->rt, s->func_state); + s->func_state = NULL; } } @@ -19530,10 +19387,19 @@ static int js_async_generator_completed_return(JSContext *ctx, JSValue promise, resolving_funcs[2], resolving_funcs1[2]; int res; - promise = js_promise_resolve(ctx, ctx->promise_ctor, - 1, (JSValueConst *)&value, 0); - if (JS_IsException(promise)) - return -1; + // Can fail looking up JS_ATOM_constructor when is_reject==0. + promise = js_promise_resolve(ctx, ctx->promise_ctor, 1, &value, + /*is_reject*/0); + // A poisoned .constructor property is observable and the resulting + // exception should be delivered to the catch handler. + if (JS_IsException(promise)) { + JSValue err = JS_GetException(ctx); + promise = js_promise_resolve(ctx, ctx->promise_ctor, 1, (JSValueConst *)&err, + /*is_reject*/1); + JS_FreeValue(ctx, err); + if (JS_IsException(promise)) + return -1; + } if (js_async_generator_resolve_function_create(ctx, JS_MKPTR(JS_TAG_OBJECT, s->generator), resolving_funcs1, @@ -19581,7 +19447,6 @@ static void js_async_generator_resume_next(JSContext *ctx, } else if (next->completion_type == GEN_MAGIC_RETURN) { s->state = JS_ASYNC_GENERATOR_STATE_AWAITING_RETURN; js_async_generator_completed_return(ctx, s, next->result); - goto done; } else { js_async_generator_reject(ctx, s, next->result); } @@ -19592,30 +19457,38 @@ static void js_async_generator_resume_next(JSContext *ctx, if (next->completion_type == GEN_MAGIC_THROW && s->state == JS_ASYNC_GENERATOR_STATE_SUSPENDED_YIELD) { JS_Throw(ctx, value); - s->func_state.throw_flag = TRUE; + s->func_state->throw_flag = TRUE; } else { /* 'yield' returns a value. 'yield *' also returns a value in case the 'throw' method is called */ - s->func_state.frame.cur_sp[-1] = value; - s->func_state.frame.cur_sp[0] = + s->func_state->frame.cur_sp[-1] = value; + s->func_state->frame.cur_sp[0] = JS_NewInt32(ctx, next->completion_type); - s->func_state.frame.cur_sp++; + s->func_state->frame.cur_sp++; exec_no_arg: - s->func_state.throw_flag = FALSE; + s->func_state->throw_flag = FALSE; } s->state = JS_ASYNC_GENERATOR_STATE_EXECUTING; resume_exec: - func_ret = async_func_resume(ctx, &s->func_state); - if (JS_IsException(func_ret)) { - value = JS_GetException(ctx); - js_async_generator_complete(ctx, s); - js_async_generator_reject(ctx, s, value); - JS_FreeValue(ctx, value); - } else if (JS_VALUE_GET_TAG(func_ret) == JS_TAG_INT) { - int func_ret_code; - value = s->func_state.frame.cur_sp[-1]; - s->func_state.frame.cur_sp[-1] = JS_UNDEFINED; + func_ret = async_func_resume(ctx, s->func_state); + if (s->func_state->is_completed) { + if (JS_IsException(func_ret)) { + value = JS_GetException(ctx); + js_async_generator_complete(ctx, s); + js_async_generator_reject(ctx, s, value); + JS_FreeValue(ctx, value); + } else { + /* end of function */ + js_async_generator_complete(ctx, s); + js_async_generator_resolve(ctx, s, func_ret, TRUE); + JS_FreeValue(ctx, func_ret); + } + } else { + int func_ret_code, ret; + assert(JS_VALUE_GET_TAG(func_ret) == JS_TAG_INT); func_ret_code = JS_VALUE_GET_INT(func_ret); + value = s->func_state->frame.cur_sp[-1]; + s->func_state->frame.cur_sp[-1] = JS_UNDEFINED; switch(func_ret_code) { case FUNC_RET_YIELD: case FUNC_RET_YIELD_STAR: @@ -19627,20 +19500,17 @@ static void js_async_generator_resume_next(JSContext *ctx, JS_FreeValue(ctx, value); break; case FUNC_RET_AWAIT: - js_async_generator_await(ctx, s, value); + ret = js_async_generator_await(ctx, s, value); JS_FreeValue(ctx, value); + if (ret < 0) { + /* exception: throw it */ + s->func_state->throw_flag = TRUE; + goto resume_exec; + } goto done; default: abort(); } - } else { - assert(JS_IsUndefined(func_ret)); - /* end of function */ - value = s->func_state.frame.cur_sp[-1]; - s->func_state.frame.cur_sp[-1] = JS_UNDEFINED; - js_async_generator_complete(ctx, s); - js_async_generator_resolve(ctx, s, value, TRUE); - JS_FreeValue(ctx, value); } break; default: @@ -19674,12 +19544,12 @@ static JSValue js_async_generator_resolve_function(JSContext *ctx, } else { /* restart function execution after await() */ assert(s->state == JS_ASYNC_GENERATOR_STATE_EXECUTING); - s->func_state.throw_flag = is_reject; + s->func_state->throw_flag = is_reject; if (is_reject) { JS_Throw(ctx, JS_DupValue(ctx, arg)); } else { /* return value of await */ - s->func_state.frame.cur_sp[-1] = JS_DupValue(ctx, arg); + s->func_state->frame.cur_sp[-1] = JS_DupValue(ctx, arg); } js_async_generator_resume_next(ctx, s); } @@ -19743,14 +19613,12 @@ static JSValue js_async_generator_function_call(JSContext *ctx, JSValueConst fun return JS_EXCEPTION; s->state = JS_ASYNC_GENERATOR_STATE_SUSPENDED_START; init_list_head(&s->queue); - if (async_func_init(ctx, &s->func_state, func_obj, this_obj, argc, argv)) { - s->state = JS_ASYNC_GENERATOR_STATE_COMPLETED; + s->func_state = async_func_init(ctx, func_obj, this_obj, argc, argv); + if (!s->func_state) goto fail; - } - /* execute the function up to 'OP_initial_yield' (no yield nor await are possible) */ - func_ret = async_func_resume(ctx, &s->func_state); + func_ret = async_func_resume(ctx, s->func_state); if (JS_IsException(func_ret)) goto fail; JS_FreeValue(ctx, func_ret); @@ -19936,6 +19804,7 @@ typedef enum JSParseFunctionEnum { JS_PARSE_FUNC_GETTER, JS_PARSE_FUNC_SETTER, JS_PARSE_FUNC_METHOD, + JS_PARSE_FUNC_CLASS_STATIC_INIT, JS_PARSE_FUNC_CLASS_CONSTRUCTOR, JS_PARSE_FUNC_DERIVED_CLASS_CONSTRUCTOR, } JSParseFunctionEnum; @@ -20055,6 +19924,7 @@ typedef struct JSFunctionDef { int source_len; JSModuleDef *module; /* != NULL when parsing a module */ + BOOL has_await; /* TRUE if await is used (used in module eval) */ } JSFunctionDef; typedef struct JSToken { @@ -20143,11 +20013,9 @@ static __exception int next_token(JSParseState *s); static void free_token(JSParseState *s, JSToken *token) { switch(token->val) { -#ifdef CONFIG_BIGNUM case TOK_NUMBER: JS_FreeValue(s->ctx, token->u.num.val); break; -#endif case TOK_STRING: case TOK_TEMPLATE: JS_FreeValue(s->ctx, token->u.str.str); @@ -20607,6 +20475,48 @@ static __exception int ident_realloc(JSContext *ctx, char **pbuf, size_t *psize, return 0; } +/* convert a TOK_IDENT to a keyword when needed */ +static void update_token_ident(JSParseState *s) +{ + if (s->token.u.ident.atom <= JS_ATOM_LAST_KEYWORD || + (s->token.u.ident.atom <= JS_ATOM_LAST_STRICT_KEYWORD && + (s->cur_func->js_mode & JS_MODE_STRICT)) || + (s->token.u.ident.atom == JS_ATOM_yield && + ((s->cur_func->func_kind & JS_FUNC_GENERATOR) || + (s->cur_func->func_type == JS_PARSE_FUNC_ARROW && + !s->cur_func->in_function_body && s->cur_func->parent && + (s->cur_func->parent->func_kind & JS_FUNC_GENERATOR)))) || + (s->token.u.ident.atom == JS_ATOM_await && + (s->is_module || + (s->cur_func->func_kind & JS_FUNC_ASYNC) || + s->cur_func->func_type == JS_PARSE_FUNC_CLASS_STATIC_INIT || + (s->cur_func->func_type == JS_PARSE_FUNC_ARROW && + !s->cur_func->in_function_body && s->cur_func->parent && + ((s->cur_func->parent->func_kind & JS_FUNC_ASYNC) || + s->cur_func->parent->func_type == JS_PARSE_FUNC_CLASS_STATIC_INIT))))) { + if (s->token.u.ident.has_escape) { + s->token.u.ident.is_reserved = TRUE; + s->token.val = TOK_IDENT; + } else { + /* The keywords atoms are pre allocated */ + s->token.val = s->token.u.ident.atom - 1 + TOK_FIRST_KEYWORD; + } + } +} + +/* if the current token is an identifier or keyword, reparse it + according to the current function type */ +static void reparse_ident_token(JSParseState *s) +{ + if (s->token.val == TOK_IDENT || + (s->token.val >= TOK_FIRST_KEYWORD && + s->token.val <= TOK_LAST_KEYWORD)) { + s->token.val = TOK_IDENT; + s->token.u.ident.is_reserved = FALSE; + update_token_ident(s); + } +} + /* 'c' is the first character. Return JS_ATOM_NULL in case of error */ static JSAtom parse_ident(JSParseState *s, const uint8_t **pp, BOOL *pident_has_escape, int c, BOOL is_private) @@ -20813,30 +20723,8 @@ static __exception int next_token(JSParseState *s) s->token.u.ident.atom = atom; s->token.u.ident.has_escape = ident_has_escape; s->token.u.ident.is_reserved = FALSE; - if (s->token.u.ident.atom <= JS_ATOM_LAST_KEYWORD || - (s->token.u.ident.atom <= JS_ATOM_LAST_STRICT_KEYWORD && - (s->cur_func->js_mode & JS_MODE_STRICT)) || - (s->token.u.ident.atom == JS_ATOM_yield && - ((s->cur_func->func_kind & JS_FUNC_GENERATOR) || - (s->cur_func->func_type == JS_PARSE_FUNC_ARROW && - !s->cur_func->in_function_body && s->cur_func->parent && - (s->cur_func->parent->func_kind & JS_FUNC_GENERATOR)))) || - (s->token.u.ident.atom == JS_ATOM_await && - (s->is_module || - (((s->cur_func->func_kind & JS_FUNC_ASYNC) || - (s->cur_func->func_type == JS_PARSE_FUNC_ARROW && - !s->cur_func->in_function_body && s->cur_func->parent && - (s->cur_func->parent->func_kind & JS_FUNC_ASYNC))))))) { - if (ident_has_escape) { - s->token.u.ident.is_reserved = TRUE; - s->token.val = TOK_IDENT; - } else { - /* The keywords atoms are pre allocated */ - s->token.val = s->token.u.ident.atom - 1 + TOK_FIRST_KEYWORD; - } - } else { - s->token.val = TOK_IDENT; - } + s->token.val = TOK_IDENT; + update_token_ident(s); break; case '#': /* private name */ @@ -20893,8 +20781,8 @@ static __exception int next_token(JSParseState *s) int flags, radix; flags = ATOD_ACCEPT_BIN_OCT | ATOD_ACCEPT_LEGACY_OCTAL | ATOD_ACCEPT_UNDERSCORES; -#ifdef CONFIG_BIGNUM flags |= ATOD_ACCEPT_SUFFIX; +#ifdef CONFIG_BIGNUM if (s->cur_func->js_mode & JS_MODE_MATH) { flags |= ATOD_MODE_BIGINT; if (s->cur_func->js_mode & JS_MODE_MATH) @@ -21483,6 +21371,31 @@ static int peek_token(JSParseState *s, BOOL no_line_terminator) return simple_next_token(&p, no_line_terminator); } +static void skip_shebang(const uint8_t **pp, const uint8_t *buf_end) +{ + const uint8_t *p = *pp; + int c; + + if (p[0] == '#' && p[1] == '!') { + p += 2; + while (p < buf_end) { + if (*p == '\n' || *p == '\r') { + break; + } else if (*p >= 0x80) { + c = unicode_from_utf8(p, UTF8_CHAR_LEN_MAX, &p); + if (c == CP_LS || c == CP_PS) { + break; + } else if (c == -1) { + p++; /* skip invalid UTF-8 */ + } + } else { + p++; + } + } + *pp = p; + } +} + /* return true if 'input' contains the source of a module (heuristic). 'input' must be a zero terminated. @@ -21493,6 +21406,8 @@ BOOL JS_DetectModule(const char *input, size_t input_len) { const uint8_t *p = (const uint8_t *)input; int tok; + + skip_shebang(&p, p + input_len); switch(simple_next_token(&p, FALSE)) { case TOK_IMPORT: tok = simple_next_token(&p, FALSE); @@ -21605,6 +21520,14 @@ static int new_label(JSParseState *s) return new_label_fd(s->cur_func, -1); } +/* don't update the last opcode and don't emit line number info */ +static void emit_label_raw(JSParseState *s, int label) +{ + emit_u8(s, OP_label); + emit_u32(s, label); + s->cur_func->label_slots[label].pos = s->cur_func->byte_code.size; +} + /* return the label ID offset */ static int emit_label(JSParseState *s, int label) { @@ -22103,7 +22026,7 @@ static int define_var(JSParseState *s, JSFunctionDef *fd, JSAtom name, /* add a private field variable in the current scope */ static int add_private_class_field(JSParseState *s, JSFunctionDef *fd, - JSAtom name, JSVarKindEnum var_kind) + JSAtom name, JSVarKindEnum var_kind, BOOL is_static) { JSContext *ctx = s->ctx; JSVarDef *vd; @@ -22115,6 +22038,7 @@ static int add_private_class_field(JSParseState *s, JSFunctionDef *fd, vd = &fd->vars[idx]; vd->is_lexical = 1; vd->is_const = 1; + vd->is_static_private = is_static; return idx; } @@ -22860,8 +22784,9 @@ static JSAtom get_private_setter_name(JSContext *ctx, JSAtom name) typedef struct { JSFunctionDef *fields_init_fd; int computed_fields_count; - BOOL has_brand; + BOOL need_brand; int brand_push_pos; + BOOL is_static; } ClassFieldsDef; static __exception int emit_class_init_start(JSParseState *s, @@ -22875,48 +22800,34 @@ static __exception int emit_class_init_start(JSParseState *s, s->cur_func = cf->fields_init_fd; - /* XXX: would be better to add the code only if needed, maybe in a - later pass */ - emit_op(s, OP_push_false); /* will be patched later */ - cf->brand_push_pos = cf->fields_init_fd->last_opcode_pos; - label_add_brand = emit_goto(s, OP_if_false, -1); - - emit_op(s, OP_scope_get_var); - emit_atom(s, JS_ATOM_this); - emit_u16(s, 0); - - emit_op(s, OP_scope_get_var); - emit_atom(s, JS_ATOM_home_object); - emit_u16(s, 0); - - emit_op(s, OP_add_brand); - - emit_label(s, label_add_brand); - - s->cur_func = s->cur_func->parent; - return 0; -} - -static __exception int add_brand(JSParseState *s, ClassFieldsDef *cf) -{ - if (!cf->has_brand) { - /* define the brand field in 'this' of the initializer */ - if (!cf->fields_init_fd) { - if (emit_class_init_start(s, cf)) - return -1; - } - /* patch the start of the function to enable the OP_add_brand code */ - cf->fields_init_fd->byte_code.buf[cf->brand_push_pos] = OP_push_true; + if (!cf->is_static) { + /* add the brand to the newly created instance */ + /* XXX: would be better to add the code only if needed, maybe in a + later pass */ + emit_op(s, OP_push_false); /* will be patched later */ + cf->brand_push_pos = cf->fields_init_fd->last_opcode_pos; + label_add_brand = emit_goto(s, OP_if_false, -1); - cf->has_brand = TRUE; + emit_op(s, OP_scope_get_var); + emit_atom(s, JS_ATOM_this); + emit_u16(s, 0); + + emit_op(s, OP_scope_get_var); + emit_atom(s, JS_ATOM_home_object); + emit_u16(s, 0); + + emit_op(s, OP_add_brand); + + emit_label(s, label_add_brand); } + s->cur_func = s->cur_func->parent; return 0; } static void emit_class_init_end(JSParseState *s, ClassFieldsDef *cf) { int cpool_idx; - + s->cur_func = cf->fields_init_fd; emit_op(s, OP_return_undef); s->cur_func = s->cur_func->parent; @@ -22943,7 +22854,7 @@ static __exception int js_parse_class(JSParseState *s, BOOL is_class_expr, const uint8_t *class_start_ptr = s->token.ptr; const uint8_t *start_ptr; ClassFieldsDef class_fields[2]; - + /* classes are parsed and executed in strict mode */ saved_js_mode = fd->js_mode; fd->js_mode |= JS_MODE_STRICT; @@ -23016,7 +22927,8 @@ static __exception int js_parse_class(JSParseState *s, BOOL is_class_expr, ClassFieldsDef *cf = &class_fields[i]; cf->fields_init_fd = NULL; cf->computed_fields_count = 0; - cf->has_brand = FALSE; + cf->need_brand = FALSE; + cf->is_static = i; } ctor_fd = NULL; @@ -23031,6 +22943,41 @@ static __exception int js_parse_class(JSParseState *s, BOOL is_class_expr, if (is_static) { if (next_token(s)) goto fail; + if (s->token.val == '{') { + ClassFieldsDef *cf = &class_fields[is_static]; + JSFunctionDef *init; + if (!cf->fields_init_fd) { + if (emit_class_init_start(s, cf)) + goto fail; + } + s->cur_func = cf->fields_init_fd; + /* XXX: could try to avoid creating a new function and + reuse 'fields_init_fd' with a specific 'var' + scope */ + // stack is now: + if (js_parse_function_decl2(s, JS_PARSE_FUNC_CLASS_STATIC_INIT, + JS_FUNC_NORMAL, JS_ATOM_NULL, + s->token.ptr, s->token.line_num, + JS_PARSE_EXPORT_NONE, &init) < 0) { + goto fail; + } + // stack is now: fclosure + push_scope(s); + emit_op(s, OP_scope_get_var); + emit_atom(s, JS_ATOM_this); + emit_u16(s, 0); + // stack is now: fclosure this + emit_op(s, OP_swap); + // stack is now: this fclosure + emit_op(s, OP_call_method); + emit_u16(s, 0); + // stack is now: returnvalue + emit_op(s, OP_drop); + // stack is now: + pop_scope(s); + s->cur_func = s->cur_func->parent; + continue; + } /* allow "static" field name */ if (s->token.val == ';' || s->token.val == '=') { is_static = FALSE; @@ -23061,24 +23008,26 @@ static __exception int js_parse_class(JSParseState *s, BOOL is_class_expr, JSFunctionDef *method_fd; if (is_private) { - int idx, var_kind; + int idx, var_kind, is_static1; idx = find_private_class_field(ctx, fd, name, fd->scope_level); if (idx >= 0) { var_kind = fd->vars[idx].var_kind; + is_static1 = fd->vars[idx].is_static_private; if (var_kind == JS_VAR_PRIVATE_FIELD || var_kind == JS_VAR_PRIVATE_METHOD || var_kind == JS_VAR_PRIVATE_GETTER_SETTER || - var_kind == (JS_VAR_PRIVATE_GETTER + is_set)) { + var_kind == (JS_VAR_PRIVATE_GETTER + is_set) || + (var_kind == (JS_VAR_PRIVATE_GETTER + 1 - is_set) && + is_static != is_static1)) { goto private_field_already_defined; } fd->vars[idx].var_kind = JS_VAR_PRIVATE_GETTER_SETTER; } else { if (add_private_class_field(s, fd, name, - JS_VAR_PRIVATE_GETTER + is_set) < 0) + JS_VAR_PRIVATE_GETTER + is_set, is_static) < 0) goto fail; } - if (add_brand(s, &class_fields[is_static]) < 0) - goto fail; + class_fields[is_static].need_brand = TRUE; } if (js_parse_function_decl2(s, JS_PARSE_FUNC_GETTER + is_set, @@ -23100,7 +23049,7 @@ static __exception int js_parse_class(JSParseState *s, BOOL is_class_expr, goto fail; emit_atom(s, setter_name); ret = add_private_class_field(s, fd, setter_name, - JS_VAR_PRIVATE_SETTER); + JS_VAR_PRIVATE_SETTER, is_static); JS_FreeAtom(ctx, setter_name); if (ret < 0) goto fail; @@ -23135,7 +23084,7 @@ static __exception int js_parse_class(JSParseState *s, BOOL is_class_expr, goto private_field_already_defined; } if (add_private_class_field(s, fd, name, - JS_VAR_PRIVATE_FIELD) < 0) + JS_VAR_PRIVATE_FIELD, is_static) < 0) goto fail; emit_op(s, OP_private_symbol); emit_atom(s, name); @@ -23225,8 +23174,7 @@ static __exception int js_parse_class(JSParseState *s, BOOL is_class_expr, func_type = JS_PARSE_FUNC_CLASS_CONSTRUCTOR; } if (is_private) { - if (add_brand(s, &class_fields[is_static]) < 0) - goto fail; + class_fields[is_static].need_brand = TRUE; } if (js_parse_function_decl2(s, func_type, func_kind, JS_ATOM_NULL, start_ptr, s->token.line_num, JS_PARSE_EXPORT_NONE, &method_fd)) goto fail; @@ -23242,7 +23190,7 @@ static __exception int js_parse_class(JSParseState *s, BOOL is_class_expr, goto fail; } if (add_private_class_field(s, fd, name, - JS_VAR_PRIVATE_METHOD) < 0) + JS_VAR_PRIVATE_METHOD, is_static) < 0) goto fail; emit_op(s, OP_set_home_object); emit_op(s, OP_set_name); @@ -23292,12 +23240,29 @@ static __exception int js_parse_class(JSParseState *s, BOOL is_class_expr, if (next_token(s)) goto fail; - /* store the function to initialize the fields to that it can be - referenced by the constructor */ { ClassFieldsDef *cf = &class_fields[0]; int var_idx; + + if (cf->need_brand) { + /* add a private brand to the prototype */ + emit_op(s, OP_dup); + emit_op(s, OP_null); + emit_op(s, OP_swap); + emit_op(s, OP_add_brand); + + /* define the brand field in 'this' of the initializer */ + if (!cf->fields_init_fd) { + if (emit_class_init_start(s, cf)) + goto fail; + } + /* patch the start of the function to enable the + OP_add_brand_instance code */ + cf->fields_init_fd->byte_code.buf[cf->brand_push_pos] = OP_push_true; + } + /* store the function to initialize the fields to that it can be + referenced by the constructor */ var_idx = define_var(s, fd, JS_ATOM_class_fields_init, JS_VAR_DEF_CONST); if (var_idx < 0) @@ -23315,6 +23280,23 @@ static __exception int js_parse_class(JSParseState *s, BOOL is_class_expr, /* drop the prototype */ emit_op(s, OP_drop); + if (class_fields[1].need_brand) { + /* add a private brand to the class */ + emit_op(s, OP_dup); + emit_op(s, OP_dup); + emit_op(s, OP_add_brand); + } + + if (class_name != JS_ATOM_NULL) { + /* store the class name in the scoped class name variable (it + is independent from the class statement variable + definition) */ + emit_op(s, OP_dup); + emit_op(s, OP_scope_put_var_init); + emit_atom(s, class_name); + emit_u16(s, fd->scope_level); + } + /* initialize the static fields */ if (class_fields[1].fields_init_fd != NULL) { ClassFieldsDef *cf = &class_fields[1]; @@ -23325,15 +23307,6 @@ static __exception int js_parse_class(JSParseState *s, BOOL is_class_expr, emit_op(s, OP_drop); } - if (class_name != JS_ATOM_NULL) { - /* store the class name in the scoped class name variable (it - is independent from the class statement variable - definition) */ - emit_op(s, OP_dup); - emit_op(s, OP_scope_put_var_init); - emit_atom(s, class_name); - emit_u16(s, fd->scope_level); - } pop_scope(s); pop_scope(s); @@ -24518,8 +24491,10 @@ static __exception int js_parse_postfix_expr(JSParseState *s, int parse_flags) return -1; } name = JS_DupAtom(s->ctx, s->token.u.ident.atom); - if (next_token(s)) /* update line number before emitting code */ + if (next_token(s)) { /* update line number before emitting code */ + JS_FreeAtom(s->ctx, name); return -1; + } do_get_var: emit_op(s, OP_scope_get_var); emit_u32(s, name); @@ -24666,6 +24641,25 @@ static __exception int js_parse_postfix_expr(JSParseState *s, int parse_flags) fd->byte_code.buf[fd->last_opcode_pos] = OP_get_field2; drop_count = 2; break; + case OP_get_field_opt_chain: + { + int opt_chain_label, next_label; + opt_chain_label = get_u32(fd->byte_code.buf + + fd->last_opcode_pos + 1 + 4 + 1); + /* keep the object on the stack */ + fd->byte_code.buf[fd->last_opcode_pos] = OP_get_field2; + fd->byte_code.size = fd->last_opcode_pos + 1 + 4; + next_label = emit_goto(s, OP_goto, -1); + emit_label(s, opt_chain_label); + /* need an additional undefined value for the + case where the optional field does not + exists */ + emit_op(s, OP_undefined); + emit_label(s, next_label); + drop_count = 2; + opcode = OP_get_field; + } + break; case OP_scope_get_private_field: /* keep the object on the stack */ fd->byte_code.buf[fd->last_opcode_pos] = OP_scope_get_private_field2; @@ -24676,6 +24670,25 @@ static __exception int js_parse_postfix_expr(JSParseState *s, int parse_flags) fd->byte_code.buf[fd->last_opcode_pos] = OP_get_array_el2; drop_count = 2; break; + case OP_get_array_el_opt_chain: + { + int opt_chain_label, next_label; + opt_chain_label = get_u32(fd->byte_code.buf + + fd->last_opcode_pos + 1 + 1); + /* keep the object on the stack */ + fd->byte_code.buf[fd->last_opcode_pos] = OP_get_array_el2; + fd->byte_code.size = fd->last_opcode_pos + 1; + next_label = emit_goto(s, OP_goto, -1); + emit_label(s, opt_chain_label); + /* need an additional undefined value for the + case where the optional field does not + exists */ + emit_op(s, OP_undefined); + emit_label(s, next_label); + drop_count = 2; + opcode = OP_get_array_el; + } + break; case OP_scope_get_var: { JSAtom name; @@ -24958,8 +24971,23 @@ static __exception int js_parse_postfix_expr(JSParseState *s, int parse_flags) break; } } - if (optional_chaining_label >= 0) - emit_label(s, optional_chaining_label); + if (optional_chaining_label >= 0) { + JSFunctionDef *fd = s->cur_func; + int opcode; + emit_label_raw(s, optional_chaining_label); + /* modify the last opcode so that it is an indicator of an + optional chain */ + opcode = get_prev_opcode(fd); + if (opcode == OP_get_field || opcode == OP_get_array_el) { + if (opcode == OP_get_field) + opcode = OP_get_field_opt_chain; + else + opcode = OP_get_array_el_opt_chain; + fd->byte_code.buf[fd->last_opcode_pos] = opcode; + } else { + fd->last_opcode_pos = -1; + } + } return 0; } @@ -24975,27 +25003,57 @@ static __exception int js_parse_delete(JSParseState *s) return -1; switch(opcode = get_prev_opcode(fd)) { case OP_get_field: + case OP_get_field_opt_chain: { JSValue val; - int ret; - + int ret, opt_chain_label, next_label; + if (opcode == OP_get_field_opt_chain) { + opt_chain_label = get_u32(fd->byte_code.buf + + fd->last_opcode_pos + 1 + 4 + 1); + } else { + opt_chain_label = -1; + } name = get_u32(fd->byte_code.buf + fd->last_opcode_pos + 1); fd->byte_code.size = fd->last_opcode_pos; - fd->last_opcode_pos = -1; val = JS_AtomToValue(s->ctx, name); ret = emit_push_const(s, val, 1); JS_FreeValue(s->ctx, val); JS_FreeAtom(s->ctx, name); if (ret) return ret; + emit_op(s, OP_delete); + if (opt_chain_label >= 0) { + next_label = emit_goto(s, OP_goto, -1); + emit_label(s, opt_chain_label); + /* if the optional chain is not taken, return 'true' */ + emit_op(s, OP_drop); + emit_op(s, OP_push_true); + emit_label(s, next_label); + } + fd->last_opcode_pos = -1; } - goto do_delete; + break; case OP_get_array_el: fd->byte_code.size = fd->last_opcode_pos; fd->last_opcode_pos = -1; - do_delete: emit_op(s, OP_delete); break; + case OP_get_array_el_opt_chain: + { + int opt_chain_label, next_label; + opt_chain_label = get_u32(fd->byte_code.buf + + fd->last_opcode_pos + 1 + 1); + fd->byte_code.size = fd->last_opcode_pos; + emit_op(s, OP_delete); + next_label = emit_goto(s, OP_goto, -1); + emit_label(s, opt_chain_label); + /* if the optional chain is not taken, return 'true' */ + emit_op(s, OP_drop); + emit_op(s, OP_push_true); + emit_label(s, next_label); + fd->last_opcode_pos = -1; + } + break; case OP_scope_get_var: /* 'delete this': this is not a reference */ name = get_u32(fd->byte_code.buf + fd->last_opcode_pos + 1); @@ -25010,6 +25068,8 @@ static __exception int js_parse_delete(JSParseState *s) case OP_scope_get_private_field: return js_parse_error(s, "cannot delete a private class field"); case OP_get_super_value: + fd->byte_code.size = fd->last_opcode_pos; + fd->last_opcode_pos = -1; emit_op(s, OP_throw_error); emit_atom(s, JS_ATOM_NULL); emit_u8(s, JS_THROW_ERROR_DELETE_SUPER); @@ -25109,6 +25169,7 @@ static __exception int js_parse_unary(JSParseState *s, int parse_flags) return -1; if (js_parse_unary(s, PF_POW_FORBIDDEN)) return -1; + s->cur_func->has_await = TRUE; emit_op(s, OP_await); parse_flags = 0; break; @@ -25180,9 +25241,32 @@ static __exception int js_parse_expr_binary(JSParseState *s, int level, if (level == 0) { return js_parse_unary(s, (parse_flags & PF_ARROW_FUNC) | PF_POW_ALLOWED); + } else if (s->token.val == TOK_PRIVATE_NAME && + (parse_flags & PF_IN_ACCEPTED) && level == 4 && + peek_token(s, FALSE) == TOK_IN) { + JSAtom atom; + + atom = JS_DupAtom(s->ctx, s->token.u.ident.atom); + if (next_token(s)) + goto fail_private_in; + if (s->token.val != TOK_IN) + goto fail_private_in; + if (next_token(s)) + goto fail_private_in; + if (js_parse_expr_binary(s, level - 1, parse_flags & ~PF_ARROW_FUNC)) { + fail_private_in: + JS_FreeAtom(s->ctx, atom); + return -1; + } + emit_op(s, OP_scope_in_private_field); + emit_atom(s, atom); + emit_u16(s, s->cur_func->scope_level); + JS_FreeAtom(s->ctx, atom); + return 0; + } else { + if (js_parse_expr_binary(s, level - 1, parse_flags)) + return -1; } - if (js_parse_expr_binary(s, level - 1, parse_flags)) - return -1; for(;;) { op = s->token.val; switch(level) { @@ -25482,7 +25566,6 @@ static __exception int js_parse_assign_expr2(JSParseState *s, int parse_flags) /* OP_async_yield_star takes the value as parameter */ emit_op(s, OP_get_field); emit_atom(s, JS_ATOM_value); - emit_op(s, OP_await); emit_op(s, OP_async_yield_star); } else { /* OP_yield_star takes (value, done) as parameter */ @@ -25776,61 +25859,61 @@ static __exception int emit_break(JSParseState *s, JSAtom name, int is_cont) static void emit_return(JSParseState *s, BOOL hasval) { BlockEnv *top; - int drop_count; - drop_count = 0; + if (s->cur_func->func_kind != JS_FUNC_NORMAL) { + if (!hasval) { + /* no value: direct return in case of async generator */ + emit_op(s, OP_undefined); + hasval = TRUE; + } else if (s->cur_func->func_kind == JS_FUNC_ASYNC_GENERATOR) { + /* the await must be done before handling the "finally" in + case it raises an exception */ + emit_op(s, OP_await); + } + } + top = s->cur_func->top_break; while (top != NULL) { - /* XXX: emit the appropriate OP_leave_scope opcodes? Probably not - required as all local variables will be closed upon returning - from JS_CallInternal, but not in the same order. */ - if (top->has_iterator) { - /* with 'yield', the exact number of OP_drop to emit is - unknown, so we use a specific operation to look for - the catch offset */ + if (top->has_iterator || top->label_finally != -1) { if (!hasval) { emit_op(s, OP_undefined); hasval = TRUE; } - emit_op(s, OP_iterator_close_return); - if (s->cur_func->func_kind == JS_FUNC_ASYNC_GENERATOR) { - int label_next, label_next2; - - emit_op(s, OP_drop); /* catch offset */ - emit_op(s, OP_drop); /* next */ - emit_op(s, OP_get_field2); - emit_atom(s, JS_ATOM_return); - /* stack: iter_obj return_func */ - emit_op(s, OP_dup); - emit_op(s, OP_is_undefined_or_null); - label_next = emit_goto(s, OP_if_true, -1); - emit_op(s, OP_call_method); - emit_u16(s, 0); - emit_op(s, OP_iterator_check_object); - emit_op(s, OP_await); - label_next2 = emit_goto(s, OP_goto, -1); - emit_label(s, label_next); - emit_op(s, OP_drop); - emit_label(s, label_next2); - emit_op(s, OP_drop); + /* Remove the stack elements up to and including the catch + offset. When 'yield' is used in an expression we have + no easy way to count them, so we use this specific + instruction instead. */ + emit_op(s, OP_nip_catch); + /* stack: iter_obj next ret_val */ + if (top->has_iterator) { + if (s->cur_func->func_kind == JS_FUNC_ASYNC_GENERATOR) { + int label_next, label_next2; + emit_op(s, OP_nip); /* next */ + emit_op(s, OP_swap); + emit_op(s, OP_get_field2); + emit_atom(s, JS_ATOM_return); + /* stack: iter_obj return_func */ + emit_op(s, OP_dup); + emit_op(s, OP_is_undefined_or_null); + label_next = emit_goto(s, OP_if_true, -1); + emit_op(s, OP_call_method); + emit_u16(s, 0); + emit_op(s, OP_iterator_check_object); + emit_op(s, OP_await); + label_next2 = emit_goto(s, OP_goto, -1); + emit_label(s, label_next); + emit_op(s, OP_drop); + emit_label(s, label_next2); + emit_op(s, OP_drop); + } else { + emit_op(s, OP_rot3r); + emit_op(s, OP_undefined); /* dummy catch offset */ + emit_op(s, OP_iterator_close); + } } else { - emit_op(s, OP_iterator_close); + /* execute the "finally" block */ + emit_goto(s, OP_gosub, top->label_finally); } - drop_count = -3; - } - drop_count += top->drop_count; - if (top->label_finally != -1) { - while(drop_count) { - /* must keep the stack top if hasval */ - emit_op(s, hasval ? OP_nip : OP_drop); - drop_count--; - } - if (!hasval) { - /* must push return value to keep same stack size */ - emit_op(s, OP_undefined); - hasval = TRUE; - } - emit_goto(s, OP_gosub, top->label_finally); } top = top->prev; } @@ -25847,20 +25930,15 @@ static void emit_return(JSParseState *s, BOOL hasval) label_return = -1; } - /* XXX: if this is not initialized, should throw the - ReferenceError in the caller realm */ - emit_op(s, OP_scope_get_var); + /* The error should be raised in the caller context, so we use + a specific opcode */ + emit_op(s, OP_scope_get_var_checkthis); emit_atom(s, JS_ATOM_this); emit_u16(s, 0); emit_label(s, label_return); emit_op(s, OP_return); } else if (s->cur_func->func_kind != JS_FUNC_NORMAL) { - if (!hasval) { - emit_op(s, OP_undefined); - } else if (s->cur_func->func_kind == JS_FUNC_ASYNC_GENERATOR) { - emit_op(s, OP_await); - } emit_op(s, OP_return_async); } else { emit_op(s, hasval ? OP_return : OP_return_undef); @@ -26127,6 +26205,9 @@ static __exception int js_parse_for_in_of(JSParseState *s, int label_name, emit_atom(s, var_name); emit_u16(s, fd->scope_level); } + } else if (!is_async && token_is_pseudo_keyword(s, JS_ATOM_async) && + peek_token(s, FALSE) == TOK_OF) { + return js_parse_error(s, "'for of' expression cannot start with 'async'"); } else { int skip_bits; if ((s->token.val == '[' || s->token.val == '{') @@ -26343,6 +26424,10 @@ static __exception int js_parse_statement_or_decl(JSParseState *s, js_parse_error(s, "return not in a function"); goto fail; } + if (s->cur_func->func_type == JS_PARSE_FUNC_CLASS_STATIC_INIT) { + js_parse_error(s, "return in a static initializer block"); + goto fail; + } if (next_token(s)) goto fail; if (s->token.val != ';' && s->token.val != '}' && !s->got_lf) { @@ -26511,6 +26596,7 @@ static __exception int js_parse_statement_or_decl(JSParseState *s, is_async = TRUE; if (next_token(s)) goto fail; + s->cur_func->has_await = TRUE; } if (js_parse_expect(s, '(')) goto fail; @@ -27041,6 +27127,9 @@ static JSModuleDef *js_new_module_def(JSContext *ctx, JSAtom name) m->func_obj = JS_UNDEFINED; m->eval_exception = JS_UNDEFINED; m->meta_obj = JS_UNDEFINED; + m->promise = JS_UNDEFINED; + m->resolving_funcs[0] = JS_UNDEFINED; + m->resolving_funcs[1] = JS_UNDEFINED; list_add_tail(&m->link, &ctx->loaded_modules); return m; } @@ -27062,6 +27151,9 @@ static void js_mark_module_def(JSRuntime *rt, JSModuleDef *m, JS_MarkValue(rt, m->func_obj, mark_func); JS_MarkValue(rt, m->eval_exception, mark_func); JS_MarkValue(rt, m->meta_obj, mark_func); + JS_MarkValue(rt, m->promise, mark_func); + JS_MarkValue(rt, m->resolving_funcs[0], mark_func); + JS_MarkValue(rt, m->resolving_funcs[1], mark_func); } static void js_free_module_def(JSContext *ctx, JSModuleDef *m) @@ -27092,11 +27184,15 @@ static void js_free_module_def(JSContext *ctx, JSModuleDef *m) JS_FreeAtom(ctx, mi->import_name); } js_free(ctx, m->import_entries); + js_free(ctx, m->async_parent_modules); JS_FreeValue(ctx, m->module_ns); JS_FreeValue(ctx, m->func_obj); JS_FreeValue(ctx, m->eval_exception); JS_FreeValue(ctx, m->meta_obj); + JS_FreeValue(ctx, m->promise); + JS_FreeValue(ctx, m->resolving_funcs[0]); + JS_FreeValue(ctx, m->resolving_funcs[1]); list_del(&m->link); js_free(ctx, m); } @@ -27952,7 +28048,8 @@ static int js_create_module_function(JSContext *ctx, JSModuleDef *m) /* Prepare a module to be executed by resolving all the imported variables. */ -static int js_link_module(JSContext *ctx, JSModuleDef *m) +static int js_inner_module_linking(JSContext *ctx, JSModuleDef *m, + JSModuleDef **pstack_top, int index) { int i; JSImportEntry *mi; @@ -27962,21 +28059,47 @@ static int js_link_module(JSContext *ctx, JSModuleDef *m) BOOL is_c_module; JSValue ret_val; - if (m->instantiated) - return 0; - m->instantiated = TRUE; - + if (js_check_stack_overflow(ctx->rt, 0)) { + JS_ThrowStackOverflow(ctx); + return -1; + } + #ifdef DUMP_MODULE_RESOLVE { char buf1[ATOM_GET_STR_BUF_SIZE]; - printf("start instantiating module '%s':\n", JS_AtomGetStr(ctx, buf1, sizeof(buf1), m->module_name)); + printf("js_inner_module_linking '%s':\n", JS_AtomGetStr(ctx, buf1, sizeof(buf1), m->module_name)); } #endif + if (m->status == JS_MODULE_STATUS_LINKING || + m->status == JS_MODULE_STATUS_LINKED || + m->status == JS_MODULE_STATUS_EVALUATING_ASYNC || + m->status == JS_MODULE_STATUS_EVALUATED) + return index; + + assert(m->status == JS_MODULE_STATUS_UNLINKED); + m->status = JS_MODULE_STATUS_LINKING; + m->dfs_index = index; + m->dfs_ancestor_index = index; + index++; + /* push 'm' on stack */ + m->stack_prev = *pstack_top; + *pstack_top = m; + for(i = 0; i < m->req_module_entries_count; i++) { JSReqModuleEntry *rme = &m->req_module_entries[i]; - if (js_link_module(ctx, rme->module) < 0) + m1 = rme->module; + index = js_inner_module_linking(ctx, m1, pstack_top, index); + if (index < 0) goto fail; + assert(m1->status == JS_MODULE_STATUS_LINKING || + m1->status == JS_MODULE_STATUS_LINKED || + m1->status == JS_MODULE_STATUS_EVALUATING_ASYNC || + m1->status == JS_MODULE_STATUS_EVALUATED); + if (m1->status == JS_MODULE_STATUS_LINKING) { + m->dfs_ancestor_index = min_int(m->dfs_ancestor_index, + m1->dfs_ancestor_index); + } } #ifdef DUMP_MODULE_RESOLVE @@ -28102,14 +28225,59 @@ static int js_link_module(JSContext *ctx, JSModuleDef *m) JS_FreeValue(ctx, ret_val); } + assert(m->dfs_ancestor_index <= m->dfs_index); + if (m->dfs_index == m->dfs_ancestor_index) { + for(;;) { + /* pop m1 from stack */ + m1 = *pstack_top; + *pstack_top = m1->stack_prev; + m1->status = JS_MODULE_STATUS_LINKED; + if (m1 == m) + break; + } + } + #ifdef DUMP_MODULE_RESOLVE - printf("done instantiate\n"); + printf("js_inner_module_linking done\n"); #endif - return 0; + return index; fail: return -1; } +/* Prepare a module to be executed by resolving all the imported + variables. */ +static int js_link_module(JSContext *ctx, JSModuleDef *m) +{ + JSModuleDef *stack_top, *m1; + +#ifdef DUMP_MODULE_RESOLVE + { + char buf1[ATOM_GET_STR_BUF_SIZE]; + printf("js_link_module '%s':\n", JS_AtomGetStr(ctx, buf1, sizeof(buf1), m->module_name)); + } +#endif + assert(m->status == JS_MODULE_STATUS_UNLINKED || + m->status == JS_MODULE_STATUS_LINKED || + m->status == JS_MODULE_STATUS_EVALUATING_ASYNC || + m->status == JS_MODULE_STATUS_EVALUATED); + stack_top = NULL; + if (js_inner_module_linking(ctx, m, &stack_top, 0) < 0) { + while (stack_top != NULL) { + m1 = stack_top; + assert(m1->status == JS_MODULE_STATUS_LINKING); + m1->status = JS_MODULE_STATUS_UNLINKED; + stack_top = m1->stack_prev; + } + return -1; + } + assert(stack_top == NULL); + assert(m->status == JS_MODULE_STATUS_LINKED || + m->status == JS_MODULE_STATUS_EVALUATING_ASYNC || + m->status == JS_MODULE_STATUS_EVALUATED); + return 0; +} + /* return JS_ATOM_NULL if the name cannot be found. Only works with not striped bytecode functions. */ JSAtom JS_GetScriptOrModuleName(JSContext *ctx, int n_stack_levels) @@ -28118,8 +28286,8 @@ JSAtom JS_GetScriptOrModuleName(JSContext *ctx, int n_stack_levels) JSFunctionBytecode *b; JSObject *p; /* XXX: currently we just use the filename of the englobing - function. It does not work for eval(). Need to add a - ScriptOrModule info in JSFunctionBytecode */ + function from the debug info. May need to add a ScriptOrModule + info in JSFunctionBytecode. */ sf = ctx->rt->current_stack_frame; if (!sf) return JS_ATOM_NULL; @@ -28128,15 +28296,23 @@ JSAtom JS_GetScriptOrModuleName(JSContext *ctx, int n_stack_levels) if (!sf) return JS_ATOM_NULL; } - if (JS_VALUE_GET_TAG(sf->cur_func) != JS_TAG_OBJECT) - return JS_ATOM_NULL; - p = JS_VALUE_GET_OBJ(sf->cur_func); - if (!js_class_has_bytecode(p->class_id)) - return JS_ATOM_NULL; - b = p->u.func.function_bytecode; - if (!b->has_debug) - return JS_ATOM_NULL; - return JS_DupAtom(ctx, b->debug.filename); + for(;;) { + if (JS_VALUE_GET_TAG(sf->cur_func) != JS_TAG_OBJECT) + return JS_ATOM_NULL; + p = JS_VALUE_GET_OBJ(sf->cur_func); + if (!js_class_has_bytecode(p->class_id)) + return JS_ATOM_NULL; + b = p->u.func.function_bytecode; + if (!b->is_direct_or_indirect_eval) { + if (!b->has_debug) + return JS_ATOM_NULL; + return JS_DupAtom(ctx, b->debug.filename); + } else { + sf = sf->prev_frame; + if (!sf) + return JS_ATOM_NULL; + } + } } JSAtom JS_GetModuleName(JSContext *ctx, JSModuleDef *m) @@ -28179,29 +28355,110 @@ static JSValue js_import_meta(JSContext *ctx) return JS_GetImportMeta(ctx, m); } -/* used by os.Worker() and import() */ -JSModuleDef *JS_RunModule(JSContext *ctx, const char *basename, - const char *filename) +static JSValue JS_NewModuleValue(JSContext *ctx, JSModuleDef *m) { + return JS_DupValue(ctx, JS_MKPTR(JS_TAG_MODULE, m)); +} + +static JSValue js_load_module_rejected(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv, int magic, JSValue *func_data) +{ + JSValueConst *resolving_funcs = (JSValueConst *)func_data; + JSValueConst error; + JSValue ret; + + /* XXX: check if the test is necessary */ + if (argc >= 1) + error = argv[0]; + else + error = JS_UNDEFINED; + ret = JS_Call(ctx, resolving_funcs[1], JS_UNDEFINED, + 1, &error); + JS_FreeValue(ctx, ret); + return JS_UNDEFINED; +} + +static JSValue js_load_module_fulfilled(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv, int magic, JSValue *func_data) +{ + JSValueConst *resolving_funcs = (JSValueConst *)func_data; + JSModuleDef *m = JS_VALUE_GET_PTR(func_data[2]); + JSValue ret, ns; + + /* return the module namespace */ + ns = js_get_module_ns(ctx, m); + if (JS_IsException(ns)) { + JSValue err = JS_GetException(ctx); + js_load_module_rejected(ctx, JS_UNDEFINED, 1, (JSValueConst *)&err, 0, func_data); + return JS_UNDEFINED; + } + ret = JS_Call(ctx, resolving_funcs[0], JS_UNDEFINED, + 1, (JSValueConst *)&ns); + JS_FreeValue(ctx, ret); + JS_FreeValue(ctx, ns); + return JS_UNDEFINED; +} + +static void JS_LoadModuleInternal(JSContext *ctx, const char *basename, + const char *filename, + JSValueConst *resolving_funcs) +{ + JSValue evaluate_promise; JSModuleDef *m; - JSValue ret, func_obj; + JSValue ret, err, func_obj, evaluate_resolving_funcs[2]; + JSValueConst func_data[3]; m = js_host_resolve_imported_module(ctx, basename, filename); if (!m) - return NULL; + goto fail; if (js_resolve_module(ctx, m) < 0) { js_free_modules(ctx, JS_FREE_MODULE_NOT_RESOLVED); - return NULL; + goto fail; } /* Evaluate the module code */ - func_obj = JS_DupValue(ctx, JS_MKPTR(JS_TAG_MODULE, m)); - ret = JS_EvalFunction(ctx, func_obj); - if (JS_IsException(ret)) - return NULL; + func_obj = JS_NewModuleValue(ctx, m); + evaluate_promise = JS_EvalFunction(ctx, func_obj); + if (JS_IsException(evaluate_promise)) { + fail: + err = JS_GetException(ctx); + ret = JS_Call(ctx, resolving_funcs[1], JS_UNDEFINED, + 1, (JSValueConst *)&err); + JS_FreeValue(ctx, ret); /* XXX: what to do if exception ? */ + JS_FreeValue(ctx, err); + return; + } + + func_obj = JS_NewModuleValue(ctx, m); + func_data[0] = resolving_funcs[0]; + func_data[1] = resolving_funcs[1]; + func_data[2] = func_obj; + evaluate_resolving_funcs[0] = JS_NewCFunctionData(ctx, js_load_module_fulfilled, 0, 0, 3, func_data); + evaluate_resolving_funcs[1] = JS_NewCFunctionData(ctx, js_load_module_rejected, 0, 0, 3, func_data); + JS_FreeValue(ctx, func_obj); + ret = js_promise_then(ctx, evaluate_promise, 2, (JSValueConst *)evaluate_resolving_funcs); JS_FreeValue(ctx, ret); - return m; + JS_FreeValue(ctx, evaluate_resolving_funcs[0]); + JS_FreeValue(ctx, evaluate_resolving_funcs[1]); + JS_FreeValue(ctx, evaluate_promise); +} + +/* Return a promise or an exception in case of memory error. Used by + os.Worker() */ +JSValue JS_LoadModule(JSContext *ctx, const char *basename, + const char *filename) +{ + JSValue promise, resolving_funcs[2]; + + promise = JS_NewPromiseCapability(ctx, resolving_funcs); + if (JS_IsException(promise)) + return JS_EXCEPTION; + JS_LoadModuleInternal(ctx, basename, filename, + (JSValueConst *)resolving_funcs); + JS_FreeValue(ctx, resolving_funcs[0]); + JS_FreeValue(ctx, resolving_funcs[1]); + return promise; } static JSValue js_dynamic_import_job(JSContext *ctx, @@ -28210,9 +28467,8 @@ static JSValue js_dynamic_import_job(JSContext *ctx, JSValueConst *resolving_funcs = argv; JSValueConst basename_val = argv[2]; JSValueConst specifier = argv[3]; - JSModuleDef *m; const char *basename = NULL, *filename; - JSValue ret, err, ns; + JSValue ret, err; if (!JS_IsString(basename_val)) { JS_ThrowTypeError(ctx, "no function filename for import()"); @@ -28226,24 +28482,12 @@ static JSValue js_dynamic_import_job(JSContext *ctx, if (!filename) goto exception; - m = JS_RunModule(ctx, basename, filename); + JS_LoadModuleInternal(ctx, basename, filename, + resolving_funcs); JS_FreeCString(ctx, filename); - if (!m) - goto exception; - - /* return the module namespace */ - ns = js_get_module_ns(ctx, m); - if (JS_IsException(ns)) - goto exception; - - ret = JS_Call(ctx, resolving_funcs[0], JS_UNDEFINED, - 1, (JSValueConst *)&ns); - JS_FreeValue(ctx, ret); /* XXX: what to do if exception ? */ - JS_FreeValue(ctx, ns); JS_FreeCString(ctx, basename); return JS_UNDEFINED; exception: - err = JS_GetException(ctx); ret = JS_Call(ctx, resolving_funcs[1], JS_UNDEFINED, 1, (JSValueConst *)&err); @@ -28279,6 +28523,8 @@ static JSValue js_dynamic_import(JSContext *ctx, JSValueConst specifier) args[2] = basename_val; args[3] = specifier; + /* cannot run JS_LoadModuleInternal synchronously because it would + cause an unexpected recursion in js_evaluate_module() */ JS_EnqueueJob(ctx, js_dynamic_import_job, 4, args); JS_FreeValue(ctx, basename_val); @@ -28287,60 +28533,397 @@ static JSValue js_dynamic_import(JSContext *ctx, JSValueConst specifier) return promise; } -/* Run the function of the module and of all its requested - modules. */ -static JSValue js_evaluate_module(JSContext *ctx, JSModuleDef *m) +static void js_set_module_evaluated(JSContext *ctx, JSModuleDef *m) +{ + m->status = JS_MODULE_STATUS_EVALUATED; + if (!JS_IsUndefined(m->promise)) { + JSValue value, ret_val; + assert(m->cycle_root == m); + value = JS_UNDEFINED; + ret_val = JS_Call(ctx, m->resolving_funcs[0], JS_UNDEFINED, + 1, (JSValueConst *)&value); + JS_FreeValue(ctx, ret_val); + } +} + +typedef struct { + JSModuleDef **tab; + int count; + int size; +} ExecModuleList; + +/* XXX: slow. Could use a linked list instead of ExecModuleList */ +static BOOL find_in_exec_module_list(ExecModuleList *exec_list, JSModuleDef *m) +{ + int i; + for(i = 0; i < exec_list->count; i++) { + if (exec_list->tab[i] == m) + return TRUE; + } + return FALSE; +} + +static int gather_available_ancestors(JSContext *ctx, JSModuleDef *module, + ExecModuleList *exec_list) +{ + int i; + + if (js_check_stack_overflow(ctx->rt, 0)) { + JS_ThrowStackOverflow(ctx); + return -1; + } + for(i = 0; i < module->async_parent_modules_count; i++) { + JSModuleDef *m = module->async_parent_modules[i]; + if (!find_in_exec_module_list(exec_list, m) && + !m->cycle_root->eval_has_exception) { + assert(m->status == JS_MODULE_STATUS_EVALUATING_ASYNC); + assert(!m->eval_has_exception); + assert(m->async_evaluation); + assert(m->pending_async_dependencies > 0); + m->pending_async_dependencies--; + if (m->pending_async_dependencies == 0) { + if (js_resize_array(ctx, (void **)&exec_list->tab, sizeof(exec_list->tab[0]), &exec_list->size, exec_list->count + 1)) { + return -1; + } + exec_list->tab[exec_list->count++] = m; + if (!m->has_tla) { + if (gather_available_ancestors(ctx, m, exec_list)) + return -1; + } + } + } + } + return 0; +} + +static int exec_module_list_cmp(const void *p1, const void *p2, void *opaque) +{ + JSModuleDef *m1 = *(JSModuleDef **)p1; + JSModuleDef *m2 = *(JSModuleDef **)p2; + return (m1->async_evaluation_timestamp > m2->async_evaluation_timestamp) - + (m1->async_evaluation_timestamp < m2->async_evaluation_timestamp); +} + +static int js_execute_async_module(JSContext *ctx, JSModuleDef *m); +static int js_execute_sync_module(JSContext *ctx, JSModuleDef *m, + JSValue *pvalue); + +static JSValue js_async_module_execution_rejected(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv, int magic, JSValue *func_data) +{ + JSModuleDef *module = JS_VALUE_GET_PTR(func_data[0]); + JSValueConst error = argv[0]; + int i; + + if (js_check_stack_overflow(ctx->rt, 0)) + return JS_ThrowStackOverflow(ctx); + + if (module->status == JS_MODULE_STATUS_EVALUATED) { + assert(module->eval_has_exception); + return JS_UNDEFINED; + } + + assert(module->status == JS_MODULE_STATUS_EVALUATING_ASYNC); + assert(!module->eval_has_exception); + assert(module->async_evaluation); + + module->eval_has_exception = TRUE; + module->eval_exception = JS_DupValue(ctx, error); + module->status = JS_MODULE_STATUS_EVALUATED; + + for(i = 0; i < module->async_parent_modules_count; i++) { + JSModuleDef *m = module->async_parent_modules[i]; + JSValue m_obj = JS_NewModuleValue(ctx, m); + js_async_module_execution_rejected(ctx, JS_UNDEFINED, 1, &error, 0, + &m_obj); + JS_FreeValue(ctx, m_obj); + } + + if (!JS_IsUndefined(module->promise)) { + JSValue ret_val; + assert(module->cycle_root == module); + ret_val = JS_Call(ctx, module->resolving_funcs[1], JS_UNDEFINED, + 1, &error); + JS_FreeValue(ctx, ret_val); + } + return JS_UNDEFINED; +} + +static JSValue js_async_module_execution_fulfilled(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv, int magic, JSValue *func_data) +{ + JSModuleDef *module = JS_VALUE_GET_PTR(func_data[0]); + ExecModuleList exec_list_s, *exec_list = &exec_list_s; + int i; + + if (module->status == JS_MODULE_STATUS_EVALUATED) { + assert(module->eval_has_exception); + return JS_UNDEFINED; + } + assert(module->status == JS_MODULE_STATUS_EVALUATING_ASYNC); + assert(!module->eval_has_exception); + assert(module->async_evaluation); + module->async_evaluation = FALSE; + js_set_module_evaluated(ctx, module); + + exec_list->tab = NULL; + exec_list->count = 0; + exec_list->size = 0; + + if (gather_available_ancestors(ctx, module, exec_list) < 0) { + js_free(ctx, exec_list->tab); + return JS_EXCEPTION; + } + + /* sort by increasing async_evaluation timestamp */ + rqsort(exec_list->tab, exec_list->count, sizeof(exec_list->tab[0]), + exec_module_list_cmp, NULL); + + for(i = 0; i < exec_list->count; i++) { + JSModuleDef *m = exec_list->tab[i]; + if (m->status == JS_MODULE_STATUS_EVALUATED) { + assert(m->eval_has_exception); + } else if (m->has_tla) { + js_execute_async_module(ctx, m); + } else { + JSValue error; + if (js_execute_sync_module(ctx, m, &error) < 0) { + JSValue m_obj = JS_NewModuleValue(ctx, m); + js_async_module_execution_rejected(ctx, JS_UNDEFINED, + 1, (JSValueConst *)&error, 0, + &m_obj); + JS_FreeValue(ctx, m_obj); + JS_FreeValue(ctx, error); + } else { + js_set_module_evaluated(ctx, m); + } + } + } + js_free(ctx, exec_list->tab); + return JS_UNDEFINED; +} + +static int js_execute_async_module(JSContext *ctx, JSModuleDef *m) +{ + JSValue promise, m_obj; + JSValue resolve_funcs[2], ret_val; + promise = js_async_function_call(ctx, m->func_obj, JS_UNDEFINED, 0, NULL, 0); + if (JS_IsException(promise)) + return -1; + m_obj = JS_NewModuleValue(ctx, m); + resolve_funcs[0] = JS_NewCFunctionData(ctx, js_async_module_execution_fulfilled, 0, 0, 1, (JSValueConst *)&m_obj); + resolve_funcs[1] = JS_NewCFunctionData(ctx, js_async_module_execution_rejected, 0, 0, 1, (JSValueConst *)&m_obj); + ret_val = js_promise_then(ctx, promise, 2, (JSValueConst *)resolve_funcs); + JS_FreeValue(ctx, ret_val); + JS_FreeValue(ctx, m_obj); + JS_FreeValue(ctx, resolve_funcs[0]); + JS_FreeValue(ctx, resolve_funcs[1]); + JS_FreeValue(ctx, promise); + return 0; +} + +/* return < 0 in case of exception. *pvalue contains the exception. */ +static int js_execute_sync_module(JSContext *ctx, JSModuleDef *m, + JSValue *pvalue) +{ + if (m->init_func) { + /* C module init : no asynchronous execution */ + if (m->init_func(ctx, m) < 0) + goto fail; + } else { + JSValue promise; + JSPromiseStateEnum state; + + promise = js_async_function_call(ctx, m->func_obj, JS_UNDEFINED, 0, NULL, 0); + if (JS_IsException(promise)) + goto fail; + state = JS_PromiseState(ctx, promise); + if (state == JS_PROMISE_FULFILLED) { + JS_FreeValue(ctx, promise); + } else if (state == JS_PROMISE_REJECTED) { + *pvalue = JS_PromiseResult(ctx, promise); + JS_FreeValue(ctx, promise); + return -1; + } else { + JS_FreeValue(ctx, promise); + JS_ThrowTypeError(ctx, "promise is pending"); + fail: + *pvalue = JS_GetException(ctx); + return -1; + } + } + *pvalue = JS_UNDEFINED; + return 0; +} + +/* spec: InnerModuleEvaluation. Return (index, JS_UNDEFINED) or (-1, + exception) */ +static int js_inner_module_evaluation(JSContext *ctx, JSModuleDef *m, + int index, JSModuleDef **pstack_top, + JSValue *pvalue) { JSModuleDef *m1; int i; - JSValue ret_val; - if (m->eval_mark) - return JS_UNDEFINED; /* avoid cycles */ + if (js_check_stack_overflow(ctx->rt, 0)) { + JS_ThrowStackOverflow(ctx); + *pvalue = JS_GetException(ctx); + return -1; + } + +#ifdef DUMP_MODULE_RESOLVE + { + char buf1[ATOM_GET_STR_BUF_SIZE]; + printf("js_inner_module_evaluation '%s':\n", JS_AtomGetStr(ctx, buf1, sizeof(buf1), m->module_name)); + } +#endif - if (m->evaluated) { - /* if the module was already evaluated, rethrow the exception - it raised */ + if (m->status == JS_MODULE_STATUS_EVALUATING_ASYNC || + m->status == JS_MODULE_STATUS_EVALUATED) { if (m->eval_has_exception) { - return JS_Throw(ctx, JS_DupValue(ctx, m->eval_exception)); + *pvalue = JS_DupValue(ctx, m->eval_exception); + return -1; } else { - return JS_UNDEFINED; + *pvalue = JS_UNDEFINED; + return index; } } + if (m->status == JS_MODULE_STATUS_EVALUATING) { + *pvalue = JS_UNDEFINED; + return index; + } + assert(m->status == JS_MODULE_STATUS_LINKED); - m->eval_mark = TRUE; - + m->status = JS_MODULE_STATUS_EVALUATING; + m->dfs_index = index; + m->dfs_ancestor_index = index; + m->pending_async_dependencies = 0; + index++; + /* push 'm' on stack */ + m->stack_prev = *pstack_top; + *pstack_top = m; + for(i = 0; i < m->req_module_entries_count; i++) { JSReqModuleEntry *rme = &m->req_module_entries[i]; m1 = rme->module; - if (!m1->eval_mark) { - ret_val = js_evaluate_module(ctx, m1); - if (JS_IsException(ret_val)) { - m->eval_mark = FALSE; - return ret_val; + index = js_inner_module_evaluation(ctx, m1, index, pstack_top, pvalue); + if (index < 0) + return -1; + assert(m1->status == JS_MODULE_STATUS_EVALUATING || + m1->status == JS_MODULE_STATUS_EVALUATING_ASYNC || + m1->status == JS_MODULE_STATUS_EVALUATED); + if (m1->status == JS_MODULE_STATUS_EVALUATING) { + m->dfs_ancestor_index = min_int(m->dfs_ancestor_index, + m1->dfs_ancestor_index); + } else { + m1 = m1->cycle_root; + assert(m1->status == JS_MODULE_STATUS_EVALUATING_ASYNC || + m1->status == JS_MODULE_STATUS_EVALUATED); + if (m1->eval_has_exception) { + *pvalue = JS_DupValue(ctx, m1->eval_exception); + return -1; } - JS_FreeValue(ctx, ret_val); + } + if (m1->async_evaluation) { + m->pending_async_dependencies++; + if (js_resize_array(ctx, (void **)&m1->async_parent_modules, sizeof(m1->async_parent_modules[0]), &m1->async_parent_modules_size, m1->async_parent_modules_count + 1)) { + *pvalue = JS_GetException(ctx); + return -1; + } + m1->async_parent_modules[m1->async_parent_modules_count++] = m; } } - if (m->init_func) { - /* C module init */ - if (m->init_func(ctx, m) < 0) - ret_val = JS_EXCEPTION; - else - ret_val = JS_UNDEFINED; + if (m->pending_async_dependencies > 0) { + assert(!m->async_evaluation); + m->async_evaluation = TRUE; + m->async_evaluation_timestamp = + ctx->rt->module_async_evaluation_next_timestamp++; + } else if (m->has_tla) { + assert(!m->async_evaluation); + m->async_evaluation = TRUE; + m->async_evaluation_timestamp = + ctx->rt->module_async_evaluation_next_timestamp++; + js_execute_async_module(ctx, m); } else { - ret_val = JS_CallFree(ctx, m->func_obj, JS_UNDEFINED, 0, NULL); - m->func_obj = JS_UNDEFINED; + if (js_execute_sync_module(ctx, m, pvalue) < 0) + return -1; } - if (JS_IsException(ret_val)) { - /* save the thrown exception value */ - m->eval_has_exception = TRUE; - m->eval_exception = JS_DupValue(ctx, ctx->rt->current_exception); + + assert(m->dfs_ancestor_index <= m->dfs_index); + if (m->dfs_index == m->dfs_ancestor_index) { + for(;;) { + /* pop m1 from stack */ + m1 = *pstack_top; + *pstack_top = m1->stack_prev; + if (!m1->async_evaluation) { + m1->status = JS_MODULE_STATUS_EVALUATED; + } else { + m1->status = JS_MODULE_STATUS_EVALUATING_ASYNC; + } + /* spec bug: cycle_root must be assigned before the test */ + m1->cycle_root = m; + if (m1 == m) + break; + } } - m->eval_mark = FALSE; - m->evaluated = TRUE; - return ret_val; + *pvalue = JS_UNDEFINED; + return index; +} + +/* Run the function of the module and of all its requested + modules. Return a promise or an exception. */ +static JSValue js_evaluate_module(JSContext *ctx, JSModuleDef *m) +{ + JSModuleDef *m1, *stack_top; + JSValue ret_val, result; + + assert(m->status == JS_MODULE_STATUS_LINKED || + m->status == JS_MODULE_STATUS_EVALUATING_ASYNC || + m->status == JS_MODULE_STATUS_EVALUATED); + if (m->status == JS_MODULE_STATUS_EVALUATING_ASYNC || + m->status == JS_MODULE_STATUS_EVALUATED) { + m = m->cycle_root; + } + /* a promise may be created only on the cycle_root of a cycle */ + if (!JS_IsUndefined(m->promise)) + return JS_DupValue(ctx, m->promise); + m->promise = JS_NewPromiseCapability(ctx, m->resolving_funcs); + if (JS_IsException(m->promise)) + return JS_EXCEPTION; + + stack_top = NULL; + if (js_inner_module_evaluation(ctx, m, 0, &stack_top, &result) < 0) { + while (stack_top != NULL) { + m1 = stack_top; + assert(m1->status == JS_MODULE_STATUS_EVALUATING); + m1->status = JS_MODULE_STATUS_EVALUATED; + m1->eval_has_exception = TRUE; + m1->eval_exception = JS_DupValue(ctx, result); + m1->cycle_root = m; /* spec bug: should be present */ + stack_top = m1->stack_prev; + } + JS_FreeValue(ctx, result); + assert(m->status == JS_MODULE_STATUS_EVALUATED); + assert(m->eval_has_exception); + ret_val = JS_Call(ctx, m->resolving_funcs[1], JS_UNDEFINED, + 1, (JSValueConst *)&m->eval_exception); + JS_FreeValue(ctx, ret_val); + } else { + assert(m->status == JS_MODULE_STATUS_EVALUATING_ASYNC || + m->status == JS_MODULE_STATUS_EVALUATED); + assert(!m->eval_has_exception); + if (!m->async_evaluation) { + JSValue value; + assert(m->status == JS_MODULE_STATUS_EVALUATED); + value = JS_UNDEFINED; + ret_val = JS_Call(ctx, m->resolving_funcs[0], JS_UNDEFINED, + 1, (JSValueConst *)&value); + JS_FreeValue(ctx, ret_val); + } + assert(stack_top == NULL); + } + return JS_DupValue(ctx, m->promise); } static __exception JSAtom js_parse_from_clause(JSParseState *s) @@ -29694,6 +30277,7 @@ static int resolve_scope_var(JSContext *ctx, JSFunctionDef *s, case OP_scope_get_ref: dbuf_putc(bc, OP_undefined); /* fall thru */ + case OP_scope_get_var_checkthis: case OP_scope_get_var_undef: case OP_scope_get_var: case OP_scope_put_var: @@ -29719,7 +30303,12 @@ static int resolve_scope_var(JSContext *ctx, JSFunctionDef *s, } } else { if (s->vars[var_idx].is_lexical) { - dbuf_putc(bc, OP_get_loc_check); + if (op == OP_scope_get_var_checkthis) { + /* only used for 'this' return in derived class constructors */ + dbuf_putc(bc, OP_get_loc_checkthis); + } else { + dbuf_putc(bc, OP_get_loc_check); + } } else { dbuf_putc(bc, OP_get_loc); } @@ -30176,12 +30765,17 @@ static int resolve_scope_private_field(JSContext *ctx, JSFunctionDef *s, /* obj func value */ dbuf_putc(bc, OP_call_method); dbuf_put_u16(bc, 1); + dbuf_putc(bc, OP_drop); } break; default: abort(); } break; + case OP_scope_in_private_field: + get_loc_or_ref(bc, is_ref, idx); + dbuf_putc(bc, OP_private_in); + break; default: abort(); } @@ -30300,12 +30894,13 @@ static void add_eval_variables(JSContext *ctx, JSFunctionDef *s) is_arg_scope = (scope_idx == ARG_SCOPE_END); if (!is_arg_scope) { /* add unscoped variables */ + /* XXX: propagate is_const and var_kind too ? */ for(i = 0; i < fd->arg_count; i++) { vd = &fd->args[i]; if (vd->var_name != JS_ATOM_NULL) { get_closure_var(ctx, s, fd, - TRUE, i, vd->var_name, FALSE, FALSE, - JS_VAR_NORMAL); + TRUE, i, vd->var_name, FALSE, + vd->is_lexical, JS_VAR_NORMAL); } } for(i = 0; i < fd->var_count; i++) { @@ -30315,8 +30910,8 @@ static void add_eval_variables(JSContext *ctx, JSFunctionDef *s) vd->var_name != JS_ATOM__ret_ && vd->var_name != JS_ATOM_NULL) { get_closure_var(ctx, s, fd, - FALSE, i, vd->var_name, FALSE, FALSE, - JS_VAR_NORMAL); + FALSE, i, vd->var_name, FALSE, + vd->is_lexical, JS_VAR_NORMAL); } } } else { @@ -30325,8 +30920,8 @@ static void add_eval_variables(JSContext *ctx, JSFunctionDef *s) /* do not close top level last result */ if (vd->scope_level == 0 && is_var_in_arg_scope(vd)) { get_closure_var(ctx, s, fd, - FALSE, i, vd->var_name, FALSE, FALSE, - JS_VAR_NORMAL); + FALSE, i, vd->var_name, FALSE, + vd->is_lexical, JS_VAR_NORMAL); } } } @@ -30858,6 +31453,7 @@ static __exception int resolve_variables(JSContext *ctx, JSFunctionDef *s) dbuf_putc(&bc_out, op); dbuf_put_u16(&bc_out, s->scopes[scope].first + 1); break; + case OP_scope_get_var_checkthis: case OP_scope_get_var_undef: case OP_scope_get_var: case OP_scope_put_var: @@ -30887,6 +31483,7 @@ static __exception int resolve_variables(JSContext *ctx, JSFunctionDef *s) case OP_scope_get_private_field: case OP_scope_get_private_field2: case OP_scope_put_private_field: + case OP_scope_in_private_field: { int ret; var_name = get_u32(bc_buf + pos + 1); @@ -31098,6 +31695,17 @@ static __exception int resolve_variables(JSContext *ctx, JSFunctionDef *s) case OP_set_class_name: /* only used during parsing */ break; + + case OP_get_field_opt_chain: /* equivalent to OP_get_field */ + { + JSAtom name = get_u32(bc_buf + pos + 1); + dbuf_putc(&bc_out, OP_get_field); + dbuf_put_u32(&bc_out, name); + } + break; + case OP_get_array_el_opt_chain: /* equivalent to OP_get_array_el */ + dbuf_putc(&bc_out, OP_get_array_el); + break; default: no_change: @@ -32230,6 +32838,7 @@ typedef struct StackSizeState { int bc_len; int stack_len_max; uint16_t *stack_level_tab; + int32_t *catch_pos_tab; int *pc_stack; int pc_stack_len; int pc_stack_size; @@ -32237,7 +32846,7 @@ typedef struct StackSizeState { /* 'op' is only used for error indication */ static __exception int ss_check(JSContext *ctx, StackSizeState *s, - int pos, int op, int stack_len) + int pos, int op, int stack_len, int catch_pos) { if ((unsigned)pos >= s->bc_len) { JS_ThrowInternalError(ctx, "bytecode buffer overflow (op=%d, pc=%d)", op, pos); @@ -32253,9 +32862,13 @@ static __exception int ss_check(JSContext *ctx, StackSizeState *s, if (s->stack_level_tab[pos] != 0xffff) { /* already explored: check that the stack size is consistent */ if (s->stack_level_tab[pos] != stack_len) { - JS_ThrowInternalError(ctx, "unconsistent stack size: %d %d (pc=%d)", + JS_ThrowInternalError(ctx, "inconsistent stack size: %d %d (pc=%d)", s->stack_level_tab[pos], stack_len, pos); return -1; + } else if (s->catch_pos_tab[pos] != catch_pos) { + JS_ThrowInternalError(ctx, "inconsistent catch position: %d %d (pc=%d)", + s->catch_pos_tab[pos], catch_pos, pos); + return -1; } else { return 0; } @@ -32263,7 +32876,8 @@ static __exception int ss_check(JSContext *ctx, StackSizeState *s, /* mark as explored and store the stack size */ s->stack_level_tab[pos] = stack_len; - + s->catch_pos_tab[pos] = catch_pos; + /* queue the new PC to explore */ if (js_resize_array(ctx, (void **)&s->pc_stack, sizeof(s->pc_stack[0]), &s->pc_stack_size, s->pc_stack_len + 1)) @@ -32277,7 +32891,7 @@ static __exception int compute_stack_size(JSContext *ctx, int *pstack_size) { StackSizeState s_s, *s = &s_s; - int i, diff, n_pop, pos_next, stack_len, pos, op; + int i, diff, n_pop, pos_next, stack_len, pos, op, catch_pos, catch_level; const JSOpCode *oi; const uint8_t *bc_buf; @@ -32290,24 +32904,33 @@ static __exception int compute_stack_size(JSContext *ctx, return -1; for(i = 0; i < s->bc_len; i++) s->stack_level_tab[i] = 0xffff; - s->stack_len_max = 0; s->pc_stack = NULL; + s->catch_pos_tab = js_malloc(ctx, sizeof(s->catch_pos_tab[0]) * + s->bc_len); + if (!s->catch_pos_tab) + goto fail; + + s->stack_len_max = 0; s->pc_stack_len = 0; s->pc_stack_size = 0; /* breadth-first graph exploration */ - if (ss_check(ctx, s, 0, OP_invalid, 0)) + if (ss_check(ctx, s, 0, OP_invalid, 0, -1)) goto fail; while (s->pc_stack_len > 0) { pos = s->pc_stack[--s->pc_stack_len]; stack_len = s->stack_level_tab[pos]; + catch_pos = s->catch_pos_tab[pos]; op = bc_buf[pos]; if (op == 0 || op >= OP_COUNT) { JS_ThrowInternalError(ctx, "invalid opcode (op=%d, pc=%d)", op, pos); goto fail; } oi = &short_opcode_info(op); +#if defined(DUMP_BYTECODE) && (DUMP_BYTECODE & 64) + printf("%5d: %10s %5d %5d\n", pos, oi->name, stack_len, catch_pos); +#endif pos_next = pos + oi->size; if (pos_next > s->bc_len) { JS_ThrowInternalError(ctx, "bytecode buffer overflow (op=%d, pc=%d)", op, pos); @@ -32363,55 +32986,104 @@ static __exception int compute_stack_size(JSContext *ctx, case OP_if_true8: case OP_if_false8: diff = (int8_t)bc_buf[pos + 1]; - if (ss_check(ctx, s, pos + 1 + diff, op, stack_len)) + if (ss_check(ctx, s, pos + 1 + diff, op, stack_len, catch_pos)) goto fail; break; #endif case OP_if_true: case OP_if_false: - case OP_catch: diff = get_u32(bc_buf + pos + 1); - if (ss_check(ctx, s, pos + 1 + diff, op, stack_len)) + if (ss_check(ctx, s, pos + 1 + diff, op, stack_len, catch_pos)) goto fail; break; case OP_gosub: diff = get_u32(bc_buf + pos + 1); - if (ss_check(ctx, s, pos + 1 + diff, op, stack_len + 1)) + if (ss_check(ctx, s, pos + 1 + diff, op, stack_len + 1, catch_pos)) goto fail; break; case OP_with_get_var: case OP_with_delete_var: diff = get_u32(bc_buf + pos + 5); - if (ss_check(ctx, s, pos + 5 + diff, op, stack_len + 1)) + if (ss_check(ctx, s, pos + 5 + diff, op, stack_len + 1, catch_pos)) goto fail; break; case OP_with_make_ref: case OP_with_get_ref: case OP_with_get_ref_undef: diff = get_u32(bc_buf + pos + 5); - if (ss_check(ctx, s, pos + 5 + diff, op, stack_len + 2)) + if (ss_check(ctx, s, pos + 5 + diff, op, stack_len + 2, catch_pos)) goto fail; break; case OP_with_put_var: diff = get_u32(bc_buf + pos + 5); - if (ss_check(ctx, s, pos + 5 + diff, op, stack_len - 1)) + if (ss_check(ctx, s, pos + 5 + diff, op, stack_len - 1, catch_pos)) goto fail; break; - + case OP_catch: + diff = get_u32(bc_buf + pos + 1); + if (ss_check(ctx, s, pos + 1 + diff, op, stack_len, catch_pos)) + goto fail; + catch_pos = pos; + break; + case OP_for_of_start: + case OP_for_await_of_start: + catch_pos = pos; + break; + /* we assume the catch offset entry is only removed with + some op codes */ + case OP_drop: + catch_level = stack_len; + goto check_catch; + case OP_nip: + catch_level = stack_len - 1; + goto check_catch; + case OP_nip1: + catch_level = stack_len - 1; + goto check_catch; + case OP_iterator_close: + catch_level = stack_len + 2; + check_catch: + /* Note: for for_of_start/for_await_of_start we consider + the catch offset is on the first stack entry instead of + the thirst */ + if (catch_pos >= 0) { + int level; + level = s->stack_level_tab[catch_pos]; + if (bc_buf[catch_pos] != OP_catch) + level++; /* for_of_start, for_wait_of_start */ + /* catch_level = stack_level before op_catch is executed ? */ + if (catch_level == level) { + catch_pos = s->catch_pos_tab[catch_pos]; + } + } + break; + case OP_nip_catch: + if (catch_pos < 0) { + JS_ThrowInternalError(ctx, "nip_catch: no catch op (pc=%d)", pos); + goto fail; + } + stack_len = s->stack_level_tab[catch_pos]; + if (bc_buf[catch_pos] != OP_catch) + stack_len++; /* for_of_start, for_wait_of_start */ + stack_len++; /* no stack overflow is possible by construction */ + catch_pos = s->catch_pos_tab[catch_pos]; + break; default: break; } - if (ss_check(ctx, s, pos_next, op, stack_len)) + if (ss_check(ctx, s, pos_next, op, stack_len, catch_pos)) goto fail; done_insn: ; } - js_free(ctx, s->stack_level_tab); js_free(ctx, s->pc_stack); + js_free(ctx, s->catch_pos_tab); + js_free(ctx, s->stack_level_tab); *pstack_size = s->stack_len_max; return 0; fail: - js_free(ctx, s->stack_level_tab); js_free(ctx, s->pc_stack); + js_free(ctx, s->catch_pos_tab); + js_free(ctx, s->stack_level_tab); *pstack_size = 0; return -1; } @@ -32656,6 +33328,8 @@ static JSValue js_create_function(JSContext *ctx, JSFunctionDef *fd) b->super_allowed = fd->super_allowed; b->arguments_allowed = fd->arguments_allowed; b->backtrace_barrier = fd->backtrace_barrier; + b->is_direct_or_indirect_eval = (fd->eval_type == JS_EVAL_TYPE_DIRECT || + fd->eval_type == JS_EVAL_TYPE_INDIRECT); b->realm = JS_DupContext(ctx); add_gc_object(ctx->rt, &b->header, JS_GC_OBJ_TYPE_FUNCTION_BYTECODE); @@ -32938,8 +33612,9 @@ static __exception int js_parse_function_decl2(JSParseState *s, func_type == JS_PARSE_FUNC_EXPR && (func_kind & JS_FUNC_GENERATOR)) || (s->token.u.ident.atom == JS_ATOM_await && - func_type == JS_PARSE_FUNC_EXPR && - (func_kind & JS_FUNC_ASYNC))) { + ((func_type == JS_PARSE_FUNC_EXPR && + (func_kind & JS_FUNC_ASYNC)) || + func_type == JS_PARSE_FUNC_CLASS_STATIC_INIT))) { return js_parse_error_reserved_identifier(s); } } @@ -33033,7 +33708,8 @@ static __exception int js_parse_function_decl2(JSParseState *s, func_type == JS_PARSE_FUNC_SETTER || func_type == JS_PARSE_FUNC_CLASS_CONSTRUCTOR || func_type == JS_PARSE_FUNC_DERIVED_CLASS_CONSTRUCTOR); - fd->has_arguments_binding = (func_type != JS_PARSE_FUNC_ARROW); + fd->has_arguments_binding = (func_type != JS_PARSE_FUNC_ARROW && + func_type != JS_PARSE_FUNC_CLASS_STATIC_INIT); fd->has_this_binding = fd->has_arguments_binding; fd->is_derived_class_constructor = (func_type == JS_PARSE_FUNC_DERIVED_CLASS_CONSTRUCTOR); if (func_type == JS_PARSE_FUNC_ARROW) { @@ -33041,6 +33717,11 @@ static __exception int js_parse_function_decl2(JSParseState *s, fd->super_call_allowed = fd->parent->super_call_allowed; fd->super_allowed = fd->parent->super_allowed; fd->arguments_allowed = fd->parent->arguments_allowed; + } else if (func_type == JS_PARSE_FUNC_CLASS_STATIC_INIT) { + fd->new_target_allowed = TRUE; // although new.target === undefined + fd->super_call_allowed = FALSE; + fd->super_allowed = TRUE; + fd->arguments_allowed = FALSE; } else { fd->new_target_allowed = TRUE; fd->super_call_allowed = fd->is_derived_class_constructor; @@ -33078,7 +33759,7 @@ static __exception int js_parse_function_decl2(JSParseState *s, if (add_arg(ctx, fd, name) < 0) goto fail; fd->defined_arg_count = 1; - } else { + } else if (func_type != JS_PARSE_FUNC_CLASS_STATIC_INIT) { if (s->token.val == '(') { int skip_bits; /* if there is an '=' inside the parameter list, we @@ -33299,8 +33980,10 @@ static __exception int js_parse_function_decl2(JSParseState *s, } } - if (js_parse_expect(s, '{')) - goto fail; + if (func_type != JS_PARSE_FUNC_CLASS_STATIC_INIT) { + if (js_parse_expect(s, '{')) + goto fail; + } if (js_parse_directives(s)) goto fail; @@ -33330,9 +34013,15 @@ static __exception int js_parse_function_decl2(JSParseState *s, if (js_is_live_code(s)) { emit_return(s, FALSE); } -done: + done: s->cur_func = fd->parent; + /* Reparse identifiers after the function is terminated so that + the token is parsed in the englobing function. It could be done + by just using next_token() here for normal functions, but it is + necessary for arrow functions with an expression body. */ + reparse_ident_token(s); + /* create the function object */ { int idx; @@ -33487,9 +34176,9 @@ static __exception int js_parse_program(JSParseState *s) emit_op(s, OP_get_loc); emit_u16(s, fd->eval_ret_idx); - emit_op(s, OP_return); + emit_return(s, TRUE); } else { - emit_op(s, OP_return_undef); + emit_return(s, FALSE); } return 0; @@ -33532,7 +34221,6 @@ static JSValue JS_EvalFunctionInternal(JSContext *ctx, JSValue fun_obj, ret_val = js_evaluate_module(ctx, m); if (JS_IsException(ret_val)) { fail: - js_free_modules(ctx, JS_FREE_MODULE_NOT_EVALUATED); return JS_EXCEPTION; } } else { @@ -33547,31 +34235,6 @@ JSValue JS_EvalFunction(JSContext *ctx, JSValue fun_obj) return JS_EvalFunctionInternal(ctx, fun_obj, ctx->global_obj, NULL, NULL); } -static void skip_shebang(JSParseState *s) -{ - const uint8_t *p = s->buf_ptr; - int c; - - if (p[0] == '#' && p[1] == '!') { - p += 2; - while (p < s->buf_end) { - if (*p == '\n' || *p == '\r') { - break; - } else if (*p >= 0x80) { - c = unicode_from_utf8(p, UTF8_CHAR_LEN_MAX, &p); - if (c == CP_LS || c == CP_PS) { - break; - } else if (c == -1) { - p++; /* skip invalid UTF-8 */ - } - } else { - p++; - } - } - s->buf_ptr = p; - } -} - /* 'input' must be zero terminated i.e. input[input_len] = '\0'. */ static JSValue __JS_EvalInternal(JSContext *ctx, JSValueConst this_obj, const char *input, size_t input_len, @@ -33587,7 +34250,7 @@ static JSValue __JS_EvalInternal(JSContext *ctx, JSValueConst this_obj, JSModuleDef *m; js_parse_init(ctx, s, input, input_len, filename); - skip_shebang(s); + skip_shebang(&s->buf_ptr, s->buf_end); eval_type = flags & JS_EVAL_TYPE_MASK; m = NULL; @@ -33645,6 +34308,10 @@ static JSValue __JS_EvalInternal(JSContext *ctx, JSValueConst this_obj, goto fail; } fd->module = m; + if (m != NULL || (flags & JS_EVAL_FLAG_ASYNC)) { + fd->in_function_body = TRUE; + fd->func_kind = JS_FUNC_ASYNC; + } s->is_module = (m != NULL); s->allow_html_comments = !s->is_module; @@ -33659,6 +34326,9 @@ static JSValue __JS_EvalInternal(JSContext *ctx, JSValueConst this_obj, goto fail1; } + if (m != NULL) + m->has_tla = fd->has_await; + /* create the function object and all the enclosed functions */ fun_obj = js_create_function(ctx, fd); if (JS_IsException(fun_obj)) @@ -33668,7 +34338,7 @@ static JSValue __JS_EvalInternal(JSContext *ctx, JSValueConst this_obj, m->func_obj = fun_obj; if (js_resolve_module(ctx, m) < 0) goto fail1; - fun_obj = JS_DupValue(ctx, JS_MKPTR(JS_TAG_MODULE, m)); + fun_obj = JS_NewModuleValue(ctx, m); } if (flags & JS_EVAL_FLAG_COMPILE_ONLY) { ret_val = fun_obj; @@ -34151,7 +34821,6 @@ static void JS_WriteString(BCWriterState *s, JSString *p) } } -#ifdef CONFIG_BIGNUM static int JS_WriteBigNum(BCWriterState *s, JSValueConst obj) { uint32_t tag, tag1; @@ -34166,12 +34835,14 @@ static int JS_WriteBigNum(BCWriterState *s, JSValueConst obj) case JS_TAG_BIG_INT: tag1 = BC_TAG_BIG_INT; break; +#ifdef CONFIG_BIGNUM case JS_TAG_BIG_FLOAT: tag1 = BC_TAG_BIG_FLOAT; break; case JS_TAG_BIG_DECIMAL: tag1 = BC_TAG_BIG_DECIMAL; break; +#endif default: abort(); } @@ -34286,7 +34957,6 @@ static int JS_WriteBigNum(BCWriterState *s, JSValueConst obj) } return 0; } -#endif /* CONFIG_BIGNUM */ static int JS_WriteObjectRec(BCWriterState *s, JSValueConst obj); @@ -34309,6 +34979,7 @@ static int JS_WriteFunctionTag(BCWriterState *s, JSValueConst obj) bc_set_flags(&flags, &idx, b->arguments_allowed, 1); bc_set_flags(&flags, &idx, b->has_debug, 1); bc_set_flags(&flags, &idx, b->backtrace_barrier, 1); + bc_set_flags(&flags, &idx, b->is_direct_or_indirect_eval, 1); assert(idx <= 16); bc_put_u16(s, flags); bc_put_u8(s, b->js_mode); @@ -34414,6 +35085,8 @@ static int JS_WriteModule(BCWriterState *s, JSValueConst obj) bc_put_atom(s, mi->import_name); bc_put_leb128(s, mi->req_module_idx); } + + bc_put_u8(s, m->has_tla); if (JS_WriteObjectRec(s, m->func_obj)) goto fail; @@ -34643,8 +35316,8 @@ static int JS_WriteObjectRec(BCWriterState *s, JSValueConst obj) case JS_CLASS_NUMBER: case JS_CLASS_STRING: case JS_CLASS_BOOLEAN: -#ifdef CONFIG_BIGNUM case JS_CLASS_BIG_INT: +#ifdef CONFIG_BIGNUM case JS_CLASS_BIG_FLOAT: case JS_CLASS_BIG_DECIMAL: #endif @@ -34666,14 +35339,14 @@ static int JS_WriteObjectRec(BCWriterState *s, JSValueConst obj) goto fail; } break; -#ifdef CONFIG_BIGNUM case JS_TAG_BIG_INT: +#ifdef CONFIG_BIGNUM case JS_TAG_BIG_FLOAT: case JS_TAG_BIG_DECIMAL: +#endif if (JS_WriteBigNum(s, obj)) goto fail; break; -#endif default: invalid_tag: JS_ThrowInternalError(s->ctx, "unsupported tag (%d)", tag); @@ -35065,7 +35738,6 @@ static int JS_ReadFunctionBytecode(BCReaderState *s, JSFunctionBytecode *b, return 0; } -#ifdef CONFIG_BIGNUM static JSValue JS_ReadBigNum(BCReaderState *s, int tag) { JSValue obj = JS_UNDEFINED; @@ -35085,12 +35757,14 @@ static JSValue JS_ReadBigNum(BCReaderState *s, int tag) case BC_TAG_BIG_INT: obj = JS_MKPTR(JS_TAG_BIG_INT, p); break; +#ifdef CONFIG_BIGNUM case BC_TAG_BIG_FLOAT: obj = JS_MKPTR(JS_TAG_BIG_FLOAT, p); break; case BC_TAG_BIG_DECIMAL: obj = JS_MKPTR(JS_TAG_BIG_DECIMAL, p); break; +#endif default: abort(); } @@ -35197,7 +35871,6 @@ static JSValue JS_ReadBigNum(BCReaderState *s, int tag) JS_FreeValue(s->ctx, obj); return JS_EXCEPTION; } -#endif /* CONFIG_BIGNUM */ static JSValue JS_ReadObjectRec(BCReaderState *s); @@ -35247,6 +35920,7 @@ static JSValue JS_ReadFunctionTag(BCReaderState *s) bc.arguments_allowed = bc_get_flags(v16, &idx, 1); bc.has_debug = bc_get_flags(v16, &idx, 1); bc.backtrace_barrier = bc_get_flags(v16, &idx, 1); + bc.is_direct_or_indirect_eval = bc_get_flags(v16, &idx, 1); bc.read_only_bytecode = s->is_rom_data; if (bc_get_u8(s, &v8)) goto fail; @@ -35425,7 +36099,7 @@ static JSValue JS_ReadModule(BCReaderState *s) m = js_new_module_def(ctx, module_name); if (!m) goto fail; - obj = JS_DupValue(ctx, JS_MKPTR(JS_TAG_MODULE, m)); + obj = JS_NewModuleValue(ctx, m); if (bc_get_leb128_int(s, &m->req_module_entries_count)) goto fail; if (m->req_module_entries_count != 0) { @@ -35498,6 +36172,10 @@ static JSValue JS_ReadModule(BCReaderState *s) } } + if (bc_get_u8(s, &v8)) + goto fail; + m->has_tla = (v8 != 0); + m->func_obj = JS_ReadObjectRec(s); if (JS_IsException(m->func_obj)) goto fail; @@ -35822,13 +36500,13 @@ static JSValue JS_ReadObjectRec(BCReaderState *s) case BC_TAG_OBJECT_VALUE: obj = JS_ReadObjectValue(s); break; -#ifdef CONFIG_BIGNUM case BC_TAG_BIG_INT: +#ifdef CONFIG_BIGNUM case BC_TAG_BIG_FLOAT: case BC_TAG_BIG_DECIMAL: +#endif obj = JS_ReadBigNum(s, tag); break; -#endif case BC_TAG_OBJECT_REFERENCE: { uint32_t val; @@ -36260,10 +36938,10 @@ static JSValue JS_ToObject(JSContext *ctx, JSValueConst val) case JS_TAG_OBJECT: case JS_TAG_EXCEPTION: return JS_DupValue(ctx, val); -#ifdef CONFIG_BIGNUM case JS_TAG_BIG_INT: obj = JS_NewObjectClass(ctx, JS_CLASS_BIG_INT); goto set_value; +#ifdef CONFIG_BIGNUM case JS_TAG_BIG_FLOAT: obj = JS_NewObjectClass(ctx, JS_CLASS_BIG_FLOAT); goto set_value; @@ -36882,6 +37560,32 @@ static JSValue js_object_hasOwnProperty(JSContext *ctx, JSValueConst this_val, return JS_NewBool(ctx, ret); } +static JSValue js_object_hasOwn(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + JSValue obj; + JSAtom atom; + JSObject *p; + BOOL ret; + + obj = JS_ToObject(ctx, argv[0]); + if (JS_IsException(obj)) + return obj; + atom = JS_ValueToAtom(ctx, argv[1]); + if (unlikely(atom == JS_ATOM_NULL)) { + JS_FreeValue(ctx, obj); + return JS_EXCEPTION; + } + p = JS_VALUE_GET_OBJ(obj); + ret = JS_GetOwnPropertyInternal(ctx, NULL, p, atom); + JS_FreeAtom(ctx, atom); + JS_FreeValue(ctx, obj); + if (ret < 0) + return JS_EXCEPTION; + else + return JS_NewBool(ctx, ret); +} + static JSValue js_object_valueOf(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { @@ -37429,6 +38133,7 @@ static const JSCFunctionListEntry js_object_funcs[] = { JS_CFUNC_DEF("defineProperties", 2, js_object_defineProperties ), JS_CFUNC_DEF("getOwnPropertyNames", 1, js_object_getOwnPropertyNames ), JS_CFUNC_DEF("getOwnPropertySymbols", 1, js_object_getOwnPropertySymbols ), + JS_CFUNC_MAGIC_DEF("groupBy", 2, js_object_groupBy, 0 ), JS_CFUNC_MAGIC_DEF("keys", 1, js_object_keys, JS_ITERATOR_KIND_KEY ), JS_CFUNC_MAGIC_DEF("values", 1, js_object_keys, JS_ITERATOR_KIND_VALUE ), JS_CFUNC_MAGIC_DEF("entries", 1, js_object_keys, JS_ITERATOR_KIND_KEY_AND_VALUE ), @@ -37454,6 +38159,7 @@ static const JSCFunctionListEntry js_object_funcs[] = { //JS_CFUNC_DEF("__getObjectData", 1, js_object___getObjectData ), //JS_CFUNC_DEF("__setObjectData", 2, js_object___setObjectData ), JS_CFUNC_DEF("fromEntries", 1, js_object_fromEntries ), + JS_CFUNC_DEF("hasOwn", 2, js_object_hasOwn ), }; static const JSCFunctionListEntry js_object_proto_funcs[] = { @@ -37858,7 +38564,8 @@ static JSValue js_error_constructor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv, int magic) { JSValue obj, msg, proto; - JSValueConst message; + JSValueConst message, options; + int arg_index; if (JS_IsUndefined(new_target)) new_target = JS_GetActiveFunction(ctx); @@ -37884,12 +38591,9 @@ static JSValue js_error_constructor(JSContext *ctx, JSValueConst new_target, JS_FreeValue(ctx, proto); if (JS_IsException(obj)) return obj; - if (magic == JS_AGGREGATE_ERROR) { - message = argv[1]; - } else { - message = argv[0]; - } + arg_index = (magic == JS_AGGREGATE_ERROR); + message = argv[arg_index++]; if (!JS_IsUndefined(message)) { msg = JS_ToString(ctx, message); if (unlikely(JS_IsException(msg))) @@ -37898,6 +38602,22 @@ static JSValue js_error_constructor(JSContext *ctx, JSValueConst new_target, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE); } + if (arg_index < argc) { + options = argv[arg_index]; + if (JS_IsObject(options)) { + int present = JS_HasProperty(ctx, options, JS_ATOM_cause); + if (present < 0) + goto exception; + if (present) { + JSValue cause = JS_GetProperty(ctx, options, JS_ATOM_cause); + if (JS_IsException(cause)) + goto exception; + JS_DefinePropertyValue(ctx, obj, JS_ATOM_cause, cause, + JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE); + } + } + } + if (magic == JS_AGGREGATE_ERROR) { JSValue error_list = iterator_to_array(ctx, argv[0]); if (JS_IsException(error_list)) @@ -37973,12 +38693,20 @@ static int JS_CopySubArray(JSContext *ctx, JSValueConst obj, int64_t to_pos, int64_t from_pos, int64_t count, int dir) { - int64_t i, from, to; + JSObject *p; + int64_t i, from, to, len; JSValue val; int fromPresent; - /* XXX: should special case fast arrays */ - for (i = 0; i < count; i++) { + p = NULL; + if (JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT) { + p = JS_VALUE_GET_OBJ(obj); + if (p->class_id != JS_CLASS_ARRAY || !p->fast_array) { + p = NULL; + } + } + + for (i = 0; i < count; ) { if (dir < 0) { from = from_pos + count - i - 1; to = to_pos + count - i - 1; @@ -37986,16 +38714,43 @@ static int JS_CopySubArray(JSContext *ctx, from = from_pos + i; to = to_pos + i; } - fromPresent = JS_TryGetPropertyInt64(ctx, obj, from, &val); - if (fromPresent < 0) - goto exception; - - if (fromPresent) { - if (JS_SetPropertyInt64(ctx, obj, to, val) < 0) - goto exception; + if (p && p->fast_array && + from >= 0 && from < (len = p->u.array.count) && + to >= 0 && to < len) { + int64_t l, j; + /* Fast path for fast arrays. Since we don't look at the + prototype chain, we can optimize only the cases where + all the elements are present in the array. */ + l = count - i; + if (dir < 0) { + l = min_int64(l, from + 1); + l = min_int64(l, to + 1); + for(j = 0; j < l; j++) { + set_value(ctx, &p->u.array.u.values[to - j], + JS_DupValue(ctx, p->u.array.u.values[from - j])); + } + } else { + l = min_int64(l, len - from); + l = min_int64(l, len - to); + for(j = 0; j < l; j++) { + set_value(ctx, &p->u.array.u.values[to + j], + JS_DupValue(ctx, p->u.array.u.values[from + j])); + } + } + i += l; } else { - if (JS_DeletePropertyInt64(ctx, obj, to, JS_PROP_THROW) < 0) + fromPresent = JS_TryGetPropertyInt64(ctx, obj, from, &val); + if (fromPresent < 0) goto exception; + + if (fromPresent) { + if (JS_SetPropertyInt64(ctx, obj, to, val) < 0) + goto exception; + } else { + if (JS_DeletePropertyInt64(ctx, obj, to, JS_PROP_THROW) < 0) + goto exception; + } + i++; } } return 0; @@ -38256,6 +39011,106 @@ static int JS_isConcatSpreadable(JSContext *ctx, JSValueConst obj) return JS_IsArray(ctx, obj); } +static JSValue js_array_at(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + JSValue obj, ret; + int64_t len, idx; + JSValue *arrp; + uint32_t count; + + obj = JS_ToObject(ctx, this_val); + if (js_get_length64(ctx, &len, obj)) + goto exception; + + if (JS_ToInt64Sat(ctx, &idx, argv[0])) + goto exception; + + if (idx < 0) + idx = len + idx; + if (idx < 0 || idx >= len) { + ret = JS_UNDEFINED; + } else if (js_get_fast_array(ctx, obj, &arrp, &count) && idx < count) { + ret = JS_DupValue(ctx, arrp[idx]); + } else { + int present = JS_TryGetPropertyInt64(ctx, obj, idx, &ret); + if (present < 0) + goto exception; + if (!present) + ret = JS_UNDEFINED; + } + JS_FreeValue(ctx, obj); + return ret; + exception: + JS_FreeValue(ctx, obj); + return JS_EXCEPTION; +} + +static JSValue js_array_with(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + JSValue arr, obj, ret, *arrp, *pval; + JSObject *p; + int64_t i, len, idx; + uint32_t count32; + + ret = JS_EXCEPTION; + arr = JS_UNDEFINED; + obj = JS_ToObject(ctx, this_val); + if (js_get_length64(ctx, &len, obj)) + goto exception; + + if (JS_ToInt64Sat(ctx, &idx, argv[0])) + goto exception; + + if (idx < 0) + idx = len + idx; + + if (idx < 0 || idx >= len) { + JS_ThrowRangeError(ctx, "out of bound"); + goto exception; + } + + arr = js_allocate_fast_array(ctx, len); + if (JS_IsException(arr)) + goto exception; + + p = JS_VALUE_GET_OBJ(arr); + i = 0; + pval = p->u.array.u.values; + if (js_get_fast_array(ctx, obj, &arrp, &count32) && count32 == len) { + for (; i < idx; i++, pval++) + *pval = JS_DupValue(ctx, arrp[i]); + *pval = JS_DupValue(ctx, argv[1]); + for (i++, pval++; i < len; i++, pval++) + *pval = JS_DupValue(ctx, arrp[i]); + } else { + for (; i < idx; i++, pval++) + if (-1 == JS_TryGetPropertyInt64(ctx, obj, i, pval)) + goto fill_and_fail; + *pval = JS_DupValue(ctx, argv[1]); + for (i++, pval++; i < len; i++, pval++) { + if (-1 == JS_TryGetPropertyInt64(ctx, obj, i, pval)) { + fill_and_fail: + for (; i < len; i++, pval++) + *pval = JS_UNDEFINED; + goto exception; + } + } + } + + if (JS_SetProperty(ctx, arr, JS_ATOM_length, JS_NewInt64(ctx, len)) < 0) + goto exception; + + ret = arr; + arr = JS_UNDEFINED; + +exception: + JS_FreeValue(ctx, arr); + JS_FreeValue(ctx, obj); + return ret; +} + static JSValue js_array_concat(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { @@ -38754,13 +39609,21 @@ static JSValue js_array_lastIndexOf(JSContext *ctx, JSValueConst this_val, return JS_EXCEPTION; } +enum { + special_find, + special_findIndex, + special_findLast, + special_findLastIndex, +}; + static JSValue js_array_find(JSContext *ctx, JSValueConst this_val, - int argc, JSValueConst *argv, int findIndex) + int argc, JSValueConst *argv, int mode) { JSValueConst func, this_arg; JSValueConst args[3]; JSValue obj, val, index_val, res; - int64_t len, k; + int64_t len, k, end; + int dir; index_val = JS_UNDEFINED; val = JS_UNDEFINED; @@ -38776,7 +39639,18 @@ static JSValue js_array_find(JSContext *ctx, JSValueConst this_val, if (argc > 1) this_arg = argv[1]; - for(k = 0; k < len; k++) { + if (mode == special_findLast || mode == special_findLastIndex) { + k = len - 1; + dir = -1; + end = -1; + } else { + k = 0; + dir = 1; + end = len; + } + + // TODO(bnoordhuis) add fast path for fast arrays + for(; k != end; k += dir) { index_val = JS_NewInt64(ctx, k); if (JS_IsException(index_val)) goto exception; @@ -38790,7 +39664,7 @@ static JSValue js_array_find(JSContext *ctx, JSValueConst this_val, if (JS_IsException(res)) goto exception; if (JS_ToBoolFree(ctx, res)) { - if (findIndex) { + if (mode == special_findIndex || mode == special_findLastIndex) { JS_FreeValue(ctx, val); JS_FreeValue(ctx, obj); return index_val; @@ -38804,7 +39678,7 @@ static JSValue js_array_find(JSContext *ctx, JSValueConst this_val, JS_FreeValue(ctx, index_val); } JS_FreeValue(ctx, obj); - if (findIndex) + if (mode == special_findIndex || mode == special_findLastIndex) return JS_NewInt32(ctx, -1); else return JS_UNDEFINED; @@ -38957,64 +39831,27 @@ static JSValue js_array_push(JSContext *ctx, JSValueConst this_val, int64_t len, from, newLen; obj = JS_ToObject(ctx, this_val); - - if (JS_VALUE_GET_TAG(obj) == JS_TAG_OBJECT) { - JSObject *p = JS_VALUE_GET_OBJ(obj); - if (p->class_id != JS_CLASS_ARRAY || - !p->fast_array || !p->extensible) - goto generic_case; - /* length must be writable */ - if (unlikely(!(get_shape_prop(p->shape)->flags & JS_PROP_WRITABLE))) - goto generic_case; - /* check the length */ - if (unlikely(JS_VALUE_GET_TAG(p->prop[0].u.value) != JS_TAG_INT)) - goto generic_case; - len = JS_VALUE_GET_INT(p->prop[0].u.value); - /* we don't support holes */ - if (unlikely(len != p->u.array.count)) - goto generic_case; - newLen = len + argc; - if (unlikely(newLen > INT32_MAX)) - goto generic_case; - if (newLen > p->u.array.u1.size) { - if (expand_fast_array(ctx, p, newLen)) - goto exception; - } - if (unshift && argc > 0) { - memmove(p->u.array.u.values + argc, p->u.array.u.values, - len * sizeof(p->u.array.u.values[0])); - from = 0; - } else { - from = len; - } - for(i = 0; i < argc; i++) { - p->u.array.u.values[from + i] = JS_DupValue(ctx, argv[i]); - } - p->u.array.count = newLen; - p->prop[0].u.value = JS_NewInt32(ctx, newLen); - } else { - generic_case: - if (js_get_length64(ctx, &len, obj)) + if (js_get_length64(ctx, &len, obj)) + goto exception; + newLen = len + argc; + if (newLen > MAX_SAFE_INTEGER) { + JS_ThrowTypeError(ctx, "Array loo long"); + goto exception; + } + from = len; + if (unshift && argc > 0) { + if (JS_CopySubArray(ctx, obj, argc, 0, len, -1)) goto exception; - newLen = len + argc; - if (newLen > MAX_SAFE_INTEGER) { - JS_ThrowTypeError(ctx, "Array loo long"); - goto exception; - } - from = len; - if (unshift && argc > 0) { - if (JS_CopySubArray(ctx, obj, argc, 0, len, -1)) - goto exception; - from = 0; - } - for(i = 0; i < argc; i++) { - if (JS_SetPropertyInt64(ctx, obj, from + i, - JS_DupValue(ctx, argv[i])) < 0) - goto exception; - } - if (JS_SetProperty(ctx, obj, JS_ATOM_length, JS_NewInt64(ctx, newLen)) < 0) + from = 0; + } + for(i = 0; i < argc; i++) { + if (JS_SetPropertyInt64(ctx, obj, from + i, + JS_DupValue(ctx, argv[i])) < 0) goto exception; } + if (JS_SetProperty(ctx, obj, JS_ATOM_length, JS_NewInt64(ctx, newLen)) < 0) + goto exception; + JS_FreeValue(ctx, obj); return JS_NewInt64(ctx, newLen); @@ -39092,6 +39929,61 @@ static JSValue js_array_reverse(JSContext *ctx, JSValueConst this_val, return JS_EXCEPTION; } +// Note: a.toReversed() is a.slice().reverse() with the twist that a.slice() +// leaves holes in sparse arrays intact whereas a.toReversed() replaces them +// with undefined, thus in effect creating a dense array. +// Does not use Array[@@species], always returns a base Array. +static JSValue js_array_toReversed(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + JSValue arr, obj, ret, *arrp, *pval; + JSObject *p; + int64_t i, len; + uint32_t count32; + + ret = JS_EXCEPTION; + arr = JS_UNDEFINED; + obj = JS_ToObject(ctx, this_val); + if (js_get_length64(ctx, &len, obj)) + goto exception; + + arr = js_allocate_fast_array(ctx, len); + if (JS_IsException(arr)) + goto exception; + + if (len > 0) { + p = JS_VALUE_GET_OBJ(arr); + + i = len - 1; + pval = p->u.array.u.values; + if (js_get_fast_array(ctx, obj, &arrp, &count32) && count32 == len) { + for (; i >= 0; i--, pval++) + *pval = JS_DupValue(ctx, arrp[i]); + } else { + // Query order is observable; test262 expects descending order. + for (; i >= 0; i--, pval++) { + if (-1 == JS_TryGetPropertyInt64(ctx, obj, i, pval)) { + // Exception; initialize remaining elements. + for (; i >= 0; i--, pval++) + *pval = JS_UNDEFINED; + goto exception; + } + } + } + + if (JS_SetProperty(ctx, arr, JS_ATOM_length, JS_NewInt64(ctx, len)) < 0) + goto exception; + } + + ret = arr; + arr = JS_UNDEFINED; + +exception: + JS_FreeValue(ctx, arr); + JS_FreeValue(ctx, obj); + return ret; +} + static JSValue js_array_slice(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int splice) { @@ -39199,6 +40091,92 @@ static JSValue js_array_slice(JSContext *ctx, JSValueConst this_val, return JS_EXCEPTION; } +static JSValue js_array_toSpliced(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + JSValue arr, obj, ret, *arrp, *pval, *last; + JSObject *p; + int64_t i, j, len, newlen, start, add, del; + uint32_t count32; + + pval = NULL; + last = NULL; + ret = JS_EXCEPTION; + arr = JS_UNDEFINED; + + obj = JS_ToObject(ctx, this_val); + if (js_get_length64(ctx, &len, obj)) + goto exception; + + start = 0; + if (argc > 0) + if (JS_ToInt64Clamp(ctx, &start, argv[0], 0, len, len)) + goto exception; + + del = 0; + if (argc > 0) + del = len - start; + if (argc > 1) + if (JS_ToInt64Clamp(ctx, &del, argv[1], 0, del, 0)) + goto exception; + + add = 0; + if (argc > 2) + add = argc - 2; + + newlen = len + add - del; + if (newlen > MAX_SAFE_INTEGER) { + JS_ThrowTypeError(ctx, "invalid array length"); + goto exception; + } + + arr = js_allocate_fast_array(ctx, newlen); + if (JS_IsException(arr)) + goto exception; + + if (newlen <= 0) + goto done; + + p = JS_VALUE_GET_OBJ(arr); + pval = &p->u.array.u.values[0]; + last = &p->u.array.u.values[newlen]; + + if (js_get_fast_array(ctx, obj, &arrp, &count32) && count32 == len) { + for (i = 0; i < start; i++, pval++) + *pval = JS_DupValue(ctx, arrp[i]); + for (j = 0; j < add; j++, pval++) + *pval = JS_DupValue(ctx, argv[2 + j]); + for (i += del; i < len; i++, pval++) + *pval = JS_DupValue(ctx, arrp[i]); + } else { + for (i = 0; i < start; i++, pval++) + if (-1 == JS_TryGetPropertyInt64(ctx, obj, i, pval)) + goto exception; + for (j = 0; j < add; j++, pval++) + *pval = JS_DupValue(ctx, argv[2 + j]); + for (i += del; i < len; i++, pval++) + if (-1 == JS_TryGetPropertyInt64(ctx, obj, i, pval)) + goto exception; + } + + assert(pval == last); + + if (JS_SetProperty(ctx, arr, JS_ATOM_length, JS_NewInt64(ctx, newlen)) < 0) + goto exception; + +done: + ret = arr; + arr = JS_UNDEFINED; + +exception: + while (pval != last) + *pval++ = JS_UNDEFINED; + + JS_FreeValue(ctx, arr); + JS_FreeValue(ctx, obj); + return ret; +} + static JSValue js_array_copyWithin(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { @@ -39502,6 +40480,68 @@ fail: return JS_EXCEPTION; } +// Note: a.toSorted() is a.slice().sort() with the twist that a.slice() +// leaves holes in sparse arrays intact whereas a.toSorted() replaces them +// with undefined, thus in effect creating a dense array. +// Does not use Array[@@species], always returns a base Array. +static JSValue js_array_toSorted(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + JSValue arr, obj, ret, *arrp, *pval; + JSObject *p; + int64_t i, len; + uint32_t count32; + int ok; + + ok = JS_IsUndefined(argv[0]) || JS_IsFunction(ctx, argv[0]); + if (!ok) + return JS_ThrowTypeError(ctx, "not a function"); + + ret = JS_EXCEPTION; + arr = JS_UNDEFINED; + obj = JS_ToObject(ctx, this_val); + if (js_get_length64(ctx, &len, obj)) + goto exception; + + arr = js_allocate_fast_array(ctx, len); + if (JS_IsException(arr)) + goto exception; + + if (len > 0) { + p = JS_VALUE_GET_OBJ(arr); + i = 0; + pval = p->u.array.u.values; + if (js_get_fast_array(ctx, obj, &arrp, &count32) && count32 == len) { + for (; i < len; i++, pval++) + *pval = JS_DupValue(ctx, arrp[i]); + } else { + for (; i < len; i++, pval++) { + if (-1 == JS_TryGetPropertyInt64(ctx, obj, i, pval)) { + for (; i < len; i++, pval++) + *pval = JS_UNDEFINED; + goto exception; + } + } + } + + if (JS_SetProperty(ctx, arr, JS_ATOM_length, JS_NewInt64(ctx, len)) < 0) + goto exception; + } + + ret = js_array_sort(ctx, arr, argc, argv); + if (JS_IsException(ret)) + goto exception; + JS_FreeValue(ctx, ret); + + ret = arr; + arr = JS_UNDEFINED; + +exception: + JS_FreeValue(ctx, arr); + JS_FreeValue(ctx, obj); + return ret; +} + typedef struct JSArrayIteratorData { JSValue obj; JSIteratorKindEnum kind; @@ -39654,6 +40694,8 @@ static const JSCFunctionListEntry js_iterator_proto_funcs[] = { }; static const JSCFunctionListEntry js_array_proto_funcs[] = { + JS_CFUNC_DEF("at", 1, js_array_at ), + JS_CFUNC_DEF("with", 2, js_array_with ), JS_CFUNC_DEF("concat", 1, js_array_concat ), JS_CFUNC_MAGIC_DEF("every", 1, js_array_every, special_every ), JS_CFUNC_MAGIC_DEF("some", 1, js_array_every, special_some ), @@ -39663,8 +40705,10 @@ static const JSCFunctionListEntry js_array_proto_funcs[] = { JS_CFUNC_MAGIC_DEF("reduce", 1, js_array_reduce, special_reduce ), JS_CFUNC_MAGIC_DEF("reduceRight", 1, js_array_reduce, special_reduceRight ), JS_CFUNC_DEF("fill", 1, js_array_fill ), - JS_CFUNC_MAGIC_DEF("find", 1, js_array_find, 0 ), - JS_CFUNC_MAGIC_DEF("findIndex", 1, js_array_find, 1 ), + JS_CFUNC_MAGIC_DEF("find", 1, js_array_find, special_find ), + JS_CFUNC_MAGIC_DEF("findIndex", 1, js_array_find, special_findIndex ), + JS_CFUNC_MAGIC_DEF("findLast", 1, js_array_find, special_findLast ), + JS_CFUNC_MAGIC_DEF("findLastIndex", 1, js_array_find, special_findLastIndex ), JS_CFUNC_DEF("indexOf", 1, js_array_indexOf ), JS_CFUNC_DEF("lastIndexOf", 1, js_array_lastIndexOf ), JS_CFUNC_DEF("includes", 1, js_array_includes ), @@ -39676,9 +40720,12 @@ static const JSCFunctionListEntry js_array_proto_funcs[] = { JS_CFUNC_MAGIC_DEF("shift", 0, js_array_pop, 1 ), JS_CFUNC_MAGIC_DEF("unshift", 1, js_array_push, 1 ), JS_CFUNC_DEF("reverse", 0, js_array_reverse ), + JS_CFUNC_DEF("toReversed", 0, js_array_toReversed ), JS_CFUNC_DEF("sort", 1, js_array_sort ), + JS_CFUNC_DEF("toSorted", 1, js_array_toSorted ), JS_CFUNC_MAGIC_DEF("slice", 2, js_array_slice, 0 ), JS_CFUNC_MAGIC_DEF("splice", 2, js_array_slice, 1 ), + JS_CFUNC_DEF("toSpliced", 2, js_array_toSpliced ), JS_CFUNC_DEF("copyWithin", 2, js_array_copyWithin ), JS_CFUNC_MAGIC_DEF("flatMap", 1, js_array_flatten, 1 ), JS_CFUNC_MAGIC_DEF("flat", 0, js_array_flatten, 0 ), @@ -39706,9 +40753,10 @@ static JSValue js_number_constructor(JSContext *ctx, JSValueConst new_target, if (JS_IsException(val)) return val; switch(JS_VALUE_GET_TAG(val)) { -#ifdef CONFIG_BIGNUM case JS_TAG_BIG_INT: +#ifdef CONFIG_BIGNUM case JS_TAG_BIG_FLOAT: +#endif { JSBigFloat *p = JS_VALUE_GET_PTR(val); double d; @@ -39717,6 +40765,7 @@ static JSValue js_number_constructor(JSContext *ctx, JSValueConst new_target, val = __JS_NewFloat64(ctx, d); } break; +#ifdef CONFIG_BIGNUM case JS_TAG_BIG_DECIMAL: val = JS_ToStringFree(ctx, val); if (JS_IsException(val)) @@ -40351,7 +41400,7 @@ static JSValue js_string_charCodeAt(JSContext *ctx, JSValueConst this_val, } static JSValue js_string_charAt(JSContext *ctx, JSValueConst this_val, - int argc, JSValueConst *argv) + int argc, JSValueConst *argv, int is_at) { JSValue val, ret; JSString *p; @@ -40365,8 +41414,13 @@ static JSValue js_string_charAt(JSContext *ctx, JSValueConst this_val, JS_FreeValue(ctx, val); return JS_EXCEPTION; } + if (idx < 0 && is_at) + idx += p->len; if (idx < 0 || idx >= p->len) { - ret = js_new_string8(ctx, NULL, 0); + if (is_at) + ret = JS_UNDEFINED; + else + ret = js_new_string8(ctx, NULL, 0); } else { if (p->is_wide_char) c = p->u.str16[idx]; @@ -40479,6 +41533,84 @@ static int64_t string_advance_index(JSString *p, int64_t index, BOOL unicode) return index; } +/* return the position of the first invalid character in the string or + -1 if none */ +static int js_string_find_invalid_codepoint(JSString *p) +{ + int i, c; + if (!p->is_wide_char) + return -1; + for(i = 0; i < p->len; i++) { + c = p->u.str16[i]; + if (c >= 0xD800 && c <= 0xDFFF) { + if (c >= 0xDC00 || (i + 1) >= p->len) + return i; + c = p->u.str16[i + 1]; + if (c < 0xDC00 || c > 0xDFFF) + return i; + i++; + } + } + return -1; +} + +static JSValue js_string_isWellFormed(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + JSValue str; + JSString *p; + BOOL ret; + + str = JS_ToStringCheckObject(ctx, this_val); + if (JS_IsException(str)) + return JS_EXCEPTION; + p = JS_VALUE_GET_STRING(str); + ret = (js_string_find_invalid_codepoint(p) < 0); + JS_FreeValue(ctx, str); + return JS_NewBool(ctx, ret); +} + +static JSValue js_string_toWellFormed(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + JSValue str, ret; + JSString *p; + int c, i; + + str = JS_ToStringCheckObject(ctx, this_val); + if (JS_IsException(str)) + return JS_EXCEPTION; + + p = JS_VALUE_GET_STRING(str); + /* avoid reallocating the string if it is well-formed */ + i = js_string_find_invalid_codepoint(p); + if (i < 0) + return str; + + ret = js_new_string16(ctx, p->u.str16, p->len); + JS_FreeValue(ctx, str); + if (JS_IsException(ret)) + return JS_EXCEPTION; + + p = JS_VALUE_GET_STRING(ret); + for (; i < p->len; i++) { + c = p->u.str16[i]; + if (c >= 0xD800 && c <= 0xDFFF) { + if (c >= 0xDC00 || (i + 1) >= p->len) { + p->u.str16[i] = 0xFFFD; + } else { + c = p->u.str16[i + 1]; + if (c < 0xDC00 || c > 0xDFFF) { + p->u.str16[i] = 0xFFFD; + } else { + i++; + } + } + } + } + return ret; +} + static JSValue js_string_indexOf(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int lastIndexOf) { @@ -41291,26 +42423,6 @@ static BOOL test_final_sigma(JSString *p, int sigma_pos) return !lre_is_cased(c1); } -static JSValue js_string_localeCompare(JSContext *ctx, JSValueConst this_val, - int argc, JSValueConst *argv) -{ - JSValue a, b; - int cmp; - - a = JS_ToStringCheckObject(ctx, this_val); - if (JS_IsException(a)) - return JS_EXCEPTION; - b = JS_ToString(ctx, argv[0]); - if (JS_IsException(b)) { - JS_FreeValue(ctx, a); - return JS_EXCEPTION; - } - cmp = js_string_compare(ctx, JS_VALUE_GET_STRING(a), JS_VALUE_GET_STRING(b)); - JS_FreeValue(ctx, a); - JS_FreeValue(ctx, b); - return JS_NewInt32(ctx, cmp); -} - static JSValue js_string_toLowerCase(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int to_lower) { @@ -41396,23 +42508,38 @@ static JSValue JS_NewUTF32String(JSContext *ctx, const uint32_t *buf, int len) return JS_EXCEPTION; } +static int js_string_normalize1(JSContext *ctx, uint32_t **pout_buf, + JSValueConst val, + UnicodeNormalizationEnum n_type) +{ + int buf_len, out_len; + uint32_t *buf, *out_buf; + + buf_len = JS_ToUTF32String(ctx, &buf, val); + if (buf_len < 0) + return -1; + out_len = unicode_normalize(&out_buf, buf, buf_len, n_type, + ctx->rt, (DynBufReallocFunc *)js_realloc_rt); + js_free(ctx, buf); + if (out_len < 0) + return -1; + *pout_buf = out_buf; + return out_len; +} + static JSValue js_string_normalize(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { const char *form, *p; size_t form_len; - int is_compat, buf_len, out_len; + int is_compat, out_len; UnicodeNormalizationEnum n_type; JSValue val; - uint32_t *buf, *out_buf; + uint32_t *out_buf; val = JS_ToStringCheckObject(ctx, this_val); if (JS_IsException(val)) return val; - buf_len = JS_ToUTF32String(ctx, &buf, val); - JS_FreeValue(ctx, val); - if (buf_len < 0) - return JS_EXCEPTION; if (argc == 0 || JS_IsUndefined(argv[0])) { n_type = UNICODE_NFC; @@ -41438,22 +42565,96 @@ static JSValue js_string_normalize(JSContext *ctx, JSValueConst this_val, JS_FreeCString(ctx, form); JS_ThrowRangeError(ctx, "bad normalization form"); fail1: - js_free(ctx, buf); + JS_FreeValue(ctx, val); return JS_EXCEPTION; } JS_FreeCString(ctx, form); } - out_len = unicode_normalize(&out_buf, buf, buf_len, n_type, - ctx->rt, (DynBufReallocFunc *)js_realloc_rt); - js_free(ctx, buf); + out_len = js_string_normalize1(ctx, &out_buf, val, n_type); + JS_FreeValue(ctx, val); if (out_len < 0) return JS_EXCEPTION; val = JS_NewUTF32String(ctx, out_buf, out_len); js_free(ctx, out_buf); return val; } -#endif /* CONFIG_ALL_UNICODE */ + +/* return < 0, 0 or > 0 */ +static int js_UTF32_compare(const uint32_t *buf1, int buf1_len, + const uint32_t *buf2, int buf2_len) +{ + int i, len, c, res; + len = min_int(buf1_len, buf2_len); + for(i = 0; i < len; i++) { + /* Note: range is limited so a subtraction is valid */ + c = buf1[i] - buf2[i]; + if (c != 0) + return c; + } + if (buf1_len == buf2_len) + res = 0; + else if (buf1_len < buf2_len) + res = -1; + else + res = 1; + return res; +} + +static JSValue js_string_localeCompare(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + JSValue a, b; + int cmp, a_len, b_len; + uint32_t *a_buf, *b_buf; + + a = JS_ToStringCheckObject(ctx, this_val); + if (JS_IsException(a)) + return JS_EXCEPTION; + b = JS_ToString(ctx, argv[0]); + if (JS_IsException(b)) { + JS_FreeValue(ctx, a); + return JS_EXCEPTION; + } + a_len = js_string_normalize1(ctx, &a_buf, a, UNICODE_NFC); + JS_FreeValue(ctx, a); + if (a_len < 0) { + JS_FreeValue(ctx, b); + return JS_EXCEPTION; + } + + b_len = js_string_normalize1(ctx, &b_buf, b, UNICODE_NFC); + JS_FreeValue(ctx, b); + if (b_len < 0) { + js_free(ctx, a_buf); + return JS_EXCEPTION; + } + cmp = js_UTF32_compare(a_buf, a_len, b_buf, b_len); + js_free(ctx, a_buf); + js_free(ctx, b_buf); + return JS_NewInt32(ctx, cmp); +} +#else /* CONFIG_ALL_UNICODE */ +static JSValue js_string_localeCompare(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + JSValue a, b; + int cmp; + + a = JS_ToStringCheckObject(ctx, this_val); + if (JS_IsException(a)) + return JS_EXCEPTION; + b = JS_ToString(ctx, argv[0]); + if (JS_IsException(b)) { + JS_FreeValue(ctx, a); + return JS_EXCEPTION; + } + cmp = js_string_compare(ctx, JS_VALUE_GET_STRING(a), JS_VALUE_GET_STRING(b)); + JS_FreeValue(ctx, a); + JS_FreeValue(ctx, b); + return JS_NewInt32(ctx, cmp); +} +#endif /* !CONFIG_ALL_UNICODE */ /* also used for String.prototype.valueOf */ static JSValue js_string_toString(JSContext *ctx, JSValueConst this_val, @@ -41625,10 +42826,13 @@ static const JSCFunctionListEntry js_string_funcs[] = { static const JSCFunctionListEntry js_string_proto_funcs[] = { JS_PROP_INT32_DEF("length", 0, JS_PROP_CONFIGURABLE ), + JS_CFUNC_MAGIC_DEF("at", 1, js_string_charAt, 1 ), JS_CFUNC_DEF("charCodeAt", 1, js_string_charCodeAt ), - JS_CFUNC_DEF("charAt", 1, js_string_charAt ), + JS_CFUNC_MAGIC_DEF("charAt", 1, js_string_charAt, 0 ), JS_CFUNC_DEF("concat", 1, js_string_concat ), JS_CFUNC_DEF("codePointAt", 1, js_string_codePointAt ), + JS_CFUNC_DEF("isWellFormed", 0, js_string_isWellFormed ), + JS_CFUNC_DEF("toWellFormed", 0, js_string_toWellFormed ), JS_CFUNC_MAGIC_DEF("indexOf", 1, js_string_indexOf, 0 ), JS_CFUNC_MAGIC_DEF("lastIndexOf", 1, js_string_indexOf, 1 ), JS_CFUNC_MAGIC_DEF("includes", 1, js_string_includes, 0 ), @@ -41961,40 +43165,13 @@ static const JSCFunctionListEntry js_math_obj[] = { /* Date */ -#if 0 -/* OS dependent: return the UTC time in ms since 1970. */ -static JSValue js___date_now(JSContext *ctx, JSValueConst this_val, - int argc, JSValueConst *argv) -{ - int64_t d; - struct timeval tv; - gettimeofday(&tv, NULL); - d = (int64_t)tv.tv_sec * 1000 + (tv.tv_usec / 1000); - return JS_NewInt64(ctx, d); -} -#endif - -/* OS dependent: return the UTC time in microseconds since 1970. */ -static JSValue js___date_clock(JSContext *ctx, JSValueConst this_val, - int argc, JSValueConst *argv) -{ - int64_t d; - struct timeval tv; - gettimeofday(&tv, NULL); - d = (int64_t)tv.tv_sec * 1000000 + tv.tv_usec; - return JS_NewInt64(ctx, d); -} - /* OS dependent. d = argv[0] is in ms from 1970. Return the difference between UTC time and local time 'd' in minutes */ -static int getTimezoneOffset(int64_t time) { -#if defined(_WIN32) - /* XXX: TODO */ - return 0; -#else +static int getTimezoneOffset(int64_t time) +{ time_t ti; - struct tm tm; - + int res; + time /= 1000; /* convert to seconds */ if (sizeof(time_t) == 4) { /* on 32-bit systems, we need to clamp the time value to the @@ -42017,9 +43194,27 @@ static int getTimezoneOffset(int64_t time) { } } ti = time; - localtime_r(&ti, &tm); - return -tm.tm_gmtoff / 60; +#if defined(_WIN32) + { + struct tm *tm; + time_t gm_ti, loc_ti; + + tm = gmtime(&ti); + gm_ti = mktime(tm); + + tm = localtime(&ti); + loc_ti = mktime(tm); + + res = (gm_ti - loc_ti) / 60; + } +#else + { + struct tm tm; + localtime_r(&ti, &tm); + res = -tm.tm_gmtoff / 60; + } #endif + return res; } #if 0 @@ -42096,6 +43291,9 @@ static JSValue js_compile_regexp(JSContext *ctx, JSValueConst pattern, /* XXX: re_flags = LRE_FLAG_OCTAL unless strict mode? */ for (i = 0; i < len; i++) { switch(str[i]) { + case 'd': + mask = LRE_FLAG_INDICES; + break; case 'g': mask = LRE_FLAG_GLOBAL; break; @@ -42439,6 +43637,11 @@ static JSValue js_regexp_get_flags(JSContext *ctx, JSValueConst this_val) if (JS_VALUE_GET_TAG(this_val) != JS_TAG_OBJECT) return JS_ThrowTypeErrorNotAnObject(ctx); + res = JS_ToBoolFree(ctx, JS_GetPropertyStr(ctx, this_val, "hasIndices")); + if (res < 0) + goto exception; + if (res) + *p++ = 'd'; res = JS_ToBoolFree(ctx, JS_GetProperty(ctx, this_val, JS_ATOM_global)); if (res < 0) goto exception; @@ -42518,25 +43721,32 @@ static JSValue js_regexp_exec(JSContext *ctx, JSValueConst this_val, { JSRegExp *re = js_get_regexp(ctx, this_val, TRUE); JSString *str; - JSValue str_val, obj, val, groups = JS_UNDEFINED; + JSValue t, ret, str_val, obj, val, groups; + JSValue indices, indices_groups; uint8_t *re_bytecode; - int ret; uint8_t **capture, *str_buf; - int capture_count, shift, i, re_flags; + int rc, capture_count, shift, i, re_flags; int64_t last_index; const char *group_name_ptr; if (!re) return JS_EXCEPTION; + str_val = JS_ToString(ctx, argv[0]); if (JS_IsException(str_val)) - return str_val; - val = JS_GetProperty(ctx, this_val, JS_ATOM_lastIndex); - if (JS_IsException(val) || - JS_ToLengthFree(ctx, &last_index, val)) { - JS_FreeValue(ctx, str_val); return JS_EXCEPTION; - } + + ret = JS_EXCEPTION; + obj = JS_NULL; + groups = JS_UNDEFINED; + indices = JS_UNDEFINED; + indices_groups = JS_UNDEFINED; + capture = NULL; + + val = JS_GetProperty(ctx, this_val, JS_ATOM_lastIndex); + if (JS_IsException(val) || JS_ToLengthFree(ctx, &last_index, val)) + goto fail; + re_bytecode = re->bytecode->u.str8; re_flags = lre_get_flags(re_bytecode); if ((re_flags & (LRE_FLAG_GLOBAL | LRE_FLAG_STICKY)) == 0) { @@ -42544,27 +43754,23 @@ static JSValue js_regexp_exec(JSContext *ctx, JSValueConst this_val, } str = JS_VALUE_GET_STRING(str_val); capture_count = lre_get_capture_count(re_bytecode); - capture = NULL; if (capture_count > 0) { capture = js_malloc(ctx, sizeof(capture[0]) * capture_count * 2); - if (!capture) { - JS_FreeValue(ctx, str_val); - return JS_EXCEPTION; - } + if (!capture) + goto fail; } shift = str->is_wide_char; str_buf = str->u.str8; if (last_index > str->len) { - ret = 2; + rc = 2; } else { - ret = lre_exec(capture, re_bytecode, - str_buf, last_index, str->len, - shift, ctx); + rc = lre_exec(capture, re_bytecode, + str_buf, last_index, str->len, + shift, ctx); } - obj = JS_NULL; - if (ret != 1) { - if (ret >= 0) { - if (ret == 2 || (re_flags & (LRE_FLAG_GLOBAL | LRE_FLAG_STICKY))) { + if (rc != 1) { + if (rc >= 0) { + if (rc == 2 || (re_flags & (LRE_FLAG_GLOBAL | LRE_FLAG_STICKY))) { if (JS_SetProperty(ctx, this_val, JS_ATOM_lastIndex, JS_NewInt32(ctx, 0)) < 0) goto fail; @@ -42573,7 +43779,6 @@ static JSValue js_regexp_exec(JSContext *ctx, JSValueConst this_val, JS_ThrowInternalError(ctx, "out of memory in regexp execution"); goto fail; } - JS_FreeValue(ctx, str_val); } else { int prop_flags; if (re_flags & (LRE_FLAG_GLOBAL | LRE_FLAG_STICKY)) { @@ -42591,52 +43796,124 @@ static JSValue js_regexp_exec(JSContext *ctx, JSValueConst this_val, if (JS_IsException(groups)) goto fail; } - - for(i = 0; i < capture_count; i++) { - int start, end; - JSValue val; - if (capture[2 * i] == NULL || - capture[2 * i + 1] == NULL) { - val = JS_UNDEFINED; - } else { - start = (capture[2 * i] - str_buf) >> shift; - end = (capture[2 * i + 1] - str_buf) >> shift; - val = js_sub_string(ctx, str, start, end); - if (JS_IsException(val)) + if (re_flags & LRE_FLAG_INDICES) { + indices = JS_NewArray(ctx); + if (JS_IsException(indices)) + goto fail; + if (group_name_ptr) { + indices_groups = JS_NewObjectProto(ctx, JS_NULL); + if (JS_IsException(indices_groups)) goto fail; } + } + + for(i = 0; i < capture_count; i++) { + const char *name = NULL; + uint8_t **match = &capture[2 * i]; + int start = -1; + int end = -1; + JSValue val; + if (group_name_ptr && i > 0) { - if (*group_name_ptr) { - if (JS_DefinePropertyValueStr(ctx, groups, group_name_ptr, - JS_DupValue(ctx, val), - prop_flags) < 0) { + if (*group_name_ptr) name = group_name_ptr; + group_name_ptr += strlen(group_name_ptr) + 1; + } + + if (match[0] && match[1]) { + start = (match[0] - str_buf) >> shift; + end = (match[1] - str_buf) >> shift; + } + + if (!JS_IsUndefined(indices)) { + val = JS_UNDEFINED; + if (start != -1) { + val = JS_NewArray(ctx); + if (JS_IsException(val)) + goto fail; + if (JS_DefinePropertyValueUint32(ctx, val, 0, + JS_NewInt32(ctx, start), + prop_flags) < 0) { + JS_FreeValue(ctx, val); + goto fail; + } + if (JS_DefinePropertyValueUint32(ctx, val, 1, + JS_NewInt32(ctx, end), + prop_flags) < 0) { JS_FreeValue(ctx, val); goto fail; } } - group_name_ptr += strlen(group_name_ptr) + 1; + if (name && !JS_IsUndefined(indices_groups)) { + val = JS_DupValue(ctx, val); + if (JS_DefinePropertyValueStr(ctx, indices_groups, + name, val, prop_flags) < 0) { + JS_FreeValue(ctx, val); + goto fail; + } + } + if (JS_DefinePropertyValueUint32(ctx, indices, i, val, + prop_flags) < 0) { + goto fail; + } } + + val = JS_UNDEFINED; + if (start != -1) { + val = js_sub_string(ctx, str, start, end); + if (JS_IsException(val)) + goto fail; + } + + if (name) { + if (JS_DefinePropertyValueStr(ctx, groups, name, + JS_DupValue(ctx, val), + prop_flags) < 0) { + JS_FreeValue(ctx, val); + goto fail; + } + } + if (JS_DefinePropertyValueUint32(ctx, obj, i, val, prop_flags) < 0) goto fail; } + + t = groups, groups = JS_UNDEFINED; if (JS_DefinePropertyValue(ctx, obj, JS_ATOM_groups, - groups, prop_flags) < 0) + t, prop_flags) < 0) { goto fail; - if (JS_DefinePropertyValue(ctx, obj, JS_ATOM_index, - JS_NewInt32(ctx, (capture[0] - str_buf) >> shift), prop_flags) < 0) + } + + t = JS_NewInt32(ctx, (capture[0] - str_buf) >> shift); + if (JS_DefinePropertyValue(ctx, obj, JS_ATOM_index, t, prop_flags) < 0) goto fail; - if (JS_DefinePropertyValue(ctx, obj, JS_ATOM_input, str_val, prop_flags) < 0) - goto fail1; + + t = str_val, str_val = JS_UNDEFINED; + if (JS_DefinePropertyValue(ctx, obj, JS_ATOM_input, t, prop_flags) < 0) + goto fail; + + if (!JS_IsUndefined(indices)) { + t = indices_groups, indices_groups = JS_UNDEFINED; + if (JS_DefinePropertyValue(ctx, indices, JS_ATOM_groups, + t, prop_flags) < 0) { + goto fail; + } + t = indices, indices = JS_UNDEFINED; + if (JS_DefinePropertyValue(ctx, obj, JS_ATOM_indices, + t, prop_flags) < 0) { + goto fail; + } + } } - js_free(ctx, capture); - return obj; + ret = obj; + obj = JS_UNDEFINED; fail: - JS_FreeValue(ctx, groups); + JS_FreeValue(ctx, indices_groups); + JS_FreeValue(ctx, indices); JS_FreeValue(ctx, str_val); -fail1: + JS_FreeValue(ctx, groups); JS_FreeValue(ctx, obj); js_free(ctx, capture); - return JS_EXCEPTION; + return ret; } /* delete portions of a string that match a given regex */ @@ -42788,7 +44065,7 @@ static JSValue js_regexp_Symbol_match(JSContext *ctx, JSValueConst this_val, { // [Symbol.match](str) JSValueConst rx = this_val; - JSValue A, S, result, matchStr; + JSValue A, S, flags, result, matchStr; int global, n, fullUnicode, isEmpty; JSString *p; @@ -42796,16 +44073,23 @@ static JSValue js_regexp_Symbol_match(JSContext *ctx, JSValueConst this_val, return JS_ThrowTypeErrorNotAnObject(ctx); A = JS_UNDEFINED; + flags = JS_UNDEFINED; result = JS_UNDEFINED; matchStr = JS_UNDEFINED; S = JS_ToString(ctx, argv[0]); if (JS_IsException(S)) goto exception; - global = JS_ToBoolFree(ctx, JS_GetProperty(ctx, rx, JS_ATOM_global)); - if (global < 0) + flags = JS_GetProperty(ctx, rx, JS_ATOM_flags); + if (JS_IsException(flags)) goto exception; + flags = JS_ToStringFree(ctx, flags); + if (JS_IsException(flags)) + goto exception; + p = JS_VALUE_GET_STRING(flags); + // TODO(bnoordhuis) query 'u' flag the same way? + global = (-1 != string_indexof_char(p, 'g', 0)); if (!global) { A = JS_RegExpExec(ctx, rx, S); } else { @@ -42849,12 +44133,14 @@ static JSValue js_regexp_Symbol_match(JSContext *ctx, JSValueConst this_val, } } JS_FreeValue(ctx, result); + JS_FreeValue(ctx, flags); JS_FreeValue(ctx, S); return A; exception: JS_FreeValue(ctx, A); JS_FreeValue(ctx, result); + JS_FreeValue(ctx, flags); JS_FreeValue(ctx, S); return JS_EXCEPTION; } @@ -43097,8 +44383,8 @@ static JSValue js_regexp_Symbol_replace(JSContext *ctx, JSValueConst this_val, // [Symbol.replace](str, rep) JSValueConst rx = this_val, rep = argv[1]; JSValueConst args[6]; - JSValue str, rep_val, matched, tab, rep_str, namedCaptures, res; - JSString *sp, *rp; + JSValue flags, str, rep_val, matched, tab, rep_str, namedCaptures, res; + JSString *p, *sp, *rp; StringBuffer b_s, *b = &b_s; ValueBuffer v_b, *results = &v_b; int nextSourcePosition, n, j, functionalReplace, is_global, fullUnicode; @@ -43114,6 +44400,7 @@ static JSValue js_regexp_Symbol_replace(JSContext *ctx, JSValueConst this_val, rep_val = JS_UNDEFINED; matched = JS_UNDEFINED; tab = JS_UNDEFINED; + flags = JS_UNDEFINED; rep_str = JS_UNDEFINED; namedCaptures = JS_UNDEFINED; @@ -43130,10 +44417,18 @@ static JSValue js_regexp_Symbol_replace(JSContext *ctx, JSValueConst this_val, goto exception; rp = JS_VALUE_GET_STRING(rep_val); } - fullUnicode = 0; - is_global = JS_ToBoolFree(ctx, JS_GetProperty(ctx, rx, JS_ATOM_global)); - if (is_global < 0) + + flags = JS_GetProperty(ctx, rx, JS_ATOM_flags); + if (JS_IsException(flags)) goto exception; + flags = JS_ToStringFree(ctx, flags); + if (JS_IsException(flags)) + goto exception; + p = JS_VALUE_GET_STRING(flags); + + // TODO(bnoordhuis) query 'u' flag the same way? + fullUnicode = 0; + is_global = (-1 != string_indexof_char(p, 'g', 0)); if (is_global) { fullUnicode = JS_ToBoolFree(ctx, JS_GetProperty(ctx, rx, JS_ATOM_unicode)); if (fullUnicode < 0) @@ -43267,6 +44562,7 @@ done1: value_buffer_free(results); JS_FreeValue(ctx, rep_val); JS_FreeValue(ctx, matched); + JS_FreeValue(ctx, flags); JS_FreeValue(ctx, tab); JS_FreeValue(ctx, rep_str); JS_FreeValue(ctx, namedCaptures); @@ -43467,12 +44763,13 @@ static const JSCFunctionListEntry js_regexp_funcs[] = { static const JSCFunctionListEntry js_regexp_proto_funcs[] = { JS_CGETSET_DEF("flags", js_regexp_get_flags, NULL ), JS_CGETSET_DEF("source", js_regexp_get_source, NULL ), - JS_CGETSET_MAGIC_DEF("global", js_regexp_get_flag, NULL, 1 ), - JS_CGETSET_MAGIC_DEF("ignoreCase", js_regexp_get_flag, NULL, 2 ), - JS_CGETSET_MAGIC_DEF("multiline", js_regexp_get_flag, NULL, 4 ), - JS_CGETSET_MAGIC_DEF("dotAll", js_regexp_get_flag, NULL, 8 ), - JS_CGETSET_MAGIC_DEF("unicode", js_regexp_get_flag, NULL, 16 ), - JS_CGETSET_MAGIC_DEF("sticky", js_regexp_get_flag, NULL, 32 ), + JS_CGETSET_MAGIC_DEF("global", js_regexp_get_flag, NULL, LRE_FLAG_GLOBAL ), + JS_CGETSET_MAGIC_DEF("ignoreCase", js_regexp_get_flag, NULL, LRE_FLAG_IGNORECASE ), + JS_CGETSET_MAGIC_DEF("multiline", js_regexp_get_flag, NULL, LRE_FLAG_MULTILINE ), + JS_CGETSET_MAGIC_DEF("dotAll", js_regexp_get_flag, NULL, LRE_FLAG_DOTALL ), + JS_CGETSET_MAGIC_DEF("unicode", js_regexp_get_flag, NULL, LRE_FLAG_UTF16 ), + JS_CGETSET_MAGIC_DEF("sticky", js_regexp_get_flag, NULL, LRE_FLAG_STICKY ), + JS_CGETSET_MAGIC_DEF("hasIndices", js_regexp_get_flag, NULL, LRE_FLAG_INDICES ), JS_CFUNC_DEF("exec", 1, js_regexp_exec ), JS_CFUNC_DEF("compile", 2, js_regexp_compile ), JS_CFUNC_DEF("test", 1, js_regexp_test ), @@ -43809,10 +45106,8 @@ static JSValue js_json_check(JSContext *ctx, JSONStringifyContext *jsc, JSValue v; JSValueConst args[2]; - if (JS_IsObject(val) -#ifdef CONFIG_BIGNUM - || JS_IsBigInt(ctx, val) /* XXX: probably useless */ -#endif + if (JS_IsObject(val) || + JS_IsBigInt(ctx, val) /* XXX: probably useless */ ) { JSValue f = JS_GetProperty(ctx, val, JS_ATOM_toJSON); if (JS_IsException(f)) @@ -43850,9 +45145,7 @@ static JSValue js_json_check(JSContext *ctx, JSONStringifyContext *jsc, #endif case JS_TAG_BOOL: case JS_TAG_NULL: -#ifdef CONFIG_BIGNUM case JS_TAG_BIG_INT: -#endif case JS_TAG_EXCEPTION: return val; default: @@ -43903,15 +45196,16 @@ static int js_json_to_str(JSContext *ctx, JSONStringifyContext *jsc, ret = string_buffer_concat_value(jsc->b, p->u.object_data); JS_FreeValue(ctx, val); return ret; - } + } else #ifdef CONFIG_BIGNUM - else if (cl == JS_CLASS_BIG_FLOAT) { + if (cl == JS_CLASS_BIG_FLOAT) { return string_buffer_concat_value_free(jsc->b, val); - } else if (cl == JS_CLASS_BIG_INT) { + } else +#endif + if (cl == JS_CLASS_BIG_INT) { JS_ThrowTypeError(ctx, "bigint are forbidden in JSON.stringify"); goto exception; } -#endif v = js_array_includes(ctx, jsc->stack, 1, (JSValueConst *)&val); if (JS_IsException(v)) goto exception; @@ -44041,11 +45335,9 @@ static int js_json_to_str(JSContext *ctx, JSONStringifyContext *jsc, case JS_TAG_NULL: concat_value: return string_buffer_concat_value_free(jsc->b, val); -#ifdef CONFIG_BIGNUM case JS_TAG_BIG_INT: JS_ThrowTypeError(ctx, "bigint are forbidden in JSON.stringify"); goto exception; -#endif default: JS_FreeValue(ctx, val); return 0; @@ -44335,8 +45627,8 @@ static JSValue js_reflect_set(JSContext *ctx, JSValueConst this_val, atom = JS_ValueToAtom(ctx, prop); if (unlikely(atom == JS_ATOM_NULL)) return JS_EXCEPTION; - ret = JS_SetPropertyGeneric(ctx, obj, atom, - JS_DupValue(ctx, val), receiver, 0); + ret = JS_SetPropertyInternal(ctx, obj, atom, + JS_DupValue(ctx, val), receiver, 0); JS_FreeAtom(ctx, atom); if (ret < 0) return JS_EXCEPTION; @@ -44683,9 +45975,9 @@ static int js_proxy_set(JSContext *ctx, JSValueConst obj, JSAtom atom, if (!s) return -1; if (JS_IsUndefined(method)) { - return JS_SetPropertyGeneric(ctx, s->target, atom, - JS_DupValue(ctx, value), receiver, - flags); + return JS_SetPropertyInternal(ctx, s->target, atom, + JS_DupValue(ctx, value), receiver, + flags); } atom_val = JS_AtomToValue(ctx, atom); if (JS_IsException(atom_val)) { @@ -45218,6 +46510,10 @@ static int js_proxy_isArray(JSContext *ctx, JSValueConst obj) JSProxyData *s = JS_GetOpaque(obj, JS_CLASS_PROXY); if (!s) return FALSE; + if (js_check_stack_overflow(ctx->rt, 0)) { + JS_ThrowStackOverflow(ctx); + return -1; + } if (s->is_revoked) { JS_ThrowTypeErrorRevokedProxy(ctx); return -1; @@ -45943,6 +47239,123 @@ static JSValue js_map_forEach(JSContext *ctx, JSValueConst this_val, return JS_UNDEFINED; } +static JSValue js_object_groupBy(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv, int is_map) +{ + JSValueConst cb, args[2]; + JSValue res, iter, next, groups, key, v, prop; + JSAtom key_atom = JS_ATOM_NULL; + int64_t idx; + BOOL done; + + // "is function?" check must be observed before argv[0] is accessed + cb = argv[1]; + if (check_function(ctx, cb)) + return JS_EXCEPTION; + + iter = JS_GetIterator(ctx, argv[0], /*is_async*/FALSE); + if (JS_IsException(iter)) + return JS_EXCEPTION; + + key = JS_UNDEFINED; + key_atom = JS_ATOM_NULL; + v = JS_UNDEFINED; + prop = JS_UNDEFINED; + groups = JS_UNDEFINED; + + next = JS_GetProperty(ctx, iter, JS_ATOM_next); + if (JS_IsException(next)) + goto exception; + + if (is_map) { + groups = js_map_constructor(ctx, JS_UNDEFINED, 0, NULL, 0); + } else { + groups = JS_NewObjectProto(ctx, JS_NULL); + } + if (JS_IsException(groups)) + goto exception; + + for (idx = 0; ; idx++) { + if (idx >= MAX_SAFE_INTEGER) { + JS_ThrowTypeError(ctx, "too many elements"); + goto iterator_close_exception; + } + v = JS_IteratorNext(ctx, iter, next, 0, NULL, &done); + if (JS_IsException(v)) + goto exception; + if (done) + break; // v is JS_UNDEFINED + + args[0] = v; + args[1] = JS_NewInt64(ctx, idx); + key = JS_Call(ctx, cb, ctx->global_obj, 2, args); + if (JS_IsException(key)) + goto iterator_close_exception; + + if (is_map) { + prop = js_map_get(ctx, groups, 1, (JSValueConst *)&key, 0); + } else { + key_atom = JS_ValueToAtom(ctx, key); + JS_FreeValue(ctx, key); + key = JS_UNDEFINED; + if (key_atom == JS_ATOM_NULL) + goto iterator_close_exception; + prop = JS_GetProperty(ctx, groups, key_atom); + } + if (JS_IsException(prop)) + goto exception; + + if (JS_IsUndefined(prop)) { + prop = JS_NewArray(ctx); + if (JS_IsException(prop)) + goto exception; + if (is_map) { + args[0] = key; + args[1] = prop; + res = js_map_set(ctx, groups, 2, args, 0); + if (JS_IsException(res)) + goto exception; + JS_FreeValue(ctx, res); + } else { + prop = JS_DupValue(ctx, prop); + if (JS_DefinePropertyValue(ctx, groups, key_atom, prop, + JS_PROP_C_W_E) < 0) { + goto exception; + } + } + } + res = js_array_push(ctx, prop, 1, (JSValueConst *)&v, /*unshift*/0); + if (JS_IsException(res)) + goto exception; + // res is an int64 + + JS_FreeValue(ctx, prop); + JS_FreeValue(ctx, key); + JS_FreeAtom(ctx, key_atom); + JS_FreeValue(ctx, v); + prop = JS_UNDEFINED; + key = JS_UNDEFINED; + key_atom = JS_ATOM_NULL; + v = JS_UNDEFINED; + } + + JS_FreeValue(ctx, iter); + JS_FreeValue(ctx, next); + return groups; + + iterator_close_exception: + JS_IteratorClose(ctx, iter, TRUE); + exception: + JS_FreeAtom(ctx, key_atom); + JS_FreeValue(ctx, prop); + JS_FreeValue(ctx, key); + JS_FreeValue(ctx, v); + JS_FreeValue(ctx, groups); + JS_FreeValue(ctx, iter); + JS_FreeValue(ctx, next); + return JS_EXCEPTION; +} + static void js_map_finalizer(JSRuntime *rt, JSValue val) { JSObject *p; @@ -46123,6 +47536,7 @@ static JSValue js_map_iterator_next(JSContext *ctx, JSValueConst this_val, } static const JSCFunctionListEntry js_map_funcs[] = { + JS_CFUNC_MAGIC_DEF("groupBy", 2, js_object_groupBy, 1 ), JS_CGETSET_DEF("[Symbol.species]", js_get_this, NULL ), }; @@ -46243,12 +47657,6 @@ static const JSCFunctionListEntry js_generator_proto_funcs[] = { /* Promise */ -typedef enum JSPromiseStateEnum { - JS_PROMISE_PENDING, - JS_PROMISE_FULFILLED, - JS_PROMISE_REJECTED, -} JSPromiseStateEnum; - typedef struct JSPromiseData { JSPromiseStateEnum promise_state; /* 0=fulfill, 1=reject, list of JSPromiseReactionData.link */ @@ -46273,6 +47681,22 @@ typedef struct JSPromiseReactionData { JSValue handler; } JSPromiseReactionData; +JSPromiseStateEnum JS_PromiseState(JSContext *ctx, JSValue promise) +{ + JSPromiseData *s = JS_GetOpaque(promise, JS_CLASS_PROMISE); + if (!s) + return -1; + return s->promise_state; +} + +JSValue JS_PromiseResult(JSContext *ctx, JSValue promise) +{ + JSPromiseData *s = JS_GetOpaque(promise, JS_CLASS_PROMISE); + if (!s) + return JS_UNDEFINED; + return JS_DupValue(ctx, s->promise_result); +} + static int js_create_resolving_functions(JSContext *ctx, JSValue *args, JSValueConst promise); @@ -46718,17 +48142,14 @@ static JSValue js_promise_resolve(JSContext *ctx, JSValueConst this_val, return result_promise; } -#if 0 -static JSValue js_promise___newPromiseCapability(JSContext *ctx, - JSValueConst this_val, - int argc, JSValueConst *argv) +static JSValue js_promise_withResolvers(JSContext *ctx, + JSValueConst this_val, + int argc, JSValueConst *argv) { JSValue result_promise, resolving_funcs[2], obj; - JSValueConst ctor; - ctor = argv[0]; - if (!JS_IsObject(ctor)) + if (!JS_IsObject(this_val)) return JS_ThrowTypeErrorNotAnObject(ctx); - result_promise = js_new_promise_capability(ctx, resolving_funcs, ctor); + result_promise = js_new_promise_capability(ctx, resolving_funcs, this_val); if (JS_IsException(result_promise)) return result_promise; obj = JS_NewObject(ctx); @@ -46743,7 +48164,6 @@ static JSValue js_promise___newPromiseCapability(JSContext *ctx, JS_DefinePropertyValue(ctx, obj, JS_ATOM_reject, resolving_funcs[1], JS_PROP_C_W_E); return obj; } -#endif static __exception int remainingElementsCount_add(JSContext *ctx, JSValueConst resolve_element_env, @@ -47233,7 +48653,7 @@ static const JSCFunctionListEntry js_promise_funcs[] = { JS_CFUNC_MAGIC_DEF("allSettled", 1, js_promise_all, PROMISE_MAGIC_allSettled ), JS_CFUNC_MAGIC_DEF("any", 1, js_promise_all, PROMISE_MAGIC_any ), JS_CFUNC_DEF("race", 1, js_promise_race ), - //JS_CFUNC_DEF("__newPromiseCapability", 1, js_promise___newPromiseCapability ), + JS_CFUNC_DEF("withResolvers", 0, js_promise_withResolvers ), JS_CGETSET_DEF("[Symbol.species]", js_get_this, NULL), }; @@ -47844,12 +49264,6 @@ static const JSCFunctionListEntry js_global_funcs[] = { JS_PROP_DOUBLE_DEF("Infinity", 1.0 / 0.0, 0 ), JS_PROP_DOUBLE_DEF("NaN", NAN, 0 ), JS_PROP_UNDEFINED_DEF("undefined", 0 ), - - /* for the 'Date' implementation */ - JS_CFUNC_DEF("__date_clock", 0, js___date_clock ), - //JS_CFUNC_DEF("__date_now", 0, js___date_now ), - //JS_CFUNC_DEF("__date_getTimezoneOffset", 1, js___date_getTimezoneOffset ), - //JS_CFUNC_DEF("__date_create", 3, js___date_create ), }; /* Date */ @@ -48055,20 +49469,19 @@ static JSValue set_date_field(JSContext *ctx, JSValueConst this_val, res = get_date_fields(ctx, this_val, fields, is_local, first_field == 0); if (res < 0) return JS_EXCEPTION; + + // Argument coercion is observable and must be done unconditionally. + n = min_int(argc, end_field - first_field); + for(i = 0; i < n; i++) { + if (JS_ToFloat64(ctx, &a, argv[i])) + return JS_EXCEPTION; + if (!isfinite(a)) + res = FALSE; + fields[first_field + i] = trunc(a); + } if (res && argc > 0) { - n = end_field - first_field; - if (argc < n) - n = argc; - for(i = 0; i < n; i++) { - if (JS_ToFloat64(ctx, &a, argv[i])) - return JS_EXCEPTION; - if (!isfinite(a)) - goto done; - fields[first_field + i] = trunc(a); - } d = set_date_fields(fields, is_local); } -done: return JS_SetThisTimeValue(ctx, this_val, d); } @@ -48178,7 +49591,7 @@ static JSValue get_date_string(JSContext *ctx, JSValueConst this_val, break; case 3: pos += snprintf(buf + pos, sizeof(buf) - pos, - "%02d:%02d:%02d %cM", (h + 1) % 12 - 1, m, s, + "%02d:%02d:%02d %cM", (h + 11) % 12 + 1, m, s, (h < 12) ? 'A' : 'P'); break; } @@ -48339,8 +49752,11 @@ static int string_get_signed_digits(JSString *sp, int *pp, int64_t *pval) { p++; res = string_get_digits(sp, &p, pval); - if (res == 0 && sgn == '-') + if (res == 0 && sgn == '-') { + if (*pval == 0) + return -1; // reject negative zero *pval = -*pval; + } *pp = p; return res; } @@ -49091,6 +50507,7 @@ void JS_AddIntrinsicOperators(JSContext *ctx) js_operators_set_default(ctx, ctx->class_proto[JS_CLASS_BIG_FLOAT]); js_operators_set_default(ctx, ctx->class_proto[JS_CLASS_BIG_DECIMAL]); } +#endif /* CONFIG_BIGNUM */ /* BigInt */ @@ -49108,11 +50525,17 @@ static JSValue JS_ToBigIntCtorFree(JSContext *ctx, JSValue val) case JS_TAG_BIG_INT: break; case JS_TAG_FLOAT64: +#ifdef CONFIG_BIGNUM case JS_TAG_BIG_FLOAT: +#endif { bf_t *a, a_s; a = JS_ToBigFloat(ctx, &a_s, val); + if (!a) { + JS_FreeValue(ctx, val); + return JS_EXCEPTION; + } if (!bf_is_finite(a)) { JS_FreeValue(ctx, val); val = JS_ThrowRangeError(ctx, "cannot convert NaN or Infinity to bigint"); @@ -49142,11 +50565,13 @@ static JSValue JS_ToBigIntCtorFree(JSContext *ctx, JSValue val) bf_delete(a); } break; +#ifdef CONFIG_BIGNUM case JS_TAG_BIG_DECIMAL: val = JS_ToStringFree(ctx, val); if (JS_IsException(val)) break; goto redo; +#endif case JS_TAG_STRING: val = JS_StringToBigIntErr(ctx, val); break; @@ -49219,6 +50644,7 @@ static JSValue js_bigint_valueOf(JSContext *ctx, JSValueConst this_val, return js_thisBigIntValue(ctx, this_val); } +#ifdef CONFIG_BIGNUM static JSValue js_bigint_div(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic) @@ -49347,6 +50773,7 @@ static JSValue js_bigint_op1(JSContext *ctx, JS_FreeBigInt(ctx, a, &a_s); return JS_NewBigInt64(ctx, res); } +#endif static JSValue js_bigint_asUintN(JSContext *ctx, JSValueConst this_val, @@ -49391,6 +50818,7 @@ static JSValue js_bigint_asUintN(JSContext *ctx, static const JSCFunctionListEntry js_bigint_funcs[] = { JS_CFUNC_MAGIC_DEF("asUintN", 2, js_bigint_asUintN, 0 ), JS_CFUNC_MAGIC_DEF("asIntN", 2, js_bigint_asUintN, 1 ), +#ifdef CONFIG_BIGNUM /* QuickJS extensions */ JS_CFUNC_MAGIC_DEF("tdiv", 2, js_bigint_div, BF_RNDZ ), JS_CFUNC_MAGIC_DEF("fdiv", 2, js_bigint_div, BF_RNDD ), @@ -49404,6 +50832,7 @@ static const JSCFunctionListEntry js_bigint_funcs[] = { JS_CFUNC_MAGIC_DEF("sqrtrem", 1, js_bigint_sqrt, 1 ), JS_CFUNC_MAGIC_DEF("floorLog2", 1, js_bigint_op1, 0 ), JS_CFUNC_MAGIC_DEF("ctz", 1, js_bigint_op1, 1 ), +#endif }; static const JSCFunctionListEntry js_bigint_proto_funcs[] = { @@ -49422,7 +50851,7 @@ void JS_AddIntrinsicBigInt(JSContext *ctx) rt->bigint_ops.unary_arith = js_unary_arith_bigint; rt->bigint_ops.binary_arith = js_binary_arith_bigint; rt->bigint_ops.compare = js_compare_bigfloat; - + ctx->class_proto[JS_CLASS_BIG_INT] = JS_NewObject(ctx); JS_SetPropertyFunctionList(ctx, ctx->class_proto[JS_CLASS_BIG_INT], js_bigint_proto_funcs, @@ -49433,6 +50862,8 @@ void JS_AddIntrinsicBigInt(JSContext *ctx) countof(js_bigint_funcs)); } +#ifdef CONFIG_BIGNUM + /* BigFloat */ static JSValue js_thisBigFloatValue(JSContext *ctx, JSValueConst this_val) @@ -49906,6 +51337,10 @@ static JSValue js_bigfloat_fop(JSContext *ctx, JSValueConst this_val, if (JS_IsException(op1)) return op1; a = JS_ToBigFloat(ctx, &a_s, op1); + if (!a) { + JS_FreeValue(ctx, op1); + return JS_EXCEPTION; + } fe = &ctx->fp_env; if (argc > 1) { fe = JS_GetOpaque2(ctx, argv[1], JS_CLASS_FLOAT_ENV); @@ -50004,7 +51439,11 @@ static JSValue js_bigfloat_fop2(JSContext *ctx, JSValueConst this_val, return op2; } a = JS_ToBigFloat(ctx, &a_s, op1); + if (!a) + goto fail1; b = JS_ToBigFloat(ctx, &b_s, op2); + if (!b) + goto fail2; fe = &ctx->fp_env; if (argc > 2) { fe = JS_GetOpaque2(ctx, argv[2], JS_CLASS_FLOAT_ENV); @@ -50014,10 +51453,12 @@ static JSValue js_bigfloat_fop2(JSContext *ctx, JSValueConst this_val, res = JS_NewBigFloat(ctx); if (JS_IsException(res)) { fail: - if (a == &a_s) - bf_delete(a); if (b == &b_s) bf_delete(b); + fail2: + if (a == &a_s) + bf_delete(a); + fail1: JS_FreeValue(ctx, op1); JS_FreeValue(ctx, op2); return JS_EXCEPTION; @@ -50966,8 +52407,22 @@ void JS_AddIntrinsicBaseObjects(JSContext *ctx) /* XXX: create auto_initializer */ { /* initialize Array.prototype[Symbol.unscopables] */ - char const unscopables[] = "copyWithin" "\0" "entries" "\0" "fill" "\0" "find" "\0" - "findIndex" "\0" "flat" "\0" "flatMap" "\0" "includes" "\0" "keys" "\0" "values" "\0"; + char const unscopables[] = + "copyWithin" "\0" + "entries" "\0" + "fill" "\0" + "find" "\0" + "findIndex" "\0" + "findLast" "\0" + "findLastIndex" "\0" + "flat" "\0" + "flatMap" "\0" + "includes" "\0" + "keys" "\0" + "toReversed" "\0" + "toSorted" "\0" + "toSpliced" "\0" + "values" "\0"; const char *p = unscopables; obj1 = JS_NewObjectProto(ctx, JS_NULL); for(p = unscopables; *p; p += strlen(p) + 1) { @@ -51091,9 +52546,7 @@ void JS_AddIntrinsicBaseObjects(JSContext *ctx) static uint8_t const typed_array_size_log2[JS_TYPED_ARRAY_COUNT] = { 0, 0, 0, 1, 1, 2, 2, -#ifdef CONFIG_BIGNUM 3, 3, /* BigInt64Array, BigUint64Array */ -#endif 2, 3 }; @@ -51223,11 +52676,26 @@ static void js_array_buffer_finalizer(JSRuntime *rt, JSValue val) { JSObject *p = JS_VALUE_GET_OBJ(val); JSArrayBuffer *abuf = p->u.array_buffer; + struct list_head *el, *el1; + if (abuf) { /* The ArrayBuffer finalizer may be called before the typed array finalizers using it, so abuf->array_list is not necessarily empty. */ - // assert(list_empty(&abuf->array_list)); + list_for_each_safe(el, el1, &abuf->array_list) { + JSTypedArray *ta; + JSObject *p1; + + ta = list_entry(el, JSTypedArray, link); + ta->link.prev = NULL; + ta->link.next = NULL; + p1 = ta->obj; + /* Note: the typed array length and offset fields are not modified */ + if (p1->class_id != JS_CLASS_DATAVIEW) { + p1->u.array.count = 0; + p1->u.array.u.ptr = NULL; + } + } if (abuf->shared && rt->sab_funcs.sab_free) { rt->sab_funcs.sab_free(rt->sab_funcs.sab_opaque, abuf->data); } else { @@ -51654,6 +53122,69 @@ fail: return JS_EXCEPTION; } +static JSValue js_typed_array_at(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + JSObject *p; + int64_t idx, len; + + p = get_typed_array(ctx, this_val, 0); + if (!p) + return JS_EXCEPTION; + + if (typed_array_is_detached(ctx, p)) { + JS_ThrowTypeErrorDetachedArrayBuffer(ctx); + return JS_EXCEPTION; + } + + if (JS_ToInt64Sat(ctx, &idx, argv[0])) + return JS_EXCEPTION; + + len = p->u.array.count; + if (idx < 0) + idx = len + idx; + if (idx < 0 || idx >= len) + return JS_UNDEFINED; + return JS_GetPropertyInt64(ctx, this_val, idx); +} + +static JSValue js_typed_array_with(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + JSValue arr, val; + JSObject *p; + int64_t idx, len; + + p = get_typed_array(ctx, this_val, /*is_dataview*/0); + if (!p) + return JS_EXCEPTION; + + if (JS_ToInt64Sat(ctx, &idx, argv[0])) + return JS_EXCEPTION; + + len = p->u.array.count; + if (idx < 0) + idx = len + idx; + if (idx < 0 || idx >= len) + return JS_ThrowRangeError(ctx, "out of bound"); + + val = JS_ToPrimitive(ctx, argv[1], HINT_NUMBER); + if (JS_IsException(val)) + return JS_EXCEPTION; + + arr = js_typed_array_constructor_ta(ctx, JS_UNDEFINED, this_val, + p->class_id); + if (JS_IsException(arr)) { + JS_FreeValue(ctx, val); + return JS_EXCEPTION; + } + if (JS_SetPropertyInt64(ctx, arr, idx, val) < 0) { + JS_FreeValue(ctx, arr); + return JS_EXCEPTION; + } + return arr; +} + static JSValue js_typed_array_set(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) @@ -51943,14 +53474,10 @@ static JSValue js_typed_array_fill(JSContext *ctx, JSValueConst this_val, if (JS_ToUint32(ctx, &v, argv[0])) return JS_EXCEPTION; v64 = v; - } else -#ifdef CONFIG_BIGNUM - if (p->class_id <= JS_CLASS_BIG_UINT64_ARRAY) { + } else if (p->class_id <= JS_CLASS_BIG_UINT64_ARRAY) { if (JS_ToBigInt64(ctx, (int64_t *)&v64, argv[0])) return JS_EXCEPTION; - } else -#endif - { + } else { double d; if (JS_ToFloat64(ctx, &d, argv[0])) return JS_EXCEPTION; @@ -52012,12 +53539,13 @@ static JSValue js_typed_array_fill(JSContext *ctx, JSValueConst this_val, } static JSValue js_typed_array_find(JSContext *ctx, JSValueConst this_val, - int argc, JSValueConst *argv, int findIndex) + int argc, JSValueConst *argv, int mode) { JSValueConst func, this_arg; JSValueConst args[3]; JSValue val, index_val, res; - int len, k; + int len, k, end; + int dir; val = JS_UNDEFINED; len = js_typed_array_get_length_internal(ctx, this_val); @@ -52032,7 +53560,17 @@ static JSValue js_typed_array_find(JSContext *ctx, JSValueConst this_val, if (argc > 1) this_arg = argv[1]; - for(k = 0; k < len; k++) { + if (mode == special_findLast || mode == special_findLastIndex) { + k = len - 1; + dir = -1; + end = -1; + } else { + k = 0; + dir = 1; + end = len; + } + + for(; k != end; k += dir) { index_val = JS_NewInt32(ctx, k); val = JS_GetPropertyValue(ctx, this_val, index_val); if (JS_IsException(val)) @@ -52044,7 +53582,7 @@ static JSValue js_typed_array_find(JSContext *ctx, JSValueConst this_val, if (JS_IsException(res)) goto exception; if (JS_ToBoolFree(ctx, res)) { - if (findIndex) { + if (mode == special_findIndex || mode == special_findLastIndex) { JS_FreeValue(ctx, val); return index_val; } else { @@ -52053,7 +53591,7 @@ static JSValue js_typed_array_find(JSContext *ctx, JSValueConst this_val, } JS_FreeValue(ctx, val); } - if (findIndex) + if (mode == special_findIndex || mode == special_findLastIndex) return JS_NewInt32(ctx, -1); else return JS_UNDEFINED; @@ -52137,9 +53675,7 @@ static JSValue js_typed_array_indexOf(JSContext *ctx, JSValueConst this_val, d = JS_VALUE_GET_FLOAT64(argv[0]); v64 = d; is_int = (v64 == d); - } else -#ifdef CONFIG_BIGNUM - if (tag == JS_TAG_BIG_INT) { + } else if (tag == JS_TAG_BIG_INT) { JSBigFloat *p1 = JS_VALUE_GET_PTR(argv[0]); if (p->class_id == JS_CLASS_BIG_INT64_ARRAY) { @@ -52153,9 +53689,7 @@ static JSValue js_typed_array_indexOf(JSContext *ctx, JSValueConst this_val, } d = 0; is_bigint = 1; - } else -#endif - { + } else { goto done; } @@ -52272,7 +53806,6 @@ static JSValue js_typed_array_indexOf(JSContext *ctx, JSValueConst this_val, } } break; -#ifdef CONFIG_BIGNUM case JS_CLASS_BIG_INT64_ARRAY: if (is_bigint || (is_math_mode(ctx) && is_int && v64 >= -MAX_SAFE_INTEGER && @@ -52296,7 +53829,6 @@ static JSValue js_typed_array_indexOf(JSContext *ctx, JSValueConst this_val, } } break; -#endif } done: @@ -52431,6 +53963,24 @@ static JSValue js_typed_array_reverse(JSContext *ctx, JSValueConst this_val, return JS_DupValue(ctx, this_val); } +static JSValue js_typed_array_toReversed(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + JSValue arr, ret; + JSObject *p; + + p = get_typed_array(ctx, this_val, /*is_dataview*/0); + if (!p) + return JS_EXCEPTION; + arr = js_typed_array_constructor_ta(ctx, JS_UNDEFINED, this_val, + p->class_id); + if (JS_IsException(arr)) + return JS_EXCEPTION; + ret = js_typed_array_reverse(ctx, arr, argc, argv); + JS_FreeValue(ctx, arr); + return ret; +} + static JSValue js_typed_array_slice(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { @@ -52577,7 +54127,6 @@ static int js_TA_cmp_uint32(const void *a, const void *b, void *opaque) { return (y < x) - (y > x); } -#ifdef CONFIG_BIGNUM static int js_TA_cmp_int64(const void *a, const void *b, void *opaque) { int64_t x = *(const int64_t *)a; int64_t y = *(const int64_t *)b; @@ -52589,7 +54138,6 @@ static int js_TA_cmp_uint64(const void *a, const void *b, void *opaque) { uint64_t y = *(const uint64_t *)b; return (y < x) - (y > x); } -#endif static int js_TA_cmp_float32(const void *a, const void *b, void *opaque) { return js_cmp_doubles(*(const float *)a, *(const float *)b); @@ -52623,7 +54171,6 @@ static JSValue js_TA_get_uint32(JSContext *ctx, const void *a) { return JS_NewUint32(ctx, *(const uint32_t *)a); } -#ifdef CONFIG_BIGNUM static JSValue js_TA_get_int64(JSContext *ctx, const void *a) { return JS_NewBigInt64(ctx, *(int64_t *)a); } @@ -52631,7 +54178,6 @@ static JSValue js_TA_get_int64(JSContext *ctx, const void *a) { static JSValue js_TA_get_uint64(JSContext *ctx, const void *a) { return JS_NewBigUint64(ctx, *(uint64_t *)a); } -#endif static JSValue js_TA_get_float32(JSContext *ctx, const void *a) { return __JS_NewFloat64(ctx, *(const float *)a); @@ -52643,7 +54189,7 @@ static JSValue js_TA_get_float64(JSContext *ctx, const void *a) { struct TA_sort_context { JSContext *ctx; - int exception; + int exception; /* 1 = exception, 2 = detached typed array */ JSValueConst arr; JSValueConst cmp; JSValue (*getfun)(JSContext *ctx, const void *a); @@ -52661,6 +54207,8 @@ static int js_TA_cmp_generic(const void *a, const void *b, void *opaque) { cmp = 0; if (!psc->exception) { + /* Note: the typed array can be detached without causing an + error */ a_idx = *(uint32_t *)a; b_idx = *(uint32_t *)b; argv[0] = psc->getfun(ctx, psc->array_ptr + @@ -52688,8 +54236,9 @@ static int js_TA_cmp_generic(const void *a, const void *b, void *opaque) { /* make sort stable: compare array offsets */ cmp = (a_idx > b_idx) - (a_idx < b_idx); } - if (validate_typed_array(ctx, psc->arr) < 0) { - psc->exception = 1; + if (unlikely(typed_array_is_detached(ctx, + JS_VALUE_GET_PTR(psc->arr)))) { + psc->exception = 2; } done: JS_FreeValue(ctx, (JSValue)argv[0]); @@ -52713,11 +54262,11 @@ static JSValue js_typed_array_sort(JSContext *ctx, JSValueConst this_val, tsc.arr = this_val; tsc.cmp = argv[0]; + if (!JS_IsUndefined(tsc.cmp) && check_function(ctx, tsc.cmp)) + return JS_EXCEPTION; len = js_typed_array_get_length_internal(ctx, this_val); if (len < 0) return JS_EXCEPTION; - if (!JS_IsUndefined(tsc.cmp) && check_function(ctx, tsc.cmp)) - return JS_EXCEPTION; if (len > 1) { p = JS_VALUE_GET_OBJ(this_val); @@ -52747,7 +54296,6 @@ static JSValue js_typed_array_sort(JSContext *ctx, JSValueConst this_val, tsc.getfun = js_TA_get_uint32; cmpfun = js_TA_cmp_uint32; break; -#ifdef CONFIG_BIGNUM case JS_CLASS_BIG_INT64_ARRAY: tsc.getfun = js_TA_get_int64; cmpfun = js_TA_cmp_int64; @@ -52756,7 +54304,6 @@ static JSValue js_typed_array_sort(JSContext *ctx, JSValueConst this_val, tsc.getfun = js_TA_get_uint64; cmpfun = js_TA_cmp_uint64; break; -#endif case JS_CLASS_FLOAT32_ARRAY: tsc.getfun = js_TA_get_float32; cmpfun = js_TA_cmp_float32; @@ -52785,44 +54332,48 @@ static JSValue js_typed_array_sort(JSContext *ctx, JSValueConst this_val, tsc.elt_size = elt_size; rqsort(array_idx, len, sizeof(array_idx[0]), js_TA_cmp_generic, &tsc); - if (tsc.exception) - goto fail; - array_tmp = js_malloc(ctx, len * elt_size); - if (!array_tmp) { - fail: - js_free(ctx, array_idx); - return JS_EXCEPTION; + if (tsc.exception) { + if (tsc.exception == 1) + goto fail; + /* detached typed array during the sort: no error */ + } else { + array_tmp = js_malloc(ctx, len * elt_size); + if (!array_tmp) { + fail: + js_free(ctx, array_idx); + return JS_EXCEPTION; + } + memcpy(array_tmp, array_ptr, len * elt_size); + switch(elt_size) { + case 1: + for(i = 0; i < len; i++) { + j = array_idx[i]; + ((uint8_t *)array_ptr)[i] = ((uint8_t *)array_tmp)[j]; + } + break; + case 2: + for(i = 0; i < len; i++) { + j = array_idx[i]; + ((uint16_t *)array_ptr)[i] = ((uint16_t *)array_tmp)[j]; + } + break; + case 4: + for(i = 0; i < len; i++) { + j = array_idx[i]; + ((uint32_t *)array_ptr)[i] = ((uint32_t *)array_tmp)[j]; + } + break; + case 8: + for(i = 0; i < len; i++) { + j = array_idx[i]; + ((uint64_t *)array_ptr)[i] = ((uint64_t *)array_tmp)[j]; + } + break; + default: + abort(); + } + js_free(ctx, array_tmp); } - memcpy(array_tmp, array_ptr, len * elt_size); - switch(elt_size) { - case 1: - for(i = 0; i < len; i++) { - j = array_idx[i]; - ((uint8_t *)array_ptr)[i] = ((uint8_t *)array_tmp)[j]; - } - break; - case 2: - for(i = 0; i < len; i++) { - j = array_idx[i]; - ((uint16_t *)array_ptr)[i] = ((uint16_t *)array_tmp)[j]; - } - break; - case 4: - for(i = 0; i < len; i++) { - j = array_idx[i]; - ((uint32_t *)array_ptr)[i] = ((uint32_t *)array_tmp)[j]; - } - break; - case 8: - for(i = 0; i < len; i++) { - j = array_idx[i]; - ((uint64_t *)array_ptr)[i] = ((uint64_t *)array_tmp)[j]; - } - break; - default: - abort(); - } - js_free(ctx, array_tmp); js_free(ctx, array_idx); } else { rqsort(array_ptr, len, elt_size, cmpfun, &tsc); @@ -52833,6 +54384,24 @@ static JSValue js_typed_array_sort(JSContext *ctx, JSValueConst this_val, return JS_DupValue(ctx, this_val); } +static JSValue js_typed_array_toSorted(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv) +{ + JSValue arr, ret; + JSObject *p; + + p = get_typed_array(ctx, this_val, /*is_dataview*/0); + if (!p) + return JS_EXCEPTION; + arr = js_typed_array_constructor_ta(ctx, JS_UNDEFINED, this_val, + p->class_id); + if (JS_IsException(arr)) + return JS_EXCEPTION; + ret = js_typed_array_sort(ctx, arr, argc, argv); + JS_FreeValue(ctx, arr); + return ret; +} + static const JSCFunctionListEntry js_typed_array_base_funcs[] = { JS_CFUNC_DEF("from", 1, js_typed_array_from ), JS_CFUNC_DEF("of", 0, js_typed_array_of ), @@ -52844,6 +54413,8 @@ static const JSCFunctionListEntry js_typed_array_base_funcs[] = { static const JSCFunctionListEntry js_typed_array_base_proto_funcs[] = { JS_CGETSET_DEF("length", js_typed_array_get_length, NULL ), + JS_CFUNC_DEF("at", 1, js_typed_array_at ), + JS_CFUNC_DEF("with", 2, js_typed_array_with ), JS_CGETSET_MAGIC_DEF("buffer", js_typed_array_get_buffer, NULL, 0 ), JS_CGETSET_MAGIC_DEF("byteLength", js_typed_array_get_byteLength, NULL, 0 ), JS_CGETSET_MAGIC_DEF("byteOffset", js_typed_array_get_byteOffset, NULL, 0 ), @@ -52862,12 +54433,16 @@ static const JSCFunctionListEntry js_typed_array_base_proto_funcs[] = { JS_CFUNC_MAGIC_DEF("reduce", 1, js_array_reduce, special_reduce | special_TA ), JS_CFUNC_MAGIC_DEF("reduceRight", 1, js_array_reduce, special_reduceRight | special_TA ), JS_CFUNC_DEF("fill", 1, js_typed_array_fill ), - JS_CFUNC_MAGIC_DEF("find", 1, js_typed_array_find, 0 ), - JS_CFUNC_MAGIC_DEF("findIndex", 1, js_typed_array_find, 1 ), + JS_CFUNC_MAGIC_DEF("find", 1, js_typed_array_find, special_find ), + JS_CFUNC_MAGIC_DEF("findIndex", 1, js_typed_array_find, special_findIndex ), + JS_CFUNC_MAGIC_DEF("findLast", 1, js_typed_array_find, special_findLast ), + JS_CFUNC_MAGIC_DEF("findLastIndex", 1, js_typed_array_find, special_findLastIndex ), JS_CFUNC_DEF("reverse", 0, js_typed_array_reverse ), + JS_CFUNC_DEF("toReversed", 0, js_typed_array_toReversed ), JS_CFUNC_DEF("slice", 2, js_typed_array_slice ), JS_CFUNC_DEF("subarray", 2, js_typed_array_subarray ), JS_CFUNC_DEF("sort", 1, js_typed_array_sort ), + JS_CFUNC_DEF("toSorted", 1, js_typed_array_toSorted ), JS_CFUNC_MAGIC_DEF("join", 1, js_typed_array_join, 0 ), JS_CFUNC_MAGIC_DEF("toLocaleString", 0, js_typed_array_join, 1 ), JS_CFUNC_MAGIC_DEF("indexOf", 1, js_typed_array_indexOf, special_indexOf ), @@ -53014,7 +54589,7 @@ static JSValue js_typed_array_constructor_ta(JSContext *ctx, { JSObject *p, *src_buffer; JSTypedArray *ta; - JSValue ctor, obj, buffer; + JSValue obj, buffer; uint32_t len, i; int size_log2; JSArrayBuffer *src_abuf, *abuf; @@ -53031,19 +54606,9 @@ static JSValue js_typed_array_constructor_ta(JSContext *ctx, len = p->u.array.count; src_buffer = ta->buffer; src_abuf = src_buffer->u.array_buffer; - if (!src_abuf->shared) { - ctor = JS_SpeciesConstructor(ctx, JS_MKPTR(JS_TAG_OBJECT, src_buffer), - JS_UNDEFINED); - if (JS_IsException(ctor)) - goto fail; - } else { - /* force ArrayBuffer default constructor */ - ctor = JS_UNDEFINED; - } size_log2 = typed_array_size_log2(classid); - buffer = js_array_buffer_constructor1(ctx, ctor, + buffer = js_array_buffer_constructor1(ctx, JS_UNDEFINED, (uint64_t)len << size_log2); - JS_FreeValue(ctx, ctor); if (JS_IsException(buffer)) goto fail; /* necessary because it could have been detached */ @@ -53149,7 +54714,7 @@ static void js_typed_array_finalizer(JSRuntime *rt, JSValue val) if (ta) { /* during the GC the finalizers are called in an arbitrary order so the ArrayBuffer finalizer may have been called */ - if (JS_IsLiveObject(rt, JS_MKPTR(JS_TAG_OBJECT, ta->buffer))) { + if (ta->link.next) { list_del(&ta->link); } JS_FreeValueRT(rt, JS_MKPTR(JS_TAG_OBJECT, ta->buffer)); @@ -53281,7 +54846,6 @@ static JSValue js_dataview_getValue(JSContext *ctx, if (is_swap) v = bswap32(v); return JS_NewUint32(ctx, v); -#ifdef CONFIG_BIGNUM case JS_CLASS_BIG_INT64_ARRAY: { uint64_t v; @@ -53300,7 +54864,6 @@ static JSValue js_dataview_getValue(JSContext *ctx, return JS_NewBigUint64(ctx, v); } break; -#endif case JS_CLASS_FLOAT32_ARRAY: { union { @@ -53354,14 +54917,10 @@ static JSValue js_dataview_setValue(JSContext *ctx, if (class_id <= JS_CLASS_UINT32_ARRAY) { if (JS_ToUint32(ctx, &v, val)) return JS_EXCEPTION; - } else -#ifdef CONFIG_BIGNUM - if (class_id <= JS_CLASS_BIG_UINT64_ARRAY) { + } else if (class_id <= JS_CLASS_BIG_UINT64_ARRAY) { if (JS_ToBigInt64(ctx, (int64_t *)&v64, val)) return JS_EXCEPTION; - } else -#endif - { + } else { double d; if (JS_ToFloat64(ctx, &d, val)) return JS_EXCEPTION; @@ -53409,10 +54968,8 @@ static JSValue js_dataview_setValue(JSContext *ctx, v = bswap32(v); put_u32(ptr, v); break; -#ifdef CONFIG_BIGNUM case JS_CLASS_BIG_INT64_ARRAY: case JS_CLASS_BIG_UINT64_ARRAY: -#endif case JS_CLASS_FLOAT64_ARRAY: if (is_swap) v64 = bswap64(v64); @@ -53434,10 +54991,8 @@ static const JSCFunctionListEntry js_dataview_proto_funcs[] = { JS_CFUNC_MAGIC_DEF("getUint16", 1, js_dataview_getValue, JS_CLASS_UINT16_ARRAY ), JS_CFUNC_MAGIC_DEF("getInt32", 1, js_dataview_getValue, JS_CLASS_INT32_ARRAY ), JS_CFUNC_MAGIC_DEF("getUint32", 1, js_dataview_getValue, JS_CLASS_UINT32_ARRAY ), -#ifdef CONFIG_BIGNUM JS_CFUNC_MAGIC_DEF("getBigInt64", 1, js_dataview_getValue, JS_CLASS_BIG_INT64_ARRAY ), JS_CFUNC_MAGIC_DEF("getBigUint64", 1, js_dataview_getValue, JS_CLASS_BIG_UINT64_ARRAY ), -#endif JS_CFUNC_MAGIC_DEF("getFloat32", 1, js_dataview_getValue, JS_CLASS_FLOAT32_ARRAY ), JS_CFUNC_MAGIC_DEF("getFloat64", 1, js_dataview_getValue, JS_CLASS_FLOAT64_ARRAY ), JS_CFUNC_MAGIC_DEF("setInt8", 2, js_dataview_setValue, JS_CLASS_INT8_ARRAY ), @@ -53446,10 +55001,8 @@ static const JSCFunctionListEntry js_dataview_proto_funcs[] = { JS_CFUNC_MAGIC_DEF("setUint16", 2, js_dataview_setValue, JS_CLASS_UINT16_ARRAY ), JS_CFUNC_MAGIC_DEF("setInt32", 2, js_dataview_setValue, JS_CLASS_INT32_ARRAY ), JS_CFUNC_MAGIC_DEF("setUint32", 2, js_dataview_setValue, JS_CLASS_UINT32_ARRAY ), -#ifdef CONFIG_BIGNUM JS_CFUNC_MAGIC_DEF("setBigInt64", 2, js_dataview_setValue, JS_CLASS_BIG_INT64_ARRAY ), JS_CFUNC_MAGIC_DEF("setBigUint64", 2, js_dataview_setValue, JS_CLASS_BIG_UINT64_ARRAY ), -#endif JS_CFUNC_MAGIC_DEF("setFloat32", 2, js_dataview_setValue, JS_CLASS_FLOAT32_ARRAY ), JS_CFUNC_MAGIC_DEF("setFloat64", 2, js_dataview_setValue, JS_CLASS_FLOAT64_ARRAY ), JS_PROP_STRING_DEF("[Symbol.toStringTag]", "DataView", JS_PROP_CONFIGURABLE ), @@ -53486,20 +55039,12 @@ static void *js_atomics_get_ptr(JSContext *ctx, if (JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT) goto fail; p = JS_VALUE_GET_OBJ(obj); -#ifdef CONFIG_BIGNUM if (is_waitable) err = (p->class_id != JS_CLASS_INT32_ARRAY && p->class_id != JS_CLASS_BIG_INT64_ARRAY); else err = !(p->class_id >= JS_CLASS_INT8_ARRAY && p->class_id <= JS_CLASS_BIG_UINT64_ARRAY); -#else - if (is_waitable) - err = (p->class_id != JS_CLASS_INT32_ARRAY); - else - err = !(p->class_id >= JS_CLASS_INT8_ARRAY && - p->class_id <= JS_CLASS_UINT32_ARRAY); -#endif if (err) { fail: JS_ThrowTypeError(ctx, "integer TypedArray expected"); @@ -53541,11 +55086,7 @@ static JSValue js_atomics_op(JSContext *ctx, int argc, JSValueConst *argv, int op) { int size_log2; -#ifdef CONFIG_BIGNUM uint64_t v, a, rep_val; -#else - uint32_t v, a, rep_val; -#endif void *ptr; JSValue ret; JSClassID class_id; @@ -53559,7 +55100,6 @@ static JSValue js_atomics_op(JSContext *ctx, if (op == ATOMICS_OP_LOAD) { v = 0; } else { -#ifdef CONFIG_BIGNUM if (size_log2 == 3) { int64_t v64; if (JS_ToBigInt64(ctx, &v64, argv[2])) @@ -53570,9 +55110,7 @@ static JSValue js_atomics_op(JSContext *ctx, return JS_EXCEPTION; rep_val = v64; } - } else -#endif - { + } else { uint32_t v32; if (JS_ToUint32(ctx, &v32, argv[2])) return JS_EXCEPTION; @@ -53589,7 +55127,6 @@ static JSValue js_atomics_op(JSContext *ctx, switch(op | (size_log2 << 3)) { -#ifdef CONFIG_BIGNUM #define OP(op_name, func_name) \ case ATOMICS_OP_ ## op_name | (0 << 3): \ a = func_name((_Atomic(uint8_t) *)ptr, v); \ @@ -53603,18 +55140,7 @@ static JSValue js_atomics_op(JSContext *ctx, case ATOMICS_OP_ ## op_name | (3 << 3): \ a = func_name((_Atomic(uint64_t) *)ptr, v); \ break; -#else -#define OP(op_name, func_name) \ - case ATOMICS_OP_ ## op_name | (0 << 3): \ - a = func_name((_Atomic(uint8_t) *)ptr, v); \ - break; \ - case ATOMICS_OP_ ## op_name | (1 << 3): \ - a = func_name((_Atomic(uint16_t) *)ptr, v); \ - break; \ - case ATOMICS_OP_ ## op_name | (2 << 3): \ - a = func_name((_Atomic(uint32_t) *)ptr, v); \ - break; -#endif + OP(ADD, atomic_fetch_add) OP(AND, atomic_fetch_and) OP(OR, atomic_fetch_or) @@ -53632,11 +55158,9 @@ static JSValue js_atomics_op(JSContext *ctx, case ATOMICS_OP_LOAD | (2 << 3): a = atomic_load((_Atomic(uint32_t) *)ptr); break; -#ifdef CONFIG_BIGNUM case ATOMICS_OP_LOAD | (3 << 3): a = atomic_load((_Atomic(uint64_t) *)ptr); break; -#endif case ATOMICS_OP_COMPARE_EXCHANGE | (0 << 3): { @@ -53659,7 +55183,6 @@ static JSValue js_atomics_op(JSContext *ctx, a = v1; } break; -#ifdef CONFIG_BIGNUM case ATOMICS_OP_COMPARE_EXCHANGE | (3 << 3): { uint64_t v1 = v; @@ -53667,7 +55190,6 @@ static JSValue js_atomics_op(JSContext *ctx, a = v1; } break; -#endif default: abort(); } @@ -53692,14 +55214,12 @@ static JSValue js_atomics_op(JSContext *ctx, case JS_CLASS_UINT32_ARRAY: ret = JS_NewUint32(ctx, a); break; -#ifdef CONFIG_BIGNUM case JS_CLASS_BIG_INT64_ARRAY: ret = JS_NewBigInt64(ctx, a); break; case JS_CLASS_BIG_UINT64_ARRAY: ret = JS_NewBigUint64(ctx, a); break; -#endif default: abort(); } @@ -53719,7 +55239,6 @@ static JSValue js_atomics_store(JSContext *ctx, argv[0], argv[1], 0); if (!ptr) return JS_EXCEPTION; -#ifdef CONFIG_BIGNUM if (size_log2 == 3) { int64_t v64; ret = JS_ToBigIntValueFree(ctx, JS_DupValue(ctx, argv[2])); @@ -53732,9 +55251,7 @@ static JSValue js_atomics_store(JSContext *ctx, if (abuf->detached) return JS_ThrowTypeErrorDetachedArrayBuffer(ctx); atomic_store((_Atomic(uint64_t) *)ptr, v64); - } else -#endif - { + } else { uint32_t v; /* XXX: spec, would be simpler to return the written value */ ret = JS_ToIntegerFree(ctx, JS_DupValue(ctx, argv[2])); @@ -53770,11 +55287,7 @@ static JSValue js_atomics_isLockFree(JSContext *ctx, int v, ret; if (JS_ToInt32Sat(ctx, &v, argv[0])) return JS_EXCEPTION; - ret = (v == 1 || v == 2 || v == 4 -#ifdef CONFIG_BIGNUM - || v == 8 -#endif - ); + ret = (v == 1 || v == 2 || v == 4 || v == 8); return JS_NewBool(ctx, ret); } @@ -53806,13 +55319,10 @@ static JSValue js_atomics_wait(JSContext *ctx, argv[0], argv[1], 2); if (!ptr) return JS_EXCEPTION; -#ifdef CONFIG_BIGNUM if (size_log2 == 3) { if (JS_ToBigInt64(ctx, &v, argv[2])) return JS_EXCEPTION; - } else -#endif - { + } else { if (JS_ToInt32(ctx, &v32, argv[2])) return JS_EXCEPTION; v = v32; diff --git a/libquickjs-sys/embed/quickjs/quickjs.h b/libquickjs-sys/embed/quickjs/quickjs.h index d4a5cd3..700ee61 100644 --- a/libquickjs-sys/embed/quickjs/quickjs.h +++ b/libquickjs-sys/embed/quickjs/quickjs.h @@ -307,6 +307,9 @@ static inline JS_BOOL JS_VALUE_IS_NAN(JSValue v) #define JS_EVAL_FLAG_COMPILE_ONLY (1 << 5) /* don't include the stack frames before this eval in the Error() backtraces */ #define JS_EVAL_FLAG_BACKTRACE_BARRIER (1 << 6) +/* allow top-level await in normal script. JS_Eval() returns a + promise. Only allowed with JS_EVAL_TYPE_GLOBAL */ +#define JS_EVAL_FLAG_ASYNC (1 << 7) typedef JSValue JSCFunction(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv); typedef JSValue JSCFunctionMagic(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic); @@ -733,13 +736,13 @@ JSValue JS_GetPropertyStr(JSContext *ctx, JSValueConst this_obj, JSValue JS_GetPropertyUint32(JSContext *ctx, JSValueConst this_obj, uint32_t idx); -int JS_SetPropertyInternal(JSContext *ctx, JSValueConst this_obj, - JSAtom prop, JSValue val, +int JS_SetPropertyInternal(JSContext *ctx, JSValueConst obj, + JSAtom prop, JSValue val, JSValueConst this_obj, int flags); static inline int JS_SetProperty(JSContext *ctx, JSValueConst this_obj, JSAtom prop, JSValue val) { - return JS_SetPropertyInternal(ctx, this_obj, prop, val, JS_PROP_THROW); + return JS_SetPropertyInternal(ctx, this_obj, prop, val, this_obj, JS_PROP_THROW); } int JS_SetPropertyUint32(JSContext *ctx, JSValueConst this_obj, uint32_t idx, JSValue val); @@ -831,7 +834,15 @@ typedef struct { void JS_SetSharedArrayBufferFunctions(JSRuntime *rt, const JSSharedArrayBufferFunctions *sf); +typedef enum JSPromiseStateEnum { + JS_PROMISE_PENDING, + JS_PROMISE_FULFILLED, + JS_PROMISE_REJECTED, +} JSPromiseStateEnum; + JSValue JS_NewPromiseCapability(JSContext *ctx, JSValue *resolving_funcs); +JSPromiseStateEnum JS_PromiseState(JSContext *ctx, JSValue promise); +JSValue JS_PromiseResult(JSContext *ctx, JSValue promise); /* is_handled = TRUE means that the rejection is handled */ typedef void JSHostPromiseRejectionTracker(JSContext *ctx, JSValueConst promise, @@ -902,8 +913,8 @@ int JS_ResolveModule(JSContext *ctx, JSValueConst obj); /* only exported for os.Worker() */ JSAtom JS_GetScriptOrModuleName(JSContext *ctx, int n_stack_levels); /* only exported for os.Worker() */ -JSModuleDef *JS_RunModule(JSContext *ctx, const char *basename, - const char *filename); +JSValue JS_LoadModule(JSContext *ctx, const char *basename, + const char *filename); /* C function definition */ typedef enum JSCFunctionEnum { /* XXX: should rename for namespace isolation */ diff --git a/libquickjs-sys/embed/quickjs/unicode_gen.c b/libquickjs-sys/embed/quickjs/unicode_gen.c index f18aaa0..54da2c1 100644 --- a/libquickjs-sys/embed/quickjs/unicode_gen.c +++ b/libquickjs-sys/embed/quickjs/unicode_gen.c @@ -42,6 +42,7 @@ //#define DUMP_TABLE_SIZE //#define DUMP_CC_TABLE //#define DUMP_DECOMP_TABLE +//#define DUMP_CASE_FOLDING_SPECIAL_CASES /* Ideas: - Generalize run length encoding + index for all tables @@ -217,15 +218,16 @@ static const char *unicode_prop_short_name[] = { #undef DEF }; -#undef UNICODE_SPROP_LIST +#undef UNICODE_PROP_LIST typedef struct { /* case conv */ uint8_t u_len; uint8_t l_len; - int u_data[CC_LEN_MAX]; - int l_data[CC_LEN_MAX]; - int f_code; + uint8_t f_len; + int u_data[CC_LEN_MAX]; /* to upper case */ + int l_data[CC_LEN_MAX]; /* to lower case */ + int f_data[CC_LEN_MAX]; /* to case folding */ uint8_t combining_class; uint8_t is_compat:1; @@ -499,7 +501,7 @@ void parse_case_folding(CCInfo *tab, const char *filename) FILE *f; char line[1024]; const char *p; - int code; + int code, status; CCInfo *ci; f = fopen(filename, "rb"); @@ -530,14 +532,28 @@ void parse_case_folding(CCInfo *tab, const char *filename) /* locale dependent casing */ while (isspace(*p)) p++; - if (*p != 'C' && *p != 'S') + status = *p; + if (status != 'C' && status != 'S' && status != 'F') continue; p = get_field(line, 2); - assert(p != 0); - assert(ci->f_code == 0); - ci->f_code = strtoul(p, NULL, 16); - assert(ci->f_code != 0 && ci->f_code != code); + assert(p != NULL); + if (status == 'S') { + /* we always select the simple case folding and assume it + * comes after the full case folding case */ + assert(ci->f_len >= 2); + ci->f_len = 0; + } else { + assert(ci->f_len == 0); + } + for(;;) { + while (isspace(*p)) + p++; + if (*p == ';') + break; + assert(ci->l_len < CC_LEN_MAX); + ci->f_data[ci->f_len++] = strtoul(p, (char **)&p, 16); + } } fclose(f); @@ -864,19 +880,21 @@ void dump_cc_info(CCInfo *ci, int i) for(j = 0; j < ci->l_len; j++) printf(" %05x", ci->l_data[j]); } - if (ci->f_code != 0) { - printf(" F: %05x", ci->f_code); + if (ci->f_len != 0) { + printf(" F:"); + for(j = 0; j < ci->f_len; j++) + printf(" %05x", ci->f_data[j]); } printf("\n"); } -void dump_data(CCInfo *tab) +void dump_unicode_data(CCInfo *tab) { int i; CCInfo *ci; for(i = 0; i <= CHARCODE_MAX; i++) { ci = &tab[i]; - if (ci->u_len != 0 || ci->l_len != 0 || ci->f_code != 0) { + if (ci->u_len != 0 || ci->l_len != 0 || ci->f_len != 0) { dump_cc_info(ci, i); } } @@ -886,8 +904,8 @@ BOOL is_complicated_case(const CCInfo *ci) { return (ci->u_len > 1 || ci->l_len > 1 || (ci->u_len > 0 && ci->l_len > 0) || - (ci->f_code != 0) != ci->l_len || - (ci->f_code != 0 && ci->l_data[0] != ci->f_code)); + (ci->f_len != ci->l_len) || + (memcmp(ci->f_data, ci->l_data, ci->f_len * sizeof(ci->f_data[0])) != 0)); } #ifndef USE_TEST @@ -903,9 +921,9 @@ enum { RUN_TYPE_UF_D1_EXT, RUN_TYPE_U_EXT, RUN_TYPE_LF_EXT, - RUN_TYPE_U_EXT2, - RUN_TYPE_L_EXT2, - RUN_TYPE_U_EXT3, + RUN_TYPE_UF_EXT2, + RUN_TYPE_LF_EXT2, + RUN_TYPE_UF_EXT3, }; #endif @@ -921,9 +939,9 @@ const char *run_type_str[] = { "UF_D1_EXT", "U_EXT", "LF_EXT", - "U_EXT2", - "L_EXT2", - "U_EXT3", + "UF_EXT2", + "LF_EXT2", + "UF_EXT3", }; typedef struct { @@ -936,6 +954,13 @@ typedef struct { int data_index; /* 'data' coming from the table */ } TableEntry; +static int simple_to_lower(CCInfo *tab, int c) +{ + if (tab[c].l_len != 1) + return c; + return tab[c].l_data[0]; +} + /* code (17), len (7), type (4) */ void find_run_type(TableEntry *te, CCInfo *tab, int code) @@ -949,15 +974,15 @@ void find_run_type(TableEntry *te, CCInfo *tab, int code) te->code = code; if (ci->l_len == 1 && ci->l_data[0] == code + 2 && - ci->f_code == ci->l_data[0] && + ci->f_len == 1 && ci->f_data[0] == ci->l_data[0] && ci->u_len == 0 && ci1->l_len == 1 && ci1->l_data[0] == code + 2 && - ci1->f_code == ci1->l_data[0] && + ci1->f_len == 1 && ci1->f_data[0] == ci1->l_data[0] && ci1->u_len == 1 && ci1->u_data[0] == code && ci2->l_len == 0 && - ci2->f_code == 0 && + ci2->f_len == 0 && ci2->u_len == 1 && ci2->u_data[0] == code) { te->len = 3; te->data = 0; @@ -972,7 +997,7 @@ void find_run_type(TableEntry *te, CCInfo *tab, int code) if (ci1->u_len != 1 || ci1->u_data[0] != ci->u_data[0] + len || ci1->l_len != 0 || - ci1->f_code != ci1->u_data[0]) + ci1->f_len != 1 || ci1->f_data[0] != ci1->u_data[0]) break; len++; } @@ -983,21 +1008,25 @@ void find_run_type(TableEntry *te, CCInfo *tab, int code) return; } - if (ci->u_len == 2 && ci->u_data[1] == 0x399 && - ci->f_code == 0 && ci->l_len == 0) { + if (ci->l_len == 0 && + ci->u_len == 2 && ci->u_data[1] == 0x399 && + ci->f_len == 2 && ci->f_data[1] == 0x3B9 && + ci->f_data[0] == simple_to_lower(tab, ci->u_data[0])) { len = 1; while (code + len <= CHARCODE_MAX) { ci1 = &tab[code + len]; if (!(ci1->u_len == 2 && - ci1->u_data[1] == 0x399 && + ci1->u_data[1] == ci->u_data[1] && ci1->u_data[0] == ci->u_data[0] + len && - ci1->f_code == 0 && + ci1->f_len == 2 && + ci1->f_data[1] == ci->f_data[1] && + ci1->f_data[0] == ci->f_data[0] + len && ci1->l_len == 0)) break; len++; } te->len = len; - te->type = RUN_TYPE_U_EXT2; + te->type = RUN_TYPE_UF_EXT2; te->ext_data[0] = ci->u_data[0]; te->ext_data[1] = ci->u_data[1]; te->ext_len = 2; @@ -1005,7 +1034,8 @@ void find_run_type(TableEntry *te, CCInfo *tab, int code) } if (ci->u_len == 2 && ci->u_data[1] == 0x399 && - ci->l_len == 1 && ci->f_code == ci->l_data[0]) { + ci->l_len == 1 && + ci->f_len == 1 && ci->f_data[0] == ci->l_data[0]) { len = 1; while (code + len <= CHARCODE_MAX) { ci1 = &tab[code + len]; @@ -1014,7 +1044,7 @@ void find_run_type(TableEntry *te, CCInfo *tab, int code) ci1->u_data[0] == ci->u_data[0] + len && ci1->l_len == 1 && ci1->l_data[0] == ci->l_data[0] + len && - ci1->f_code == ci1->l_data[0])) + ci1->f_len == 1 && ci1->f_data[0] == ci1->l_data[0])) break; len++; } @@ -1026,13 +1056,13 @@ void find_run_type(TableEntry *te, CCInfo *tab, int code) return; } - if (ci->l_len == 1 && ci->u_len == 0 && ci->f_code == 0) { + if (ci->l_len == 1 && ci->u_len == 0 && ci->f_len == 0) { len = 1; while (code + len <= CHARCODE_MAX) { ci1 = &tab[code + len]; if (!(ci1->l_len == 1 && ci1->l_data[0] == ci->l_data[0] + len && - ci1->u_len == 0 && ci1->f_code == 0)) + ci1->u_len == 0 && ci1->f_len == 0)) break; len++; } @@ -1045,32 +1075,39 @@ void find_run_type(TableEntry *te, CCInfo *tab, int code) if (ci->l_len == 0 && ci->u_len == 1 && ci->u_data[0] < 0x1000 && - ci->f_code == ci->u_data[0] + 0x20) { + ci->f_len == 1 && ci->f_data[0] == ci->u_data[0] + 0x20) { te->len = 1; te->type = RUN_TYPE_UF_D20; te->data = ci->u_data[0]; } else if (ci->l_len == 0 && - ci->u_len == 1 && - ci->f_code == ci->u_data[0] + 1) { + ci->u_len == 1 && + ci->f_len == 1 && ci->f_data[0] == ci->u_data[0] + 1) { te->len = 1; te->type = RUN_TYPE_UF_D1_EXT; te->ext_data[0] = ci->u_data[0]; te->ext_len = 1; - } else if (ci->l_len == 2 && ci->u_len == 0 && ci->f_code == 0) { + } else if (ci->l_len == 2 && ci->u_len == 0 && ci->f_len == 2 && + ci->l_data[0] == ci->f_data[0] && + ci->l_data[1] == ci->f_data[1]) { te->len = 1; - te->type = RUN_TYPE_L_EXT2; + te->type = RUN_TYPE_LF_EXT2; te->ext_data[0] = ci->l_data[0]; te->ext_data[1] = ci->l_data[1]; te->ext_len = 2; - } else if (ci->u_len == 2 && ci->l_len == 0 && ci->f_code == 0) { + } else if (ci->u_len == 2 && ci->l_len == 0 && ci->f_len == 2 && + ci->f_data[0] == simple_to_lower(tab, ci->u_data[0]) && + ci->f_data[1] == simple_to_lower(tab, ci->u_data[1])) { te->len = 1; - te->type = RUN_TYPE_U_EXT2; + te->type = RUN_TYPE_UF_EXT2; te->ext_data[0] = ci->u_data[0]; te->ext_data[1] = ci->u_data[1]; te->ext_len = 2; - } else if (ci->u_len == 3 && ci->l_len == 0 && ci->f_code == 0) { + } else if (ci->u_len == 3 && ci->l_len == 0 && ci->f_len == 3 && + ci->f_data[0] == simple_to_lower(tab, ci->u_data[0]) && + ci->f_data[1] == simple_to_lower(tab, ci->u_data[1]) && + ci->f_data[2] == simple_to_lower(tab, ci->u_data[2])) { te->len = 1; - te->type = RUN_TYPE_U_EXT3; + te->type = RUN_TYPE_UF_EXT3; te->ext_data[0] = ci->u_data[0]; te->ext_data[1] = ci->u_data[1]; te->ext_data[2] = ci->u_data[2]; @@ -1188,7 +1225,7 @@ void build_conv_table(CCInfo *tab) te = conv_table; for(code = 0; code <= CHARCODE_MAX; code++) { ci = &tab[code]; - if (ci->u_len == 0 && ci->l_len == 0 && ci->f_code == 0) + if (ci->u_len == 0 && ci->l_len == 0 && ci->f_len == 0) continue; assert(te - conv_table < countof(conv_table)); find_run_type(te, tab, code); @@ -1244,7 +1281,7 @@ void build_conv_table(CCInfo *tab) /* find the data index for ext_data */ for(i = 0; i < conv_table_len; i++) { te = &conv_table[i]; - if (te->type == RUN_TYPE_U_EXT3) { + if (te->type == RUN_TYPE_UF_EXT3) { int p, v; v = 0; for(j = 0; j < 3; j++) { @@ -1258,8 +1295,8 @@ void build_conv_table(CCInfo *tab) for(i = 0; i < conv_table_len; i++) { te = &conv_table[i]; - if (te->type == RUN_TYPE_L_EXT2 || - te->type == RUN_TYPE_U_EXT2 || + if (te->type == RUN_TYPE_LF_EXT2 || + te->type == RUN_TYPE_UF_EXT2 || te->type == RUN_TYPE_U2L_399_EXT2) { int p, v; v = 0; @@ -1322,6 +1359,54 @@ void dump_case_conv_table(FILE *f) fprintf(f, "\n};\n\n"); } + +static CCInfo *global_tab; + +static int sp_cc_cmp(const void *p1, const void *p2) +{ + CCInfo *c1 = &global_tab[*(const int *)p1]; + CCInfo *c2 = &global_tab[*(const int *)p2]; + if (c1->f_len < c2->f_len) { + return -1; + } else if (c2->f_len < c1->f_len) { + return 1; + } else { + return memcmp(c1->f_data, c2->f_data, sizeof(c1->f_data[0]) * c1->f_len); + } +} + +/* dump the case special cases (multi character results which are + identical and need specific handling in lre_canonicalize() */ +void dump_case_folding_special_cases(CCInfo *tab) +{ + int i, len, j; + int *perm; + + perm = malloc(sizeof(perm[0]) * (CHARCODE_MAX + 1)); + for(i = 0; i <= CHARCODE_MAX; i++) + perm[i] = i; + global_tab = tab; + qsort(perm, CHARCODE_MAX + 1, sizeof(perm[0]), sp_cc_cmp); + for(i = 0; i <= CHARCODE_MAX;) { + if (tab[perm[i]].f_len <= 1) { + i++; + } else { + len = 1; + while ((i + len) <= CHARCODE_MAX && !sp_cc_cmp(&perm[i], &perm[i + len])) + len++; + + if (len > 1) { + for(j = i; j < i + len; j++) + dump_cc_info(&tab[perm[j]], perm[j]); + } + i += len; + } + } + free(perm); + global_tab = NULL; +} + + int tabcmp(const int *tab1, const int *tab2, int n) { int i; @@ -1348,7 +1433,7 @@ void compute_internal_props(void) for(i = 0; i <= CHARCODE_MAX; i++) { CCInfo *ci = &unicode_db[i]; - has_ul = (ci->u_len != 0 || ci->l_len != 0 || ci->f_code != 0); + has_ul = (ci->u_len != 0 || ci->l_len != 0 || ci->f_len != 0); if (has_ul) { assert(get_prop(i, PROP_Cased)); } else { @@ -1363,10 +1448,10 @@ void compute_internal_props(void) set_prop(i, PROP_Changes_When_Titlecased1, get_prop(i, PROP_Changes_When_Titlecased) ^ (ci->u_len != 0)); set_prop(i, PROP_Changes_When_Casefolded1, - get_prop(i, PROP_Changes_When_Casefolded) ^ (ci->f_code != 0)); + get_prop(i, PROP_Changes_When_Casefolded) ^ (ci->f_len != 0)); /* XXX: reduce table size (438 bytes) */ set_prop(i, PROP_Changes_When_NFKC_Casefolded1, - get_prop(i, PROP_Changes_When_NFKC_Casefolded) ^ (ci->f_code != 0)); + get_prop(i, PROP_Changes_When_NFKC_Casefolded) ^ (ci->f_len != 0)); #if 0 /* TEST */ #define M(x) (1U << GCAT_ ## x) @@ -1797,8 +1882,10 @@ void check_case_conv(void) ci->u_len = 1; ci->u_data[0] = code; } - if (ci->f_code == 0) - ci->f_code = code; + if (ci->f_len == 0) { + ci->f_len = 1; + ci->f_data[0] = code; + } error = 0; l = check_conv(res, code, 0); @@ -1812,7 +1899,7 @@ void check_case_conv(void) error++; } l = check_conv(res, code, 2); - if (l != 1 || res[0] != ci->f_code) { + if (l != ci->f_len || tabcmp((int *)res, ci->f_data, l)) { printf("ERROR: F\n"); error++; } @@ -3007,11 +3094,12 @@ int main(int argc, char **argv) unicode_db_path); parse_prop_list(filename); - // dump_data(unicode_db); - + // dump_unicode_data(unicode_db); build_conv_table(unicode_db); - - // dump_table(); + +#ifdef DUMP_CASE_FOLDING_SPECIAL_CASES + dump_case_folding_special_cases(unicode_db); +#endif if (!outfilename) { #ifdef USE_TEST diff --git a/libquickjs-sys/embed/quickjs/unicode_gen_def.h b/libquickjs-sys/embed/quickjs/unicode_gen_def.h index 47b0e39..e7c2464 100644 --- a/libquickjs-sys/embed/quickjs/unicode_gen_def.h +++ b/libquickjs-sys/embed/quickjs/unicode_gen_def.h @@ -72,6 +72,7 @@ DEF(Coptic, "Copt,Qaac") DEF(Cuneiform, "Xsux") DEF(Cypriot, "Cprt") DEF(Cyrillic, "Cyrl") +DEF(Cypro_Minoan, "Cpmn") DEF(Deseret, "Dsrt") DEF(Devanagari, "Deva") DEF(Dives_Akuru, "Diak") @@ -104,6 +105,7 @@ DEF(Javanese, "Java") DEF(Kaithi, "Kthi") DEF(Kannada, "Knda") DEF(Katakana, "Kana") +DEF(Kawi, "Kawi") DEF(Kayah_Li, "Kali") DEF(Kharoshthi, "Khar") DEF(Khmer, "Khmr") @@ -138,6 +140,7 @@ DEF(Mro, "Mroo") DEF(Multani, "Mult") DEF(Myanmar, "Mymr") DEF(Nabataean, "Nbat") +DEF(Nag_Mundari, "Nagm") DEF(Nandinagari, "Nand") DEF(New_Tai_Lue, "Talu") DEF(Newa, "Newa") @@ -154,6 +157,7 @@ DEF(Old_Persian, "Xpeo") DEF(Old_Sogdian, "Sogo") DEF(Old_South_Arabian, "Sarb") DEF(Old_Turkic, "Orkh") +DEF(Old_Uyghur, "Ougr") DEF(Oriya, "Orya") DEF(Osage, "Osge") DEF(Osmanya, "Osma") @@ -192,8 +196,11 @@ DEF(Thai, "Thai") DEF(Tibetan, "Tibt") DEF(Tifinagh, "Tfng") DEF(Tirhuta, "Tirh") +DEF(Tangsa, "Tnsa") +DEF(Toto, "Toto") DEF(Ugaritic, "Ugar") DEF(Vai, "Vaii") +DEF(Vithkuqi, "Vith") DEF(Wancho, "Wcho") DEF(Warang_Citi, "Wara") DEF(Yezidi, "Yezi") diff --git a/src/bindings/mod.rs b/src/bindings/mod.rs index 2582302..6f25f0f 100644 --- a/src/bindings/mod.rs +++ b/src/bindings/mod.rs @@ -19,6 +19,7 @@ use crate::{ use value::{JsFunction, OwnedJsObject}; +#[allow(unused_imports)] pub use value::{JsCompiledFunction, OwnedJsValue}; // JS_TAG_* constants from quickjs. diff --git a/src/tests.rs b/src/tests.rs index 4885898..9ad4167 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -578,7 +578,7 @@ fn test_bigint_serialize_bigint() { } } -#[cfg(feature = "patch_dateparser")] +#[cfg(feature = "patch-dateparser")] mod dateparser { use super::*; From 31956cfd75c1783020c7fd0956f8830a4be96ecd Mon Sep 17 00:00:00 2001 From: ThetaDev Date: Sat, 23 Mar 2024 01:32:06 +0100 Subject: [PATCH 16/16] fix: update dateparser patch --- libquickjs-sys/embed/patches/dateparser.patch | 764 ++++-------------- 1 file changed, 168 insertions(+), 596 deletions(-) diff --git a/libquickjs-sys/embed/patches/dateparser.patch b/libquickjs-sys/embed/patches/dateparser.patch index 28addea..f9401e6 100644 --- a/libquickjs-sys/embed/patches/dateparser.patch +++ b/libquickjs-sys/embed/patches/dateparser.patch @@ -1,19 +1,19 @@ diff --git a/libquickjs-sys/embed/quickjs/quickjs.c b/libquickjs-sys/embed/quickjs/quickjs.c -index 48aeffc..a3325b3 100644 +index 4e58a98..93cf853 100644 --- a/libquickjs-sys/embed/quickjs/quickjs.c +++ b/libquickjs-sys/embed/quickjs/quickjs.c -@@ -1435,6 +1435,10 @@ static inline int is_digit(int c) { +@@ -1459,6 +1459,10 @@ static inline int is_digit(int c) { return c >= '0' && c <= '9'; } +static inline int is_space_like(char c) { -+ return c == ' ' || c == ',' || c == ':' || c == '-'; ++ return c == ' ' || c == ',' || c == ':' || c == '-' || c == '/'; +} + typedef struct JSClassShortDef { JSAtom class_name; JSClassFinalizer *finalizer; -@@ -47929,6 +47933,23 @@ static int const month_days[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 +@@ -49343,6 +49347,23 @@ static int const month_days[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 static char const month_names[] = "JanFebMarAprMayJunJulAugSepOctNovDec"; static char const day_names[] = "SunMonTueWedThuFriSat"; @@ -37,7 +37,7 @@ index 48aeffc..a3325b3 100644 static __exception int get_date_fields(JSContext *ctx, JSValueConst obj, double fields[9], int is_local, int force) { -@@ -48294,14 +48315,46 @@ static JSValue js_Date_UTC(JSContext *ctx, JSValueConst this_val, +@@ -49707,14 +49728,44 @@ static JSValue js_Date_UTC(JSContext *ctx, JSValueConst this_val, return JS_NewFloat64(ctx, set_date_fields(fields, 0)); } @@ -50,7 +50,7 @@ index 48aeffc..a3325b3 100644 + int nxt = *pp + 1; + + // interpret - before a number as a sign rather than a comment char -+ if (ch == '-' && nxt < sp->len && is_digit(string_get(sp, nxt))) { ++ if (ch == '-' && nesting == 0 && nxt < sp->len && is_digit(string_get(sp, nxt))) { + break; + } + if (!is_space_like(ch)) { @@ -70,12 +70,10 @@ index 48aeffc..a3325b3 100644 -static void string_skip_non_spaces(JSString *sp, int *pp) { - while (*pp < sp->len && string_get(sp, *pp) != ' ') - *pp += 1; -+static BOOL char_eq_ignorecase(char c1, char c2) { -+ if (c1 == c2) return TRUE; -+ -+ if (c1 >= 'A' && c1 <= 'Z' && c2 == c1 + 32) return TRUE; -+ if (c1 >= 'a' && c1 <= 'z' && c2 == c1 - 32) return TRUE; -+ return FALSE; ++static inline BOOL char_eq_ignorecase(char c1, char c2) { ++ if ((c1 >= 'A' && c1 <= 'Z') || (c1 >= 'a' && c1 <= 'z')) ++ return (c1 | 0x20) == (c2 | 0x20); ++ return c1 == c2; +} + +static BOOL string_eq_ignorecase(JSString *s1, int p, const char *s2, int len) { @@ -89,7 +87,55 @@ index 48aeffc..a3325b3 100644 } /* parse a numeric field with an optional sign if accept_sign is TRUE */ -@@ -48406,27 +48459,30 @@ static int find_abbrev(JSString *sp, int p, const char *list, int count) { +@@ -49752,11 +49803,7 @@ static int string_get_signed_digits(JSString *sp, int *pp, int64_t *pval) { + p++; + + res = string_get_digits(sp, &p, pval); +- if (res == 0 && sgn == '-') { +- if (*pval == 0) +- return -1; // reject negative zero +- *pval = -*pval; +- } ++ if (res == 0 && sgn == '-') *pval = -*pval; + *pp = p; + return res; + } +@@ -49805,6 +49852,34 @@ static int string_get_milliseconds(JSString *sp, int *pp, int64_t *pval) { + return 0; + } + ++static int string_get_num_timezone(JSString *sp, int *pp, int64_t *pval) ++{ ++ int p = *pp; ++ ++ int64_t o; ++ if (string_get_signed_digits(sp, &p, &o)) ++ return -1; ++ ++ if (o < -9959 || o > 9959) { ++ return -1; ++ } ++ ++ int sgn = (o < 0) ? -1 : 1; ++ o = abs((int32_t) o); ++ ++ if (string_get(sp, p) != ':') { ++ *pval = ((o / 100) * 60 + (o % 100)) * sgn; ++ } else { ++ p++; ++ int64_t o2; ++ if (string_get_digits(sp, &p, &o2)) ++ return -1; ++ *pval = (o * 60 + o2) * sgn; ++ } ++ ++ *pp = p; ++ return 0; ++} + + static int find_abbrev(JSString *sp, int p, const char *list, int count) { + int n, i; +@@ -49822,27 +49897,30 @@ static int find_abbrev(JSString *sp, int p, const char *list, int count) { return -1; } @@ -135,7 +181,74 @@ index 48aeffc..a3325b3 100644 double d; int p, i, c, sgn, l; JSString *sp; -@@ -48513,68 +48569,268 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, +@@ -49856,7 +49934,18 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, + + sp = JS_VALUE_GET_STRING(s); + p = 0; +- if (p < sp->len && (((c = string_get(sp, p)) >= '0' && c <= '9') || c == '+' || c == '-')) { ++ string_skip_spaces_and_comments(sp, &p); ++ ++ int end_of_digits = p; ++ if (string_get(sp, end_of_digits) == '+' || string_get(sp, end_of_digits) == '-') { ++ p++; ++ } ++ while (end_of_digits < sp->len && is_digit(string_get(sp, end_of_digits))) { ++ end_of_digits++; ++ } ++ ++ if ((end_of_digits - p) > 0 && ++ (string_get(sp, end_of_digits) == '-' || string_get(sp, end_of_digits) == 'T')) { + /* ISO format */ + /* year field can be negative */ + if (string_get_signed_digits(sp, &p, &fields[0])) +@@ -49866,23 +49955,28 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, + if (p >= sp->len) + break; + switch(i) { +- case 1: +- case 2: ++ case 1: // Year ++ case 2: // Month + c = '-'; + break; +- case 3: ++ case 3: // Day + c = 'T'; + break; +- case 4: +- case 5: ++ case 4: // Hour ++ case 5: // Minute + c = ':'; + break; +- case 6: ++ case 6: // Second + c = '.'; + break; + } +- if (string_get(sp, p) != c) +- break; ++ if (string_get(sp, p) != c) { ++ // 2000T08:00Z ++ if (i < 3 && string_get(sp, p) == 'T') { ++ i = 3; ++ } ++ else break; ++ } + p++; + if (i == 6) { + if (string_get_milliseconds(sp, &p, &fields[i])) +@@ -49892,6 +49986,9 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, + goto done; + } + } ++ // Hour only is invalid ++ if (i == 4) goto done; ++ + /* no time: UTC by default */ + is_local = (i > 3); + fields[1] -= 1; +@@ -49929,68 +50026,250 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, goto done; } } else { @@ -154,7 +267,7 @@ index 48aeffc..a3325b3 100644 + if (p - word_start >= 3) { + month = find_abbrev(sp, word_start, month_names, 12); + } -+ string_skip_spaces_and_comments(sp, &p); // and comments ++ string_skip_spaces_and_comments(sp, &p); + word_start = p; + } else { + p++; @@ -168,7 +281,7 @@ index 48aeffc..a3325b3 100644 + month = find_abbrev(sp, word_start, month_names, 12); + } + -+ string_skip_spaces_and_comments(sp, &p); // and comments ++ string_skip_spaces_and_comments(sp, &p); + if (sp->len <= p) goto done; - c = string_get(sp, p); @@ -181,7 +294,7 @@ index 48aeffc..a3325b3 100644 + if (string_get_digits(sp, &p, &day)) + goto done; + -+ int64_t year = 0; ++ int64_t year = -1; + if (day > 31) { + if (string_get(sp, p) != '/') goto done; @@ -221,7 +334,7 @@ index 48aeffc..a3325b3 100644 + if (string_get_digits(sp, &p, &day)) + goto done; + -+ if (string_get(sp, p) != '/') ++ if (!is_space_like(string_get(sp, p))) + goto done; + p++; + if (sp->len <= p) @@ -230,40 +343,29 @@ index 48aeffc..a3325b3 100644 + if (string_get(sp, p) == '-') { + p++; + } -+ string_skip_spaces_and_comments(sp, &p); // and comments -+ -+ if (string_get(sp, p) == ',') { -+ p++; -+ } ++ string_skip_spaces_and_comments(sp, &p); - /* hour, min, seconds */ - string_skip_spaces(sp, &p); - for(i = 0; i < 3; i++) { - if (i == 1 || i == 2) { - if (p >= sp->len) ++ // Jan,2000,08:00:00 UT + if (month == -1) { + month = find_abbrev(sp, p, month_names, 12); + if (month == -1) -+ goto done; + goto done; +- if (string_get(sp, p) != ':') + -+ while (p < sp->len && string_get(sp, p) != '-' && string_get(sp, p) != ' ') { ++ while (p < sp->len && !is_space_like(string_get(sp, p))) { + p++; + } + if (sp->len <= p) goto done; -- if (string_get(sp, p) != ':') -+ -+ // '-99 23:12:40 GMT' -+ if (string_get(sp, p) != '-' && string_get(sp, p) != '/' && string_get(sp, p) != ' ') { - goto done; -+ } p++; } - if (string_get_digits(sp, &p, &fields[3 + i])) -+ -+ if (month < 0 || month > 11) { - goto done; -+ } +- goto done; } - // XXX: parse optional milliseconds? @@ -273,11 +375,14 @@ index 48aeffc..a3325b3 100644 - for (tz = 0; p < sp->len; p++) { - sgn = string_get(sp, p); - if (sgn == '+' || sgn == '-') { -+ if (year <= 0) { -+ if (string_get_digits(sp, &p, &year)) -+ goto done; -+ if (year <= 0) { -+ goto done; ++ string_skip_spaces_and_comments(sp, &p); ++ ++ if (year < 0) { ++ // Year following, e.g. 01 Jan 2000 08:00:00 UT ++ // Time following, e.g. Jan 01 08:00:00 UT 2000 ++ if (sp->len <= p + 2 || string_get(sp, p + 2) != ':') { ++ if (string_get_digits(sp, &p, &year)) ++ goto done; + } + } + @@ -294,9 +399,7 @@ index 48aeffc..a3325b3 100644 + } else if (is_space_like(string_get(sp, p))) { p++; - if (string_get_fixed_width_digits(sp, &p, 2, &hh)) -+ string_skip_spaces_and_comments(sp, &p); // and comments -+ } else { -+ goto done; ++ string_skip_spaces_and_comments(sp, &p); + } + + // Read a number? If not, this might be a timezone name. @@ -321,10 +424,6 @@ index 48aeffc..a3325b3 100644 + + if (string_get_digits(sp, &p, &minute)) + goto done; -+ -+ if (minute < 0 || minute > 59) { -+ goto done; -+ } + + // ':40 GMT' + // seconds are optional in rfc822 + rfc2822 @@ -333,10 +432,6 @@ index 48aeffc..a3325b3 100644 + + if (string_get_digits(sp, &p, &second)) + goto done; -+ -+ if (second < 0 || second > 59) { -+ goto done; -+ } + + // disallow trailing colon seconds + if (string_get(sp, p) == ':') { @@ -346,7 +441,7 @@ index 48aeffc..a3325b3 100644 + goto done; + } + -+ string_skip_spaces_and_comments(sp, &p); // and comments ++ string_skip_spaces_and_comments(sp, &p); + + if (string_eq_ignorecase(sp, p, "AM", 2)) { + if (hour > 12) { @@ -356,7 +451,7 @@ index 48aeffc..a3325b3 100644 + hour = 0; + } + p += 2; -+ string_skip_spaces_and_comments(sp, &p); // and comments ++ string_skip_spaces_and_comments(sp, &p); + } else if (string_eq_ignorecase(sp, p, "PM", 2)) { + if (hour > 12) { + goto done; @@ -365,35 +460,17 @@ index 48aeffc..a3325b3 100644 + hour += 12; + } + p += 2; -+ string_skip_spaces_and_comments(sp, &p); // and comments ++ string_skip_spaces_and_comments(sp, &p); + } -+ } -+ } + } + } + + // Don't fail if the time zone is missing. + // Some websites omit the time zone + if (sp->len > p) { + if (string_get(sp, p) == '+' || string_get(sp, p) == '-') { -+ int64_t o; -+ if (string_get_digits(sp, &p, &o)) ++ if (string_get_num_timezone(sp, &p, &tz)) + goto done; -+ -+ if (o < -9959 || o > 9959) { -+ goto done; -+ } -+ -+ int sgn = (o < 0) ? -1 : 1; -+ o = abs((int32_t) o); -+ -+ if (string_get(sp, p) != ':') { -+ tz = ((o / 100) * 60 + (o % 100)) * sgn; -+ } else { -+ p++; -+ int64_t o2; -+ if (string_get_digits(sp, &p, &o2)) -+ goto done; -+ tz = (o * 60 + o2) * sgn; -+ } + is_local = FALSE; + } else { + for (int i = 0; i < sizeof(known_zones) / sizeof(struct KnownZone); i++) { @@ -401,6 +478,15 @@ index 48aeffc..a3325b3 100644 + tz = known_zones[i].tzOffset; + p += strlen(known_zones[i].tzName); + is_local = FALSE; ++ ++ // TZ offset (GMT+0) ++ if (string_get(sp, p) == '+' || string_get(sp, p) == '-') { ++ int64_t o; ++ if (string_get_num_timezone(sp, &p, &o)) ++ goto done; ++ ++ tz += o; ++ } + break; + } + } @@ -427,8 +513,8 @@ index 48aeffc..a3325b3 100644 + year += 2000; + } else { + year += 1900; - } - } ++ } ++ } + + fields[0] = year; + fields[1] = month; @@ -438,521 +524,6 @@ index 48aeffc..a3325b3 100644 + fields[5] = second; } + - for(i = 0; i < 7; i++) - fields1[i] = fields[i]; -- d = set_date_fields(fields1, is_local) - tz * 60000; -+ d = set_date_fields(fields1, is_local) - (tz * 60000); - rv = JS_NewFloat64(ctx, d); - - done: --- -2.39.1 - - -From f52e54d69ca1b62c9c855f360881ca8e4886ed1a Mon Sep 17 00:00:00 2001 -From: ThetaDev -Date: Sat, 13 Aug 2022 01:39:24 +0200 -Subject: [PATCH 2/5] 2 small fixes - ---- - libquickjs-sys/embed/quickjs/quickjs.c | 20 ++++++++++++-------- - 1 file changed, 12 insertions(+), 8 deletions(-) - -diff --git a/libquickjs-sys/embed/quickjs/quickjs.c b/libquickjs-sys/embed/quickjs/quickjs.c -index a3325b3..8ff9f4e 100644 ---- a/libquickjs-sys/embed/quickjs/quickjs.c -+++ b/libquickjs-sys/embed/quickjs/quickjs.c -@@ -48322,7 +48322,7 @@ static void string_skip_spaces_and_comments(JSString *sp, int *pp) { - int nxt = *pp + 1; - - // interpret - before a number as a sign rather than a comment char -- if (ch == '-' && nxt < sp->len && is_digit(string_get(sp, nxt))) { -+ if (ch == '-' && nesting == 0 && nxt < sp->len && is_digit(string_get(sp, nxt))) { - break; - } - if (!is_space_like(ch)) { -@@ -48496,6 +48496,8 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, - - sp = JS_VALUE_GET_STRING(s); - p = 0; -+ string_skip_spaces_and_comments(sp, &p); -+ - if (p < sp->len && (((c = string_get(sp, p)) >= '0' && c <= '9') || c == '+' || c == '-')) { - /* ISO format */ - /* year field can be negative */ -@@ -48579,7 +48581,7 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, - if (p - word_start >= 3) { - month = find_abbrev(sp, word_start, month_names, 12); - } -- string_skip_spaces_and_comments(sp, &p); // and comments -+ string_skip_spaces_and_comments(sp, &p); - word_start = p; - } else { - p++; -@@ -48593,7 +48595,7 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, - month = find_abbrev(sp, word_start, month_names, 12); - } - -- string_skip_spaces_and_comments(sp, &p); // and comments -+ string_skip_spaces_and_comments(sp, &p); - if (sp->len <= p) - goto done; - -@@ -48640,7 +48642,7 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, - if (string_get(sp, p) == '-') { - p++; - } -- string_skip_spaces_and_comments(sp, &p); // and comments -+ string_skip_spaces_and_comments(sp, &p); - - if (string_get(sp, p) == ',') { - p++; -@@ -48669,6 +48671,8 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, - } - } - -+ string_skip_spaces_and_comments(sp, &p); -+ - if (year <= 0) { - if (string_get_digits(sp, &p, &year)) - goto done; -@@ -48689,7 +48693,7 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, - year = -1; - } else if (is_space_like(string_get(sp, p))) { - p++; -- string_skip_spaces_and_comments(sp, &p); // and comments -+ string_skip_spaces_and_comments(sp, &p); - } else { - goto done; - } -@@ -48736,7 +48740,7 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, - goto done; - } - -- string_skip_spaces_and_comments(sp, &p); // and comments -+ string_skip_spaces_and_comments(sp, &p); - - if (string_eq_ignorecase(sp, p, "AM", 2)) { - if (hour > 12) { -@@ -48746,7 +48750,7 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, - hour = 0; - } - p += 2; -- string_skip_spaces_and_comments(sp, &p); // and comments -+ string_skip_spaces_and_comments(sp, &p); - } else if (string_eq_ignorecase(sp, p, "PM", 2)) { - if (hour > 12) { - goto done; -@@ -48755,7 +48759,7 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, - hour += 12; - } - p += 2; -- string_skip_spaces_and_comments(sp, &p); // and comments -+ string_skip_spaces_and_comments(sp, &p); - } - } - } --- -2.39.1 - - -From ad17c000b6664c6f9ef2ecedbcaade19fc41c1eb Mon Sep 17 00:00:00 2001 -From: ThetaDev -Date: Sat, 13 Aug 2022 10:11:06 +0200 -Subject: [PATCH 3/5] fix y2k issue - ---- - libquickjs-sys/embed/quickjs/quickjs.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/libquickjs-sys/embed/quickjs/quickjs.c b/libquickjs-sys/embed/quickjs/quickjs.c -index 8ff9f4e..e7c71b0 100644 ---- a/libquickjs-sys/embed/quickjs/quickjs.c -+++ b/libquickjs-sys/embed/quickjs/quickjs.c -@@ -48604,7 +48604,7 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, - if (string_get_digits(sp, &p, &day)) - goto done; - -- int64_t year = 0; -+ int64_t year = -1; - if (day > 31) { - if (string_get(sp, p) != '/') - goto done; -@@ -48673,10 +48673,10 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, - - string_skip_spaces_and_comments(sp, &p); - -- if (year <= 0) { -+ if (year < 0) { - if (string_get_digits(sp, &p, &year)) - goto done; -- if (year <= 0) { -+ if (year < 0) { - goto done; - } - } --- -2.39.1 - - -From 333283c377422f62a5e72605814c34b74f0f875d Mon Sep 17 00:00:00 2001 -From: ThetaDev -Date: Sat, 13 Aug 2022 15:02:04 +0200 -Subject: [PATCH 4/5] fix more date formats, now passes all tests - ---- - libquickjs-sys/embed/quickjs/quickjs.c | 84 +++++++++++++++++--------- - 1 file changed, 56 insertions(+), 28 deletions(-) - -diff --git a/libquickjs-sys/embed/quickjs/quickjs.c b/libquickjs-sys/embed/quickjs/quickjs.c -index e7c71b0..91b34c7 100644 ---- a/libquickjs-sys/embed/quickjs/quickjs.c -+++ b/libquickjs-sys/embed/quickjs/quickjs.c -@@ -1436,7 +1436,7 @@ static inline int is_digit(int c) { - } - - static inline int is_space_like(char c) { -- return c == ' ' || c == ',' || c == ':' || c == '-'; -+ return c == ' ' || c == ',' || c == ':' || c == '-' || c == '/'; - } - - typedef struct JSClassShortDef { -@@ -48339,12 +48339,10 @@ static void string_skip_spaces_and_comments(JSString *sp, int *pp) { - } - } - --static BOOL char_eq_ignorecase(char c1, char c2) { -- if (c1 == c2) return TRUE; -- -- if (c1 >= 'A' && c1 <= 'Z' && c2 == c1 + 32) return TRUE; -- if (c1 >= 'a' && c1 <= 'z' && c2 == c1 - 32) return TRUE; -- return FALSE; -+static inline BOOL char_eq_ignorecase(char c1, char c2) { -+ if ((c1 >= 'A' && c1 <= 'Z') || (c1 >= 'a' && c1 <= 'z')) -+ return (c1 | 0x20) == (c2 | 0x20); -+ return c1 == c2; - } - - static BOOL string_eq_ignorecase(JSString *s1, int p, const char *s2, int len) { -@@ -48498,7 +48496,16 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, - p = 0; - string_skip_spaces_and_comments(sp, &p); - -- if (p < sp->len && (((c = string_get(sp, p)) >= '0' && c <= '9') || c == '+' || c == '-')) { -+ int end_of_digits = p; -+ if (string_get(sp, end_of_digits) == '+' || string_get(sp, end_of_digits) == '-') { -+ p++; -+ } -+ while (end_of_digits < sp->len && is_digit(string_get(sp, end_of_digits))) { -+ end_of_digits++; -+ } -+ -+ if ((end_of_digits - p) > 0 && -+ (string_get(sp, end_of_digits) == '-' || string_get(sp, end_of_digits) == 'T')) { - /* ISO format */ - /* year field can be negative */ - if (string_get_signed_digits(sp, &p, &fields[0])) -@@ -48523,8 +48530,13 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, - c = '.'; - break; - } -- if (string_get(sp, p) != c) -- break; -+ if (string_get(sp, p) != c) { -+ // 2000T08:00Z -+ if (i < 3 && string_get(sp, p) == 'T') { -+ i = 3; -+ } -+ else break; -+ } - p++; - if (i == 6) { - if (string_get_milliseconds(sp, &p, &fields[i])) -@@ -48633,7 +48645,7 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, - if (string_get_digits(sp, &p, &day)) - goto done; - -- if (string_get(sp, p) != '/') -+ if (!is_space_like(string_get(sp, p))) - goto done; - p++; - if (sp->len <= p) -@@ -48644,25 +48656,17 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, - } - string_skip_spaces_and_comments(sp, &p); - -- if (string_get(sp, p) == ',') { -- p++; -- } -- -+ // Jan,2000,08:00:00 UT - if (month == -1) { - month = find_abbrev(sp, p, month_names, 12); - if (month == -1) - goto done; - -- while (p < sp->len && string_get(sp, p) != '-' && string_get(sp, p) != ' ') { -+ while (p < sp->len && !is_space_like(string_get(sp, p))) { - p++; - } - if (sp->len <= p) - goto done; -- -- // '-99 23:12:40 GMT' -- if (string_get(sp, p) != '-' && string_get(sp, p) != '/' && string_get(sp, p) != ' ') { -- goto done; -- } - p++; - } - -@@ -48674,10 +48678,11 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, - string_skip_spaces_and_comments(sp, &p); - - if (year < 0) { -- if (string_get_digits(sp, &p, &year)) -- goto done; -- if (year < 0) { -- goto done; -+ // Year following, e.g. 01 Jan 2000 08:00:00 UT -+ // Time following, e.g. Jan 01 08:00:00 UT 2000 -+ if (sp->len <= p + 2 || string_get(sp, p + 2) != ':') { -+ if (string_get_digits(sp, &p, &year)) -+ goto done; - } - } - -@@ -48694,8 +48699,6 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, - } else if (is_space_like(string_get(sp, p))) { - p++; - string_skip_spaces_and_comments(sp, &p); -- } else { -- goto done; - } - - // Read a number? If not, this might be a timezone name. -@@ -48769,7 +48772,7 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, - if (sp->len > p) { - if (string_get(sp, p) == '+' || string_get(sp, p) == '-') { - int64_t o; -- if (string_get_digits(sp, &p, &o)) -+ if (string_get_signed_digits(sp, &p, &o)) - goto done; - - if (o < -9959 || o > 9959) { -@@ -48795,6 +48798,31 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, - tz = known_zones[i].tzOffset; - p += strlen(known_zones[i].tzName); - is_local = FALSE; -+ -+ // TZ offset (GMT+0) -+ if (string_get(sp, p) == '+' || string_get(sp, p) == '-') { -+ int64_t o; -+ if (string_get_signed_digits(sp, &p, &o)) -+ goto done; -+ -+ if (o < -9959 || o > 9959) { -+ goto done; -+ } -+ -+ int sgn = (o < 0) ? -1 : 1; -+ o = abs((int32_t) o); -+ -+ if (string_get(sp, p) != ':') { -+ tz += ((o / 100) * 60 + (o % 100)) * sgn; -+ } else { -+ p++; -+ int64_t o2; -+ if (string_get_digits(sp, &p, &o2)) -+ goto done; -+ tz += (o * 60 + o2) * sgn; -+ } -+ } -+ - break; - } - } --- -2.39.1 - - -From 749be29936abc5c9d1d1dedf863a70d7bafaa795 Mon Sep 17 00:00:00 2001 -From: ThetaDev -Date: Sat, 13 Aug 2022 18:07:09 +0200 -Subject: [PATCH 5/5] added date validation - ---- - libquickjs-sys/embed/quickjs/quickjs.c | 105 ++++++++++++------------- - 1 file changed, 50 insertions(+), 55 deletions(-) - -diff --git a/libquickjs-sys/embed/quickjs/quickjs.c b/libquickjs-sys/embed/quickjs/quickjs.c -index 91b34c7..68f0120 100644 ---- a/libquickjs-sys/embed/quickjs/quickjs.c -+++ b/libquickjs-sys/embed/quickjs/quickjs.c -@@ -48440,6 +48440,34 @@ static int string_get_milliseconds(JSString *sp, int *pp, int64_t *pval) { - return 0; - } - -+static int string_get_num_timezone(JSString *sp, int *pp, int64_t *pval) -+{ -+ int p = *pp; -+ -+ int64_t o; -+ if (string_get_signed_digits(sp, &p, &o)) -+ return -1; -+ -+ if (o < -9959 || o > 9959) { -+ return -1; -+ } -+ -+ int sgn = (o < 0) ? -1 : 1; -+ o = abs((int32_t) o); -+ -+ if (string_get(sp, p) != ':') { -+ *pval = ((o / 100) * 60 + (o % 100)) * sgn; -+ } else { -+ p++; -+ int64_t o2; -+ if (string_get_digits(sp, &p, &o2)) -+ return -1; -+ *pval = (o * 60 + o2) * sgn; -+ } -+ -+ *pp = p; -+ return 0; -+} - - static int find_abbrev(JSString *sp, int p, const char *list, int count) { - int n, i; -@@ -48515,18 +48543,18 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, - if (p >= sp->len) - break; - switch(i) { -- case 1: -- case 2: -+ case 1: // Year -+ case 2: // Month - c = '-'; - break; -- case 3: -+ case 3: // Day - c = 'T'; - break; -- case 4: -- case 5: -+ case 4: // Hour -+ case 5: // Minute - c = ':'; - break; -- case 6: -+ case 6: // Second - c = '.'; - break; - } -@@ -48546,6 +48574,9 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, - goto done; - } - } -+ // Hour only is invalid -+ if (i == 4) goto done; -+ - /* no time: UTC by default */ - is_local = (i > 3); - fields[1] -= 1; -@@ -48669,10 +48700,6 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, - goto done; - p++; - } -- -- if (month < 0 || month > 11) { -- goto done; -- } - } - - string_skip_spaces_and_comments(sp, &p); -@@ -48718,10 +48745,6 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, - - if (string_get_digits(sp, &p, &minute)) - goto done; -- -- if (minute < 0 || minute > 59) { -- goto done; -- } - - // ':40 GMT' - // seconds are optional in rfc822 + rfc2822 -@@ -48730,10 +48753,6 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, - - if (string_get_digits(sp, &p, &second)) - goto done; -- -- if (second < 0 || second > 59) { -- goto done; -- } - - // disallow trailing colon seconds - if (string_get(sp, p) == ':') { -@@ -48771,26 +48790,8 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, - // Some websites omit the time zone - if (sp->len > p) { - if (string_get(sp, p) == '+' || string_get(sp, p) == '-') { -- int64_t o; -- if (string_get_signed_digits(sp, &p, &o)) -- goto done; -- -- if (o < -9959 || o > 9959) { -+ if (string_get_num_timezone(sp, &p, &tz)) - goto done; -- } -- -- int sgn = (o < 0) ? -1 : 1; -- o = abs((int32_t) o); -- -- if (string_get(sp, p) != ':') { -- tz = ((o / 100) * 60 + (o % 100)) * sgn; -- } else { -- p++; -- int64_t o2; -- if (string_get_digits(sp, &p, &o2)) -- goto done; -- tz = (o * 60 + o2) * sgn; -- } - is_local = FALSE; - } else { - for (int i = 0; i < sizeof(known_zones) / sizeof(struct KnownZone); i++) { -@@ -48802,27 +48803,11 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, - // TZ offset (GMT+0) - if (string_get(sp, p) == '+' || string_get(sp, p) == '-') { - int64_t o; -- if (string_get_signed_digits(sp, &p, &o)) -+ if (string_get_num_timezone(sp, &p, &o)) - goto done; - -- if (o < -9959 || o > 9959) { -- goto done; -- } -- -- int sgn = (o < 0) ? -1 : 1; -- o = abs((int32_t) o); -- -- if (string_get(sp, p) != ':') { -- tz += ((o / 100) * 60 + (o % 100)) * sgn; -- } else { -- p++; -- int64_t o2; -- if (string_get_digits(sp, &p, &o2)) -- goto done; -- tz += (o * 60 + o2) * sgn; -- } -+ tz += o; - } -- - break; - } - } -@@ -48860,6 +48845,16 @@ static JSValue js_Date_parse(JSContext *ctx, JSValueConst this_val, - fields[5] = second; - } - + // Validate fields + if (fields[1] < 0 || fields[1] > 11 || + fields[2] < 1 || fields[2] > 31 || @@ -965,7 +536,8 @@ index 91b34c7..68f0120 100644 + for(i = 0; i < 7; i++) fields1[i] = fields[i]; - d = set_date_fields(fields1, is_local) - (tz * 60000); --- -2.39.1 - +- d = set_date_fields(fields1, is_local) - tz * 60000; ++ d = set_date_fields(fields1, is_local) - (tz * 60000); + rv = JS_NewFloat64(ctx, d); + + done: