From bbfde72dfb5389b8731c10f7c1a18eebfd257a7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=88=B1=E7=89=B9=E6=AF=8F=E7=BE=8A=E9=98=9F?= Date: Tue, 9 Jun 2026 00:01:31 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E8=A1=A8=E9=A9=B1=E5=8A=A8?= =?UTF-8?q?=E5=8C=96=20builtin=20=E7=BB=91=E5=AE=9A=E4=B8=8E=20Number=20?= =?UTF-8?q?=E5=B8=B8=E9=87=8F=E6=B3=A8=E5=86=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/oxide_kernel/src/builtin.rs | 701 ++++-------------- crates/oxide_vm/src/bindings/bind_number.rs | 102 +-- .../oxide_vm/tests/builtins_number_tests.rs | 14 + 3 files changed, 170 insertions(+), 647 deletions(-) diff --git a/crates/oxide_kernel/src/builtin.rs b/crates/oxide_kernel/src/builtin.rs index 8acdfd3..754fb3d 100644 --- a/crates/oxide_kernel/src/builtin.rs +++ b/crates/oxide_kernel/src/builtin.rs @@ -7,7 +7,7 @@ use crate::string_forge::StringForge; #[macro_export] macro_rules! bind_method { - ($world:expr, $target:expr, $sf:expr, $sh:expr, $name:literal, $func:path, $nargs:literal) => { + ($world:expr, $target:expr, $sf:expr, $sh:expr, $name:literal, $func:expr, $nargs:expr) => { let _ = $world.bind_method($target, $sh, $sf, $name, $func as *const (), $nargs); }; } @@ -15,11 +15,29 @@ macro_rules! bind_method { #[macro_export] macro_rules! bind_methods { ($world:expr, $target:expr, $sf:expr, $sh:expr, - $(($name:literal, $func:path, $nargs:literal)),* $(,)?) => { + $(($name:literal, $func:expr, $nargs:expr)),* $(,)?) => { $( bind_method!($world, $target, $sf, $sh, $name, $func, $nargs); )* }; } +#[macro_export] +macro_rules! bind_methods_static { + ($target:expr, $sf:expr, $sh:expr, $wrapper_proto:expr, + $(($name:literal, $func:expr, $nargs:expr)),* $(,)?) => { + $( + let _ = $crate::builtin::BuiltinWorld::bind_method_static( + $target, + $sh, + $sf, + $name, + $func, + $nargs, + $wrapper_proto, + ); + )* + }; +} + pub struct ObjectMethods { pub keys: *const (), pub create: *const (), @@ -448,109 +466,34 @@ impl BuiltinWorld { ) { let ctor_ptr = P::as_ptr(&self.object_constructor) as *mut JsObject; let ctor = unsafe { &mut *ctor_ptr }; - - let _ = self.bind_method(ctor, shape_forge, string_forge, "keys", methods.keys, 1); - let _ = self.bind_method(ctor, shape_forge, string_forge, "create", methods.create, 2); - let _ = self.bind_method(ctor, shape_forge, string_forge, "assign", methods.assign, 2); - let _ = self.bind_method( + bind_methods!( + self, ctor, - shape_forge, string_forge, - "defineProperty", - methods.define_property, - 3, - ); - let _ = self.bind_method( - ctor, shape_forge, - string_forge, - "getOwnPropertyDescriptor", - methods.get_own_property_descriptor, - 2, + ("keys", methods.keys, 1), + ("create", methods.create, 2), + ("assign", methods.assign, 2), + ("defineProperty", methods.define_property, 3), + ( + "getOwnPropertyDescriptor", + methods.get_own_property_descriptor, + 2 + ), + ("freeze", methods.freeze, 1), + ("seal", methods.seal, 1), + ("preventExtensions", methods.prevent_extensions, 1), + ("isFrozen", methods.is_frozen, 1), + ("isSealed", methods.is_sealed, 1), + ("isExtensible", methods.is_extensible, 1), + ("getOwnPropertyNames", methods.get_own_property_names, 1), + ("defineProperties", methods.define_properties, 2), + ("fromEntries", methods.from_entries, 1), + ("getPrototypeOf", methods.get_prototype_of, 1), + ("hasOwn", methods.has_own, 2), + ("entries", methods.entries, 1), + ("values", methods.values, 1), ); - let _ = self.bind_method(ctor, shape_forge, string_forge, "freeze", methods.freeze, 1); - let _ = self.bind_method(ctor, shape_forge, string_forge, "seal", methods.seal, 1); - let _ = self.bind_method( - ctor, - shape_forge, - string_forge, - "preventExtensions", - methods.prevent_extensions, - 1, - ); - let _ = self.bind_method( - ctor, - shape_forge, - string_forge, - "isFrozen", - methods.is_frozen, - 1, - ); - let _ = self.bind_method( - ctor, - shape_forge, - string_forge, - "isSealed", - methods.is_sealed, - 1, - ); - let _ = self.bind_method( - ctor, - shape_forge, - string_forge, - "isExtensible", - methods.is_extensible, - 1, - ); - let _ = self.bind_method( - ctor, - shape_forge, - string_forge, - "getOwnPropertyNames", - methods.get_own_property_names, - 1, - ); - let _ = self.bind_method( - ctor, - shape_forge, - string_forge, - "defineProperties", - methods.define_properties, - 2, - ); - let _ = self.bind_method( - ctor, - shape_forge, - string_forge, - "fromEntries", - methods.from_entries, - 1, - ); - let _ = self.bind_method( - ctor, - shape_forge, - string_forge, - "getPrototypeOf", - methods.get_prototype_of, - 1, - ); - let _ = self.bind_method( - ctor, - shape_forge, - string_forge, - "hasOwn", - methods.has_own, - 2, - ); - let _ = self.bind_method( - ctor, - shape_forge, - string_forge, - "entries", - methods.entries, - 1, - ); - let _ = self.bind_method(ctor, shape_forge, string_forge, "values", methods.values, 1); } pub fn bind_array_methods( @@ -561,140 +504,40 @@ impl BuiltinWorld { ) { let proto_ptr = P::as_ptr(&self.array_proto) as *mut JsObject; let proto = unsafe { &mut *proto_ptr }; - - let _ = self.bind_method(proto, shape_forge, string_forge, "push", methods.push, 1); - let _ = self.bind_method(proto, shape_forge, string_forge, "pop", methods.pop, 0); - let _ = self.bind_method(proto, shape_forge, string_forge, "slice", methods.slice, 2); - let _ = self.bind_method( + bind_methods!( + self, proto, - shape_forge, string_forge, - "splice", - methods.splice, - 2, - ); - let _ = self.bind_method( - proto, shape_forge, - string_forge, - "concat", - methods.concat, - 1, + ("push", methods.push, 1), + ("pop", methods.pop, 0), + ("slice", methods.slice, 2), + ("splice", methods.splice, 2), + ("concat", methods.concat, 1), + ("join", methods.join, 1), + ("indexOf", methods.index_of, 1), + ("includes", methods.includes, 1), + ("reverse", methods.reverse, 0), + ("forEach", methods.for_each, 1), + ("map", methods.map, 1), + ("filter", methods.filter, 1), + ("reduce", methods.reduce, 1), + ("find", methods.find, 1), + ("some", methods.some, 1), + ("every", methods.every, 1), + ("flat", methods.flat, 0), + ("flatMap", methods.flat_map, 1), + ("shift", methods.shift, 0), + ("unshift", methods.unshift, 1), + ("fill", methods.fill, 1), + ("copyWithin", methods.copy_within, 2), + ("at", methods.at, 1), + ("lastIndexOf", methods.last_index_of, 1), + ("findIndex", methods.find_index, 1), + ("findLast", methods.find_last, 1), + ("reduceRight", methods.reduce_right, 1), + ("sort", methods.sort, 0), ); - let _ = self.bind_method(proto, shape_forge, string_forge, "join", methods.join, 1); - let _ = self.bind_method( - proto, - shape_forge, - string_forge, - "indexOf", - methods.index_of, - 1, - ); - let _ = self.bind_method( - proto, - shape_forge, - string_forge, - "includes", - methods.includes, - 1, - ); - let _ = self.bind_method( - proto, - shape_forge, - string_forge, - "reverse", - methods.reverse, - 0, - ); - let _ = self.bind_method( - proto, - shape_forge, - string_forge, - "forEach", - methods.for_each, - 1, - ); - let _ = self.bind_method(proto, shape_forge, string_forge, "map", methods.map, 1); - let _ = self.bind_method( - proto, - shape_forge, - string_forge, - "filter", - methods.filter, - 1, - ); - let _ = self.bind_method( - proto, - shape_forge, - string_forge, - "reduce", - methods.reduce, - 1, - ); - let _ = self.bind_method(proto, shape_forge, string_forge, "find", methods.find, 1); - let _ = self.bind_method(proto, shape_forge, string_forge, "some", methods.some, 1); - let _ = self.bind_method(proto, shape_forge, string_forge, "every", methods.every, 1); - let _ = self.bind_method(proto, shape_forge, string_forge, "flat", methods.flat, 0); - let _ = self.bind_method( - proto, - shape_forge, - string_forge, - "flatMap", - methods.flat_map, - 1, - ); - let _ = self.bind_method(proto, shape_forge, string_forge, "shift", methods.shift, 0); - let _ = self.bind_method( - proto, - shape_forge, - string_forge, - "unshift", - methods.unshift, - 1, - ); - let _ = self.bind_method(proto, shape_forge, string_forge, "fill", methods.fill, 1); - let _ = self.bind_method( - proto, - shape_forge, - string_forge, - "copyWithin", - methods.copy_within, - 2, - ); - let _ = self.bind_method(proto, shape_forge, string_forge, "at", methods.at, 1); - let _ = self.bind_method( - proto, - shape_forge, - string_forge, - "lastIndexOf", - methods.last_index_of, - 1, - ); - let _ = self.bind_method( - proto, - shape_forge, - string_forge, - "findIndex", - methods.find_index, - 1, - ); - let _ = self.bind_method( - proto, - shape_forge, - string_forge, - "findLast", - methods.find_last, - 1, - ); - let _ = self.bind_method( - proto, - shape_forge, - string_forge, - "reduceRight", - methods.reduce_right, - 1, - ); - let _ = self.bind_method(proto, shape_forge, string_forge, "sort", methods.sort, 0); } pub fn bind_error_methods( @@ -705,68 +548,30 @@ impl BuiltinWorld { ) { let ctor_ptr = P::as_ptr(&self.error_constructor) as *mut JsObject; let ctor = unsafe { &mut *ctor_ptr }; - - let _ = self.bind_method(ctor, shape_forge, string_forge, "Error", methods.error, 1); - let _ = self.bind_method( + bind_methods!( + self, ctor, - shape_forge, string_forge, - "TypeError", - methods.type_error, - 1, - ); - let _ = self.bind_method( - ctor, shape_forge, - string_forge, - "ReferenceError", - methods.reference_error, - 1, - ); - let _ = self.bind_method( - ctor, - shape_forge, - string_forge, - "RangeError", - methods.range_error, - 1, - ); - let _ = self.bind_method( - ctor, - shape_forge, - string_forge, - "SyntaxError", - methods.syntax_error, - 1, - ); - let _ = self.bind_method( - ctor, - shape_forge, - string_forge, - "URIError", - methods.uri_error, - 1, - ); - let _ = self.bind_method( - ctor, - shape_forge, - string_forge, - "EvalError", - methods.eval_error, - 1, + ("Error", methods.error, 1), + ("TypeError", methods.type_error, 1), + ("ReferenceError", methods.reference_error, 1), + ("RangeError", methods.range_error, 1), + ("SyntaxError", methods.syntax_error, 1), + ("URIError", methods.uri_error, 1), + ("EvalError", methods.eval_error, 1), ); let proto_ptr = P::as_ptr(&self.error_proto) as *mut JsObject; let proto = unsafe { &mut *proto_ptr }; - let _ = self.bind_method( + bind_methods!( + self, proto, - shape_forge, string_forge, - "toString", - methods.to_string, - 0, + shape_forge, + ("toString", methods.to_string, 0), + ("stack", methods.stack, 0), ); - let _ = self.bind_method(proto, shape_forge, string_forge, "stack", methods.stack, 0); } pub fn bind_string_methods( @@ -777,185 +582,36 @@ impl BuiltinWorld { ) { let proto_ptr = P::as_ptr(&self.string_proto) as *mut JsObject; let proto = unsafe { &mut *proto_ptr }; - - let _ = self.bind_method( + bind_methods!( + self, proto, - shape_forge, string_forge, - "indexOf", - methods.index_of, - 1, - ); - let _ = self.bind_method( - proto, shape_forge, - string_forge, - "includes", - methods.includes, - 1, - ); - let _ = self.bind_method( - proto, - shape_forge, - string_forge, - "charAt", - methods.char_at, - 1, - ); - let _ = self.bind_method( - proto, - shape_forge, - string_forge, - "charCodeAt", - methods.char_code_at, - 1, - ); - let _ = self.bind_method( - proto, - shape_forge, - string_forge, - "concat", - methods.concat, - 1, - ); - let _ = self.bind_method(proto, shape_forge, string_forge, "slice", methods.slice, 2); - let _ = self.bind_method( - proto, - shape_forge, - string_forge, - "substring", - methods.substring, - 2, - ); - let _ = self.bind_method( - proto, - shape_forge, - string_forge, - "toUpperCase", - methods.to_upper_case, - 0, - ); - let _ = self.bind_method( - proto, - shape_forge, - string_forge, - "toLowerCase", - methods.to_lower_case, - 0, - ); - let _ = self.bind_method(proto, shape_forge, string_forge, "trim", methods.trim, 0); - let _ = self.bind_method( - proto, - shape_forge, - string_forge, - "repeat", - methods.repeat, - 1, - ); - let _ = self.bind_method( - proto, - shape_forge, - string_forge, - "padStart", - methods.pad_start, - 1, - ); - let _ = self.bind_method( - proto, - shape_forge, - string_forge, - "padEnd", - methods.pad_end, - 1, - ); - let _ = self.bind_method( - proto, - shape_forge, - string_forge, - "startsWith", - methods.starts_with, - 1, - ); - let _ = self.bind_method( - proto, - shape_forge, - string_forge, - "endsWith", - methods.ends_with, - 1, - ); - let _ = self.bind_method(proto, shape_forge, string_forge, "split", methods.split, 1); - let _ = self.bind_method( - proto, - shape_forge, - string_forge, - "replace", - methods.replace, - 2, - ); - let _ = self.bind_method( - proto, - shape_forge, - string_forge, - "match", - methods.match_fn, - 1, - ); - let _ = self.bind_method( - proto, - shape_forge, - string_forge, - "search", - methods.search, - 1, - ); - let _ = self.bind_method( - proto, - shape_forge, - string_forge, - "trimStart", - methods.trim_start, - 0, - ); - let _ = self.bind_method( - proto, - shape_forge, - string_forge, - "trimEnd", - methods.trim_end, - 0, - ); - let _ = self.bind_method( - proto, - shape_forge, - string_forge, - "codePointAt", - methods.code_point_at, - 1, - ); - let _ = self.bind_method( - proto, - shape_forge, - string_forge, - "normalize", - methods.normalize, - 0, - ); - let _ = self.bind_method( - proto, - shape_forge, - string_forge, - "matchAll", - methods.match_all, - 1, - ); - let _ = self.bind_method( - proto, - shape_forge, - string_forge, - "replaceAll", - methods.replace_all, - 2, + ("indexOf", methods.index_of, 1), + ("includes", methods.includes, 1), + ("charAt", methods.char_at, 1), + ("charCodeAt", methods.char_code_at, 1), + ("concat", methods.concat, 1), + ("slice", methods.slice, 2), + ("substring", methods.substring, 2), + ("toUpperCase", methods.to_upper_case, 0), + ("toLowerCase", methods.to_lower_case, 0), + ("trim", methods.trim, 0), + ("repeat", methods.repeat, 1), + ("padStart", methods.pad_start, 1), + ("padEnd", methods.pad_end, 1), + ("startsWith", methods.starts_with, 1), + ("endsWith", methods.ends_with, 1), + ("split", methods.split, 1), + ("replace", methods.replace, 2), + ("match", methods.match_fn, 1), + ("search", methods.search, 1), + ("trimStart", methods.trim_start, 0), + ("trimEnd", methods.trim_end, 0), + ("codePointAt", methods.code_point_at, 1), + ("normalize", methods.normalize, 0), + ("matchAll", methods.match_all, 1), + ("replaceAll", methods.replace_all, 2), ); } @@ -969,88 +625,28 @@ impl BuiltinWorld { let ctor = unsafe { &mut *ctor_ptr }; let proto_ptr = P::as_ptr(&self.number_proto) as *mut JsObject; let proto = unsafe { &mut *proto_ptr }; - - let _ = self.bind_method(ctor, shape_forge, string_forge, "isNaN", methods.is_nan, 1); - let _ = self.bind_method( + bind_methods!( + self, ctor, - shape_forge, string_forge, - "isFinite", - methods.is_finite, - 1, - ); - let _ = self.bind_method( - ctor, shape_forge, - string_forge, - "parseInt", - methods.parse_int, - 1, + ("isNaN", methods.is_nan, 1), + ("isFinite", methods.is_finite, 1), + ("parseInt", methods.parse_int, 1), + ("parseFloat", methods.parse_float, 1), + ("isInteger", methods.is_integer, 1), + ("isSafeInteger", methods.is_safe_integer, 1), ); - let _ = self.bind_method( - ctor, - shape_forge, - string_forge, - "parseFloat", - methods.parse_float, - 1, - ); - - let _ = self.bind_method( + bind_methods!( + self, proto, - shape_forge, string_forge, - "toString", - methods.to_string, - 0, - ); - let _ = self.bind_method( - proto, shape_forge, - string_forge, - "toFixed", - methods.to_fixed, - 0, - ); - let _ = self.bind_method( - ctor, - shape_forge, - string_forge, - "isInteger", - methods.is_integer, - 1, - ); - let _ = self.bind_method( - ctor, - shape_forge, - string_forge, - "isSafeInteger", - methods.is_safe_integer, - 1, - ); - let _ = self.bind_method( - proto, - shape_forge, - string_forge, - "toExponential", - methods.to_exponential, - 0, - ); - let _ = self.bind_method( - proto, - shape_forge, - string_forge, - "toPrecision", - methods.to_precision, - 0, - ); - let _ = self.bind_method( - proto, - shape_forge, - string_forge, - "valueOf", - methods.value_of, - 0, + ("toString", methods.to_string, 0), + ("toFixed", methods.to_fixed, 0), + ("toExponential", methods.to_exponential, 0), + ("toPrecision", methods.to_precision, 0), + ("valueOf", methods.value_of, 0), ); } @@ -1063,42 +659,15 @@ impl BuiltinWorld { let proto_ptr = P::as_ptr(&self.function_proto) as *mut JsObject; let proto = unsafe { &mut *proto_ptr }; let fp = self.fn_proto_val(); - - let _ = Self::bind_method_static( + bind_methods_static!( proto, - shape_forge, string_forge, - "call", - methods.call, - 1, - fp, - ); - let _ = Self::bind_method_static( - proto, shape_forge, - string_forge, - "apply", - methods.apply, - 2, - fp, - ); - let _ = Self::bind_method_static( - proto, - shape_forge, - string_forge, - "bind", - methods.bind, - 1, - fp, - ); - let _ = Self::bind_method_static( - proto, - shape_forge, - string_forge, - "toString", - methods.to_string, - 0, fp, + ("call", methods.call, 1), + ("apply", methods.apply, 2), + ("bind", methods.bind, 1), + ("toString", methods.to_string, 0), ); } diff --git a/crates/oxide_vm/src/bindings/bind_number.rs b/crates/oxide_vm/src/bindings/bind_number.rs index e261748..68805c7 100644 --- a/crates/oxide_vm/src/bindings/bind_number.rs +++ b/crates/oxide_vm/src/bindings/bind_number.rs @@ -1,8 +1,8 @@ use std::sync::Arc; -use oxide_kernel::bind_method; use oxide_kernel::builtin::NumberMethods; use oxide_kernel::kernel::OxideKernel; +use oxide_kernel::{bind_method, bind_methods}; use oxide_types::object::JsObject; use oxide_types::value::JsValue; @@ -43,93 +43,33 @@ pub fn bind_number(kernel: &Arc, global: &mut JsObject) { )); num_ctor.set_native_arg_count(1); - num_ctor - .ensure_hash_props() - .push(Box::new(JsValue::float(2.220446049250313e-16))); - let eps_si = kernel.string_forge().intern("EPSILON").0; - let _shape1 = kernel.shape_forge().make_shape(num_ctor.shape_id(), eps_si); - num_ctor.set_shape_id(_shape1); - - num_ctor - .ensure_hash_props() - .push(Box::new(JsValue::float(9007199254740991f64))); - let max_safe_si = kernel.string_forge().intern("MAX_SAFE_INTEGER").0; - let _shape2 = kernel - .shape_forge() - .make_shape(num_ctor.shape_id(), max_safe_si); - num_ctor.set_shape_id(_shape2); - - num_ctor - .ensure_hash_props() - .push(Box::new(JsValue::float(-9007199254740991f64))); - let min_safe_si = kernel.string_forge().intern("MIN_SAFE_INTEGER").0; - let _shape3 = kernel - .shape_forge() - .make_shape(num_ctor.shape_id(), min_safe_si); - num_ctor.set_shape_id(_shape3); - - num_ctor - .ensure_hash_props() - .push(Box::new(JsValue::float(1.7976931348623157e308))); - let max_val_si = kernel.string_forge().intern("MAX_VALUE").0; - let _shape4 = kernel - .shape_forge() - .make_shape(num_ctor.shape_id(), max_val_si); - num_ctor.set_shape_id(_shape4); - - num_ctor - .ensure_hash_props() - .push(Box::new(JsValue::float(5e-324))); - let min_val_si = kernel.string_forge().intern("MIN_VALUE").0; - let _shape5 = kernel - .shape_forge() - .make_shape(num_ctor.shape_id(), min_val_si); - num_ctor.set_shape_id(_shape5); - - num_ctor - .ensure_hash_props() - .push(Box::new(JsValue::float(f64::NAN))); - let nan_si = kernel.string_forge().intern("NaN").0; - let _shape6 = kernel.shape_forge().make_shape(num_ctor.shape_id(), nan_si); - num_ctor.set_shape_id(_shape6); - - num_ctor - .ensure_hash_props() - .push(Box::new(JsValue::float(f64::NEG_INFINITY))); - let neg_inf_si = kernel.string_forge().intern("NEGATIVE_INFINITY").0; - let _shape7 = kernel - .shape_forge() - .make_shape(num_ctor.shape_id(), neg_inf_si); - num_ctor.set_shape_id(_shape7); - - num_ctor - .ensure_hash_props() - .push(Box::new(JsValue::float(f64::INFINITY))); - let pos_inf_si = kernel.string_forge().intern("POSITIVE_INFINITY").0; - let _shape8 = kernel - .shape_forge() - .make_shape(num_ctor.shape_id(), pos_inf_si); - num_ctor.set_shape_id(_shape8); + for (name, value) in [ + ("EPSILON", JsValue::float(2.220446049250313e-16)), + ("MAX_SAFE_INTEGER", JsValue::float(9007199254740991f64)), + ("MIN_SAFE_INTEGER", JsValue::float(-9007199254740991f64)), + ("MAX_VALUE", JsValue::float(1.7976931348623157e308)), + ("MIN_VALUE", JsValue::float(5e-324)), + ("NaN", JsValue::float(f64::NAN)), + ("NEGATIVE_INFINITY", JsValue::float(f64::NEG_INFINITY)), + ("POSITIVE_INFINITY", JsValue::float(f64::INFINITY)), + ] { + num_ctor.ensure_hash_props().push(Box::new(value)); + let prop_si = kernel.string_forge().intern(name).0; + let next_shape = kernel + .shape_forge() + .make_shape(num_ctor.shape_id(), prop_si); + num_ctor.set_shape_id(next_shape); + } } let pi_fn = crate::builtins::number::number_parse_int as *const (); let pf_fn = crate::builtins::number::number_parse_float as *const (); - bind_method!( + bind_methods!( kernel.builtin_world(), global, kernel.string_forge().as_ref(), kernel.shape_forge().as_ref(), - "parseInt", - pi_fn, - 1 - ); - bind_method!( - kernel.builtin_world(), - global, - kernel.string_forge().as_ref(), - kernel.shape_forge().as_ref(), - "parseFloat", - pf_fn, - 1 + ("parseInt", pi_fn, 1), + ("parseFloat", pf_fn, 1), ); } diff --git a/crates/oxide_vm/tests/builtins_number_tests.rs b/crates/oxide_vm/tests/builtins_number_tests.rs index 01d068f..f7252f7 100644 --- a/crates/oxide_vm/tests/builtins_number_tests.rs +++ b/crates/oxide_vm/tests/builtins_number_tests.rs @@ -131,3 +131,17 @@ fn number_to_exponential() { .unwrap_or_default(); assert_eq!(s, "1.23e2"); } + +#[test] +fn number_static_constants_remain_bound() { + let mut vm = Vm::new(); + assert_eq!( + eval(&mut vm, "Number.MAX_SAFE_INTEGER") + .unwrap() + .as_double(), + 9007199254740991f64 + ); + assert!(eval(&mut vm, "Number.POSITIVE_INFINITY > 0") + .unwrap() + .as_bool()); +}