From 5d1d25074e801103b1ca1919794e6de3c9d5a86f 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:53:46 +0800 Subject: [PATCH] =?UTF-8?q?style:=20=E5=87=8F=E5=B0=91=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E6=A0=BC=E5=BC=8F=E5=8C=96=E6=8D=A2=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/oxide_cli/src/main.rs | 28 +- crates/oxide_cli/tests/cli_smoke.rs | 15 +- crates/oxide_compiler/src/compiler.rs | 25 +- crates/oxide_compiler/src/counter.rs | 14 +- crates/oxide_compiler/src/emitter.rs | 249 +++------------- crates/oxide_compiler/src/module.rs | 4 +- crates/oxide_compiler/src/symbol_table.rs | 35 +-- .../tests/arrow_template_tests.rs | 45 +-- .../tests/compile_expr_tests.rs | 105 ++----- .../tests/compile_stmt_tests.rs | 97 ++----- .../tests/structural_hash_tests.rs | 28 +- .../tests/symbol_table_tests.rs | 15 +- crates/oxide_kernel/src/builtin.rs | 210 +++----------- crates/oxide_kernel/src/code_forge.rs | 21 +- crates/oxide_kernel/src/kernel.rs | 12 +- crates/oxide_kernel/src/prop_forge.rs | 4 +- crates/oxide_kernel/src/string_forge.rs | 3 +- crates/oxide_parser/src/lib.rs | 5 +- crates/oxide_parser/tests/parse_smoke.rs | 15 +- crates/oxide_test262/src/main.rs | 78 +---- crates/oxide_types/src/object.rs | 19 +- crates/oxide_types/src/value.rs | 12 +- crates/oxide_vm/src/bindings/bind_array.rs | 9 +- crates/oxide_vm/src/bindings/bind_boolean.rs | 27 +- crates/oxide_vm/src/bindings/bind_date.rs | 204 +++---------- crates/oxide_vm/src/bindings/bind_error.rs | 28 +- crates/oxide_vm/src/bindings/bind_json.rs | 6 +- crates/oxide_vm/src/bindings/bind_map.rs | 9 +- crates/oxide_vm/src/bindings/bind_math.rs | 8 +- crates/oxide_vm/src/bindings/bind_number.rs | 12 +- crates/oxide_vm/src/bindings/bind_object.rs | 20 +- crates/oxide_vm/src/bindings/bind_regexp.rs | 21 +- crates/oxide_vm/src/bindings/bind_set.rs | 9 +- crates/oxide_vm/src/bindings/bind_string.rs | 4 +- crates/oxide_vm/src/bindings/bind_symbol.rs | 28 +- crates/oxide_vm/src/bindings/mod.rs | 18 +- crates/oxide_vm/src/builtins/array.rs | 180 +++--------- crates/oxide_vm/src/builtins/boolean.rs | 6 +- crates/oxide_vm/src/builtins/date.rs | 151 ++-------- crates/oxide_vm/src/builtins/error.rs | 34 +-- crates/oxide_vm/src/builtins/function.rs | 40 +-- crates/oxide_vm/src/builtins/global.rs | 5 +- crates/oxide_vm/src/builtins/json.rs | 38 +-- crates/oxide_vm/src/builtins/map.rs | 25 +- crates/oxide_vm/src/builtins/math.rs | 18 +- crates/oxide_vm/src/builtins/number.rs | 17 +- crates/oxide_vm/src/builtins/object.rs | 15 +- crates/oxide_vm/src/builtins/regexp.rs | 44 +-- crates/oxide_vm/src/builtins/set.rs | 30 +- crates/oxide_vm/src/builtins/string.rs | 73 ++--- crates/oxide_vm/src/builtins/symbol.rs | 11 +- crates/oxide_vm/src/coercion.rs | 24 +- crates/oxide_vm/src/dispatch/call.rs | 13 +- crates/oxide_vm/src/dispatch/comparison.rs | 36 +-- crates/oxide_vm/src/dispatch/member.rs | 97 ++----- crates/oxide_vm/src/dispatch/property.rs | 63 +--- crates/oxide_vm/src/vm.rs | 269 ++++-------------- crates/oxide_vm/src/vm_pool.rs | 6 +- crates/oxide_vm/tests/arrow_tests.rs | 5 +- crates/oxide_vm/tests/bench_tests.rs | 6 +- crates/oxide_vm/tests/builtins_array_tests.rs | 7 +- .../oxide_vm/tests/builtins_boolean_tests.rs | 16 +- crates/oxide_vm/tests/builtins_date_tests.rs | 18 +- crates/oxide_vm/tests/builtins_error_tests.rs | 25 +- .../oxide_vm/tests/builtins_function_tests.rs | 13 +- .../oxide_vm/tests/builtins_globals_tests.rs | 7 +- crates/oxide_vm/tests/builtins_map_tests.rs | 22 +- crates/oxide_vm/tests/builtins_math_tests.rs | 7 +- .../oxide_vm/tests/builtins_number_tests.rs | 36 +-- .../oxide_vm/tests/builtins_object_tests.rs | 7 +- .../oxide_vm/tests/builtins_regexp_tests.rs | 18 +- crates/oxide_vm/tests/builtins_set_tests.rs | 17 +- .../oxide_vm/tests/builtins_string_tests.rs | 12 +- .../oxide_vm/tests/builtins_symbol_tests.rs | 12 +- crates/oxide_vm/tests/coercion_tests.rs | 40 +-- crates/oxide_vm/tests/control_flow_tests.rs | 55 +--- crates/oxide_vm/tests/function_tests.rs | 43 +-- crates/oxide_vm/tests/json_tests.rs | 24 +- crates/oxide_vm/tests/mem_tests.rs | 5 +- crates/oxide_vm/tests/proto_chain_tests.rs | 157 ++-------- crates/oxide_vm/tests/regression_tests.rs | 51 +--- crates/oxide_vm/tests/scoping_tests.rs | 10 +- crates/oxide_vm/tests/template_tests.rs | 16 +- crates/oxide_vm/tests/value_tests.rs | 4 +- crates/oxide_vm/tests/vm_tests.rs | 30 +- rustfmt.toml | 17 +- 86 files changed, 672 insertions(+), 2645 deletions(-) diff --git a/crates/oxide_cli/src/main.rs b/crates/oxide_cli/src/main.rs index fabff5f..d3b03df 100644 --- a/crates/oxide_cli/src/main.rs +++ b/crates/oxide_cli/src/main.rs @@ -77,11 +77,7 @@ fn make_kernel() -> Arc { } fn make_pool(kernel: &Arc) -> Arc { - VmPool::new( - Arc::clone(kernel), - kernel.config().min_pool_size, - kernel.config().max_pool_size, - ) + VmPool::new(Arc::clone(kernel), kernel.config().min_pool_size, kernel.config().max_pool_size) } fn eval(code: &str, kernel: &Arc, pool: &Arc) -> ExitCode { @@ -108,11 +104,7 @@ fn eval(code: &str, kernel: &Arc, pool: &Arc) -> ExitCode { let mut guard = pool.spawn(); match guard.vm_mut().run(&module) { Ok(result) => { - format_result( - kernel.string_forge().as_ref(), - kernel.shape_forge().as_ref(), - result, - ); + format_result(kernel.string_forge().as_ref(), kernel.shape_forge().as_ref(), result); ExitCode::SUCCESS } Err(err) => { @@ -218,10 +210,7 @@ fn compile(expr: Option, file: Option) -> ExitCode { } } } else { - eprintln!( - "{}", - Red.paint("compile requires -e '' or a file path") - ); + eprintln!("{}", Red.paint("compile requires -e '' or a file path")); return ExitCode::FAILURE; }; @@ -279,11 +268,7 @@ fn repl() -> ExitCode { let mut input_buf = String::new(); loop { - let prompt = if input_buf.is_empty() { - "oxide> " - } else { - "...> " - }; + let prompt = if input_buf.is_empty() { "oxide> " } else { "...> " }; match rl.readline(prompt) { Ok(line) => { let trimmed = line.trim(); @@ -336,9 +321,6 @@ fn repl() -> ExitCode { } fn not_implemented(command: &str) -> ExitCode { use ansi_term::Colour::Yellow; - eprintln!( - "{}", - Yellow.paint(format!("'{command}' is not yet implemented")) - ); + eprintln!("{}", Yellow.paint(format!("'{command}' is not yet implemented"))); ExitCode::SUCCESS } diff --git a/crates/oxide_cli/tests/cli_smoke.rs b/crates/oxide_cli/tests/cli_smoke.rs index ba770c6..d7451f8 100644 --- a/crates/oxide_cli/tests/cli_smoke.rs +++ b/crates/oxide_cli/tests/cli_smoke.rs @@ -19,15 +19,9 @@ fn eval_syntax_error() { .output() .expect("failed to run oxide eval"); - assert!( - !output.status.success(), - "syntax error should exit non-zero" - ); + assert!(!output.status.success(), "syntax error should exit non-zero"); let stderr = String::from_utf8_lossy(&output.stderr); - assert!( - !stderr.is_empty(), - "syntax error should produce stderr output" - ); + assert!(!stderr.is_empty(), "syntax error should produce stderr output"); } #[test] @@ -51,8 +45,5 @@ fn bench_not_implemented() { .expect("failed to run oxide bench"); let stderr = String::from_utf8_lossy(&output.stderr); - assert!( - stderr.contains("not yet implemented"), - "bench should print not-implemented message" - ); + assert!(stderr.contains("not yet implemented"), "bench should print not-implemented message"); } diff --git a/crates/oxide_compiler/src/compiler.rs b/crates/oxide_compiler/src/compiler.rs index 968b58a..3340e28 100644 --- a/crates/oxide_compiler/src/compiler.rs +++ b/crates/oxide_compiler/src/compiler.rs @@ -97,12 +97,7 @@ impl CompileCtx { } pub(crate) fn emit_load_const(&mut self, reg: u8, idx: u16) { - self.emit(opcode::encode( - OpCode::LOAD_CONST, - reg, - (idx & 0xFF) as u8, - ((idx >> 8) & 0xFF) as u8, - )); + self.emit(opcode::encode(OpCode::LOAD_CONST, reg, (idx & 0xFF) as u8, ((idx >> 8) & 0xFF) as u8)); } pub(crate) fn alloc_reg(&mut self) -> u8 { @@ -153,21 +148,13 @@ impl CompileCtx { } pub(crate) fn declare( - &mut self, - name: &str, - reg: u8, - kind: VariableDeclarationKind, - is_const: bool, + &mut self, name: &str, reg: u8, kind: VariableDeclarationKind, is_const: bool, ) -> Result<(), String> { self.symbols.declare(name, reg, kind, is_const) } pub(crate) fn declare_initialized( - &mut self, - name: &str, - reg: u8, - kind: VariableDeclarationKind, - is_const: bool, + &mut self, name: &str, reg: u8, kind: VariableDeclarationKind, is_const: bool, ) -> Result<(), String> { self.symbols.declare_initialized(name, reg, kind, is_const) } @@ -277,11 +264,7 @@ impl Compiler { /// When `is_expression_body` is true (arrow function with expression body), /// the last expression's value is returned instead of undefined. pub(crate) fn compile_function_body<'a>( - &self, - param_names: &[String], - body_stmts: &[Statement<'a>], - parent_ctx: &CompileCtx, - is_expression_body: bool, + &self, param_names: &[String], body_stmts: &[Statement<'a>], parent_ctx: &CompileCtx, is_expression_body: bool, ) -> Result { let mut ctx = CompileCtx::new(); diff --git a/crates/oxide_compiler/src/counter.rs b/crates/oxide_compiler/src/counter.rs index 924c5a3..ac386bb 100644 --- a/crates/oxide_compiler/src/counter.rs +++ b/crates/oxide_compiler/src/counter.rs @@ -1,6 +1,6 @@ use oxide_parser::{ - AssignmentOperator, Expression, ForStatementInit, SimpleAssignmentTarget, Statement, - UnaryOperator, VariableDeclarationKind, + AssignmentOperator, Expression, ForStatementInit, SimpleAssignmentTarget, Statement, UnaryOperator, + VariableDeclarationKind, }; use crate::compiler::{is_side_effect_free, CompileCtx, Compiler, Label}; @@ -192,8 +192,7 @@ impl Compiler { // Hoisting: declare function name as initialized let func_reg = ctx.alloc_reg(); - let _ = - ctx.declare_initialized(&name, func_reg, VariableDeclarationKind::Var, false); + let _ = ctx.declare_initialized(&name, func_reg, VariableDeclarationKind::Var, false); // Body is compiled in the emit pass only. // FD emits LOAD_CONST(BytecodeFunc) + STORE_VAR @@ -326,8 +325,7 @@ impl Compiler { ctx.projected_pc += 1; // LOAD_VAR result <- regs[0] } Expression::AssignmentExpression(assign) => { - if let oxide_parser::AssignmentTarget::StaticMemberExpression(member) = &assign.left - { + if let oxide_parser::AssignmentTarget::StaticMemberExpression(member) = &assign.left { self.count_expression(&member.object, ctx); self.count_expression(&assign.right, ctx); if assign.operator != AssignmentOperator::Assign { @@ -338,9 +336,7 @@ impl Compiler { ctx.projected_pc += 1; // LOAD_CONST key ctx.projected_pc += 1; // IC_SET_PROP or COMPOUND_MEMBER_* ctx.projected_pc += 3; // 3 IC ext words - } else if let oxide_parser::AssignmentTarget::ComputedMemberExpression(member) = - &assign.left - { + } else if let oxide_parser::AssignmentTarget::ComputedMemberExpression(member) = &assign.left { self.count_expression(&member.object, ctx); self.count_expression(&member.expression, ctx); self.count_expression(&assign.right, ctx); diff --git a/crates/oxide_compiler/src/emitter.rs b/crates/oxide_compiler/src/emitter.rs index 5d3e65d..f9fd2ed 100644 --- a/crates/oxide_compiler/src/emitter.rs +++ b/crates/oxide_compiler/src/emitter.rs @@ -1,23 +1,17 @@ use crate::compiler::Label; use crate::opcode::{self, OpCode}; use oxide_parser::{ - AssignmentOperator, Expression, ForStatementInit, ForStatementLeft, SimpleAssignmentTarget, - Statement, UnaryOperator, UpdateOperator, VariableDeclarationKind, + AssignmentOperator, Expression, ForStatementInit, ForStatementLeft, SimpleAssignmentTarget, Statement, + UnaryOperator, UpdateOperator, VariableDeclarationKind, }; use crate::compiler::{is_int_literal, is_side_effect_free, BinaryOperator, CompileCtx, Compiler}; use crate::module::Constant; impl Compiler { - pub(crate) fn emit_statement( - &self, - stmt: &Statement, - ctx: &mut CompileCtx, - ) -> Result, String> { + pub(crate) fn emit_statement(&self, stmt: &Statement, ctx: &mut CompileCtx) -> Result, String> { match stmt { - Statement::ExpressionStatement(es) => { - Ok(Some(self.emit_expression(&es.expression, ctx)?)) - } + Statement::ExpressionStatement(es) => Ok(Some(self.emit_expression(&es.expression, ctx)?)), Statement::VariableDeclaration(decl) => { let mut r = None; for d in &decl.declarations { @@ -34,12 +28,7 @@ impl Compiler { if let Some(init) = &d.init { let val_reg = self.emit_expression(init, ctx)?; let const_flag = if is_const { 1 } else { 0 }; - ctx.emit(opcode::encode( - OpCode::STORE_VAR, - var_reg, - val_reg, - const_flag, - )); + ctx.emit(opcode::encode(OpCode::STORE_VAR, var_reg, val_reg, const_flag)); ctx.init_var(name); // Name inference (D-04): if the initializer is an arrow function, // set the compiled sub_module's function_name. @@ -176,18 +165,11 @@ impl Compiler { } else if let ForStatementInit::VariableDeclaration(decl) = init { for d in &decl.declarations { let name = match &d.id { - oxide_parser::BindingPattern::BindingIdentifier(bi) => { - bi.name.as_str() - } + oxide_parser::BindingPattern::BindingIdentifier(bi) => bi.name.as_str(), _ => return Err("destructuring not supported".into()), }; let var_reg = ctx.alloc_reg(); - ctx.declare( - name, - var_reg, - decl.kind, - matches!(decl.kind, VariableDeclarationKind::Const), - )?; + ctx.declare(name, var_reg, decl.kind, matches!(decl.kind, VariableDeclarationKind::Const))?; if let Some(init_expr) = &d.init { let val_reg = self.emit_expression(init_expr, ctx)?; ctx.emit(opcode::encode(OpCode::STORE_VAR, var_reg, val_reg, 0)); @@ -243,18 +225,11 @@ impl Compiler { ForStatementLeft::VariableDeclaration(decl) => { for d in &decl.declarations { let name = match &d.id { - oxide_parser::BindingPattern::BindingIdentifier(bi) => { - bi.name.as_str() - } + oxide_parser::BindingPattern::BindingIdentifier(bi) => bi.name.as_str(), _ => return Err("destructuring not supported".into()), }; let var_reg = ctx.alloc_reg(); - ctx.declare( - name, - var_reg, - decl.kind, - matches!(decl.kind, VariableDeclarationKind::Const), - )?; + ctx.declare(name, var_reg, decl.kind, matches!(decl.kind, VariableDeclarationKind::Const))?; ctx.emit(opcode::encode(OpCode::STORE_VAR, var_reg, key_reg, 0)); ctx.init_var(name); } @@ -321,9 +296,7 @@ impl Compiler { let break_label = if let Some(sw_label) = ctx.current_switch() { *sw_label } else { - let (bl, _) = ctx - .current_loop() - .ok_or("break outside switch or loop".to_string())?; + let (bl, _) = ctx.current_loop().ok_or("break outside switch or loop".to_string())?; *bl }; let break_pos = ctx.resolve_label(break_label)?; @@ -332,9 +305,7 @@ impl Compiler { Ok(None) } Statement::ContinueStatement(_) => { - let (_, continue_label) = ctx - .current_loop() - .ok_or("continue outside loop".to_string())?; + let (_, continue_label) = ctx.current_loop().ok_or("continue outside loop".to_string())?; let continue_pos = ctx.resolve_label(*continue_label)?; let offset = (continue_pos as isize) - (ctx.bytecode.len() as isize); ctx.emit(opcode::encode_jmp(offset as i16)); @@ -357,15 +328,10 @@ impl Compiler { } // Extract body statements (pass by reference) - let body_stmts: &[Statement] = if let Some(body) = &fd.body { - &body.statements - } else { - &[] - }; + let body_stmts: &[Statement] = if let Some(body) = &fd.body { &body.statements } else { &[] }; // Compile body into sub-module - let mut sub_module = - self.compile_function_body(¶m_names, body_stmts, ctx, false)?; + let mut sub_module = self.compile_function_body(¶m_names, body_stmts, ctx, false)?; sub_module.function_name = Some(name.clone()); ctx.sub_modules.push(sub_module); // 1-indexed: 0 = no sub_module (sentinel) @@ -414,12 +380,7 @@ impl Compiler { last_try_result = Some(r); } } - ctx.emit(opcode::encode( - OpCode::LOAD_VAR, - result_reg, - last_try_result.unwrap_or(result_reg), - 0, - )); + ctx.emit(opcode::encode(OpCode::LOAD_VAR, result_reg, last_try_result.unwrap_or(result_reg), 0)); if has_catch { ctx.emit(opcode::encode(OpCode::TRY_END, 0, 0, 0)); @@ -446,14 +407,8 @@ impl Compiler { ctx.push_scope(); if let Some(param) = &catch.param { let catch_reg = ctx.alloc_reg(); - if let oxide_parser::BindingPattern::BindingIdentifier(bi) = ¶m.pattern - { - ctx.declare_initialized( - bi.name.as_str(), - catch_reg, - VariableDeclarationKind::Let, - false, - )?; + if let oxide_parser::BindingPattern::BindingIdentifier(bi) = ¶m.pattern { + ctx.declare_initialized(bi.name.as_str(), catch_reg, VariableDeclarationKind::Let, false)?; ctx.emit(opcode::encode(OpCode::STORE_VAR, catch_reg, 0, 0)); } } @@ -463,12 +418,7 @@ impl Compiler { last_catch_result = Some(r); } } - ctx.emit(opcode::encode( - OpCode::LOAD_VAR, - result_reg, - last_catch_result.unwrap_or(result_reg), - 0, - )); + ctx.emit(opcode::encode(OpCode::LOAD_VAR, result_reg, last_catch_result.unwrap_or(result_reg), 0)); ctx.pop_scope(); } @@ -513,11 +463,7 @@ impl Compiler { } } - pub(crate) fn emit_expression( - &self, - expr: &Expression, - ctx: &mut CompileCtx, - ) -> Result { + pub(crate) fn emit_expression(&self, expr: &Expression, ctx: &mut CompileCtx) -> Result { match expr { Expression::NumericLiteral(n) => { let idx = if is_int_literal(n.value) { @@ -607,8 +553,7 @@ impl Compiler { Expression::StaticMemberExpression(member) => { let obj_reg = self.emit_expression(&member.object, ctx)?; let prop_name = member.property.name.as_str(); - let const_idx = - ctx.add_constant(Constant::String(prop_name.to_string())); + let const_idx = ctx.add_constant(Constant::String(prop_name.to_string())); let r = ctx.alloc_reg(); ctx.emit(opcode::encode(OpCode::DELETE_PROP_STATIC, r, obj_reg, 0)); ctx.emit(const_idx as u32); @@ -618,12 +563,7 @@ impl Compiler { let obj_reg = self.emit_expression(&member.object, ctx)?; let key_reg = self.emit_expression(&member.expression, ctx)?; let r = ctx.alloc_reg(); - ctx.emit(opcode::encode( - OpCode::DELETE_PROP_DYNAMIC, - r, - obj_reg, - key_reg, - )); + ctx.emit(opcode::encode(OpCode::DELETE_PROP_DYNAMIC, r, obj_reg, key_reg)); Ok(r) } _ => Err("invalid delete target".into()), @@ -709,12 +649,7 @@ impl Compiler { let prop_name = member.property.name.as_str(); let idx = ctx.add_constant(Constant::String(prop_name.to_string())); let key_reg = ctx.alloc_reg(); - ctx.emit(opcode::encode( - OpCode::LOAD_CONST, - key_reg, - (idx & 0xFF) as u8, - ((idx >> 8) & 0xFF) as u8, - )); + ctx.emit(opcode::encode(OpCode::LOAD_CONST, key_reg, (idx & 0xFF) as u8, ((idx >> 8) & 0xFF) as u8)); ctx.emit(opcode::encode(OpCode::IC_GET_PROP, 0, obj_reg, key_reg)); ctx.emit(0); ctx.emit(0); @@ -725,12 +660,7 @@ impl Compiler { let obj_reg = self.emit_expression(&member.object, ctx)?; let key_reg = self.emit_expression(&member.expression, ctx)?; let r = ctx.alloc_reg(); - ctx.emit(opcode::encode( - OpCode::GET_PROP_DYNAMIC, - obj_reg, - key_reg, - r, - )); + ctx.emit(opcode::encode(OpCode::GET_PROP_DYNAMIC, obj_reg, key_reg, r)); Ok(r) } Expression::ObjectExpression(obj) => { @@ -741,9 +671,7 @@ impl Compiler { return Err("spread properties not yet supported".into()); }; let prop_name = match &p.key { - oxide_parser::PropertyKey::StaticIdentifier(ident) => { - ident.name.as_str().to_string() - } + oxide_parser::PropertyKey::StaticIdentifier(ident) => ident.name.as_str().to_string(), oxide_parser::PropertyKey::StringLiteral(s) => s.value.to_string(), _ => return Err("unsupported object property key type".into()), }; @@ -765,12 +693,7 @@ impl Compiler { Expression::ArrayExpression(arr) => { let arr_reg = ctx.alloc_reg(); let n = arr.elements.len() as u16; - ctx.emit(opcode::encode( - OpCode::NEW_ARRAY, - arr_reg, - (n & 0xFF) as u8, - ((n >> 8) & 0xFF) as u8, - )); + ctx.emit(opcode::encode(OpCode::NEW_ARRAY, arr_reg, (n & 0xFF) as u8, ((n >> 8) & 0xFF) as u8)); for (i, elem) in arr.elements.iter().enumerate() { let Some(e) = elem.as_expression() else { return Err("spread not supported".into()); @@ -784,8 +707,7 @@ impl Compiler { Ok(arr_reg) } Expression::AssignmentExpression(assign) => { - if let oxide_parser::AssignmentTarget::StaticMemberExpression(member) = &assign.left - { + if let oxide_parser::AssignmentTarget::StaticMemberExpression(member) = &assign.left { let obj_reg = self.emit_expression(&member.object, ctx)?; let val_reg = self.emit_expression(&assign.right, ctx)?; let prop_name = member.property.name.as_str(); @@ -808,33 +730,19 @@ impl Compiler { ctx.emit(0); Ok(val_reg) } else { - ctx.emit(opcode::encode( - OpCode::IC_SET_PROP, - obj_reg, - val_reg, - key_reg, - )); + ctx.emit(opcode::encode(OpCode::IC_SET_PROP, obj_reg, val_reg, key_reg)); ctx.emit(0); ctx.emit(0); ctx.emit(0); Ok(val_reg) } - } else if let oxide_parser::AssignmentTarget::ComputedMemberExpression(member) = - &assign.left - { + } else if let oxide_parser::AssignmentTarget::ComputedMemberExpression(member) = &assign.left { let obj_reg = self.emit_expression(&member.object, ctx)?; let key_reg = self.emit_expression(&member.expression, ctx)?; let val_reg = self.emit_expression(&assign.right, ctx)?; - ctx.emit(opcode::encode( - OpCode::SET_PROP_DYNAMIC, - obj_reg, - key_reg, - val_reg, - )); + ctx.emit(opcode::encode(OpCode::SET_PROP_DYNAMIC, obj_reg, key_reg, val_reg)); Ok(val_reg) - } else if let oxide_parser::AssignmentTarget::AssignmentTargetIdentifier(id_ref) = - &assign.left - { + } else if let oxide_parser::AssignmentTarget::AssignmentTargetIdentifier(id_ref) = &assign.left { if assign.operator != AssignmentOperator::Assign { if assign.operator == AssignmentOperator::Addition || assign.operator == AssignmentOperator::Subtraction @@ -858,10 +766,7 @@ impl Compiler { ctx.emit(opcode::encode(op, var_reg, rhs, 0)); Ok(var_reg) } else { - Err(format!( - "compound assignment operator {:?} not supported", - assign.operator - )) + Err(format!("compound assignment operator {:?} not supported", assign.operator)) } } else { let val_reg = self.emit_expression(&assign.right, ctx)?; @@ -869,12 +774,7 @@ impl Compiler { let var_reg = ctx.lookup_or_global(name); let is_const = ctx.lookup_const_flag(name); let const_flag = if is_const { 1 } else { 0 }; - ctx.emit(opcode::encode( - OpCode::STORE_VAR, - var_reg, - val_reg, - const_flag, - )); + ctx.emit(opcode::encode(OpCode::STORE_VAR, var_reg, val_reg, const_flag)); Ok(val_reg) } } else { @@ -953,12 +853,7 @@ impl Compiler { let quasi_const_idxs: Vec = quasis .iter() .map(|q| { - let s = q - .value - .cooked - .as_ref() - .map(|c| c.to_string()) - .unwrap_or_default(); + let s = q.value.cooked.as_ref().map(|c| c.to_string()).unwrap_or_default(); ctx.add_constant(Constant::String(s)) }) .collect(); @@ -1000,41 +895,21 @@ impl Compiler { // 2. Build cooked strings array (into a temp register) let cooked_temp = ctx.alloc_reg(); - ctx.emit(opcode::encode( - OpCode::NEW_ARRAY, - cooked_temp, - quasis.len() as u8, - 0, - )); + ctx.emit(opcode::encode(OpCode::NEW_ARRAY, cooked_temp, quasis.len() as u8, 0)); for (i, quasi) in quasis.iter().enumerate() { - let s = quasi - .value - .cooked - .as_ref() - .map(|c| c.to_string()) - .unwrap_or_default(); + let s = quasi.value.cooked.as_ref().map(|c| c.to_string()).unwrap_or_default(); let const_idx = ctx.add_constant(Constant::String(s)); let str_reg = ctx.alloc_reg(); ctx.emit_load_const(str_reg, const_idx); let idx_const = ctx.add_constant(Constant::Int(i as i32)); let idx_reg = ctx.alloc_reg(); ctx.emit_load_const(idx_reg, idx_const); - ctx.emit(opcode::encode( - OpCode::SET_ELEM, - cooked_temp, - idx_reg, - str_reg, - )); + ctx.emit(opcode::encode(OpCode::SET_ELEM, cooked_temp, idx_reg, str_reg)); } // 3. Build raw strings array (into a temp register) let raw_temp = ctx.alloc_reg(); - ctx.emit(opcode::encode( - OpCode::NEW_ARRAY, - raw_temp, - quasis.len() as u8, - 0, - )); + ctx.emit(opcode::encode(OpCode::NEW_ARRAY, raw_temp, quasis.len() as u8, 0)); for (i, quasi) in quasis.iter().enumerate() { let raw = quasi.value.raw.to_string(); let const_idx = ctx.add_constant(Constant::String(raw)); @@ -1061,12 +936,7 @@ impl Compiler { } // Copy temps to consecutive slots using LOAD_VAR (register-to-register move) - ctx.emit(opcode::encode( - OpCode::LOAD_VAR, - cooked_slot, - cooked_temp, - 0, - )); + ctx.emit(opcode::encode(OpCode::LOAD_VAR, cooked_slot, cooked_temp, 0)); ctx.emit(opcode::encode(OpCode::LOAD_VAR, raw_slot, raw_temp, 0)); for (slot, temp) in expr_slots.iter().zip(expr_temps.iter()) { ctx.emit(opcode::encode(OpCode::LOAD_VAR, *slot, *temp, 0)); @@ -1079,12 +949,7 @@ impl Compiler { // 7. Emit CALL(tag, undefined, cooked_slot) let arg_count = 2 + expressions.len(); - ctx.emit(opcode::encode( - OpCode::CALL, - tag_reg, - undef_reg, - cooked_slot, - )); + ctx.emit(opcode::encode(OpCode::CALL, tag_reg, undef_reg, cooked_slot)); ctx.emit(arg_count as u32); // 8. Result from regs[0] @@ -1113,8 +978,7 @@ impl Compiler { let body_stmts = &arrow.body.statements; let is_expr_body = arrow.expression; - let mut sub_module = - self.compile_function_body(¶m_names, body_stmts, ctx, is_expr_body)?; + let mut sub_module = self.compile_function_body(¶m_names, body_stmts, ctx, is_expr_body)?; sub_module.is_arrow = true; ctx.sub_modules.push(sub_module); @@ -1135,14 +999,9 @@ impl Compiler { } } - let body_stmts: &[Statement] = if let Some(body) = &fe.body { - &body.statements - } else { - &[] - }; + let body_stmts: &[Statement] = if let Some(body) = &fe.body { &body.statements } else { &[] }; - let mut sub_module = - self.compile_function_body(¶m_names, body_stmts, ctx, false)?; + let mut sub_module = self.compile_function_body(¶m_names, body_stmts, ctx, false)?; if let Some(id) = &fe.id { sub_module.function_name = Some(id.name.to_string()); } @@ -1163,18 +1022,9 @@ impl Compiler { arg_regs.push(self.emit_expression(expr, ctx)?); } } - let first_arg_reg = if arg_regs.is_empty() { - 0u8 - } else { - arg_regs[0] - }; + let first_arg_reg = if arg_regs.is_empty() { 0u8 } else { arg_regs[0] }; let r = ctx.alloc_reg(); - ctx.emit(opcode::encode( - OpCode::NEW_EXPRESSION, - r, - constructor_reg, - first_arg_reg, - )); + ctx.emit(opcode::encode(OpCode::NEW_EXPRESSION, r, constructor_reg, first_arg_reg)); ctx.emit(arg_regs.len() as u32); Ok(r) } @@ -1209,15 +1059,9 @@ impl Compiler { arg_regs.push(self.emit_expression(expr, ctx)?); } } - let first_arg_reg = if arg_regs.is_empty() { - 0u8 - } else { - arg_regs[0] - }; + let first_arg_reg = if arg_regs.is_empty() { 0u8 } else { arg_regs[0] }; let op = match &call.callee { - Expression::Identifier(ident) if ctx.is_builtin(ident.name.as_str()) => { - OpCode::CALL_NATIVE - } + Expression::Identifier(ident) if ctx.is_builtin(ident.name.as_str()) => OpCode::CALL_NATIVE, Expression::StaticMemberExpression(m) => { if let Expression::Identifier(ident) = &m.object { if ctx.is_builtin(ident.name.as_str()) { @@ -1251,8 +1095,7 @@ impl Compiler { let last_slash = raw_str.rfind('/').unwrap_or(raw_str.len() - 1); let pattern = &raw_str[1..last_slash]; let flags = &raw_str[last_slash + 1..]; - let ci = ctx - .add_constant(Constant::RegExp(pattern.to_string(), flags.to_string())); + let ci = ctx.add_constant(Constant::RegExp(pattern.to_string(), flags.to_string())); let r = ctx.alloc_reg(); ctx.emit_load_const(r, ci); Ok(r) diff --git a/crates/oxide_compiler/src/module.rs b/crates/oxide_compiler/src/module.rs index 61e5351..3a8d9cc 100644 --- a/crates/oxide_compiler/src/module.rs +++ b/crates/oxide_compiler/src/module.rs @@ -79,9 +79,7 @@ impl fmt::Display for CompiledModule { writeln!(f, "; constants:")?; for (i, c) in self.constants.iter().enumerate() { match c { - Constant::BytecodeFunc(idx) => { - writeln!(f, "; [{i}] = BytecodeFunc(sub_module[{idx}])")? - } + Constant::BytecodeFunc(idx) => writeln!(f, "; [{i}] = BytecodeFunc(sub_module[{idx}])")?, other => writeln!(f, "; [{i}] = {other:?}")?, } } diff --git a/crates/oxide_compiler/src/symbol_table.rs b/crates/oxide_compiler/src/symbol_table.rs index eeee845..1b5ecb1 100644 --- a/crates/oxide_compiler/src/symbol_table.rs +++ b/crates/oxide_compiler/src/symbol_table.rs @@ -47,10 +47,7 @@ impl SymbolTable { } pub(crate) fn push_scope_with_kind(&mut self, kind: ScopeKind) { - self.scopes.push(Scope { - bindings: HashMap::new(), - kind, - }); + self.scopes.push(Scope { bindings: HashMap::new(), kind }); } pub fn pop_scope(&mut self) { @@ -69,11 +66,7 @@ impl SymbolTable { } pub fn declare( - &mut self, - name: &str, - reg: u8, - kind: VariableDeclarationKind, - is_const: bool, + &mut self, name: &str, reg: u8, kind: VariableDeclarationKind, is_const: bool, ) -> Result<(), String> { let target_idx = if matches!(kind, VariableDeclarationKind::Var) { self.find_var_target_scope() @@ -138,11 +131,7 @@ impl SymbolTable { } pub fn declare_initialized( - &mut self, - name: &str, - reg: u8, - kind: VariableDeclarationKind, - is_const: bool, + &mut self, name: &str, reg: u8, kind: VariableDeclarationKind, is_const: bool, ) -> Result<(), String> { let target_idx = if matches!(kind, VariableDeclarationKind::Var) { self.find_var_target_scope() @@ -167,14 +156,11 @@ impl SymbolTable { } pub fn pre_register_global(&mut self, name: &str, reg: u8) { - self.scopes[0] - .bindings - .entry(name.to_string()) - .or_insert(Binding { - reg, - initialized: true, - is_const: false, - }); + self.scopes[0].bindings.entry(name.to_string()).or_insert(Binding { + reg, + initialized: true, + is_const: false, + }); } pub fn init_var(&mut self, name: &str) { @@ -220,10 +206,7 @@ mod tests { fn tdz_error() { let mut st = SymbolTable::new(); st.declare("x", 0, l(), false).unwrap(); - assert!(st - .lookup("x") - .unwrap_err() - .contains("before initialization")); + assert!(st.lookup("x").unwrap_err().contains("before initialization")); } #[test] diff --git a/crates/oxide_compiler/tests/arrow_template_tests.rs b/crates/oxide_compiler/tests/arrow_template_tests.rs index 37f39be..1c1546e 100644 --- a/crates/oxide_compiler/tests/arrow_template_tests.rs +++ b/crates/oxide_compiler/tests/arrow_template_tests.rs @@ -27,29 +27,20 @@ fn hash_arrow_expression_body() { fn hash_arrow_different_params() { let hash_a = parse_to_hash("var f = (x) => x;"); let hash_b = parse_to_hash("var f = (x, y) => x;"); - assert_ne!( - hash_a, hash_b, - "different param counts must produce different hashes" - ); + assert_ne!(hash_a, hash_b, "different param counts must produce different hashes"); } #[test] fn hash_arrow_vs_regular_function() { let hash_a = parse_to_hash("var f = () => 42;"); let hash_b = parse_to_hash("var f = function() { return 42; };"); - assert_ne!( - hash_a, hash_b, - "arrow and regular functions must have different hashes" - ); + assert_ne!(hash_a, hash_b, "arrow and regular functions must have different hashes"); } #[test] fn hash_arrow_block_body() { let hash = parse_to_hash("var f = (a, b) => { return a + b; };"); - assert!( - hash != 0, - "arrow with block body should produce a non-zero hash" - ); + assert!(hash != 0, "arrow with block body should produce a non-zero hash"); } #[test] @@ -57,10 +48,7 @@ fn hash_arrow_same_shape() { // Same structural shape: different variable name, same arrow expression let hash_a = parse_to_hash("var f = () => 1 + 2;"); let hash_b = parse_to_hash("var g = () => 1 + 2;"); - assert_eq!( - hash_a, hash_b, - "same-shaped arrow functions should have same hash" - ); + assert_eq!(hash_a, hash_b, "same-shaped arrow functions should have same hash"); } // -- Arrow function compilation tests -- @@ -70,20 +58,14 @@ fn compile_arrow_expression_body() { let module = compile_source("var f = () => 42; f();"); // Verify the sub_module for the arrow is marked as is_arrow let arrow_found = module.sub_modules.iter().any(|m| m.is_arrow); - assert!( - arrow_found, - "arrow function sub_module should have is_arrow=true" - ); + assert!(arrow_found, "arrow function sub_module should have is_arrow=true"); } #[test] fn compile_arrow_block_body() { let module = compile_source("var f = (a, b) => { return a + b; }; f(1, 2);"); let arrow_found = module.sub_modules.iter().any(|m| m.is_arrow); - assert!( - arrow_found, - "arrow with block body should have is_arrow=true" - ); + assert!(arrow_found, "arrow with block body should have is_arrow=true"); } #[test] @@ -94,10 +76,7 @@ fn compile_arrow_name_inference() { .sub_modules .iter() .any(|m| m.is_arrow && m.function_name.as_deref() == Some("myArrow")); - assert!( - named, - "arrow function should have function_name='myArrow' from D-04 inference" - ); + assert!(named, "arrow function should have function_name='myArrow' from D-04 inference"); } #[test] @@ -105,20 +84,14 @@ fn compile_regular_function_not_arrow() { let module = compile_source("var f = function() { return 42; }; f();"); // Regular FunctionExpression should NOT have is_arrow=true let has_arrow = module.sub_modules.iter().any(|m| m.is_arrow); - assert!( - !has_arrow, - "regular function expression should not be marked as arrow" - ); + assert!(!has_arrow, "regular function expression should not be marked as arrow"); } #[test] fn compile_arrow_single_param_no_parens() { let module = compile_source("var double = x => x * 2; double(5);"); let arrow_found = module.sub_modules.iter().any(|m| m.is_arrow); - assert!( - arrow_found, - "single-param arrow without parens should compile" - ); + assert!(arrow_found, "single-param arrow without parens should compile"); } #[test] diff --git a/crates/oxide_compiler/tests/compile_expr_tests.rs b/crates/oxide_compiler/tests/compile_expr_tests.rs index 409d383..5d1dafa 100644 --- a/crates/oxide_compiler/tests/compile_expr_tests.rs +++ b/crates/oxide_compiler/tests/compile_expr_tests.rs @@ -25,20 +25,14 @@ fn compile_constants() { let module = compile_source("42"); assert!(!module.constants.is_empty()); - assert_eq!( - module.constants[0], - oxide_compiler::compiler::Constant::Int(42) - ); + assert_eq!(module.constants[0], oxide_compiler::compiler::Constant::Int(42)); } #[test] fn compile_negation() { let module = compile_source("-5"); - let has_neg = module - .bytecode - .iter() - .any(|&i| opcode::opcode(i) == OpCode::NEG); + let has_neg = module.bytecode.iter().any(|&i| opcode::opcode(i) == OpCode::NEG); assert!(has_neg); } @@ -65,10 +59,7 @@ fn compile_binary_ops() { for (src, expected_op) in tests { let module = compile_source(src); - let has_op = module - .bytecode - .iter() - .any(|&i| opcode::opcode(i) == expected_op); + let has_op = module.bytecode.iter().any(|&i| opcode::opcode(i) == expected_op); assert!(has_op, "expected {:?} in '{src}'", expected_op); } } @@ -77,10 +68,7 @@ fn compile_binary_ops() { fn compile_ternary_emits_jumps() { let module = compile_source("true ? 1 : 2"); assert!( - module - .bytecode - .iter() - .any(|&i| opcode::opcode(i) == OpCode::JMP_IF_FALSE), + module.bytecode.iter().any(|&i| opcode::opcode(i) == OpCode::JMP_IF_FALSE), "ternary should contain JMP_IF_FALSE" ); } @@ -89,10 +77,7 @@ fn compile_ternary_emits_jumps() { fn compile_logical_not() { let module = compile_source("!true"); assert!( - module - .bytecode - .iter() - .any(|&i| opcode::opcode(i) == OpCode::NOT), + module.bytecode.iter().any(|&i| opcode::opcode(i) == OpCode::NOT), "!true should emit NOT opcode" ); } @@ -101,10 +86,7 @@ fn compile_logical_not() { fn compile_logical_and_simple() { let module = compile_source("1 && 2"); assert!( - module - .bytecode - .iter() - .any(|&i| opcode::opcode(i) == OpCode::AND), + module.bytecode.iter().any(|&i| opcode::opcode(i) == OpCode::AND), "simple && should emit AND opcode" ); } @@ -113,10 +95,7 @@ fn compile_logical_and_simple() { fn compile_logical_or_simple() { let module = compile_source("0 || 1"); assert!( - module - .bytecode - .iter() - .any(|&i| opcode::opcode(i) == OpCode::OR), + module.bytecode.iter().any(|&i| opcode::opcode(i) == OpCode::OR), "simple || should emit OR opcode" ); } @@ -126,20 +105,14 @@ fn regression_coalesce_consistency() { let result = std::panic::catch_unwind(|| { compile_source("a ?? b"); }); - assert!( - result.is_err(), - "a ?? b should produce an error (not silently misbehave)" - ); + assert!(result.is_err(), "a ?? b should produce an error (not silently misbehave)"); } #[test] fn compile_strict_eq() { let module = compile_source("1 === 2"); assert!( - module - .bytecode - .iter() - .any(|&i| opcode::opcode(i) == OpCode::STRICT_EQ), + module.bytecode.iter().any(|&i| opcode::opcode(i) == OpCode::STRICT_EQ), "1 === 2 should emit STRICT_EQ opcode" ); } @@ -148,10 +121,7 @@ fn compile_strict_eq() { fn compile_strict_neq() { let module = compile_source("1 !== 2"); assert!( - module - .bytecode - .iter() - .any(|&i| opcode::opcode(i) == OpCode::STRICT_NEQ), + module.bytecode.iter().any(|&i| opcode::opcode(i) == OpCode::STRICT_NEQ), "1 !== 2 should emit STRICT_NEQ opcode" ); } @@ -160,10 +130,7 @@ fn compile_strict_neq() { fn compile_unary_plus() { let module = compile_source("+'hello'"); assert!( - module - .bytecode - .iter() - .any(|&i| opcode::opcode(i) == OpCode::UNARY_PLUS), + module.bytecode.iter().any(|&i| opcode::opcode(i) == OpCode::UNARY_PLUS), "+'hello' should emit UNARY_PLUS opcode" ); } @@ -172,17 +139,11 @@ fn compile_unary_plus() { fn compile_typeof_strict_eq() { let module = compile_source("typeof 42 === 'number'"); assert!( - module - .bytecode - .iter() - .any(|&i| opcode::opcode(i) == OpCode::TYPEOF), + module.bytecode.iter().any(|&i| opcode::opcode(i) == OpCode::TYPEOF), "should emit TYPEOF opcode" ); assert!( - module - .bytecode - .iter() - .any(|&i| opcode::opcode(i) == OpCode::STRICT_EQ), + module.bytecode.iter().any(|&i| opcode::opcode(i) == OpCode::STRICT_EQ), "should emit STRICT_EQ opcode" ); } @@ -207,10 +168,7 @@ fn compile_unary_plus_no_error() { fn compile_compound_add() { let module = compile_source("var x=0; x+=1"); assert!( - module - .bytecode - .iter() - .any(|&i| opcode::opcode(i) == OpCode::COMPOUND_ADD), + module.bytecode.iter().any(|&i| opcode::opcode(i) == OpCode::COMPOUND_ADD), "x+=1 should emit COMPOUND_ADD opcode" ); } @@ -219,10 +177,7 @@ fn compile_compound_add() { fn compile_compound_exp() { let module = compile_source("var x=0; x**=2"); assert!( - module - .bytecode - .iter() - .any(|&i| opcode::opcode(i) == OpCode::COMPOUND_EXP), + module.bytecode.iter().any(|&i| opcode::opcode(i) == OpCode::COMPOUND_EXP), "x**=2 should emit COMPOUND_EXP opcode" ); } @@ -247,10 +202,7 @@ fn compile_compound_exp_no_error() { fn compile_inc_pre() { let module = compile_source("++x"); assert!( - module - .bytecode - .iter() - .any(|&i| opcode::opcode(i) == OpCode::INC_PRE), + module.bytecode.iter().any(|&i| opcode::opcode(i) == OpCode::INC_PRE), "++x should emit INC_PRE opcode" ); } @@ -259,10 +211,7 @@ fn compile_inc_pre() { fn compile_inc_post() { let module = compile_source("x++"); assert!( - module - .bytecode - .iter() - .any(|&i| opcode::opcode(i) == OpCode::INC_POST), + module.bytecode.iter().any(|&i| opcode::opcode(i) == OpCode::INC_POST), "x++ should emit INC_POST opcode" ); } @@ -287,14 +236,8 @@ fn compile_dec_no_error() { fn compile_inc_dec_diff_opcodes() { let m1 = compile_source("++x"); let m2 = compile_source("--x"); - let has_inc_pre = m1 - .bytecode - .iter() - .any(|&i| opcode::opcode(i) == OpCode::INC_PRE); - let has_dec_pre = m2 - .bytecode - .iter() - .any(|&i| opcode::opcode(i) == OpCode::DEC_PRE); + let has_inc_pre = m1.bytecode.iter().any(|&i| opcode::opcode(i) == OpCode::INC_PRE); + let has_dec_pre = m2.bytecode.iter().any(|&i| opcode::opcode(i) == OpCode::DEC_PRE); assert!(has_inc_pre, "++x should emit INC_PRE"); assert!(has_dec_pre, "--x should emit DEC_PRE"); } @@ -303,10 +246,7 @@ fn compile_inc_dec_diff_opcodes() { fn compile_member_inc() { let module = compile_source("var obj={x:1}; obj.x++"); assert!( - module - .bytecode - .iter() - .any(|&i| opcode::opcode(i) == OpCode::MEMBER_INC), + module.bytecode.iter().any(|&i| opcode::opcode(i) == OpCode::MEMBER_INC), "obj.x++ should emit MEMBER_INC" ); } @@ -315,10 +255,7 @@ fn compile_member_inc() { fn compile_dyn_member_inc() { let module = compile_source("var obj={a:3}; var k='a'; obj[k]++"); assert!( - module - .bytecode - .iter() - .any(|&i| opcode::opcode(i) == OpCode::DYN_MEMBER_INC), + module.bytecode.iter().any(|&i| opcode::opcode(i) == OpCode::DYN_MEMBER_INC), "obj[k]++ should emit DYN_MEMBER_INC" ); } diff --git a/crates/oxide_compiler/tests/compile_stmt_tests.rs b/crates/oxide_compiler/tests/compile_stmt_tests.rs index 520d453..64b8f18 100644 --- a/crates/oxide_compiler/tests/compile_stmt_tests.rs +++ b/crates/oxide_compiler/tests/compile_stmt_tests.rs @@ -13,10 +13,7 @@ fn compile_source(source: &str) -> oxide_compiler::module::CompiledModule { fn compile_var_declaration() { let module = compile_source("var x = 42;"); assert!(!module.bytecode.is_empty()); - assert_eq!( - module.constants[0], - oxide_compiler::compiler::Constant::Int(42) - ); + assert_eq!(module.constants[0], oxide_compiler::compiler::Constant::Int(42)); } #[test] @@ -29,27 +26,18 @@ fn compile_return_nothing() { #[test] fn compile_return_value() { let module = compile_source("function f() { return 42; }"); - assert!( - !module.bytecode.is_empty(), - "function declaration should produce bytecode" - ); + assert!(!module.bytecode.is_empty(), "function declaration should produce bytecode"); } #[test] fn compile_if_else_emits_jmp_if_false() { let module = compile_source("if (true) { 1 } else { 2 }"); assert!( - module - .bytecode - .iter() - .any(|&i| opcode::opcode(i) == OpCode::JMP_IF_FALSE), + module.bytecode.iter().any(|&i| opcode::opcode(i) == OpCode::JMP_IF_FALSE), "if/else should contain JMP_IF_FALSE" ); assert!( - module - .bytecode - .iter() - .any(|&i| opcode::opcode(i) == OpCode::JMP), + module.bytecode.iter().any(|&i| opcode::opcode(i) == OpCode::JMP), "if/else should contain JMP" ); } @@ -57,17 +45,10 @@ fn compile_if_else_emits_jmp_if_false() { #[test] fn compile_while_emits_jump_back() { let module = compile_source("while (true) { 1 }"); - let jmp_ops: Vec<_> = module - .bytecode - .iter() - .filter(|&&i| opcode::opcode(i) == OpCode::JMP) - .collect(); + let jmp_ops: Vec<_> = module.bytecode.iter().filter(|&&i| opcode::opcode(i) == OpCode::JMP).collect(); assert!(!jmp_ops.is_empty(), "while should contain JMP (backward)"); assert!( - module - .bytecode - .iter() - .any(|&i| opcode::opcode(i) == OpCode::JMP_IF_FALSE), + module.bytecode.iter().any(|&i| opcode::opcode(i) == OpCode::JMP_IF_FALSE), "while should contain JMP_IF_FALSE" ); } @@ -76,10 +57,7 @@ fn compile_while_emits_jump_back() { fn compile_for_emits_jumps() { let module = compile_source("for (i=0; i<3; i=i+1) { 1 }"); assert!( - module - .bytecode - .iter() - .any(|&i| opcode::opcode(i) == OpCode::JMP_IF_FALSE), + module.bytecode.iter().any(|&i| opcode::opcode(i) == OpCode::JMP_IF_FALSE), "for should contain JMP_IF_FALSE" ); } @@ -87,19 +65,13 @@ fn compile_for_emits_jumps() { #[test] fn compile_break_in_loop() { let module = compile_source("while (true) { break; }"); - assert!( - !module.bytecode.is_empty(), - "break should compile without error" - ); + assert!(!module.bytecode.is_empty(), "break should compile without error"); } #[test] fn compile_continue_in_loop() { let module = compile_source("while (true) { continue; }"); - assert!( - !module.bytecode.is_empty(), - "continue should compile without error" - ); + assert!(!module.bytecode.is_empty(), "continue should compile without error"); } #[test] @@ -126,10 +98,7 @@ fn compile_nested_if() { .iter() .filter(|&&i| opcode::opcode(i) == OpCode::JMP_IF_FALSE) .count(); - assert!( - jmp_if_false_count >= 2, - "nested if should have 2+ JMP_IF_FALSE" - ); + assert!(jmp_if_false_count >= 2, "nested if should have 2+ JMP_IF_FALSE"); } #[test] @@ -143,10 +112,7 @@ fn regression_for_var_init() { let module = compile_source("for (var i = 0; i < 3; i = i + 1) {}"); assert!(!module.bytecode.is_empty(), "for(var) init should compile"); assert!( - module - .bytecode - .iter() - .any(|&i| opcode::opcode(i) == OpCode::JMP_IF_FALSE), + module.bytecode.iter().any(|&i| opcode::opcode(i) == OpCode::JMP_IF_FALSE), "for(var) init should contain JMP_IF_FALSE" ); } @@ -165,26 +131,16 @@ fn regression_var_decl_counter_no_init() { #[test] fn regression_redundant_jmp_if_without_else() { let module = compile_source("if (true) { 1 }"); - assert!( - !module.bytecode.is_empty(), - "if without else should compile" - ); + assert!(!module.bytecode.is_empty(), "if without else should compile"); let last = opcode::opcode(*module.bytecode.last().unwrap()); - assert_eq!( - last, - OpCode::HALT, - "final opcode should be HALT, not dangling JMP" - ); + assert_eq!(last, OpCode::HALT, "final opcode should be HALT, not dangling JMP"); } #[test] fn compile_do_while_emits_jmp_if_true() { let module = compile_source("do { 1 } while (true)"); assert!( - module - .bytecode - .iter() - .any(|&i| opcode::opcode(i) == OpCode::JMP_IF_TRUE), + module.bytecode.iter().any(|&i| opcode::opcode(i) == OpCode::JMP_IF_TRUE), "do-while should contain JMP_IF_TRUE" ); } @@ -204,36 +160,24 @@ fn compile_do_while_emits_body_before_test() { #[test] fn compile_do_while_break() { let module = compile_source("do { break; } while (true)"); - assert!( - !module.bytecode.is_empty(), - "do-while with break should compile" - ); + assert!(!module.bytecode.is_empty(), "do-while with break should compile"); } #[test] fn compile_do_while_continue() { let module = compile_source("var x = 0; do { continue; } while (x < 5)"); - assert!( - !module.bytecode.is_empty(), - "do-while with continue should compile" - ); + assert!(!module.bytecode.is_empty(), "do-while with continue should compile"); } #[test] fn compile_for_in_emits_opcodes() { let module = compile_source("var obj={a:1}; for (k in obj) {}"); assert!( - module - .bytecode - .iter() - .any(|&i| opcode::opcode(i) == OpCode::FOR_IN_INIT), + module.bytecode.iter().any(|&i| opcode::opcode(i) == OpCode::FOR_IN_INIT), "for-in should emit FOR_IN_INIT" ); assert!( - module - .bytecode - .iter() - .any(|&i| opcode::opcode(i) == OpCode::FOR_IN_NEXT), + module.bytecode.iter().any(|&i| opcode::opcode(i) == OpCode::FOR_IN_NEXT), "for-in should emit FOR_IN_NEXT" ); } @@ -254,10 +198,7 @@ fn compile_for_in_let_decl() { fn compile_switch_emits_jmp_if_true() { let module = compile_source("var x=0; switch(x){case 1:1;case 2:2;}"); assert!( - module - .bytecode - .iter() - .any(|&i| opcode::opcode(i) == OpCode::JMP_IF_TRUE), + module.bytecode.iter().any(|&i| opcode::opcode(i) == OpCode::JMP_IF_TRUE), "switch should emit JMP_IF_TRUE" ); } diff --git a/crates/oxide_compiler/tests/structural_hash_tests.rs b/crates/oxide_compiler/tests/structural_hash_tests.rs index 1d963dc..4fa1cda 100644 --- a/crates/oxide_compiler/tests/structural_hash_tests.rs +++ b/crates/oxide_compiler/tests/structural_hash_tests.rs @@ -23,17 +23,10 @@ fn structural_hash_hit() { let allocator = Allocator::default(); let program = oxide_parser::parse(&allocator, "1 + 2").expect("parse failed"); - let m1 = forge - .get_or_compile(&program, &compiler) - .expect("first compile"); - let m2 = forge - .get_or_compile(&program, &compiler) - .expect("second compile"); + let m1 = forge.get_or_compile(&program, &compiler).expect("first compile"); + let m2 = forge.get_or_compile(&program, &compiler).expect("second compile"); - assert_eq!( - (m1.bytecode.len(), m1.n_registers), - (m2.bytecode.len(), m2.n_registers) - ); + assert_eq!((m1.bytecode.len(), m1.n_registers), (m2.bytecode.len(), m2.n_registers)); } #[test] @@ -75,27 +68,18 @@ fn structural_hash_different_shape() { fn regression_forstatement_hash() { let hash_a = parse_to_hash("for(i=0;i<3;i++){1}"); let hash_b = parse_to_hash("for(;;){1}"); - assert_ne!( - hash_a, hash_b, - "different for-loop init/test/update must produce different hashes" - ); + assert_ne!(hash_a, hash_b, "different for-loop init/test/update must produce different hashes"); } #[test] fn regression_conditionalexpression_hash() { let hash_a = parse_to_hash("a?1:2"); let hash_b = parse_to_hash("a?3:4"); - assert_ne!( - hash_a, hash_b, - "different ternary branches must produce different hashes" - ); + assert_ne!(hash_a, hash_b, "different ternary branches must produce different hashes"); let hash_c = parse_to_hash("a?1:2"); let hash_d = parse_to_hash("a?1:2||3"); - assert_ne!( - hash_c, hash_d, - "different expression types with same test must produce different hashes" - ); + assert_ne!(hash_c, hash_d, "different expression types with same test must produce different hashes"); } #[test] diff --git a/crates/oxide_compiler/tests/symbol_table_tests.rs b/crates/oxide_compiler/tests/symbol_table_tests.rs index e6890d2..13dce6e 100644 --- a/crates/oxide_compiler/tests/symbol_table_tests.rs +++ b/crates/oxide_compiler/tests/symbol_table_tests.rs @@ -13,10 +13,7 @@ fn compile_source(source: &str) -> oxide_compiler::module::CompiledModule { fn symbol_table_declare_and_lookup() { let module = compile_source("var x = 42;"); assert!(!module.bytecode.is_empty()); - assert_eq!( - module.constants[0], - oxide_compiler::compiler::Constant::Int(42) - ); + assert_eq!(module.constants[0], oxide_compiler::compiler::Constant::Int(42)); } #[test] @@ -36,10 +33,7 @@ fn symbol_table_tdz_global_shadow() { let result = std::panic::catch_unwind(|| { compile_source("var x = 1; { var x = x; }"); }); - assert!( - result.is_err(), - "TDZ: accessing x in its own initializer inside a block should error" - ); + assert!(result.is_err(), "TDZ: accessing x in its own initializer inside a block should error"); } #[test] @@ -56,8 +50,5 @@ fn symbol_table_duplicate_var() { #[test] fn symbol_table_undeclared_auto_global() { let module = compile_source("x = 5;"); - assert!( - !module.bytecode.is_empty(), - "undeclared assignment should auto-create global" - ); + assert!(!module.bytecode.is_empty(), "undeclared assignment should auto-create global"); } diff --git a/crates/oxide_kernel/src/builtin.rs b/crates/oxide_kernel/src/builtin.rs index a494e3e..3c836a5 100644 --- a/crates/oxide_kernel/src/builtin.rs +++ b/crates/oxide_kernel/src/builtin.rs @@ -202,11 +202,7 @@ fn intern_label(string_forge: &StringForge, label: &str) -> u32 { } fn make_pair( - string_forge: &StringForge, - shape_forge: &ShapeForge, - name: &str, - si_prototype: u32, - si_constructor: u32, + string_forge: &StringForge, shape_forge: &ShapeForge, name: &str, si_prototype: u32, si_constructor: u32, si_name: u32, ) -> (P, P) { intern_label(string_forge, name); @@ -226,13 +222,9 @@ fn make_pair( // Pre-allocate Vec slots so wire_ctor_proto can overwrite vec[0] later. // Proto: 1 property ("constructor"), Ctor: 2 properties ("prototype", "name"). - proto - .ensure_hash_props() - .push(Box::new(JsValue::undefined())); // slot 0: "constructor" placeholder - ctor.ensure_hash_props() - .push(Box::new(JsValue::undefined())); // slot 0: "prototype" placeholder - ctor.ensure_hash_props() - .push(Box::new(JsValue::undefined())); // slot 1: "name" placeholder + proto.ensure_hash_props().push(Box::new(JsValue::undefined())); // slot 0: "constructor" placeholder + ctor.ensure_hash_props().push(Box::new(JsValue::undefined())); // slot 0: "prototype" placeholder + ctor.ensure_hash_props().push(Box::new(JsValue::undefined())); // slot 1: "name" placeholder (P::new(proto), P::new(ctor)) } @@ -250,70 +242,22 @@ impl BuiltinWorld { intern_label(string_forge, "toString"); intern_label(string_forge, "valueOf"); - let (object_proto, object_constructor) = make_pair( - string_forge, - shape_forge, - "Object", - si_prototype, - si_constructor, - si_name, - ); - let (array_proto, array_constructor) = make_pair( - string_forge, - shape_forge, - "Array", - si_prototype, - si_constructor, - si_name, - ); - let (function_proto, function_constructor) = make_pair( - string_forge, - shape_forge, - "Function", - si_prototype, - si_constructor, - si_name, - ); - let (string_proto, string_constructor) = make_pair( - string_forge, - shape_forge, - "String", - si_prototype, - si_constructor, - si_name, - ); - let (number_proto, number_constructor) = make_pair( - string_forge, - shape_forge, - "Number", - si_prototype, - si_constructor, - si_name, - ); - let (boolean_proto, boolean_constructor) = make_pair( - string_forge, - shape_forge, - "Boolean", - si_prototype, - si_constructor, - si_name, - ); - let (error_proto, error_constructor) = make_pair( - string_forge, - shape_forge, - "Error", - si_prototype, - si_constructor, - si_name, - ); - let (symbol_proto, symbol_constructor) = make_pair( - string_forge, - shape_forge, - "Symbol", - si_prototype, - si_constructor, - si_name, - ); + let (object_proto, object_constructor) = + make_pair(string_forge, shape_forge, "Object", si_prototype, si_constructor, si_name); + let (array_proto, array_constructor) = + make_pair(string_forge, shape_forge, "Array", si_prototype, si_constructor, si_name); + let (function_proto, function_constructor) = + make_pair(string_forge, shape_forge, "Function", si_prototype, si_constructor, si_name); + let (string_proto, string_constructor) = + make_pair(string_forge, shape_forge, "String", si_prototype, si_constructor, si_name); + let (number_proto, number_constructor) = + make_pair(string_forge, shape_forge, "Number", si_prototype, si_constructor, si_name); + let (boolean_proto, boolean_constructor) = + make_pair(string_forge, shape_forge, "Boolean", si_prototype, si_constructor, si_name); + let (error_proto, error_constructor) = + make_pair(string_forge, shape_forge, "Error", si_prototype, si_constructor, si_name); + let (symbol_proto, symbol_constructor) = + make_pair(string_forge, shape_forge, "Symbol", si_prototype, si_constructor, si_name); let error_proto_val = JsValue::from_js_object(error_proto.as_ptr() as *mut JsObject); let type_error_proto = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, error_proto_val)); @@ -327,38 +271,14 @@ impl BuiltinWorld { let json_object = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); - let (date_proto, date_constructor) = make_pair( - string_forge, - shape_forge, - "Date", - si_prototype, - si_constructor, - si_name, - ); - let (set_proto, set_constructor) = make_pair( - string_forge, - shape_forge, - "Set", - si_prototype, - si_constructor, - si_name, - ); - let (map_proto, map_constructor) = make_pair( - string_forge, - shape_forge, - "Map", - si_prototype, - si_constructor, - si_name, - ); - let (regexp_proto, regexp_constructor) = make_pair( - string_forge, - shape_forge, - "RegExp", - si_prototype, - si_constructor, - si_name, - ); + let (date_proto, date_constructor) = + make_pair(string_forge, shape_forge, "Date", si_prototype, si_constructor, si_name); + let (set_proto, set_constructor) = + make_pair(string_forge, shape_forge, "Set", si_prototype, si_constructor, si_name); + let (map_proto, map_constructor) = + make_pair(string_forge, shape_forge, "Map", si_prototype, si_constructor, si_name); + let (regexp_proto, regexp_constructor) = + make_pair(string_forge, shape_forge, "RegExp", si_prototype, si_constructor, si_name); let sym_match = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); let sym_replace = P::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); @@ -458,12 +378,7 @@ impl BuiltinWorld { } } - pub fn bind_object_methods( - &self, - methods: &ObjectMethods, - string_forge: &StringForge, - shape_forge: &ShapeForge, - ) { + pub fn bind_object_methods(&self, methods: &ObjectMethods, string_forge: &StringForge, shape_forge: &ShapeForge) { let ctor_ptr = P::as_ptr(&self.object_constructor) as *mut JsObject; let ctor = unsafe { &mut *ctor_ptr }; bind_methods!( @@ -475,11 +390,7 @@ impl BuiltinWorld { ("create", methods.create, 2), ("assign", methods.assign, 2), ("defineProperty", methods.define_property, 3), - ( - "getOwnPropertyDescriptor", - methods.get_own_property_descriptor, - 2 - ), + ("getOwnPropertyDescriptor", methods.get_own_property_descriptor, 2), ("freeze", methods.freeze, 1), ("seal", methods.seal, 1), ("preventExtensions", methods.prevent_extensions, 1), @@ -496,12 +407,7 @@ impl BuiltinWorld { ); } - pub fn bind_array_methods( - &self, - methods: &ArrayMethods, - string_forge: &StringForge, - shape_forge: &ShapeForge, - ) { + pub fn bind_array_methods(&self, methods: &ArrayMethods, string_forge: &StringForge, shape_forge: &ShapeForge) { let proto_ptr = P::as_ptr(&self.array_proto) as *mut JsObject; let proto = unsafe { &mut *proto_ptr }; bind_methods!( @@ -540,12 +446,7 @@ impl BuiltinWorld { ); } - pub fn bind_error_methods( - &self, - methods: &ErrorMethods, - string_forge: &StringForge, - shape_forge: &ShapeForge, - ) { + pub fn bind_error_methods(&self, methods: &ErrorMethods, string_forge: &StringForge, shape_forge: &ShapeForge) { let ctor_ptr = P::as_ptr(&self.error_constructor) as *mut JsObject; let ctor = unsafe { &mut *ctor_ptr }; bind_methods!( @@ -574,12 +475,7 @@ impl BuiltinWorld { ); } - pub fn bind_string_methods( - &self, - methods: &StringMethods, - string_forge: &StringForge, - shape_forge: &ShapeForge, - ) { + pub fn bind_string_methods(&self, methods: &StringMethods, string_forge: &StringForge, shape_forge: &ShapeForge) { let proto_ptr = P::as_ptr(&self.string_proto) as *mut JsObject; let proto = unsafe { &mut *proto_ptr }; bind_methods!( @@ -615,12 +511,7 @@ impl BuiltinWorld { ); } - pub fn bind_number_methods( - &self, - methods: &NumberMethods, - string_forge: &StringForge, - shape_forge: &ShapeForge, - ) { + pub fn bind_number_methods(&self, methods: &NumberMethods, string_forge: &StringForge, shape_forge: &ShapeForge) { let ctor_ptr = P::as_ptr(&self.number_constructor) as *mut JsObject; let ctor = unsafe { &mut *ctor_ptr }; let proto_ptr = P::as_ptr(&self.number_proto) as *mut JsObject; @@ -651,10 +542,7 @@ impl BuiltinWorld { } pub fn bind_function_methods( - &self, - methods: &FunctionMethods, - string_forge: &StringForge, - shape_forge: &ShapeForge, + &self, methods: &FunctionMethods, string_forge: &StringForge, shape_forge: &ShapeForge, ) { let proto_ptr = P::as_ptr(&self.function_proto) as *mut JsObject; let proto = unsafe { &mut *proto_ptr }; @@ -672,13 +560,8 @@ impl BuiltinWorld { } pub fn bind_method( - &self, - proto: &mut JsObject, - shape_forge: &ShapeForge, - string_forge: &StringForge, - method_name: &str, - native_fn_ptr: *const (), - arg_count: u8, + &self, proto: &mut JsObject, shape_forge: &ShapeForge, string_forge: &StringForge, method_name: &str, + native_fn_ptr: *const (), arg_count: u8, ) -> Result<(), String> { Self::bind_method_static( proto, @@ -692,13 +575,8 @@ impl BuiltinWorld { } pub fn bind_method_static( - proto: &mut JsObject, - shape_forge: &ShapeForge, - string_forge: &StringForge, - method_name: &str, - native_fn_ptr: *const (), - arg_count: u8, - wrapper_proto: JsValue, + proto: &mut JsObject, shape_forge: &ShapeForge, string_forge: &StringForge, method_name: &str, + native_fn_ptr: *const (), arg_count: u8, wrapper_proto: JsValue, ) -> Result<(), String> { let si = string_forge.intern(method_name).0; let wrapper_proto_ptr = if wrapper_proto.is_object() { @@ -748,10 +626,7 @@ mod tests { &w.symbol_proto, ]; for p in protos { - assert!( - p.shape_id() > EMPTY_SHAPE_ID, - "proto should have a non-empty shape" - ); + assert!(p.shape_id() > EMPTY_SHAPE_ID, "proto should have a non-empty shape"); } } @@ -803,9 +678,6 @@ mod tests { w.object_constructor.shape_id() > EMPTY_SHAPE_ID, "constructor should have prototype + name shape" ); - assert!( - w.object_proto.shape_id() > EMPTY_SHAPE_ID, - "prototype should have constructor shape" - ); + assert!(w.object_proto.shape_id() > EMPTY_SHAPE_ID, "prototype should have constructor shape"); } } diff --git a/crates/oxide_kernel/src/code_forge.rs b/crates/oxide_kernel/src/code_forge.rs index 61b4599..4c0b9d6 100644 --- a/crates/oxide_kernel/src/code_forge.rs +++ b/crates/oxide_kernel/src/code_forge.rs @@ -13,15 +13,11 @@ pub struct CodeForge { impl CodeForge { pub fn new() -> Self { - Self { - map: DashMap::new(), - } + Self { map: DashMap::new() } } pub fn get_or_compile( - &self, - program: &oxide_parser::Program, - compiler: &Compiler, + &self, program: &oxide_parser::Program, compiler: &Compiler, ) -> Result, String> { let hash = structural_hash(program); @@ -81,17 +77,10 @@ mod tests { let allocator = Allocator::default(); let program = oxide_parser::parse(&allocator, "1 + 2").expect("parse failed"); - let first = forge - .get_or_compile(&program, &compiler) - .expect("first compile"); - let second = forge - .get_or_compile(&program, &compiler) - .expect("second compile"); + let first = forge.get_or_compile(&program, &compiler).expect("first compile"); + let second = forge.get_or_compile(&program, &compiler).expect("second compile"); - assert_eq!( - (first.bytecode.len(), first.n_registers), - (second.bytecode.len(), second.n_registers) - ); + assert_eq!((first.bytecode.len(), first.n_registers), (second.bytecode.len(), second.n_registers)); } #[test] diff --git a/crates/oxide_kernel/src/kernel.rs b/crates/oxide_kernel/src/kernel.rs index 2bc4f1e..9562570 100644 --- a/crates/oxide_kernel/src/kernel.rs +++ b/crates/oxide_kernel/src/kernel.rs @@ -96,21 +96,15 @@ impl OxideKernel { let nan_shape = shape_forge.make_shape(EMPTY_SHAPE_ID, si_nan); global_obj.set_shape_id(nan_shape); - global_obj - .ensure_hash_props() - .push(Box::new(JsValue::float(f64::NAN))); + global_obj.ensure_hash_props().push(Box::new(JsValue::float(f64::NAN))); let undef_shape = shape_forge.make_shape(nan_shape, si_undef); global_obj.set_shape_id(undef_shape); - global_obj - .ensure_hash_props() - .push(Box::new(JsValue::undefined())); + global_obj.ensure_hash_props().push(Box::new(JsValue::undefined())); let inf_shape = shape_forge.make_shape(undef_shape, si_infinity); global_obj.set_shape_id(inf_shape); - global_obj - .ensure_hash_props() - .push(Box::new(JsValue::float(f64::INFINITY))); + global_obj.ensure_hash_props().push(Box::new(JsValue::float(f64::INFINITY))); let global_object = P::new(global_obj); diff --git a/crates/oxide_kernel/src/prop_forge.rs b/crates/oxide_kernel/src/prop_forge.rs index c3eb96a..93b424f 100644 --- a/crates/oxide_kernel/src/prop_forge.rs +++ b/crates/oxide_kernel/src/prop_forge.rs @@ -18,9 +18,7 @@ pub struct PropForge { impl PropForge { pub fn new() -> Self { - Self { - templates: DashMap::new(), - } + Self { templates: DashMap::new() } } pub fn get_template(&self, shape_id: ShapeId) -> Option> { diff --git a/crates/oxide_kernel/src/string_forge.rs b/crates/oxide_kernel/src/string_forge.rs index 7a07fff..8d0663c 100644 --- a/crates/oxide_kernel/src/string_forge.rs +++ b/crates/oxide_kernel/src/string_forge.rs @@ -98,8 +98,7 @@ impl StringForge { return; } - let mut new_map: HashMap = - HashMap::with_hasher(FxBuildHasher::default()); + let mut new_map: HashMap = HashMap::with_hasher(FxBuildHasher::default()); let mut new_entries = Vec::with_capacity(inner.entries.len() - dead_count); for entry in inner.entries.drain(..) { diff --git a/crates/oxide_parser/src/lib.rs b/crates/oxide_parser/src/lib.rs index 381fb12..89f347c 100644 --- a/crates/oxide_parser/src/lib.rs +++ b/crates/oxide_parser/src/lib.rs @@ -7,10 +7,7 @@ pub use oxc_allocator::Allocator; pub use oxc_ast::ast::*; pub use oxc_span::Span; -pub fn parse<'a>( - allocator: &'a Allocator, - source: &'a str, -) -> Result, Vec> { +pub fn parse<'a>(allocator: &'a Allocator, source: &'a str) -> Result, Vec> { use oxc_parser::Parser; use oxc_span::SourceType; diff --git a/crates/oxide_parser/tests/parse_smoke.rs b/crates/oxide_parser/tests/parse_smoke.rs index b55817d..f1504b4 100644 --- a/crates/oxide_parser/tests/parse_smoke.rs +++ b/crates/oxide_parser/tests/parse_smoke.rs @@ -13,10 +13,7 @@ fn parse_empty_string() { let result = oxide_parser::parse(&allocator, ""); assert!(result.is_ok(), "empty string should parse"); let program = result.unwrap(); - assert!( - program.body.is_empty(), - "empty program should have empty body" - ); + assert!(program.body.is_empty(), "empty program should have empty body"); } #[test] @@ -25,10 +22,7 @@ fn parse_function_declaration() { let result = oxide_parser::parse(&allocator, "function foo() { return 42; }"); assert!(result.is_ok(), "function declaration should parse"); let program = result.unwrap(); - assert!( - !program.body.is_empty(), - "program with function should not be empty" - ); + assert!(!program.body.is_empty(), "program with function should not be empty"); } #[test] @@ -37,10 +31,7 @@ fn parse_syntax_error() { let result = oxide_parser::parse(&allocator, "function("); assert!(result.is_err(), "syntax error should return Err"); let errors = result.unwrap_err(); - assert!( - !errors.is_empty(), - "syntax error should produce at least one error" - ); + assert!(!errors.is_empty(), "syntax error should produce at least one error"); } #[test] diff --git a/crates/oxide_test262/src/main.rs b/crates/oxide_test262/src/main.rs index 67ef127..c9b09df 100644 --- a/crates/oxide_test262/src/main.rs +++ b/crates/oxide_test262/src/main.rs @@ -192,18 +192,14 @@ Test262Error.prototype.constructor = Test262Error; let full_source = format!("{prelude}\n{assert_js}"); let alloc = oxide_parser::Allocator::default(); - let program = oxide_parser::parse(&alloc, &full_source) - .map_err(|e| format!("harness parse error: {}", e[0].message))?; + let program = + oxide_parser::parse(&alloc, &full_source).map_err(|e| format!("harness parse error: {}", e[0].message))?; Compiler::new().compile(&program) } fn run_test( - path: &Path, - source: &str, - meta: &TestMeta, - kernel: &Arc, - harness_module: &CompiledModule, + path: &Path, source: &str, meta: &TestMeta, kernel: &Arc, harness_module: &CompiledModule, ) -> TestResult { let start = std::time::Instant::now(); @@ -215,21 +211,13 @@ fn run_test( Ok(r) => r, Err(_panic) => { let dur = start.elapsed().as_millis() as u64; - TestResult::fail( - path.to_path_buf(), - dur, - "engine panic (unsupported feature)", - ) + TestResult::fail(path.to_path_buf(), dur, "engine panic (unsupported feature)") } } } fn run_test_inner( - path: &Path, - source: &str, - meta: &TestMeta, - kernel: &Arc, - harness_module: &CompiledModule, + path: &Path, source: &str, meta: &TestMeta, kernel: &Arc, harness_module: &CompiledModule, ) -> TestResult { let start = std::time::Instant::now(); @@ -308,11 +296,7 @@ fn run_test_inner( if e.contains(&neg.error_type) { return TestResult::pass(path.to_path_buf(), dur, format!("expected: {e}")); } - TestResult::fail( - path.to_path_buf(), - dur, - format!("expected {} error, got: {e}", neg.error_type), - ) + TestResult::fail(path.to_path_buf(), dur, format!("expected {} error, got: {e}", neg.error_type)) } else if e.contains("not yet implemented") || e.contains("not supported") || e.contains("unsupported") @@ -350,10 +334,7 @@ fn categorize_fail(msg: &str) -> String { } else if reason.contains("is not defined") { "compile: not defined".into() } else { - format!( - "compile: other ({})", - reason.chars().take(60).collect::() - ) + format!("compile: other ({})", reason.chars().take(60).collect::()) } } else if msg.contains("parse error:") { "parse error".into() @@ -372,10 +353,7 @@ fn categorize_fail(msg: &str) -> String { } else if reason.contains("unsupported") { "vm: unsupported".into() } else { - format!( - "vm: other ({})", - reason.chars().take(60).collect::() - ) + format!("vm: other ({})", reason.chars().take(60).collect::()) } } else if msg.contains("engine panic") { "engine panic".into() @@ -426,11 +404,7 @@ fn run_tests() -> bool { std::process::exit(1); } - let filter = if args.len() > 2 { - Some(args[2].clone()) - } else { - None - }; + let filter = if args.len() > 2 { Some(args[2].clone()) } else { None }; eprintln!("discovering tests in: {}", test262_root.display()); let paths = discover_tests(&test262_root); @@ -476,10 +450,7 @@ fn run_tests() -> bool { let meta = match parse_meta(&source) { Some(m) => m, None => { - results.push(TestResult::skip( - path.clone(), - String::from("no YAML metadata"), - )); + results.push(TestResult::skip(path.clone(), String::from("no YAML metadata"))); stats.skip += 1; continue; } @@ -496,10 +467,7 @@ fn run_tests() -> bool { let path_str = path.to_string_lossy(); if path_str.contains("staging") { - results.push(TestResult::skip( - path.clone(), - "staging tests excluded".into(), - )); + results.push(TestResult::skip(path.clone(), "staging tests excluded".into())); stats.skip += 1; continue; } @@ -534,30 +502,14 @@ fn run_tests() -> bool { println!("═══════════════════════════════════════"); println!(" total : {}", results.len()); let total = results.len() as f64; - println!( - " pass : {} ({:.1}%)", - stats.pass, - stats.pass as f64 / total * 100.0 - ); - println!( - " fail : {} ({:.1}%)", - stats.fail, - stats.fail as f64 / total * 100.0 - ); - println!( - " skip : {} ({:.1}%)", - stats.skip, - stats.skip as f64 / total * 100.0 - ); + println!(" pass : {} ({:.1}%)", stats.pass, stats.pass as f64 / total * 100.0); + println!(" fail : {} ({:.1}%)", stats.fail, stats.fail as f64 / total * 100.0); + println!(" skip : {} ({:.1}%)", stats.skip, stats.skip as f64 / total * 100.0); println!(" time : {:?}", Duration::from_millis(stats.total_ms)); println!( " pass% : {:.1}% (of ran: {:.1}%)", stats.pass as f64 / total * 100.0, - if ran > 0 { - stats.pass as f64 / ran as f64 * 100.0 - } else { - 0.0 - } + if ran > 0 { stats.pass as f64 / ran as f64 * 100.0 } else { 0.0 } ); if !stats.fail_categories.is_empty() { println!(" --- FAIL categories ---"); diff --git a/crates/oxide_types/src/object.rs b/crates/oxide_types/src/object.rs index 6370b37..9cd1a49 100644 --- a/crates/oxide_types/src/object.rs +++ b/crates/oxide_types/src/object.rs @@ -83,12 +83,7 @@ impl JsObject { } } - pub fn new_array( - shape_id: ShapeId, - proto: JsValue, - n_elements: usize, - _bump: &bumpalo::Bump, - ) -> Self { + pub fn new_array(shape_id: ShapeId, proto: JsValue, n_elements: usize, _bump: &bumpalo::Bump) -> Self { let mut obj = Self { header: (shape_id & 0x00FF_FFFF) | (1 << 30) | (1 << 29), native_arg_count: 0, @@ -192,9 +187,7 @@ impl JsObject { return JsValue::undefined(); } let vec = unsafe { &*(self.hash_props as *const Vec>) }; - vec.get(position.to_u32() as usize) - .map(|b| **b) - .unwrap_or(JsValue::undefined()) + vec.get(position.to_u32() as usize).map(|b| **b).unwrap_or(JsValue::undefined()) } /// Set property value at position index. Vec auto-grows if needed. @@ -226,8 +219,7 @@ impl JsObject { return None; } let vec = unsafe { &*(self.hash_props as *const Vec>) }; - vec.get(position.to_u32() as usize) - .map(|b| &**b as *const JsValue) + vec.get(position.to_u32() as usize).map(|b| &**b as *const JsValue) } /// Get the length of hash_props vec (returns 0 if not allocated). @@ -336,10 +328,7 @@ mod tests { #[test] fn object_size_bounds() { let sz = std::mem::size_of::(); - assert!( - sz >= 40 && sz <= 56, - "JsObject layout mismatch - expected 40-56B, got {sz}B" - ); + assert!(sz >= 40 && sz <= 56, "JsObject layout mismatch - expected 40-56B, got {sz}B"); } #[test] diff --git a/crates/oxide_types/src/value.rs b/crates/oxide_types/src/value.rs index fe6fbc8..1077fd3 100644 --- a/crates/oxide_types/src/value.rs +++ b/crates/oxide_types/src/value.rs @@ -124,10 +124,7 @@ impl JsValue { pub fn string(index: u32, hash: u16) -> Self { let payload = ((hash as u64) << STRING_HASH_SHIFT) | (index as u64); - debug_assert!( - payload & !(STRING_HASH_MASK | STRING_INDEX_MASK) == 0, - "string payload overflow" - ); + debug_assert!(payload & !(STRING_HASH_MASK | STRING_INDEX_MASK) == 0, "string payload overflow"); Self(make_tag(TAG_STRING) | payload) } @@ -288,12 +285,7 @@ impl fmt::Debug for JsValue { } else if self.is_object() { write!(f, "JsValue(Object({:p}))", self.as_ptr()) } else if self.is_string() { - write!( - f, - "JsValue(String(idx={}, hash={:#06x}))", - self.as_string_index(), - self.as_string_hash() - ) + write!(f, "JsValue(String(idx={}, hash={:#06x}))", self.as_string_index(), self.as_string_hash()) } else if self.is_symbol() { write!(f, "JsValue(Symbol(idx={}))", self.as_symbol_index()) } else { diff --git a/crates/oxide_vm/src/bindings/bind_array.rs b/crates/oxide_vm/src/bindings/bind_array.rs index ab42cc3..efa664c 100644 --- a/crates/oxide_vm/src/bindings/bind_array.rs +++ b/crates/oxide_vm/src/bindings/bind_array.rs @@ -44,12 +44,5 @@ pub fn bind_array(kernel: &Arc, global: &mut JsObject) { ); let ctor_ptr = kernel.builtin_world().array_constructor.as_ptr() as *mut JsObject; - bind_constructor_hash!( - kernel, - global, - "Array", - ctor_ptr, - crate::builtins::array::array_constructor, - 1 - ); + bind_constructor_hash!(kernel, global, "Array", ctor_ptr, crate::builtins::array::array_constructor, 1); } diff --git a/crates/oxide_vm/src/bindings/bind_boolean.rs b/crates/oxide_vm/src/bindings/bind_boolean.rs index 1ff884e..7ae1e18 100644 --- a/crates/oxide_vm/src/bindings/bind_boolean.rs +++ b/crates/oxide_vm/src/bindings/bind_boolean.rs @@ -11,36 +11,17 @@ pub fn bind_boolean(kernel: &Arc, global: &mut JsObject) { let proto_ptr = kernel.builtin_world().boolean_proto.as_ptr() as *mut JsObject; let proto = unsafe { &mut *proto_ptr }; - configure_native_constructor( - ctor, - crate::builtins::boolean::boolean_constructor as *const (), - 1, - ); + configure_native_constructor(ctor, crate::builtins::boolean::boolean_constructor as *const (), 1); apply_binding_table( kernel.builtin_world(), proto, kernel, &[ - ( - "valueOf", - crate::builtins::boolean::boolean_prototype_value_of as *const (), - 0, - ), - ( - "toString", - crate::builtins::boolean::boolean_prototype_to_string as *const (), - 0, - ), + ("valueOf", crate::builtins::boolean::boolean_prototype_value_of as *const (), 0), + ("toString", crate::builtins::boolean::boolean_prototype_to_string as *const (), 0), ], ); - bind_constructor_hash!( - kernel, - global, - "Boolean", - ctor_ptr, - crate::builtins::boolean::boolean_constructor, - 1 - ); + bind_constructor_hash!(kernel, global, "Boolean", ctor_ptr, crate::builtins::boolean::boolean_constructor, 1); } diff --git a/crates/oxide_vm/src/bindings/bind_date.rs b/crates/oxide_vm/src/bindings/bind_date.rs index 5b3e5e2..cc15d37 100644 --- a/crates/oxide_vm/src/bindings/bind_date.rs +++ b/crates/oxide_vm/src/bindings/bind_date.rs @@ -11,11 +11,7 @@ pub fn bind_date(kernel: &Arc, global: &mut JsObject) { let proto_ptr = kernel.builtin_world().date_proto.as_ptr() as *mut JsObject; let proto = unsafe { &mut *proto_ptr }; - configure_native_constructor( - ctor, - crate::builtins::date::date_constructor as *const (), - 7, - ); + configure_native_constructor(ctor, crate::builtins::date::date_constructor as *const (), 7); apply_binding_table( kernel.builtin_world(), @@ -33,171 +29,39 @@ pub fn bind_date(kernel: &Arc, global: &mut JsObject) { proto, kernel, &[ - ( - "getTime", - crate::builtins::date::date_get_time as *const (), - 0, - ), - ( - "getFullYear", - crate::builtins::date::date_get_full_year as *const (), - 0, - ), - ( - "getMonth", - crate::builtins::date::date_get_month as *const (), - 0, - ), - ( - "getDate", - crate::builtins::date::date_get_date as *const (), - 0, - ), - ( - "getDay", - crate::builtins::date::date_get_day as *const (), - 0, - ), - ( - "getHours", - crate::builtins::date::date_get_hours as *const (), - 0, - ), - ( - "getMinutes", - crate::builtins::date::date_get_minutes as *const (), - 0, - ), - ( - "getSeconds", - crate::builtins::date::date_get_seconds as *const (), - 0, - ), - ( - "getMilliseconds", - crate::builtins::date::date_get_milliseconds as *const (), - 0, - ), - ( - "getUTCFullYear", - crate::builtins::date::date_get_utc_full_year as *const (), - 0, - ), - ( - "getUTCMonth", - crate::builtins::date::date_get_utc_month as *const (), - 0, - ), - ( - "getUTCDate", - crate::builtins::date::date_get_utc_date as *const (), - 0, - ), - ( - "getUTCDay", - crate::builtins::date::date_get_utc_day as *const (), - 0, - ), - ( - "getUTCHours", - crate::builtins::date::date_get_utc_hours as *const (), - 0, - ), - ( - "getUTCMinutes", - crate::builtins::date::date_get_utc_minutes as *const (), - 0, - ), - ( - "getUTCSeconds", - crate::builtins::date::date_get_utc_seconds as *const (), - 0, - ), - ( - "getUTCMilliseconds", - crate::builtins::date::date_get_utc_milliseconds as *const (), - 0, - ), - ( - "getTimezoneOffset", - crate::builtins::date::date_get_timezone_offset as *const (), - 0, - ), - ( - "setTime", - crate::builtins::date::date_set_time as *const (), - 1, - ), - ( - "setFullYear", - crate::builtins::date::date_set_full_year as *const (), - 3, - ), - ( - "setMonth", - crate::builtins::date::date_set_month as *const (), - 2, - ), - ( - "setDate", - crate::builtins::date::date_set_date as *const (), - 1, - ), - ( - "setHours", - crate::builtins::date::date_set_hours as *const (), - 4, - ), - ( - "setMinutes", - crate::builtins::date::date_set_minutes as *const (), - 3, - ), - ( - "setSeconds", - crate::builtins::date::date_set_seconds as *const (), - 2, - ), - ( - "setMilliseconds", - crate::builtins::date::date_set_milliseconds as *const (), - 1, - ), - ( - "toISOString", - crate::builtins::date::date_to_iso_string as *const (), - 0, - ), - ( - "toJSON", - crate::builtins::date::date_to_json as *const (), - 1, - ), - ( - "toString", - crate::builtins::date::date_to_string as *const (), - 0, - ), - ( - "toDateString", - crate::builtins::date::date_to_date_string as *const (), - 0, - ), - ( - "toTimeString", - crate::builtins::date::date_to_time_string as *const (), - 0, - ), - ( - "toUTCString", - crate::builtins::date::date_to_utc_string as *const (), - 0, - ), - ( - "valueOf", - crate::builtins::date::date_value_of as *const (), - 0, - ), + ("getTime", crate::builtins::date::date_get_time as *const (), 0), + ("getFullYear", crate::builtins::date::date_get_full_year as *const (), 0), + ("getMonth", crate::builtins::date::date_get_month as *const (), 0), + ("getDate", crate::builtins::date::date_get_date as *const (), 0), + ("getDay", crate::builtins::date::date_get_day as *const (), 0), + ("getHours", crate::builtins::date::date_get_hours as *const (), 0), + ("getMinutes", crate::builtins::date::date_get_minutes as *const (), 0), + ("getSeconds", crate::builtins::date::date_get_seconds as *const (), 0), + ("getMilliseconds", crate::builtins::date::date_get_milliseconds as *const (), 0), + ("getUTCFullYear", crate::builtins::date::date_get_utc_full_year as *const (), 0), + ("getUTCMonth", crate::builtins::date::date_get_utc_month as *const (), 0), + ("getUTCDate", crate::builtins::date::date_get_utc_date as *const (), 0), + ("getUTCDay", crate::builtins::date::date_get_utc_day as *const (), 0), + ("getUTCHours", crate::builtins::date::date_get_utc_hours as *const (), 0), + ("getUTCMinutes", crate::builtins::date::date_get_utc_minutes as *const (), 0), + ("getUTCSeconds", crate::builtins::date::date_get_utc_seconds as *const (), 0), + ("getUTCMilliseconds", crate::builtins::date::date_get_utc_milliseconds as *const (), 0), + ("getTimezoneOffset", crate::builtins::date::date_get_timezone_offset as *const (), 0), + ("setTime", crate::builtins::date::date_set_time as *const (), 1), + ("setFullYear", crate::builtins::date::date_set_full_year as *const (), 3), + ("setMonth", crate::builtins::date::date_set_month as *const (), 2), + ("setDate", crate::builtins::date::date_set_date as *const (), 1), + ("setHours", crate::builtins::date::date_set_hours as *const (), 4), + ("setMinutes", crate::builtins::date::date_set_minutes as *const (), 3), + ("setSeconds", crate::builtins::date::date_set_seconds as *const (), 2), + ("setMilliseconds", crate::builtins::date::date_set_milliseconds as *const (), 1), + ("toISOString", crate::builtins::date::date_to_iso_string as *const (), 0), + ("toJSON", crate::builtins::date::date_to_json as *const (), 1), + ("toString", crate::builtins::date::date_to_string as *const (), 0), + ("toDateString", crate::builtins::date::date_to_date_string as *const (), 0), + ("toTimeString", crate::builtins::date::date_to_time_string as *const (), 0), + ("toUTCString", crate::builtins::date::date_to_utc_string as *const (), 0), + ("valueOf", crate::builtins::date::date_value_of as *const (), 0), ], ); diff --git a/crates/oxide_vm/src/bindings/bind_error.rs b/crates/oxide_vm/src/bindings/bind_error.rs index 50ab6f8..7f3ae00 100644 --- a/crates/oxide_vm/src/bindings/bind_error.rs +++ b/crates/oxide_vm/src/bindings/bind_error.rs @@ -7,20 +7,13 @@ use oxide_types::object::JsObject; use oxide_types::value::JsValue; fn bind_error_subtype_constructor( - kernel: &Arc, - global: &mut JsObject, - name: &str, - proto_ptr: *mut JsObject, - ctor_fn: *const (), + kernel: &Arc, global: &mut JsObject, name: &str, proto_ptr: *mut JsObject, ctor_fn: *const (), ) { let sf = kernel.string_forge().as_ref(); let sh = kernel.shape_forge().as_ref(); let function_proto_ptr = kernel.builtin_world().function_proto.as_ptr() as *mut JsObject; - let mut ctor = Box::new(JsObject::new_empty( - EMPTY_SHAPE_ID, - JsValue::from_js_object(function_proto_ptr), - )); + let mut ctor = Box::new(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(function_proto_ptr))); ctor.set_function(true); ctor.set_native_fn(Some(ctor_fn)); ctor.set_native_arg_count(1); @@ -32,25 +25,19 @@ fn bind_error_subtype_constructor( let ctor_shape1 = sh.make_shape(EMPTY_SHAPE_ID, si_prototype); let ctor_shape2 = sh.make_shape(ctor_shape1, si_name); ctor.set_shape_id(ctor_shape2); - ctor.ensure_hash_props() - .push(Box::new(JsValue::from_js_object(proto_ptr))); - ctor.ensure_hash_props() - .push(Box::new(JsValue::string(name_si, 0))); + ctor.ensure_hash_props().push(Box::new(JsValue::from_js_object(proto_ptr))); + ctor.ensure_hash_props().push(Box::new(JsValue::string(name_si, 0))); let ctor_ptr = Box::into_raw(ctor); let proto = unsafe { &mut *proto_ptr }; let proto_ctor_shape = sh.make_shape(proto.shape_id(), sf.intern("constructor").0); proto.set_shape_id(proto_ctor_shape); - proto - .ensure_hash_props() - .push(Box::new(JsValue::from_js_object(ctor_ptr))); + proto.ensure_hash_props().push(Box::new(JsValue::from_js_object(ctor_ptr))); let global_shape = sh.make_shape(global.shape_id(), name_si); global.set_shape_id(global_shape); - global - .ensure_hash_props() - .push(Box::new(JsValue::from_js_object(ctor_ptr))); + global.ensure_hash_props().push(Box::new(JsValue::from_js_object(ctor_ptr))); global.bump_generation(); } @@ -74,8 +61,7 @@ pub fn bind_error(kernel: &Arc, global: &mut JsObject) { let si_err = kernel.string_forge().intern("Error").0; let err_shape = kernel.shape_forge().make_shape(global.shape_id(), si_err); - let err_val = - JsValue::from_js_object(kernel.builtin_world().error_constructor.as_ptr() as *mut JsObject); + let err_val = JsValue::from_js_object(kernel.builtin_world().error_constructor.as_ptr() as *mut JsObject); global.set_shape_id(err_shape); global.ensure_hash_props().push(Box::new(err_val)); global.bump_generation(); diff --git a/crates/oxide_vm/src/bindings/bind_json.rs b/crates/oxide_vm/src/bindings/bind_json.rs index 8a26e22..42c9262 100644 --- a/crates/oxide_vm/src/bindings/bind_json.rs +++ b/crates/oxide_vm/src/bindings/bind_json.rs @@ -15,11 +15,7 @@ pub fn bind_json(kernel: &Arc, global: &mut JsObject) { kernel, &[ ("parse", crate::builtins::json::json_parse as *const (), 1), - ( - "stringify", - crate::builtins::json::json_stringify as *const (), - 1, - ), + ("stringify", crate::builtins::json::json_stringify as *const (), 1), ], ); diff --git a/crates/oxide_vm/src/bindings/bind_map.rs b/crates/oxide_vm/src/bindings/bind_map.rs index 9b5d2a5..64b2217 100644 --- a/crates/oxide_vm/src/bindings/bind_map.rs +++ b/crates/oxide_vm/src/bindings/bind_map.rs @@ -27,12 +27,5 @@ pub fn bind_map(kernel: &Arc, global: &mut JsObject) { ], ); - bind_constructor_hash!( - kernel, - global, - "Map", - ctor_ptr, - crate::builtins::map::map_constructor, - 1 - ); + bind_constructor_hash!(kernel, global, "Map", ctor_ptr, crate::builtins::map::map_constructor, 1); } diff --git a/crates/oxide_vm/src/bindings/bind_math.rs b/crates/oxide_vm/src/bindings/bind_math.rs index f0945ed..e3dc813 100644 --- a/crates/oxide_vm/src/bindings/bind_math.rs +++ b/crates/oxide_vm/src/bindings/bind_math.rs @@ -66,18 +66,14 @@ pub fn bind_math(kernel: &Arc, global: &mut JsObject) { ("SQRT2", std::f64::consts::SQRT_2), ] { let si = kernel.string_forge().as_ref().intern(name).0; - let sh_c = kernel - .shape_forge() - .as_ref() - .make_shape(math.shape_id(), si); + let sh_c = kernel.shape_forge().as_ref().make_shape(math.shape_id(), si); math.set_shape_id(sh_c); math.ensure_hash_props().push(Box::new(JsValue::float(val))); } let si_m = kernel.string_forge().intern("Math").0; let m_shape = kernel.shape_forge().make_shape(global.shape_id(), si_m); - let m_val = - JsValue::from_js_object(kernel.builtin_world().math_object.as_ptr() as *mut JsObject); + let m_val = JsValue::from_js_object(kernel.builtin_world().math_object.as_ptr() as *mut JsObject); global.set_shape_id(m_shape); global.ensure_hash_props().push(Box::new(m_val)); global.bump_generation(); diff --git a/crates/oxide_vm/src/bindings/bind_number.rs b/crates/oxide_vm/src/bindings/bind_number.rs index 092b3d8..d258576 100644 --- a/crates/oxide_vm/src/bindings/bind_number.rs +++ b/crates/oxide_vm/src/bindings/bind_number.rs @@ -28,9 +28,7 @@ pub fn bind_number(kernel: &Arc, global: &mut JsObject) { let si_num = kernel.string_forge().intern("Number").0; let num_shape = kernel.shape_forge().make_shape(global.shape_id(), si_num); - let num_val = JsValue::from_js_object( - kernel.builtin_world().number_constructor.as_ptr() as *mut JsObject - ); + let num_val = JsValue::from_js_object(kernel.builtin_world().number_constructor.as_ptr() as *mut JsObject); global.set_shape_id(num_shape); global.ensure_hash_props().push(Box::new(num_val)); global.bump_generation(); @@ -38,9 +36,7 @@ pub fn bind_number(kernel: &Arc, global: &mut JsObject) { { let num_ctor_ptr = kernel.builtin_world().number_constructor.as_ptr() as *mut JsObject; let num_ctor = unsafe { &mut *num_ctor_ptr }; - num_ctor.set_native_fn(Some( - crate::builtins::number::number_constructor as *const (), - )); + num_ctor.set_native_fn(Some(crate::builtins::number::number_constructor as *const ())); num_ctor.set_native_arg_count(1); for (name, value) in [ @@ -55,9 +51,7 @@ pub fn bind_number(kernel: &Arc, global: &mut JsObject) { ] { 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); + let next_shape = kernel.shape_forge().make_shape(num_ctor.shape_id(), prop_si); num_ctor.set_shape_id(next_shape); } } diff --git a/crates/oxide_vm/src/bindings/bind_object.rs b/crates/oxide_vm/src/bindings/bind_object.rs index 2b453ec..54fac79 100644 --- a/crates/oxide_vm/src/bindings/bind_object.rs +++ b/crates/oxide_vm/src/bindings/bind_object.rs @@ -11,8 +11,7 @@ pub fn bind_object(kernel: &Arc, global: &mut JsObject) { create: crate::builtins::object::object_create as *const (), assign: crate::builtins::object::object_assign as *const (), define_property: crate::builtins::object::object_define_property as *const (), - get_own_property_descriptor: crate::builtins::object::object_get_own_property_descriptor - as *const (), + get_own_property_descriptor: crate::builtins::object::object_get_own_property_descriptor as *const (), freeze: crate::builtins::object::object_freeze as *const (), seal: crate::builtins::object::object_seal as *const (), prevent_extensions: crate::builtins::object::object_prevent_extensions as *const (), @@ -27,19 +26,10 @@ pub fn bind_object(kernel: &Arc, global: &mut JsObject) { entries: crate::builtins::object::object_entries as *const (), values: crate::builtins::object::object_values as *const (), }; - kernel.builtin_world().bind_object_methods( - &methods, - kernel.string_forge().as_ref(), - kernel.shape_forge().as_ref(), - ); + kernel + .builtin_world() + .bind_object_methods(&methods, kernel.string_forge().as_ref(), kernel.shape_forge().as_ref()); let ctor_ptr = kernel.builtin_world().object_constructor.as_ptr() as *mut JsObject; - bind_constructor!( - kernel, - global, - "Object", - ctor_ptr, - crate::builtins::object::object_constructor, - 1 - ); + bind_constructor!(kernel, global, "Object", ctor_ptr, crate::builtins::object::object_constructor, 1); } diff --git a/crates/oxide_vm/src/bindings/bind_regexp.rs b/crates/oxide_vm/src/bindings/bind_regexp.rs index 8269795..cac4332 100644 --- a/crates/oxide_vm/src/bindings/bind_regexp.rs +++ b/crates/oxide_vm/src/bindings/bind_regexp.rs @@ -12,11 +12,7 @@ pub fn bind_regexp(kernel: &Arc, global: &mut JsObject) { let proto_ptr = kernel.builtin_world().regexp_proto.as_ptr() as *mut JsObject; let proto = unsafe { &mut *proto_ptr }; - configure_native_constructor( - ctor, - crate::builtins::regexp::regexp_constructor as *const (), - 2, - ); + configure_native_constructor(ctor, crate::builtins::regexp::regexp_constructor as *const (), 2); apply_binding_table( kernel.builtin_world(), @@ -25,20 +21,9 @@ pub fn bind_regexp(kernel: &Arc, global: &mut JsObject) { &[ ("exec", crate::builtins::regexp::regexp_exec as *const (), 1), ("test", crate::builtins::regexp::regexp_test as *const (), 1), - ( - "toString", - crate::builtins::regexp::regexp_to_string as *const (), - 0, - ), + ("toString", crate::builtins::regexp::regexp_to_string as *const (), 0), ], ); - bind_constructor_hash!( - kernel, - global, - "RegExp", - ctor_ptr, - crate::builtins::regexp::regexp_constructor, - 2 - ); + bind_constructor_hash!(kernel, global, "RegExp", ctor_ptr, crate::builtins::regexp::regexp_constructor, 2); } diff --git a/crates/oxide_vm/src/bindings/bind_set.rs b/crates/oxide_vm/src/bindings/bind_set.rs index e188a27..7b2b533 100644 --- a/crates/oxide_vm/src/bindings/bind_set.rs +++ b/crates/oxide_vm/src/bindings/bind_set.rs @@ -26,12 +26,5 @@ pub fn bind_set(kernel: &Arc, global: &mut JsObject) { ], ); - bind_constructor_hash!( - kernel, - global, - "Set", - ctor_ptr, - crate::builtins::set::set_constructor, - 1 - ); + bind_constructor_hash!(kernel, global, "Set", ctor_ptr, crate::builtins::set::set_constructor, 1); } diff --git a/crates/oxide_vm/src/bindings/bind_string.rs b/crates/oxide_vm/src/bindings/bind_string.rs index 5704bd9..997cf22 100644 --- a/crates/oxide_vm/src/bindings/bind_string.rs +++ b/crates/oxide_vm/src/bindings/bind_string.rs @@ -41,9 +41,7 @@ pub fn bind_string(kernel: &Arc, global: &mut JsObject) { let si_str = kernel.string_forge().intern("String").0; let str_shape = kernel.shape_forge().make_shape(global.shape_id(), si_str); - let str_val = JsValue::from_js_object( - kernel.builtin_world().string_constructor.as_ptr() as *mut JsObject - ); + let str_val = JsValue::from_js_object(kernel.builtin_world().string_constructor.as_ptr() as *mut JsObject); global.set_shape_id(str_shape); global.ensure_hash_props().push(Box::new(str_val)); global.bump_generation(); diff --git a/crates/oxide_vm/src/bindings/bind_symbol.rs b/crates/oxide_vm/src/bindings/bind_symbol.rs index f41f37f..3fd8c35 100644 --- a/crates/oxide_vm/src/bindings/bind_symbol.rs +++ b/crates/oxide_vm/src/bindings/bind_symbol.rs @@ -13,21 +13,13 @@ pub fn bind_symbol(kernel: &Arc, global: &mut JsObject) { let proto_ptr = kernel.builtin_world().symbol_proto.as_ptr() as *mut JsObject; let proto = unsafe { &mut *proto_ptr }; - configure_native_constructor( - ctor, - crate::builtins::symbol::symbol_constructor as *const (), - 1, - ); + configure_native_constructor(ctor, crate::builtins::symbol::symbol_constructor as *const (), 1); apply_binding_table( kernel.builtin_world(), proto, kernel, - &[( - "toString", - crate::builtins::symbol::symbol_to_string as *const (), - 0, - )], + &[("toString", crate::builtins::symbol::symbol_to_string as *const (), 0)], ); for (name, val) in [ @@ -55,22 +47,10 @@ pub fn bind_symbol(kernel: &Arc, global: &mut JsObject) { bind_well_known_symbol(kernel, ctor, name, val); } - bind_constructor_hash!( - kernel, - global, - "Symbol", - ctor_ptr, - crate::builtins::symbol::symbol_constructor, - 1 - ); + bind_constructor_hash!(kernel, global, "Symbol", ctor_ptr, crate::builtins::symbol::symbol_constructor, 1); } -fn bind_well_known_symbol( - kernel: &Arc, - ctor: &mut JsObject, - name: &str, - val: JsValue, -) { +fn bind_well_known_symbol(kernel: &Arc, ctor: &mut JsObject, name: &str, val: JsValue) { let si = kernel.string_forge().intern(name).0; let shape_id = kernel.shape_forge().make_shape(ctor.shape_id(), si); ctor.set_shape_id(shape_id); diff --git a/crates/oxide_vm/src/bindings/mod.rs b/crates/oxide_vm/src/bindings/mod.rs index 5a43d80..b6c393a 100644 --- a/crates/oxide_vm/src/bindings/mod.rs +++ b/crates/oxide_vm/src/bindings/mod.rs @@ -49,20 +49,13 @@ macro_rules! bind_constructor_hash { }}; } -pub(crate) fn configure_native_constructor( - ctor: &mut JsObject, - native_fn: *const (), - arg_count: u8, -) { +pub(crate) fn configure_native_constructor(ctor: &mut JsObject, native_fn: *const (), arg_count: u8) { ctor.set_native_fn(Some(native_fn)); ctor.set_native_arg_count(arg_count); } pub(crate) fn apply_binding_table( - world: &BuiltinWorld, - target: &mut JsObject, - kernel: &Arc, - bindings: &[(&'static str, *const (), u8)], + world: &BuiltinWorld, target: &mut JsObject, kernel: &Arc, bindings: &[(&'static str, *const (), u8)], ) { let shape_forge = kernel.shape_forge().as_ref(); let string_forge = kernel.string_forge().as_ref(); @@ -71,12 +64,7 @@ pub(crate) fn apply_binding_table( } } -pub(crate) fn bind_global_value( - kernel: &Arc, - global: &mut JsObject, - name: &str, - value: JsValue, -) { +pub(crate) fn bind_global_value(kernel: &Arc, global: &mut JsObject, name: &str, value: JsValue) { let si = kernel.string_forge().intern(name).0; let shape = kernel.shape_forge().make_shape(global.shape_id(), si); global.set_shape_id(shape); diff --git a/crates/oxide_vm/src/builtins/array.rs b/crates/oxide_vm/src/builtins/array.rs index 56f9170..f26f064 100644 --- a/crates/oxide_vm/src/builtins/array.rs +++ b/crates/oxide_vm/src/builtins/array.rs @@ -37,20 +37,11 @@ fn get_this_array_ref(val: JsValue) -> Result<*mut JsObject, JsValue> { fn create_new_array(vm: &mut Vm, n: usize) -> *mut JsObject { let proto = vm.kernel().builtin_world().array_proto.as_ptr() as *mut JsObject; - vm.epoch().alloc(JsObject::new_array( - EMPTY_SHAPE_ID, - JsValue::from_js_object(proto), - n, - vm.epoch().bump(), - )) + vm.epoch() + .alloc(JsObject::new_array(EMPTY_SHAPE_ID, JsValue::from_js_object(proto), n, vm.epoch().bump())) } -fn invoke_native_callback( - vm: &mut Vm, - callback_val: JsValue, - this_val: JsValue, - cb_args: &[JsValue], -) -> NativeResult { +fn invoke_native_callback(vm: &mut Vm, callback_val: JsValue, this_val: JsValue, cb_args: &[JsValue]) -> NativeResult { if !callback_val.is_object() { return Err(JsValue::undefined()); } @@ -85,33 +76,24 @@ pub fn array_constructor(vm: &mut Vm, args: &[u8]) -> NativeResult { let val = vm.reg(args[1]); if val.is_int() { let n = val.as_int().max(0) as usize; - let arr = vm.epoch().alloc(JsObject::new_array( - EMPTY_SHAPE_ID, - proto_val, - n, - vm.epoch().bump(), - )); + let arr = vm + .epoch() + .alloc(JsObject::new_array(EMPTY_SHAPE_ID, proto_val, n, vm.epoch().bump())); return Ok(JsValue::from_js_object(arr)); } if val.is_double() { let n = val.as_double() as usize; - let arr = vm.epoch().alloc(JsObject::new_array( - EMPTY_SHAPE_ID, - proto_val, - n, - vm.epoch().bump(), - )); + let arr = vm + .epoch() + .alloc(JsObject::new_array(EMPTY_SHAPE_ID, proto_val, n, vm.epoch().bump())); return Ok(JsValue::from_js_object(arr)); } } let n_elems = if args.len() > 1 { args.len() - 1 } else { 0 }; - let arr = vm.epoch().alloc(JsObject::new_array( - EMPTY_SHAPE_ID, - proto_val, - n_elems, - vm.epoch().bump(), - )); + let arr = vm + .epoch() + .alloc(JsObject::new_array(EMPTY_SHAPE_ID, proto_val, n_elems, vm.epoch().bump())); for i in 0..n_elems { unsafe { (*arr).set_prop_at(i, vm.reg(args[1 + i])); @@ -359,8 +341,7 @@ pub fn array_flat(vm: &mut Vm, args: &[u8]) -> NativeResult { let arr = unsafe { &*arr_ptr }; let n = arr.prop_count() as usize; let depth = if args.len() > 1 { - (coercion::to_number(vm.reg(args[1]), vm.kernel().string_forge().as_ref()) as i32).max(1) - as usize + (coercion::to_number(vm.reg(args[1]), vm.kernel().string_forge().as_ref()) as i32).max(1) as usize } else { 1 }; @@ -407,19 +388,10 @@ pub fn array_for_each(vm: &mut Vm, args: &[u8]) -> NativeResult { if !callback_val.is_object() { return Err(JsValue::undefined()); } - let this_val = if args.len() > 2 { - vm.reg(args[2]) - } else { - JsValue::undefined() - }; + let this_val = if args.len() > 2 { vm.reg(args[2]) } else { JsValue::undefined() }; for i in 0..n { let elem = unsafe { (*arr_ptr).get_prop_at(i) }; - let _ = invoke_native_callback( - vm, - callback_val, - this_val, - &[elem, JsValue::int(i as i32), vm.reg(args[0])], - ); + let _ = invoke_native_callback(vm, callback_val, this_val, &[elem, JsValue::int(i as i32), vm.reg(args[0])]); } Ok(JsValue::undefined()) } @@ -433,20 +405,11 @@ pub fn array_map(vm: &mut Vm, args: &[u8]) -> NativeResult { if !callback_val.is_object() { return Err(JsValue::undefined()); } - let this_val = if args.len() > 2 { - vm.reg(args[2]) - } else { - JsValue::undefined() - }; + let this_val = if args.len() > 2 { vm.reg(args[2]) } else { JsValue::undefined() }; let new_arr = create_new_array(vm, n); for i in 0..n { let elem = unsafe { (*arr_ptr).get_prop_at(i) }; - match invoke_native_callback( - vm, - callback_val, - this_val, - &[elem, JsValue::int(i as i32), vm.reg(args[0])], - ) { + match invoke_native_callback(vm, callback_val, this_val, &[elem, JsValue::int(i as i32), vm.reg(args[0])]) { Ok(mapped) => unsafe { (*new_arr).set_prop_at(i, mapped); }, @@ -468,20 +431,11 @@ pub fn array_filter(vm: &mut Vm, args: &[u8]) -> NativeResult { if !callback_val.is_object() { return Err(JsValue::undefined()); } - let this_val = if args.len() > 2 { - vm.reg(args[2]) - } else { - JsValue::undefined() - }; + let this_val = if args.len() > 2 { vm.reg(args[2]) } else { JsValue::undefined() }; let mut kept: Vec = Vec::new(); for i in 0..n { let elem = unsafe { (*arr_ptr).get_prop_at(i) }; - match invoke_native_callback( - vm, - callback_val, - this_val, - &[elem, JsValue::int(i as i32), vm.reg(args[0])], - ) { + match invoke_native_callback(vm, callback_val, this_val, &[elem, JsValue::int(i as i32), vm.reg(args[0])]) { Ok(result_val) => { let sf = vm.kernel().string_forge().as_ref(); if coercion::to_boolean(result_val, sf) { @@ -548,19 +502,10 @@ pub fn array_find(vm: &mut Vm, args: &[u8]) -> NativeResult { if !callback_val.is_object() { return Ok(JsValue::undefined()); } - let this_val = if args.len() > 2 { - vm.reg(args[2]) - } else { - JsValue::undefined() - }; + let this_val = if args.len() > 2 { vm.reg(args[2]) } else { JsValue::undefined() }; for i in 0..n { let elem = unsafe { (*arr_ptr).get_prop_at(i) }; - match invoke_native_callback( - vm, - callback_val, - this_val, - &[elem, JsValue::int(i as i32), vm.reg(args[0])], - ) { + match invoke_native_callback(vm, callback_val, this_val, &[elem, JsValue::int(i as i32), vm.reg(args[0])]) { Ok(result_val) => { let sf = vm.kernel().string_forge().as_ref(); if coercion::to_boolean(result_val, sf) { @@ -582,19 +527,10 @@ pub fn array_some(vm: &mut Vm, args: &[u8]) -> NativeResult { if !callback_val.is_object() { return Ok(JsValue::bool(false)); } - let this_val = if args.len() > 2 { - vm.reg(args[2]) - } else { - JsValue::undefined() - }; + let this_val = if args.len() > 2 { vm.reg(args[2]) } else { JsValue::undefined() }; for i in 0..n { let elem = unsafe { (*arr_ptr).get_prop_at(i) }; - match invoke_native_callback( - vm, - callback_val, - this_val, - &[elem, JsValue::int(i as i32), vm.reg(args[0])], - ) { + match invoke_native_callback(vm, callback_val, this_val, &[elem, JsValue::int(i as i32), vm.reg(args[0])]) { Ok(result_val) => { let sf = vm.kernel().string_forge().as_ref(); if coercion::to_boolean(result_val, sf) { @@ -616,19 +552,10 @@ pub fn array_every(vm: &mut Vm, args: &[u8]) -> NativeResult { if !callback_val.is_object() { return Ok(JsValue::bool(false)); } - let this_val = if args.len() > 2 { - vm.reg(args[2]) - } else { - JsValue::undefined() - }; + let this_val = if args.len() > 2 { vm.reg(args[2]) } else { JsValue::undefined() }; for i in 0..n { let elem = unsafe { (*arr_ptr).get_prop_at(i) }; - match invoke_native_callback( - vm, - callback_val, - this_val, - &[elem, JsValue::int(i as i32), vm.reg(args[0])], - ) { + match invoke_native_callback(vm, callback_val, this_val, &[elem, JsValue::int(i as i32), vm.reg(args[0])]) { Ok(result_val) => { let sf = vm.kernel().string_forge().as_ref(); if !coercion::to_boolean(result_val, sf) { @@ -650,20 +577,11 @@ pub fn array_flat_map(vm: &mut Vm, args: &[u8]) -> NativeResult { if !callback_val.is_object() { return Err(JsValue::undefined()); } - let this_val = if args.len() > 2 { - vm.reg(args[2]) - } else { - JsValue::undefined() - }; + let this_val = if args.len() > 2 { vm.reg(args[2]) } else { JsValue::undefined() }; let mut flat: Vec = Vec::new(); for i in 0..n { let elem = unsafe { (*arr_ptr).get_prop_at(i) }; - match invoke_native_callback( - vm, - callback_val, - this_val, - &[elem, JsValue::int(i as i32), vm.reg(args[0])], - ) { + match invoke_native_callback(vm, callback_val, this_val, &[elem, JsValue::int(i as i32), vm.reg(args[0])]) { Ok(result) => { if result.is_object() { let r_ptr = result.as_js_object_ptr(); @@ -730,14 +648,9 @@ pub fn array_fill(vm: &mut Vm, args: &[u8]) -> NativeResult { let arr_ptr = array_ptr!(vm, args); let arr = unsafe { &mut *arr_ptr }; let len = arr.prop_count() as usize; - let value = if args.len() > 1 { - vm.reg(args[1]) - } else { - JsValue::undefined() - }; + let value = if args.len() > 1 { vm.reg(args[1]) } else { JsValue::undefined() }; let start = if args.len() > 2 { - (coercion::to_number(vm.reg(args[2]), vm.kernel().string_forge().as_ref()) as i32).max(0) - as usize + (coercion::to_number(vm.reg(args[2]), vm.kernel().string_forge().as_ref()) as i32).max(0) as usize } else { 0 }; @@ -771,8 +684,7 @@ pub fn array_copy_within(vm: &mut Vm, args: &[u8]) -> NativeResult { 0 }; let end = if args.len() > 3 { - (coercion::to_number(vm.reg(args[3]), vm.kernel().string_forge().as_ref()) as i32 as usize) - .min(len) + (coercion::to_number(vm.reg(args[3]), vm.kernel().string_forge().as_ref()) as i32 as usize).min(len) } else { len }; @@ -810,11 +722,7 @@ pub fn array_last_index_of(vm: &mut Vm, args: &[u8]) -> NativeResult { let arr_ptr = array_ptr!(vm, args); let arr = unsafe { &*arr_ptr }; let len = arr.prop_count() as i32; - let search = if args.len() > 1 { - vm.reg(args[1]) - } else { - JsValue::undefined() - }; + let search = if args.len() > 1 { vm.reg(args[1]) } else { JsValue::undefined() }; for i in (0..len).rev() { if coercion::strict_equality(arr.get_prop_at(i), search) { return Ok(JsValue::int(i)); @@ -829,19 +737,10 @@ pub fn array_find_index(vm: &mut Vm, args: &[u8]) -> NativeResult { return Ok(JsValue::int(-1)); } let callback_val = vm.reg(args[1]); - let this_val = if args.len() > 2 { - vm.reg(args[2]) - } else { - JsValue::undefined() - }; + let this_val = if args.len() > 2 { vm.reg(args[2]) } else { JsValue::undefined() }; for i in 0..n { let elem = unsafe { (*arr_ptr).get_prop_at(i) }; - match invoke_native_callback( - vm, - callback_val, - this_val, - &[elem, JsValue::int(i as i32), vm.reg(args[0])], - ) { + match invoke_native_callback(vm, callback_val, this_val, &[elem, JsValue::int(i as i32), vm.reg(args[0])]) { Ok(r) => { if coercion::to_boolean(r, vm.kernel().string_forge().as_ref()) { return Ok(JsValue::int(i as i32)); @@ -862,19 +761,10 @@ pub fn array_find_last(vm: &mut Vm, args: &[u8]) -> NativeResult { return Ok(JsValue::undefined()); } let callback_val = vm.reg(args[1]); - let this_val = if args.len() > 2 { - vm.reg(args[2]) - } else { - JsValue::undefined() - }; + let this_val = if args.len() > 2 { vm.reg(args[2]) } else { JsValue::undefined() }; for i in (0..n).rev() { let elem = unsafe { (*arr_ptr).get_prop_at(i) }; - match invoke_native_callback( - vm, - callback_val, - this_val, - &[elem, JsValue::int(i), vm.reg(args[0])], - ) { + match invoke_native_callback(vm, callback_val, this_val, &[elem, JsValue::int(i), vm.reg(args[0])]) { Ok(r) => { if coercion::to_boolean(r, vm.kernel().string_forge().as_ref()) { return Ok(elem); diff --git a/crates/oxide_vm/src/builtins/boolean.rs b/crates/oxide_vm/src/builtins/boolean.rs index b582dc9..a83ce01 100644 --- a/crates/oxide_vm/src/builtins/boolean.rs +++ b/crates/oxide_vm/src/builtins/boolean.rs @@ -13,11 +13,7 @@ pub fn boolean_constructor(vm: &mut Vm, args: &[u8]) -> NativeResult { } else if arg.is_bool() { arg.as_bool() } else if arg.is_string() { - let s = vm - .kernel() - .string_forge() - .lookup(arg.as_string_index()) - .unwrap_or_default(); + let s = vm.kernel().string_forge().lookup(arg.as_string_index()).unwrap_or_default(); !s.is_empty() } else if arg.is_object() { true diff --git a/crates/oxide_vm/src/builtins/date.rs b/crates/oxide_vm/src/builtins/date.rs index 03f4747..e11ac01 100644 --- a/crates/oxide_vm/src/builtins/date.rs +++ b/crates/oxide_vm/src/builtins/date.rs @@ -30,10 +30,7 @@ fn is_date(vm: &Vm, obj: &JsObject) -> bool { fn ensure_date(vm: &mut Vm, obj: &JsObject) -> NativeResult { if !is_date(vm, obj) { - return Err(crate::builtins::error::create_type_error( - vm, - "called on incompatible receiver", - )); + return Err(crate::builtins::error::create_type_error(vm, "called on incompatible receiver")); } Ok(JsValue::undefined()) } @@ -114,11 +111,7 @@ pub fn date_constructor(vm: &mut Vm, args: &[u8]) -> NativeResult { } else { let val = vm.reg(args[1]); if val.is_string() { - let s = vm - .kernel() - .string_forge() - .lookup(val.as_string_index()) - .unwrap_or_default(); + let s = vm.kernel().string_forge().lookup(val.as_string_index()).unwrap_or_default(); let formats = ["%Y-%m-%dT%H:%M:%S%.fZ", "%Y-%m-%dT%H:%M:%S%.f"]; let mut ts = f64::NAN; for fmt in &formats { @@ -129,10 +122,7 @@ pub fn date_constructor(vm: &mut Vm, args: &[u8]) -> NativeResult { } if ts.is_nan() { if let Ok(nd) = NaiveDate::parse_from_str(&s, "%Y-%m-%d") { - if let Some(ndt) = nd - .and_hms_opt(0, 0, 0) - .and_then(|n| n.and_local_timezone(Utc).earliest()) - { + if let Some(ndt) = nd.and_hms_opt(0, 0, 0).and_then(|n| n.and_local_timezone(Utc).earliest()) { ts = ndt.timestamp_millis() as f64; } } @@ -192,11 +182,7 @@ pub fn date_parse(vm: &mut Vm, args: &[u8]) -> NativeResult { if !val.is_string() { return Ok(JsValue::float(f64::NAN)); } - let s = vm - .kernel() - .string_forge() - .lookup(val.as_string_index()) - .unwrap_or_default(); + let s = vm.kernel().string_forge().lookup(val.as_string_index()).unwrap_or_default(); let formats = ["%Y-%m-%dT%H:%M:%S%.fZ", "%Y-%m-%dT%H:%M:%S%.f"]; let mut ts = f64::NAN; for fmt in &formats { @@ -207,10 +193,7 @@ pub fn date_parse(vm: &mut Vm, args: &[u8]) -> NativeResult { } if ts.is_nan() { if let Ok(nd) = NaiveDate::parse_from_str(&s, "%Y-%m-%d") { - if let Some(ndt) = nd - .and_hms_opt(0, 0, 0) - .and_then(|n| n.and_local_timezone(Utc).earliest()) - { + if let Some(ndt) = nd.and_hms_opt(0, 0, 0).and_then(|n| n.and_local_timezone(Utc).earliest()) { ts = ndt.timestamp_millis() as f64; } } @@ -227,10 +210,7 @@ macro_rules! make_getter { pub fn $name(vm: &mut Vm, args: &[u8]) -> NativeResult { let raw = vm.reg(if args.is_empty() { 0 } else { args[0] }); if !raw.is_object() { - return Err(crate::builtins::error::create_type_error( - vm, - "called on incompatible receiver", - )); + return Err(crate::builtins::error::create_type_error(vm, "called on incompatible receiver")); } let obj = unsafe { &*raw.as_js_object_ptr() }; ensure_date(vm, obj)?; @@ -251,10 +231,7 @@ macro_rules! make_utc_getter { pub fn $name(vm: &mut Vm, args: &[u8]) -> NativeResult { let raw = vm.reg(if args.is_empty() { 0 } else { args[0] }); if !raw.is_object() { - return Err(crate::builtins::error::create_type_error( - vm, - "called on incompatible receiver", - )); + return Err(crate::builtins::error::create_type_error(vm, "called on incompatible receiver")); } let obj = unsafe { &*raw.as_js_object_ptr() }; ensure_date(vm, obj)?; @@ -270,83 +247,27 @@ macro_rules! make_utc_getter { }; } -make_getter!( - date_get_time, - |dt: DateTime| dt.timestamp_millis() as f64, - f64::NAN -); -make_getter!( - date_get_full_year, - |dt: DateTime| dt.year() as f64, - f64::NAN -); -make_getter!( - date_get_month, - |dt: DateTime| dt.month0() as f64, - f64::NAN -); +make_getter!(date_get_time, |dt: DateTime| dt.timestamp_millis() as f64, f64::NAN); +make_getter!(date_get_full_year, |dt: DateTime| dt.year() as f64, f64::NAN); +make_getter!(date_get_month, |dt: DateTime| dt.month0() as f64, f64::NAN); make_getter!(date_get_date, |dt: DateTime| dt.day() as f64, f64::NAN); -make_getter!( - date_get_day, - |dt: DateTime| dt.weekday().num_days_from_sunday() as f64, - f64::NAN -); -make_getter!( - date_get_hours, - |dt: DateTime| dt.hour() as f64, - f64::NAN -); -make_getter!( - date_get_minutes, - |dt: DateTime| dt.minute() as f64, - f64::NAN -); -make_getter!( - date_get_seconds, - |dt: DateTime| dt.second() as f64, - f64::NAN -); -make_getter!( - date_get_milliseconds, - |dt: DateTime| dt.timestamp_subsec_millis() as f64, - f64::NAN -); +make_getter!(date_get_day, |dt: DateTime| dt.weekday().num_days_from_sunday() as f64, f64::NAN); +make_getter!(date_get_hours, |dt: DateTime| dt.hour() as f64, f64::NAN); +make_getter!(date_get_minutes, |dt: DateTime| dt.minute() as f64, f64::NAN); +make_getter!(date_get_seconds, |dt: DateTime| dt.second() as f64, f64::NAN); +make_getter!(date_get_milliseconds, |dt: DateTime| dt.timestamp_subsec_millis() as f64, f64::NAN); -make_utc_getter!( - date_get_utc_full_year, - |ndt: NaiveDateTime| ndt.date().year() as f64, - f64::NAN -); -make_utc_getter!( - date_get_utc_month, - |ndt: NaiveDateTime| ndt.date().month0() as f64, - f64::NAN -); -make_utc_getter!( - date_get_utc_date, - |ndt: NaiveDateTime| ndt.date().day() as f64, - f64::NAN -); +make_utc_getter!(date_get_utc_full_year, |ndt: NaiveDateTime| ndt.date().year() as f64, f64::NAN); +make_utc_getter!(date_get_utc_month, |ndt: NaiveDateTime| ndt.date().month0() as f64, f64::NAN); +make_utc_getter!(date_get_utc_date, |ndt: NaiveDateTime| ndt.date().day() as f64, f64::NAN); make_utc_getter!( date_get_utc_day, |ndt: NaiveDateTime| ndt.date().weekday().num_days_from_sunday() as f64, f64::NAN ); -make_utc_getter!( - date_get_utc_hours, - |ndt: NaiveDateTime| ndt.time().hour() as f64, - f64::NAN -); -make_utc_getter!( - date_get_utc_minutes, - |ndt: NaiveDateTime| ndt.time().minute() as f64, - f64::NAN -); -make_utc_getter!( - date_get_utc_seconds, - |ndt: NaiveDateTime| ndt.time().second() as f64, - f64::NAN -); +make_utc_getter!(date_get_utc_hours, |ndt: NaiveDateTime| ndt.time().hour() as f64, f64::NAN); +make_utc_getter!(date_get_utc_minutes, |ndt: NaiveDateTime| ndt.time().minute() as f64, f64::NAN); +make_utc_getter!(date_get_utc_seconds, |ndt: NaiveDateTime| ndt.time().second() as f64, f64::NAN); make_utc_getter!( date_get_utc_milliseconds, |ndt: NaiveDateTime| ndt.time().nanosecond() as f64 / 1_000_000.0, @@ -356,10 +277,7 @@ make_utc_getter!( pub fn date_get_timezone_offset(vm: &mut Vm, args: &[u8]) -> NativeResult { let raw = vm.reg(if args.is_empty() { 0 } else { args[0] }); if !raw.is_object() { - return Err(crate::builtins::error::create_type_error( - vm, - "called on incompatible receiver", - )); + return Err(crate::builtins::error::create_type_error(vm, "called on incompatible receiver")); } let obj = unsafe { &*raw.as_js_object_ptr() }; ensure_date(vm, obj)?; @@ -382,10 +300,7 @@ fn get_opt_arg(vm: &Vm, args: &[u8], idx: usize, default: u32) -> u32 { pub fn date_set_time(vm: &mut Vm, args: &[u8]) -> NativeResult { let raw = vm.reg(if args.is_empty() { 0 } else { args[0] }); if !raw.is_object() { - return Err(crate::builtins::error::create_type_error( - vm, - "called on incompatible receiver", - )); + return Err(crate::builtins::error::create_type_error(vm, "called on incompatible receiver")); } let obj = unsafe { &mut *raw.as_js_object_ptr() }; ensure_date(vm, obj)?; @@ -438,10 +353,7 @@ pub fn date_set_month(vm: &mut Vm, args: &[u8]) -> NativeResult { None => return Ok(JsValue::float(f64::NAN)), }; let d = get_opt_arg(vm, args, 2, dt.day0()); - let nd = dt - .with_month0(v as u32) - .and_then(|x| x.with_day0(d)) - .unwrap_or(dt); + let nd = dt.with_month0(v as u32).and_then(|x| x.with_day0(d)).unwrap_or(dt); let ts = nd.timestamp_millis() as f64; set_timestamp(obj, ts); Ok(JsValue::float(ts)) @@ -563,10 +475,7 @@ pub fn date_set_milliseconds(vm: &mut Vm, args: &[u8]) -> NativeResult { fn date_to_string_inner(vm: &mut Vm, args: &[u8], format_str: &str, invalid: &str) -> NativeResult { let raw = vm.reg(if args.is_empty() { 0 } else { args[0] }); if !raw.is_object() { - return Err(crate::builtins::error::create_type_error( - vm, - "called on incompatible receiver", - )); + return Err(crate::builtins::error::create_type_error(vm, "called on incompatible receiver")); } let obj = unsafe { &*raw.as_js_object_ptr() }; ensure_date(vm, obj)?; @@ -588,10 +497,7 @@ pub fn date_to_iso_string(vm: &mut Vm, args: &[u8]) -> NativeResult { pub fn date_to_json(vm: &mut Vm, args: &[u8]) -> NativeResult { let raw = vm.reg(if args.is_empty() { 0 } else { args[0] }); if !raw.is_object() { - return Err(crate::builtins::error::create_type_error( - vm, - "called on incompatible receiver", - )); + return Err(crate::builtins::error::create_type_error(vm, "called on incompatible receiver")); } let obj = unsafe { &*raw.as_js_object_ptr() }; ensure_date(vm, obj)?; @@ -625,10 +531,7 @@ pub fn date_to_utc_string(vm: &mut Vm, args: &[u8]) -> NativeResult { pub fn date_value_of(vm: &mut Vm, args: &[u8]) -> NativeResult { let raw = vm.reg(if args.is_empty() { 0 } else { args[0] }); if !raw.is_object() { - return Err(crate::builtins::error::create_type_error( - vm, - "called on incompatible receiver", - )); + return Err(crate::builtins::error::create_type_error(vm, "called on incompatible receiver")); } let obj = unsafe { &*raw.as_js_object_ptr() }; ensure_date(vm, obj)?; diff --git a/crates/oxide_vm/src/builtins/error.rs b/crates/oxide_vm/src/builtins/error.rs index e132ab0..16b13c0 100644 --- a/crates/oxide_vm/src/builtins/error.rs +++ b/crates/oxide_vm/src/builtins/error.rs @@ -9,16 +9,10 @@ use crate::coercion; use crate::native::NativeResult; use crate::vm::Vm; -fn create_error_object( - vm: &mut Vm, - error_proto_ptr: *mut JsObject, - name: &str, - message: &str, -) -> JsValue { - let obj = vm.epoch().alloc(JsObject::new_empty( - EMPTY_SHAPE_ID, - JsValue::from_js_object(error_proto_ptr), - )); +fn create_error_object(vm: &mut Vm, error_proto_ptr: *mut JsObject, name: &str, message: &str) -> JsValue { + let obj = vm + .epoch() + .alloc(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(error_proto_ptr))); let sf = Arc::clone(vm.kernel().string_forge()); let sh = Arc::clone(vm.kernel().shape_forge()); @@ -132,18 +126,13 @@ pub fn error_to_string(vm: &mut Vm, args: &[u8]) -> NativeResult { .map(|b| **b) .unwrap_or(JsValue::undefined()); ( - vm.lookup_str(name_val) - .unwrap_or_else(|| "Error".to_string()), + vm.lookup_str(name_val).unwrap_or_else(|| "Error".to_string()), vm.lookup_str(msg_val).unwrap_or_default(), ) } else { ("Error".to_string(), String::new()) }; - let result = if msg.is_empty() { - name - } else { - format!("{}: {}", name, msg) - }; + let result = if msg.is_empty() { name } else { format!("{}: {}", name, msg) }; let si = vm.kernel().string_forge().intern(&result).0; Ok(JsValue::string(si, 0)) } @@ -184,14 +173,7 @@ mod tests { }); let stack = error_stack_getter(&mut vm, &[0]).unwrap(); - let stack_str = vm - .kernel() - .string_forge() - .lookup(stack.as_string_index()) - .unwrap_or_default(); - assert!( - stack_str.contains("foo"), - "expected function name in stack: {stack_str}" - ); + let stack_str = vm.kernel().string_forge().lookup(stack.as_string_index()).unwrap_or_default(); + assert!(stack_str.contains("foo"), "expected function name in stack: {stack_str}"); } } diff --git a/crates/oxide_vm/src/builtins/function.rs b/crates/oxide_vm/src/builtins/function.rs index ada11c1..cd08f62 100644 --- a/crates/oxide_vm/src/builtins/function.rs +++ b/crates/oxide_vm/src/builtins/function.rs @@ -5,12 +5,7 @@ use oxide_types::value::JsValue; use crate::native::{NativeFn, NativeResult}; use crate::vm::Vm; -fn invoke_target( - vm: &mut Vm, - target_val: JsValue, - this_val: JsValue, - arg_regs: &[u8], -) -> NativeResult { +fn invoke_target(vm: &mut Vm, target_val: JsValue, this_val: JsValue, arg_regs: &[u8]) -> NativeResult { if !target_val.is_object() { return Err(JsValue::undefined()); } @@ -79,11 +74,7 @@ pub fn function_call(vm: &mut Vm, args: &[u8]) -> NativeResult { return Err(JsValue::undefined()); } let target_val = vm.reg(args[0]); - let this_val = if args.len() > 1 { - vm.reg(args[1]) - } else { - JsValue::undefined() - }; + let this_val = if args.len() > 1 { vm.reg(args[1]) } else { JsValue::undefined() }; let arg_regs: Vec = args.iter().skip(2).copied().collect(); invoke_target(vm, target_val, this_val, &arg_regs) } @@ -93,11 +84,7 @@ pub fn function_apply(vm: &mut Vm, args: &[u8]) -> NativeResult { return Err(JsValue::undefined()); } let target_val = vm.reg(args[0]); - let this_val = if args.len() > 1 { - vm.reg(args[1]) - } else { - JsValue::undefined() - }; + let this_val = if args.len() > 1 { vm.reg(args[1]) } else { JsValue::undefined() }; let arg_regs: Vec; if args.len() > 2 { @@ -139,15 +126,9 @@ pub fn function_bind(vm: &mut Vm, args: &[u8]) -> NativeResult { if !target_val.is_object() { return Err(JsValue::undefined()); } - let bound_this = if args.len() > 1 { - vm.reg(args[1]) - } else { - JsValue::undefined() - }; + let bound_this = if args.len() > 1 { vm.reg(args[1]) } else { JsValue::undefined() }; - let wrapper = vm - .epoch() - .alloc(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); + let wrapper = vm.epoch().alloc(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); unsafe { (*wrapper).set_function(true); (*wrapper).set_native_fn(Some(bind_dispatcher as *const ())); @@ -189,20 +170,13 @@ pub fn function_to_string(vm: &mut Vm, args: &[u8]) -> NativeResult { .unwrap_or_else(|| { let sub_idx = func.sub_module_index(); if sub_idx > 0 && (sub_idx as usize) <= vm.sub_modules.len() { - vm.sub_modules[sub_idx as usize - 1] - .function_name - .clone() - .unwrap_or_default() + vm.sub_modules[sub_idx as usize - 1].function_name.clone().unwrap_or_default() } else { String::new() } }); - let body = if func.native_fn().is_some() { - "[native code]" - } else { - "[bytecode]" - }; + let body = if func.native_fn().is_some() { "[native code]" } else { "[bytecode]" }; let result = if name.is_empty() { format!("function () {{ {body} }}") } else { diff --git a/crates/oxide_vm/src/builtins/global.rs b/crates/oxide_vm/src/builtins/global.rs index e9a168f..a1b2a56 100644 --- a/crates/oxide_vm/src/builtins/global.rs +++ b/crates/oxide_vm/src/builtins/global.rs @@ -2,9 +2,6 @@ use std::sync::Arc; use oxide_kernel::kernel::OxideKernel; -pub fn register_global_properties( - _kernel: &Arc, - _bump: &bumpalo::Bump, -) -> Result<(), String> { +pub fn register_global_properties(_kernel: &Arc, _bump: &bumpalo::Bump) -> Result<(), String> { Ok(()) } diff --git a/crates/oxide_vm/src/builtins/json.rs b/crates/oxide_vm/src/builtins/json.rs index 12fe71b..a509b8d 100644 --- a/crates/oxide_vm/src/builtins/json.rs +++ b/crates/oxide_vm/src/builtins/json.rs @@ -11,25 +11,19 @@ use crate::vm::Vm; pub fn json_parse(vm: &mut Vm, args: &[u8]) -> NativeResult { if args.len() < 2 { - return Err(crate::builtins::error::create_syntax_error( - vm, - "JSON.parse requires 1 argument", - )); + return Err(crate::builtins::error::create_syntax_error(vm, "JSON.parse requires 1 argument")); } let val = vm.reg(args[1]); if !val.is_string() { - return Err(crate::builtins::error::create_syntax_error( - vm, - "JSON.parse: argument is not a string", - )); + return Err(crate::builtins::error::create_syntax_error(vm, "JSON.parse: argument is not a string")); } let text = { let si = val.as_string_index(); vm.kernel().string_forge().lookup(si).unwrap_or_default() }; - let parsed: serde_json::Value = serde_json::from_str(&text) - .map_err(|e| crate::builtins::error::create_syntax_error(vm, &format!("{}", e)))?; + let parsed: serde_json::Value = + serde_json::from_str(&text).map_err(|e| crate::builtins::error::create_syntax_error(vm, &format!("{}", e)))?; Ok(value_to_jsvalue(vm, &parsed)) } @@ -65,8 +59,7 @@ fn value_to_jsvalue(vm: &mut Vm, val: &serde_json::Value) -> JsValue { } serde_json::Value::Object(map) => { let object_proto = vm.kernel().builtin_world().object_proto.as_ptr() as *mut JsObject; - let mut obj = - JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(object_proto)); + let mut obj = JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(object_proto)); for (key, val) in map { let si = vm.kernel().string_forge().intern(key).0; let jsv = value_to_jsvalue(vm, val); @@ -95,12 +88,7 @@ pub fn json_stringify(vm: &mut Vm, args: &[u8]) -> NativeResult { Ok(vm.intern(&output)) } -fn jsvalue_to_json( - vm: &Vm, - val: JsValue, - visited: &mut HashSet<*const u8>, - out: &mut String, -) -> Result<(), ()> { +fn jsvalue_to_json(vm: &Vm, val: JsValue, visited: &mut HashSet<*const u8>, out: &mut String) -> Result<(), ()> { if val.is_null() { out.push_str("null"); } else if val.is_undefined() { @@ -169,12 +157,7 @@ fn stringify_string(s: &str, out: &mut String) { out.push('"'); } -fn stringify_object( - vm: &Vm, - obj: &JsObject, - visited: &mut HashSet<*const u8>, - out: &mut String, -) -> Result<(), ()> { +fn stringify_object(vm: &Vm, obj: &JsObject, visited: &mut HashSet<*const u8>, out: &mut String) -> Result<(), ()> { out.push('{'); let keys = walk_own_keys(vm, obj); let mut first = true; @@ -204,12 +187,7 @@ fn stringify_object( Ok(()) } -fn stringify_array( - vm: &Vm, - obj: &JsObject, - visited: &mut HashSet<*const u8>, - out: &mut String, -) -> Result<(), ()> { +fn stringify_array(vm: &Vm, obj: &JsObject, visited: &mut HashSet<*const u8>, out: &mut String) -> Result<(), ()> { out.push('['); let len = obj.prop_vec_len(); for i in 0..len { diff --git a/crates/oxide_vm/src/builtins/map.rs b/crates/oxide_vm/src/builtins/map.rs index 399b733..3247b78 100644 --- a/crates/oxide_vm/src/builtins/map.rs +++ b/crates/oxide_vm/src/builtins/map.rs @@ -8,37 +8,22 @@ use crate::vm::Vm; const MAP_PROP_INDEX: u8 = 0; -fn get_map_inner( - vm: &mut Vm, - this_val: JsValue, -) -> Result<*mut indexmap::IndexMap, JsValue> { +fn get_map_inner(vm: &mut Vm, this_val: JsValue) -> Result<*mut indexmap::IndexMap, JsValue> { if !this_val.is_object() { - return Err(crate::builtins::error::create_type_error( - vm, - "called on non-Map object", - )); + return Err(crate::builtins::error::create_type_error(vm, "called on non-Map object")); } let map_ptr = this_val.as_js_object_ptr(); if map_ptr.is_null() { - return Err(crate::builtins::error::create_type_error( - vm, - "Map internal state invalid", - )); + return Err(crate::builtins::error::create_type_error(vm, "Map internal state invalid")); } let map_obj = unsafe { &*map_ptr }; let inner_val = map_obj.get_prop_at(MAP_PROP_INDEX); if !inner_val.is_object() { - return Err(crate::builtins::error::create_type_error( - vm, - "Map internal state invalid", - )); + return Err(crate::builtins::error::create_type_error(vm, "Map internal state invalid")); } let inner_ptr = inner_val.as_js_object_ptr() as *mut indexmap::IndexMap; if inner_ptr.is_null() { - return Err(crate::builtins::error::create_type_error( - vm, - "Map internal state invalid", - )); + return Err(crate::builtins::error::create_type_error(vm, "Map internal state invalid")); } Ok(inner_ptr) } diff --git a/crates/oxide_vm/src/builtins/math.rs b/crates/oxide_vm/src/builtins/math.rs index 86fa8d3..8ca7d50 100644 --- a/crates/oxide_vm/src/builtins/math.rs +++ b/crates/oxide_vm/src/builtins/math.rs @@ -18,16 +18,8 @@ fn arg1(vm: &Vm, args: &[u8]) -> f64 { fn arg2(vm: &Vm, args: &[u8]) -> (f64, f64) { ( - if args.len() > 1 { - num(vm, args[1]) - } else { - f64::NAN - }, - if args.len() > 2 { - num(vm, args[2]) - } else { - f64::NAN - }, + if args.len() > 1 { num(vm, args[1]) } else { f64::NAN }, + if args.len() > 2 { num(vm, args[2]) } else { f64::NAN }, ) } @@ -82,11 +74,7 @@ pub fn math_atan2(vm: &mut Vm, args: &[u8]) -> NativeResult { pub fn math_round(vm: &mut Vm, args: &[u8]) -> NativeResult { let x = arg1(vm, args); - let r = if x < 0.0 { - (x - 0.5).ceil() - } else { - (x + 0.5).floor() - }; + let r = if x < 0.0 { (x - 0.5).ceil() } else { (x + 0.5).floor() }; Ok(JsValue::float(r)) } diff --git a/crates/oxide_vm/src/builtins/number.rs b/crates/oxide_vm/src/builtins/number.rs index 9600c25..b4039f2 100644 --- a/crates/oxide_vm/src/builtins/number.rs +++ b/crates/oxide_vm/src/builtins/number.rs @@ -177,10 +177,7 @@ pub fn number_is_integer(vm: &mut Vm, args: &[u8]) -> NativeResult { pub fn number_is_safe_integer(vm: &mut Vm, args: &[u8]) -> NativeResult { let val = vm.reg(if args.len() > 1 { args[1] } else { args[0] }); let n = coercion::to_number(val, vm.kernel().string_forge().as_ref()); - let safe = n.trunc() == n - && n.is_finite() - && n >= -9007199254740991i64 as f64 - && n <= 9007199254740991i64 as f64; + let safe = n.trunc() == n && n.is_finite() && n >= -9007199254740991i64 as f64 && n <= 9007199254740991i64 as f64; Ok(JsValue::bool(safe)) } @@ -196,11 +193,7 @@ pub fn number_to_exponential(vm: &mut Vm, args: &[u8]) -> NativeResult { return Ok(vm.intern("NaN")); } if n.is_infinite() { - return Ok(vm.intern(if n.is_sign_positive() { - "Infinity" - } else { - "-Infinity" - })); + return Ok(vm.intern(if n.is_sign_positive() { "Infinity" } else { "-Infinity" })); } let formatted = format!("{:.digits$e}", n); Ok(vm.intern(&formatted)) @@ -218,11 +211,7 @@ pub fn number_to_precision(vm: &mut Vm, args: &[u8]) -> NativeResult { return Ok(vm.intern("NaN")); } if n.is_infinite() { - return Ok(vm.intern(if n.is_sign_positive() { - "Infinity" - } else { - "-Infinity" - })); + return Ok(vm.intern(if n.is_sign_positive() { "Infinity" } else { "-Infinity" })); } let formatted = format!("{:.precision$}", n); Ok(vm.intern(&formatted)) diff --git a/crates/oxide_vm/src/builtins/object.rs b/crates/oxide_vm/src/builtins/object.rs index 4a33ce7..e3081b7 100644 --- a/crates/oxide_vm/src/builtins/object.rs +++ b/crates/oxide_vm/src/builtins/object.rs @@ -38,9 +38,7 @@ pub(crate) fn walk_own_keys(vm: &Vm, obj: &JsObject) -> Vec<(u32, u32)> { } pub fn object_constructor(vm: &mut Vm, _args: &[u8]) -> NativeResult { - let obj = vm - .epoch() - .alloc(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); + let obj = vm.epoch().alloc(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); Ok(JsValue::from_js_object(obj)) } @@ -95,9 +93,7 @@ pub fn object_create(vm: &mut Vm, args: &[u8]) -> NativeResult { if !proto_val.is_null() && !proto_val.is_object() { return Ok(JsValue::undefined()); } - let obj = vm - .epoch() - .alloc(JsObject::new_empty(EMPTY_SHAPE_ID, proto_val)); + let obj = vm.epoch().alloc(JsObject::new_empty(EMPTY_SHAPE_ID, proto_val)); Ok(JsValue::from_js_object(obj)) } @@ -210,10 +206,9 @@ pub fn object_get_own_property_descriptor(vm: &mut Vm, args: &[u8]) -> NativeRes let sf_ptr = vm.kernel().string_forge().as_ref() as *const StringForge; let sh_ptr = vm.kernel().shape_forge().as_ref() as *const ShapeForge; let desc_proto = vm.kernel().builtin_world().object_proto.as_ptr() as *mut JsObject; - let desc = vm.epoch().alloc(JsObject::new_empty( - EMPTY_SHAPE_ID, - JsValue::from_js_object(desc_proto), - )); + let desc = vm + .epoch() + .alloc(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(desc_proto))); let true_val = JsValue::bool(true); let sf = unsafe { &*sf_ptr }; let sh = unsafe { &*sh_ptr }; diff --git a/crates/oxide_vm/src/builtins/regexp.rs b/crates/oxide_vm/src/builtins/regexp.rs index b957182..c7bfb17 100644 --- a/crates/oxide_vm/src/builtins/regexp.rs +++ b/crates/oxide_vm/src/builtins/regexp.rs @@ -19,13 +19,7 @@ fn get_regexp_ptr(vm: &Vm, args: &[u8]) -> Result<*mut JsObject, JsValue> { } let ptr = this_val.as_js_object_ptr(); if ptr.is_null() { - return Err(JsValue::string( - vm.kernel() - .string_forge() - .intern("TypeError: null object") - .0, - 0, - )); + return Err(JsValue::string(vm.kernel().string_forge().intern("TypeError: null object").0, 0)); } Ok(ptr) } @@ -101,10 +95,7 @@ pub fn regexp_constructor(vm: &mut Vm, args: &[u8]) -> NativeResult { } Err(e) => { let msg = format!("SyntaxError: Invalid regular expression: {}", e); - return Err(JsValue::string( - vm.kernel().string_forge().intern(&msg).0, - 0, - )); + return Err(JsValue::string(vm.kernel().string_forge().intern(&msg).0, 0)); } } @@ -128,13 +119,7 @@ pub fn regexp_test(vm: &mut Vm, args: &[u8]) -> NativeResult { let fn_ptr = match re.native_fn() { None => { - return Err(JsValue::string( - vm.kernel() - .string_forge() - .intern("TypeError: invalid RegExp") - .0, - 0, - )); + return Err(JsValue::string(vm.kernel().string_forge().intern("TypeError: invalid RegExp").0, 0)); } Some(p) => p, }; @@ -144,8 +129,7 @@ pub fn regexp_test(vm: &mut Vm, args: &[u8]) -> NativeResult { vm.kernel().string_forge().as_ref(), vm.reg(if args.len() > 1 { args[1] } else { args[0] }), ); - let last_index = - coercion::to_number(get_prop(re, 0), vm.kernel().string_forge().as_ref()) as usize; + let last_index = coercion::to_number(get_prop(re, 0), vm.kernel().string_forge().as_ref()) as usize; let is_global = get_prop(re, 3).as_bool(); if is_global { @@ -163,13 +147,7 @@ pub fn regexp_exec(vm: &mut Vm, args: &[u8]) -> NativeResult { let re = unsafe { &*re_ptr }; match re.native_fn() { None => { - return Err(JsValue::string( - vm.kernel() - .string_forge() - .intern("TypeError: invalid RegExp") - .0, - 0, - )); + return Err(JsValue::string(vm.kernel().string_forge().intern("TypeError: invalid RegExp").0, 0)); } Some(p) => p, } @@ -200,25 +178,19 @@ pub fn regexp_exec(vm: &mut Vm, args: &[u8]) -> NativeResult { if let Some(m) = match_result { let mut match_obj = JsObject::new_empty( EMPTY_SHAPE_ID, - JsValue::from_js_object( - vm.kernel().builtin_world().array_proto.as_ptr() as *mut JsObject - ), + JsValue::from_js_object(vm.kernel().builtin_world().array_proto.as_ptr() as *mut JsObject), ); let full_match = &haystack[m.start()..m.end()]; let full_si = vm.kernel().string_forge().intern(full_match).0; - match_obj - .ensure_hash_props() - .push(Box::new(JsValue::string(full_si, 0))); + match_obj.ensure_hash_props().push(Box::new(JsValue::string(full_si, 0))); let captures = regex.captures(&haystack[m.start()..m.end()]); if let Some(caps) = &captures { for i in 1..caps.len() { let cap_str = caps.get(i).map(|cm| cm.as_str()).unwrap_or(""); let si = vm.kernel().string_forge().intern(cap_str).0; - match_obj - .ensure_hash_props() - .push(Box::new(JsValue::string(si, 0))); + match_obj.ensure_hash_props().push(Box::new(JsValue::string(si, 0))); } } diff --git a/crates/oxide_vm/src/builtins/set.rs b/crates/oxide_vm/src/builtins/set.rs index 2fa58a6..4b795b5 100644 --- a/crates/oxide_vm/src/builtins/set.rs +++ b/crates/oxide_vm/src/builtins/set.rs @@ -25,10 +25,7 @@ impl PartialEq for SetKey { } return a == b; } - unsafe { - std::mem::transmute::(self.0) - == std::mem::transmute::(other.0) - } + unsafe { std::mem::transmute::(self.0) == std::mem::transmute::(other.0) } } } @@ -51,37 +48,22 @@ impl Hash for SetKey { } } -fn get_set_inner( - vm: &mut Vm, - this_val: JsValue, -) -> Result<*mut indexmap::IndexSet, JsValue> { +fn get_set_inner(vm: &mut Vm, this_val: JsValue) -> Result<*mut indexmap::IndexSet, JsValue> { if !this_val.is_object() { - return Err(crate::builtins::error::create_type_error( - vm, - "called on non-Set object", - )); + return Err(crate::builtins::error::create_type_error(vm, "called on non-Set object")); } let set_ptr = this_val.as_js_object_ptr(); if set_ptr.is_null() { - return Err(crate::builtins::error::create_type_error( - vm, - "Set internal state invalid", - )); + return Err(crate::builtins::error::create_type_error(vm, "Set internal state invalid")); } let set_obj = unsafe { &*set_ptr }; let inner_val = set_obj.get_prop_at(SET_PROP_INDEX); if !inner_val.is_object() { - return Err(crate::builtins::error::create_type_error( - vm, - "Set internal state invalid", - )); + return Err(crate::builtins::error::create_type_error(vm, "Set internal state invalid")); } let inner_ptr = inner_val.as_js_object_ptr() as *mut indexmap::IndexSet; if inner_ptr.is_null() { - return Err(crate::builtins::error::create_type_error( - vm, - "Set internal state invalid", - )); + return Err(crate::builtins::error::create_type_error(vm, "Set internal state invalid")); } Ok(inner_ptr) } diff --git a/crates/oxide_vm/src/builtins/string.rs b/crates/oxide_vm/src/builtins/string.rs index f3cdc37..b9e34e7 100644 --- a/crates/oxide_vm/src/builtins/string.rs +++ b/crates/oxide_vm/src/builtins/string.rs @@ -14,12 +14,9 @@ fn this_string(vm: &Vm, args: &[u8]) -> String { fn make_string_array(vm: &mut Vm, parts: &[String]) -> JsValue { let proto = vm.kernel().builtin_world().array_proto.as_ptr() as *mut JsObject; let n = parts.len(); - let arr = vm.epoch().alloc(JsObject::new_array( - EMPTY_SHAPE_ID, - JsValue::from_js_object(proto), - n, - vm.epoch().bump(), - )); + let arr = + vm.epoch() + .alloc(JsObject::new_array(EMPTY_SHAPE_ID, JsValue::from_js_object(proto), n, vm.epoch().bump())); unsafe { for (i, s) in parts.iter().enumerate() { let sv = vm.intern(s); @@ -62,8 +59,7 @@ pub fn string_index_of(vm: &mut Vm, args: &[u8]) -> NativeResult { } let search = as_string(vm, vm.reg(args[1])); let pos = if args.len() > 2 { - (coercion::to_number(vm.reg(args[2]), vm.kernel().string_forge().as_ref()) as usize) - .min(s.len()) + (coercion::to_number(vm.reg(args[2]), vm.kernel().string_forge().as_ref()) as usize).min(s.len()) } else { 0 }; @@ -90,8 +86,7 @@ pub fn string_includes(vm: &mut Vm, args: &[u8]) -> NativeResult { } let search = as_string(vm, vm.reg(args[1])); let pos = if args.len() > 2 { - (coercion::to_number(vm.reg(args[2]), vm.kernel().string_forge().as_ref()) as usize) - .min(s.len()) + (coercion::to_number(vm.reg(args[2]), vm.kernel().string_forge().as_ref()) as usize).min(s.len()) } else { 0 }; @@ -102,9 +97,7 @@ pub fn string_includes(vm: &mut Vm, args: &[u8]) -> NativeResult { let haystack = &s.as_bytes()[pos..]; if search.len() == 1 { - Ok(JsValue::bool( - memchr(search.as_bytes()[0], haystack).is_some(), - )) + Ok(JsValue::bool(memchr(search.as_bytes()[0], haystack).is_some())) } else { Ok(JsValue::bool(s[pos..].contains(&search))) } @@ -221,8 +214,7 @@ pub fn string_trim(vm: &mut Vm, args: &[u8]) -> NativeResult { pub fn string_repeat(vm: &mut Vm, args: &[u8]) -> NativeResult { let s = this_string(vm, args); let n = if args.len() > 1 { - (coercion::to_number(vm.reg(args[1]), vm.kernel().string_forge().as_ref()) as usize) - .min(10000) + (coercion::to_number(vm.reg(args[1]), vm.kernel().string_forge().as_ref()) as usize).min(10000) } else { 1 }; @@ -236,11 +228,7 @@ pub fn string_pad_start(vm: &mut Vm, args: &[u8]) -> NativeResult { } else { s.len() }; - let pad = if args.len() > 2 { - as_string(vm, vm.reg(args[2])) - } else { - " ".to_string() - }; + let pad = if args.len() > 2 { as_string(vm, vm.reg(args[2])) } else { " ".to_string() }; if s.len() >= target || pad.is_empty() { return Ok(vm.intern(&s)); } @@ -259,11 +247,7 @@ pub fn string_pad_end(vm: &mut Vm, args: &[u8]) -> NativeResult { } else { s.len() }; - let pad = if args.len() > 2 { - as_string(vm, vm.reg(args[2])) - } else { - " ".to_string() - }; + let pad = if args.len() > 2 { as_string(vm, vm.reg(args[2])) } else { " ".to_string() }; if s.len() >= target || pad.is_empty() { return Ok(vm.intern(&s)); } @@ -282,8 +266,7 @@ pub fn string_starts_with(vm: &mut Vm, args: &[u8]) -> NativeResult { } let search = as_string(vm, vm.reg(args[1])); let pos = if args.len() > 2 { - (coercion::to_number(vm.reg(args[2]), vm.kernel().string_forge().as_ref()) as usize) - .min(s.len()) + (coercion::to_number(vm.reg(args[2]), vm.kernel().string_forge().as_ref()) as usize).min(s.len()) } else { 0 }; @@ -297,8 +280,7 @@ pub fn string_ends_with(vm: &mut Vm, args: &[u8]) -> NativeResult { } let search = as_string(vm, vm.reg(args[1])); let end_pos = if args.len() > 2 { - (coercion::to_number(vm.reg(args[2]), vm.kernel().string_forge().as_ref()) as usize) - .min(s.len()) + (coercion::to_number(vm.reg(args[2]), vm.kernel().string_forge().as_ref()) as usize).min(s.len()) } else { s.len() }; @@ -349,11 +331,7 @@ pub fn string_replace(vm: &mut Vm, args: &[u8]) -> NativeResult { return Ok(vm.intern(&s)); } let pattern_val = vm.reg(args[1]); - let replacement = if args.len() > 2 { - as_string(vm, vm.reg(args[2])) - } else { - String::new() - }; + let replacement = if args.len() > 2 { as_string(vm, vm.reg(args[2])) } else { String::new() }; if is_regexp_obj(pattern_val, vm) { let re_ptr = pattern_val.as_js_object_ptr(); @@ -387,19 +365,13 @@ pub fn string_match_fn(vm: &mut Vm, args: &[u8]) -> NativeResult { None => return Ok(JsValue::undefined()), }; let regex = unsafe { &*(fn_ptr as *const regex::Regex) }; - let matches: Vec = regex - .find_iter(&s) - .map(|m| m.as_str().to_string()) - .collect(); + let matches: Vec = regex.find_iter(&s).map(|m| m.as_str().to_string()).collect(); return Ok(make_string_array(vm, &matches)); } let pattern = as_string(vm, pattern_val); if let Some(pos) = s.find(&pattern) { - return Ok(make_string_array( - vm, - &[s[pos..pos + pattern.len()].to_string()], - )); + return Ok(make_string_array(vm, &[s[pos..pos + pattern.len()].to_string()])); } Ok(JsValue::undefined()) } @@ -467,11 +439,7 @@ pub fn string_code_point_at(vm: &mut Vm, args: &[u8]) -> NativeResult { pub fn string_normalize(vm: &mut Vm, args: &[u8]) -> NativeResult { use unicode_normalization::UnicodeNormalization; let s = this_string(vm, args); - let form = if args.len() > 1 { - as_string(vm, vm.reg(args[1])) - } else { - "NFC".to_string() - }; + let form = if args.len() > 1 { as_string(vm, vm.reg(args[1])) } else { "NFC".to_string() }; let result: String = match form.as_str() { "NFD" => s.nfd().collect(), "NFKC" => s.nfkc().collect(), @@ -495,10 +463,7 @@ pub fn string_match_all(vm: &mut Vm, args: &[u8]) -> NativeResult { None => return Ok(JsValue::undefined()), }; let regex = unsafe { &*(fn_ptr as *const regex::Regex) }; - let matches: Vec = regex - .find_iter(&s) - .map(|m| m.as_str().to_string()) - .collect(); + let matches: Vec = regex.find_iter(&s).map(|m| m.as_str().to_string()).collect(); return Ok(make_string_array(vm, &matches)); } Ok(JsValue::undefined()) @@ -510,11 +475,7 @@ pub fn string_replace_all(vm: &mut Vm, args: &[u8]) -> NativeResult { return Ok(vm.intern(&s)); } let pattern_val = vm.reg(args[1]); - let replacement = if args.len() > 2 { - as_string(vm, vm.reg(args[2])) - } else { - String::new() - }; + let replacement = if args.len() > 2 { as_string(vm, vm.reg(args[2])) } else { String::new() }; if is_regexp_obj(pattern_val, vm) { let re_ptr = pattern_val.as_js_object_ptr(); let re = unsafe { &*re_ptr }; diff --git a/crates/oxide_vm/src/builtins/symbol.rs b/crates/oxide_vm/src/builtins/symbol.rs index 4fd30e9..a0c463a 100644 --- a/crates/oxide_vm/src/builtins/symbol.rs +++ b/crates/oxide_vm/src/builtins/symbol.rs @@ -18,10 +18,7 @@ pub fn symbol_constructor(vm: &mut Vm, args: &[u8]) -> NativeResult { let sp = vm.kernel().builtin_world().symbol_proto.as_ptr() as *mut JsObject; if std::ptr::eq(proto_ptr, sp) { return Err(JsValue::string( - vm.kernel() - .string_forge() - .intern("TypeError: Symbol is not a constructor") - .0, + vm.kernel().string_forge().intern("TypeError: Symbol is not a constructor").0, 0, )); } @@ -55,11 +52,7 @@ pub fn symbol_to_string(vm: &mut Vm, args: &[u8]) -> NativeResult { } let idx = this_val.as_symbol_index(); - let desc = vm - .symbol_descriptions - .get(idx as usize) - .cloned() - .unwrap_or_default(); + let desc = vm.symbol_descriptions.get(idx as usize).cloned().unwrap_or_default(); let result = format!("Symbol({})", desc); let si = vm.kernel().string_forge().intern(&result).0; Ok(JsValue::string(si, 0)) diff --git a/crates/oxide_vm/src/coercion.rs b/crates/oxide_vm/src/coercion.rs index 589ee7e..bfb1d00 100644 --- a/crates/oxide_vm/src/coercion.rs +++ b/crates/oxide_vm/src/coercion.rs @@ -25,9 +25,7 @@ pub fn to_number(val: JsValue, string_forge: &StringForge) -> f64 { return f64::NAN; } if val.is_string() { - let s = string_forge - .lookup(val.as_string_index()) - .unwrap_or_default(); + let s = string_forge.lookup(val.as_string_index()).unwrap_or_default(); return s.parse::().unwrap_or(f64::NAN); } if val.is_object() { @@ -68,9 +66,7 @@ pub fn to_string(string_forge: &StringForge, val: JsValue) -> String { return "undefined".to_string(); } if val.is_string() { - return string_forge - .lookup(val.as_string_index()) - .unwrap_or_default(); + return string_forge.lookup(val.as_string_index()).unwrap_or_default(); } if val.is_object() { return "[object]".to_string(); @@ -93,9 +89,7 @@ pub fn to_boolean(val: JsValue, string_forge: &StringForge) -> bool { return !(d == 0.0 || d == -0.0 || d.is_nan()); } if val.is_string() { - let s = string_forge - .lookup(val.as_string_index()) - .unwrap_or_default(); + let s = string_forge.lookup(val.as_string_index()).unwrap_or_default(); return !s.is_empty(); } if val.is_object() { @@ -190,12 +184,8 @@ fn strict_double_eq(a: f64, b: f64) -> bool { pub fn relational_compare(string_forge: &StringForge, lhs: JsValue, rhs: JsValue) -> Option { if lhs.is_string() && rhs.is_string() { - let ls = string_forge - .lookup(lhs.as_string_index()) - .unwrap_or_default(); - let rs = string_forge - .lookup(rhs.as_string_index()) - .unwrap_or_default(); + let ls = string_forge.lookup(lhs.as_string_index()).unwrap_or_default(); + let rs = string_forge.lookup(rhs.as_string_index()).unwrap_or_default(); return Some(ls < rs); } let l = to_number(lhs, string_forge); @@ -288,9 +278,7 @@ pub fn to_object(val: JsValue, vm: &mut Vm) -> Result { } let proto_ptr = &*vm.object_prototype as *const JsObject as *mut JsObject; let proto_val = JsValue::from_js_object(proto_ptr); - let obj = vm - .epoch - .alloc(JsObject::new_empty(EMPTY_SHAPE_ID, proto_val)); + let obj = vm.epoch.alloc(JsObject::new_empty(EMPTY_SHAPE_ID, proto_val)); let obj_val = JsValue::from_js_object(obj); let obj_ref = unsafe { &mut *obj }; obj_ref.ensure_hash_props().push(Box::new(val)); diff --git a/crates/oxide_vm/src/dispatch/call.rs b/crates/oxide_vm/src/dispatch/call.rs index 7f6f930..5e9e60a 100644 --- a/crates/oxide_vm/src/dispatch/call.rs +++ b/crates/oxide_vm/src/dispatch/call.rs @@ -5,11 +5,7 @@ use oxide_types::value::JsValue; impl Vm { #[inline(always)] - pub(crate) fn build_native_args( - first_arg_reg: u8, - arg_count: usize, - this_reg: u8, - ) -> ([u8; 257], usize) { + pub(crate) fn build_native_args(first_arg_reg: u8, arg_count: usize, this_reg: u8) -> ([u8; 257], usize) { let mut args_buf = [0u8; 257]; args_buf[0] = this_reg; let n = arg_count.min(256); @@ -21,12 +17,7 @@ impl Vm { #[inline(always)] pub(crate) fn dispatch_native_call( - &mut self, - obj: &JsObject, - callee: JsValue, - this_reg: u8, - first_arg_reg: u8, - arg_count: usize, + &mut self, obj: &JsObject, callee: JsValue, this_reg: u8, first_arg_reg: u8, arg_count: usize, ) -> Result<(), String> { let (args_buf, len) = Self::build_native_args(first_arg_reg, arg_count, this_reg); let args_slice = &args_buf[..len]; diff --git a/crates/oxide_vm/src/dispatch/comparison.rs b/crates/oxide_vm/src/dispatch/comparison.rs index b2c4069..7b19ac2 100644 --- a/crates/oxide_vm/src/dispatch/comparison.rs +++ b/crates/oxide_vm/src/dispatch/comparison.rs @@ -5,61 +5,37 @@ use oxide_types::value::JsValue; impl Vm { #[inline(always)] pub(crate) fn dispatch_eq(&mut self, rd: usize, a: usize, b: usize) { - let eq = coercion::abstract_eq( - self.regs[a], - self.regs[b], - self.kernel.string_forge().as_ref(), - ); + let eq = coercion::abstract_eq(self.regs[a], self.regs[b], self.kernel.string_forge().as_ref()); self.regs[rd] = JsValue::bool(eq); } #[inline(always)] pub(crate) fn dispatch_neq(&mut self, rd: usize, a: usize, b: usize) { - let ne = !coercion::abstract_eq( - self.regs[a], - self.regs[b], - self.kernel.string_forge().as_ref(), - ); + let ne = !coercion::abstract_eq(self.regs[a], self.regs[b], self.kernel.string_forge().as_ref()); self.regs[rd] = JsValue::bool(ne); } #[inline(always)] pub(crate) fn dispatch_lt(&mut self, rd: usize, a: usize, b: usize) { - let rel = coercion::relational_compare( - self.kernel.string_forge().as_ref(), - self.regs[a], - self.regs[b], - ); + let rel = coercion::relational_compare(self.kernel.string_forge().as_ref(), self.regs[a], self.regs[b]); self.regs[rd] = JsValue::bool(rel.unwrap_or(false)); } #[inline(always)] pub(crate) fn dispatch_gt(&mut self, rd: usize, a: usize, b: usize) { - let rel = coercion::relational_compare( - self.kernel.string_forge().as_ref(), - self.regs[b], - self.regs[a], - ); + let rel = coercion::relational_compare(self.kernel.string_forge().as_ref(), self.regs[b], self.regs[a]); self.regs[rd] = JsValue::bool(rel.unwrap_or(false)); } #[inline(always)] pub(crate) fn dispatch_lte(&mut self, rd: usize, a: usize, b: usize) { - let rel = coercion::relational_compare( - self.kernel.string_forge().as_ref(), - self.regs[b], - self.regs[a], - ); + let rel = coercion::relational_compare(self.kernel.string_forge().as_ref(), self.regs[b], self.regs[a]); self.regs[rd] = JsValue::bool(!rel.unwrap_or(true)); } #[inline(always)] pub(crate) fn dispatch_gte(&mut self, rd: usize, a: usize, b: usize) { - let rel = coercion::relational_compare( - self.kernel.string_forge().as_ref(), - self.regs[a], - self.regs[b], - ); + let rel = coercion::relational_compare(self.kernel.string_forge().as_ref(), self.regs[a], self.regs[b]); self.regs[rd] = JsValue::bool(!rel.unwrap_or(true)); } diff --git a/crates/oxide_vm/src/dispatch/member.rs b/crates/oxide_vm/src/dispatch/member.rs index a2d3368..4b31e24 100644 --- a/crates/oxide_vm/src/dispatch/member.rs +++ b/crates/oxide_vm/src/dispatch/member.rs @@ -6,64 +6,33 @@ use crate::coercion; use crate::vm::Vm; impl Vm { - pub(crate) fn dispatch_member_op( - &mut self, - op: OpCode, - rd: usize, - a: usize, - b: usize, - ) -> Result<(), String> { + pub(crate) fn dispatch_member_op(&mut self, op: OpCode, rd: usize, a: usize, b: usize) -> Result<(), String> { match op { OpCode::MEMBER_INC => self.dispatch_member_inc(rd, a, b), OpCode::MEMBER_DEC => self.dispatch_member_dec(rd, a, b), OpCode::DYN_MEMBER_INC => self.dispatch_dyn_member_inc(rd, a, b), OpCode::DYN_MEMBER_DEC => self.dispatch_dyn_member_dec(rd, a, b), OpCode::COMPOUND_MEMBER_ADD => self.dispatch_compound_member_add(rd, a, b), - OpCode::COMPOUND_MEMBER_SUB => self.dispatch_compound_member_numeric( - rd, - a, - b, - "COMPOUND_MEMBER_SUB on non-object", - |l, r| l - r, - ), - OpCode::COMPOUND_MEMBER_MUL => self.dispatch_compound_member_numeric( - rd, - a, - b, - "COMPOUND_MEMBER_MUL on non-object", - |l, r| l * r, - ), - OpCode::COMPOUND_MEMBER_DIV => self.dispatch_compound_member_numeric( - rd, - a, - b, - "COMPOUND_MEMBER_DIV on non-object", - |l, r| l / r, - ), - OpCode::COMPOUND_MEMBER_MOD => self.dispatch_compound_member_numeric( - rd, - a, - b, - "COMPOUND_MEMBER_MOD on non-object", - |l, r| l % r, - ), - OpCode::COMPOUND_MEMBER_EXP => self.dispatch_compound_member_numeric( - rd, - a, - b, - "COMPOUND_MEMBER_EXP on non-object", - |l, r| l.powf(r), - ), + OpCode::COMPOUND_MEMBER_SUB => { + self.dispatch_compound_member_numeric(rd, a, b, "COMPOUND_MEMBER_SUB on non-object", |l, r| l - r) + } + OpCode::COMPOUND_MEMBER_MUL => { + self.dispatch_compound_member_numeric(rd, a, b, "COMPOUND_MEMBER_MUL on non-object", |l, r| l * r) + } + OpCode::COMPOUND_MEMBER_DIV => { + self.dispatch_compound_member_numeric(rd, a, b, "COMPOUND_MEMBER_DIV on non-object", |l, r| l / r) + } + OpCode::COMPOUND_MEMBER_MOD => { + self.dispatch_compound_member_numeric(rd, a, b, "COMPOUND_MEMBER_MOD on non-object", |l, r| l % r) + } + OpCode::COMPOUND_MEMBER_EXP => { + self.dispatch_compound_member_numeric(rd, a, b, "COMPOUND_MEMBER_EXP on non-object", |l, r| l.powf(r)) + } _ => unreachable!("non-member opcode passed to dispatch_member_op"), } } - fn member_target( - &mut self, - rd: usize, - b: usize, - error_msg: &str, - ) -> Result<(*mut JsObject, u32), String> { + fn member_target(&mut self, rd: usize, b: usize, error_msg: &str) -> Result<(*mut JsObject, u32), String> { let obj_ptr = self.regs[rd].as_object_ptr() as *mut JsObject; if obj_ptr.is_null() { self.raise_type_error(error_msg)?; @@ -74,8 +43,7 @@ impl Vm { } fn dispatch_member_inc(&mut self, rd: usize, a: usize, b: usize) -> Result<(), String> { - let Ok((obj_ptr, prop_name_si)) = self.member_target(rd, b, "MEMBER_INC on non-object") - else { + let Ok((obj_ptr, prop_name_si)) = self.member_target(rd, b, "MEMBER_INC on non-object") else { return Ok(()); }; let obj = unsafe { &mut *obj_ptr }; @@ -88,8 +56,7 @@ impl Vm { } fn dispatch_member_dec(&mut self, rd: usize, a: usize, b: usize) -> Result<(), String> { - let Ok((obj_ptr, prop_name_si)) = self.member_target(rd, b, "MEMBER_DEC on non-object") - else { + let Ok((obj_ptr, prop_name_si)) = self.member_target(rd, b, "MEMBER_DEC on non-object") else { return Ok(()); }; let obj = unsafe { &mut *obj_ptr }; @@ -109,9 +76,7 @@ impl Vm { } let obj = unsafe { &mut *obj_ptr }; let prop_name_si = self.property_key_si(self.regs[a]); - let prop_val = self - .resolve_property(obj, prop_name_si) - .unwrap_or(JsValue::undefined()); + let prop_val = self.resolve_property(obj, prop_name_si).unwrap_or(JsValue::undefined()); let n = coercion::to_number(prop_val, self.kernel.string_forge().as_ref()); let new_val = JsValue::float(n + 1.0); self.set_or_create_prop_value(obj, prop_name_si, new_val); @@ -127,9 +92,7 @@ impl Vm { } let obj = unsafe { &mut *obj_ptr }; let prop_name_si = self.property_key_si(self.regs[a]); - let prop_val = self - .resolve_property(obj, prop_name_si) - .unwrap_or(JsValue::undefined()); + let prop_val = self.resolve_property(obj, prop_name_si).unwrap_or(JsValue::undefined()); let n = coercion::to_number(prop_val, self.kernel.string_forge().as_ref()); let new_val = JsValue::float(n - 1.0); self.set_or_create_prop_value(obj, prop_name_si, new_val); @@ -137,15 +100,8 @@ impl Vm { Ok(()) } - fn dispatch_compound_member_add( - &mut self, - rd: usize, - a: usize, - b: usize, - ) -> Result<(), String> { - let Ok((obj_ptr, prop_name_si)) = - self.member_target(rd, b, "COMPOUND_MEMBER_ADD on non-object") - else { + fn dispatch_compound_member_add(&mut self, rd: usize, a: usize, b: usize) -> Result<(), String> { + let Ok((obj_ptr, prop_name_si)) = self.member_target(rd, b, "COMPOUND_MEMBER_ADD on non-object") else { return Ok(()); }; let obj = unsafe { &mut *obj_ptr }; @@ -166,12 +122,7 @@ impl Vm { } fn dispatch_compound_member_numeric( - &mut self, - rd: usize, - a: usize, - b: usize, - error_msg: &str, - op: F, + &mut self, rd: usize, a: usize, b: usize, error_msg: &str, op: F, ) -> Result<(), String> where F: FnOnce(f64, f64) -> f64, diff --git a/crates/oxide_vm/src/dispatch/property.rs b/crates/oxide_vm/src/dispatch/property.rs index d7ecbd6..15021e0 100644 --- a/crates/oxide_vm/src/dispatch/property.rs +++ b/crates/oxide_vm/src/dispatch/property.rs @@ -6,13 +6,7 @@ use oxide_types::value::JsValue; use crate::vm::Vm; impl Vm { - pub(crate) fn dispatch_property_op( - &mut self, - op: OpCode, - rd: usize, - a: usize, - b: usize, - ) -> Result<(), String> { + pub(crate) fn dispatch_property_op(&mut self, op: OpCode, rd: usize, a: usize, b: usize) -> Result<(), String> { match op { OpCode::IC_GET_PROP => self.dispatch_ic_get_prop(a, b), OpCode::IC_SET_PROP => self.dispatch_ic_set_prop(rd, a, b), @@ -70,21 +64,13 @@ impl Vm { self.write_ic_back(obj.shape_id(), ptr); self.regs[a] = unsafe { *ptr }; } else { - self.regs[a] = self - .resolve_property(obj, prop_name_si) - .unwrap_or(JsValue::undefined()); + self.regs[a] = self.resolve_property(obj, prop_name_si).unwrap_or(JsValue::undefined()); } } else { - self.regs[a] = self - .resolve_property(obj, prop_name_si) - .unwrap_or(JsValue::undefined()); + self.regs[a] = self.resolve_property(obj, prop_name_si).unwrap_or(JsValue::undefined()); } } else if let Some(val) = self.resolve_property(obj, prop_name_si) { - if let Some(pos) = self - .kernel - .shape_forge() - .lookup_position(obj.shape_id(), prop_name_si) - { + if let Some(pos) = self.kernel.shape_forge().lookup_position(obj.shape_id(), prop_name_si) { if let Some(ptr) = obj.prop_ptr_at(pos) { self.write_ic_back(obj.shape_id(), ptr); } @@ -117,20 +103,13 @@ impl Vm { unsafe { *(cached_ptr as *mut JsValue) = self.regs[a]; } - } else if let Some(pos) = self - .kernel - .shape_forge() - .lookup_position(obj.shape_id(), prop_name_si) - { + } else if let Some(pos) = self.kernel.shape_forge().lookup_position(obj.shape_id(), prop_name_si) { obj.set_prop_at(pos, self.regs[a]); if let Some(ptr) = obj.prop_ptr_at(pos) { self.write_ic_back(obj.shape_id(), ptr); } } else { - let new_shape_id = self - .kernel - .shape_forge() - .make_shape(obj.shape_id(), prop_name_si); + let new_shape_id = self.kernel.shape_forge().make_shape(obj.shape_id(), prop_name_si); obj.set_shape_id(new_shape_id); let new_pos = obj.push_prop(self.regs[a]); obj.bump_generation(); @@ -159,9 +138,7 @@ impl Vm { } let obj = unsafe { &*obj_ptr }; let prop_name_si = self.property_key_si(self.regs[b]); - self.regs[a] = self - .resolve_property(obj, prop_name_si) - .unwrap_or(JsValue::undefined()); + self.regs[a] = self.resolve_property(obj, prop_name_si).unwrap_or(JsValue::undefined()); Ok(()) } @@ -173,17 +150,10 @@ impl Vm { } let obj = unsafe { &mut *obj_ptr }; let prop_name_si = self.property_key_si(self.regs[b]); - if let Some(pos) = self - .kernel - .shape_forge() - .lookup_position(obj.shape_id(), prop_name_si) - { + if let Some(pos) = self.kernel.shape_forge().lookup_position(obj.shape_id(), prop_name_si) { obj.set_prop_at(pos, self.regs[a]); } else { - let new_shape_id = self - .kernel - .shape_forge() - .make_shape(obj.shape_id(), prop_name_si); + let new_shape_id = self.kernel.shape_forge().make_shape(obj.shape_id(), prop_name_si); obj.set_shape_id(new_shape_id); obj.push_prop(self.regs[a]); obj.bump_generation(); @@ -199,9 +169,7 @@ impl Vm { } let obj = unsafe { &*obj_ptr }; let prop_name_si = self.property_key_si(self.regs[a]); - self.regs[b] = self - .resolve_property(obj, prop_name_si) - .unwrap_or(JsValue::undefined()); + self.regs[b] = self.resolve_property(obj, prop_name_si).unwrap_or(JsValue::undefined()); Ok(()) } @@ -213,17 +181,10 @@ impl Vm { } let obj = unsafe { &mut *obj_ptr }; let prop_name_si = self.property_key_si(self.regs[a]); - if let Some(pos) = self - .kernel - .shape_forge() - .lookup_position(obj.shape_id(), prop_name_si) - { + if let Some(pos) = self.kernel.shape_forge().lookup_position(obj.shape_id(), prop_name_si) { obj.set_prop_at(pos, self.regs[b]); } else { - let new_shape_id = self - .kernel - .shape_forge() - .make_shape(obj.shape_id(), prop_name_si); + let new_shape_id = self.kernel.shape_forge().make_shape(obj.shape_id(), prop_name_si); obj.set_shape_id(new_shape_id); obj.push_prop(self.regs[b]); obj.bump_generation(); diff --git a/crates/oxide_vm/src/vm.rs b/crates/oxide_vm/src/vm.rs index e4451bd..7c71ca0 100644 --- a/crates/oxide_vm/src/vm.rs +++ b/crates/oxide_vm/src/vm.rs @@ -275,11 +275,7 @@ impl Vm { .resolve_property(obj, message_si) .and_then(|v| self.lookup_str(v)) .unwrap_or_default(); - return if message.is_empty() { - name - } else { - format!("{name}: {message}") - }; + return if message.is_empty() { name } else { format!("{name}: {message}") }; } format!("{val}") } @@ -307,8 +303,7 @@ impl Vm { let pat_val = JsValue::string(pat_si, 0); let flags_val = JsValue::string(flags_si, 0); - let ctor_ptr = - self.kernel.builtin_world().regexp_constructor.as_ptr() as *mut JsObject; + let ctor_ptr = self.kernel.builtin_world().regexp_constructor.as_ptr() as *mut JsObject; let ctor = unsafe { &*ctor_ptr }; let Some(native_fn) = ctor.native_fn() else { return Err("SyntaxError: RegExp constructor unavailable".into()); @@ -378,19 +373,10 @@ impl Vm { self.kernel.string_forge().intern(&key).0 } - pub(crate) fn template_prop_ptr( - &self, - obj: &JsObject, - template: &PropTemplate, - ) -> Option<*const JsValue> { + pub(crate) fn template_prop_ptr(&self, obj: &JsObject, template: &PropTemplate) -> Option<*const JsValue> { let pos = template.position as usize; - obj.hash_props_vec().and_then(|vec| { - if pos < vec.len() { - Some(&*vec[pos] as *const JsValue) - } else { - None - } - }) + obj.hash_props_vec() + .and_then(|vec| if pos < vec.len() { Some(&*vec[pos] as *const JsValue) } else { None }) } pub(crate) fn resolve_property(&self, obj: &JsObject, prop_name_si: u32) -> Option { @@ -398,11 +384,7 @@ impl Vm { if obj.is_array() && prop_name_si == length_si { return Some(JsValue::int(obj.prop_count() as i32)); } - if let Some(pos) = self - .kernel - .shape_forge() - .lookup_position(obj.shape_id(), prop_name_si) - { + if let Some(pos) = self.kernel.shape_forge().lookup_position(obj.shape_id(), prop_name_si) { let val = obj.get_prop_at(pos); if !val.is_undefined() || obj.prop_vec_len() > pos as usize { return Some(val); @@ -411,11 +393,7 @@ impl Vm { let mut proto = obj.proto(); while proto.is_object() { let proto_obj = unsafe { &*proto.as_js_object_ptr() }; - if let Some(pos) = self - .kernel - .shape_forge() - .lookup_position(proto_obj.shape_id(), prop_name_si) - { + if let Some(pos) = self.kernel.shape_forge().lookup_position(proto_obj.shape_id(), prop_name_si) { let val = proto_obj.get_prop_at(pos); if !val.is_undefined() || proto_obj.prop_vec_len() > pos as usize { return Some(val); @@ -438,21 +416,15 @@ impl Vm { unsafe { *(cached_ptr as *const JsValue) } } else if let Some(template) = self.kernel.prop_forge().get_template(obj.shape_id()) { if template.prop_name != prop_name_si { - self.resolve_property(obj, prop_name_si) - .unwrap_or(JsValue::undefined()) + self.resolve_property(obj, prop_name_si).unwrap_or(JsValue::undefined()) } else if let Some(ptr) = self.template_prop_ptr(obj, &template) { self.write_ic_back(obj.shape_id(), ptr); unsafe { *ptr } } else { - self.resolve_property(obj, prop_name_si) - .unwrap_or(JsValue::undefined()) + self.resolve_property(obj, prop_name_si).unwrap_or(JsValue::undefined()) } } else if let Some(val) = self.resolve_property(obj, prop_name_si) { - if let Some(pos) = self - .kernel - .shape_forge() - .lookup_position(obj.shape_id(), prop_name_si) - { + if let Some(pos) = self.kernel.shape_forge().lookup_position(obj.shape_id(), prop_name_si) { if let Some(ptr) = obj.prop_ptr_at(pos) { self.write_ic_back(obj.shape_id(), ptr); } @@ -464,26 +436,16 @@ impl Vm { } pub(crate) fn set_member_prop( - &mut self, - obj: &mut JsObject, - prop_name_si: u32, - val: JsValue, + &mut self, obj: &mut JsObject, prop_name_si: u32, val: JsValue, ) -> Result<(), String> { - if let Some(pos) = self - .kernel - .shape_forge() - .lookup_position(obj.shape_id(), prop_name_si) - { + if let Some(pos) = self.kernel.shape_forge().lookup_position(obj.shape_id(), prop_name_si) { obj.set_prop_at(pos, val); // IC write-back: 3 extension words (shape_id + ptr_lo + ptr_hi) if let Some(ptr) = obj.prop_ptr_at(pos) { self.write_ic_back(obj.shape_id(), ptr); } } else { - let new_shape_id = self - .kernel - .shape_forge() - .make_shape(obj.shape_id(), prop_name_si); + let new_shape_id = self.kernel.shape_forge().make_shape(obj.shape_id(), prop_name_si); obj.set_shape_id(new_shape_id); let new_pos = obj.push_prop(val); obj.bump_generation(); @@ -503,23 +465,11 @@ impl Vm { Ok(()) } - pub(crate) fn set_or_create_prop_value( - &mut self, - obj: &mut JsObject, - prop_name_si: u32, - val: JsValue, - ) { - if let Some(pos) = self - .kernel - .shape_forge() - .lookup_position(obj.shape_id(), prop_name_si) - { + pub(crate) fn set_or_create_prop_value(&mut self, obj: &mut JsObject, prop_name_si: u32, val: JsValue) { + if let Some(pos) = self.kernel.shape_forge().lookup_position(obj.shape_id(), prop_name_si) { obj.set_prop_at(pos, val); } else { - let new_shape_id = self - .kernel - .shape_forge() - .make_shape(obj.shape_id(), prop_name_si); + let new_shape_id = self.kernel.shape_forge().make_shape(obj.shape_id(), prop_name_si); obj.set_shape_id(new_shape_id); obj.push_prop(val); obj.bump_generation(); @@ -527,10 +477,7 @@ impl Vm { } pub(crate) fn write_ic_back(&mut self, shape_id: u32, ptr: *const JsValue) { - debug_assert!( - self.pc >= 3, - "IC write-back requires 3 extension words before pc" - ); + debug_assert!(self.pc >= 3, "IC write-back requires 3 extension words before pc"); self.bytecode[self.pc - 3] = shape_id & 0x00FF_FFFF; self.bytecode[self.pc - 2] = ptr as u32; self.bytecode[self.pc - 1] = (ptr as u64 >> 32) as u32; @@ -572,11 +519,7 @@ impl Vm { for (name, reg) in &module.builtin_reg_map { let si = self.kernel.string_forge().intern(name.as_str()).0; let global = self.kernel.global_object(); - if let Some(pos) = self - .kernel - .shape_forge() - .lookup_position(global.shape_id(), si) - { + if let Some(pos) = self.kernel.shape_forge().lookup_position(global.shape_id(), si) { self.regs[*reg as usize] = global.get_prop_at(pos); } } @@ -587,11 +530,7 @@ impl Vm { /// Call a bytecode function from native code (D-09). /// Stub: sub_module storage not yet wired (plan 12.1-03). #[allow(dead_code)] - pub fn call_bytecode_func( - &mut self, - _callback_obj: &JsObject, - _args_regs: &[u8], - ) -> Result { + pub fn call_bytecode_func(&mut self, _callback_obj: &JsObject, _args_regs: &[u8]) -> Result { Err("bytecode function calls not yet supported".into()) } @@ -715,8 +654,7 @@ impl Vm { } OpCode::JMP_IF_FALSE => { - let cond = - coercion::to_boolean(self.regs[rd], self.kernel.string_forge().as_ref()); + let cond = coercion::to_boolean(self.regs[rd], self.kernel.string_forge().as_ref()); if !cond { let offset = opcode::offset16(instr) as isize; self.pc = ((self.pc as isize) + offset - 1) as usize; @@ -724,8 +662,7 @@ impl Vm { } OpCode::JMP_IF_TRUE => { - let cond = - coercion::to_boolean(self.regs[rd], self.kernel.string_forge().as_ref()); + let cond = coercion::to_boolean(self.regs[rd], self.kernel.string_forge().as_ref()); if cond { let offset = opcode::offset16(instr) as isize; self.pc = ((self.pc as isize) + offset - 1) as usize; @@ -763,13 +700,7 @@ impl Vm { let arg_count = (ext & 0xFF) as usize; if obj.native_fn().is_some() { - match self.dispatch_native_call( - obj, - callee, - this_reg, - first_arg_reg, - arg_count, - ) { + match self.dispatch_native_call(obj, callee, this_reg, first_arg_reg, arg_count) { Ok(()) => continue, Err(e) => return Err(e), } @@ -785,9 +716,7 @@ impl Vm { } if self.frames.len() >= self.kernel.config.max_call_depth { - return Err( - "RangeError: Maximum call stack size exceeded".into() - ); + return Err("RangeError: Maximum call stack size exceeded".into()); } // Clone sub_module data before mutably borrowing self @@ -795,13 +724,10 @@ impl Vm { let sub_n_args = self.sub_modules[sub_idx].n_args as usize; let sub_n_registers = self.sub_modules[sub_idx].n_registers; let sub_constants = self.sub_modules[sub_idx].constants.clone(); - let sub_param_base = - self.sub_modules[sub_idx].param_base as usize; + let sub_param_base = self.sub_modules[sub_idx].param_base as usize; let sub_is_arrow = self.sub_modules[sub_idx].is_arrow; let caller_reg_limit = self.active_reg_limit.max(1); - let saved_regs = self.regs[..caller_reg_limit as usize] - .to_vec() - .into_boxed_slice(); + let saved_regs = self.regs[..caller_reg_limit as usize].to_vec().into_boxed_slice(); let saved_this = self.regs[254]; let saved_new_target = self.regs[255]; @@ -812,21 +738,14 @@ impl Vm { } // Set this (reg 254 convention). // Arrow functions use captured lexical `this` (D-01). - self.regs[254] = if sub_is_arrow { - obj.captured_this() - } else { - callee - }; + self.regs[254] = if sub_is_arrow { obj.captured_this() } else { callee }; self.regs[255] = JsValue::undefined(); - let converted_sub_constants = - self.convert_constants(&sub_constants)?; + let converted_sub_constants = self.convert_constants(&sub_constants)?; // Save current bytecode/constants - self.saved_bytecode_stack - .push(std::mem::take(&mut self.bytecode)); - self.saved_constants_stack - .push(std::mem::take(&mut self.constants)); + self.saved_bytecode_stack.push(std::mem::take(&mut self.bytecode)); + self.saved_constants_stack.push(std::mem::take(&mut self.constants)); // Push call frame self.frames.push(CallFrame { @@ -850,10 +769,8 @@ impl Vm { for (name, reg) in &self.sub_modules[sub_idx].builtin_reg_map { let si = self.kernel.string_forge().intern(name.as_str()).0; let global = self.kernel.global_object(); - if let Some(pos) = self - .kernel - .shape_forge() - .lookup_position(global.shape_id(), si) + if let Some(pos) = + self.kernel.shape_forge().lookup_position(global.shape_id(), si) { self.regs[*reg as usize] = global.get_prop_at(pos); } @@ -886,11 +803,7 @@ impl Vm { } let obj = unsafe { &*obj_ptr }; if !obj.is_function() || obj.native_fn().is_none() { - throw_err!( - self, - TypeError, - "CALL_NATIVE target is not a native function" - ); + throw_err!(self, TypeError, "CALL_NATIVE target is not a native function"); } let ext = self.bytecode[self.pc]; @@ -906,11 +819,7 @@ impl Vm { let constructor = self.regs[constructor_reg]; if !constructor.is_object() { - throw_err!( - self, - TypeError, - "NEW_EXPRESSION: constructor is not an object" - ); + throw_err!(self, TypeError, "NEW_EXPRESSION: constructor is not an object"); } let ctor_ptr = constructor.as_js_object_ptr(); if ctor_ptr.is_null() { @@ -918,19 +827,11 @@ impl Vm { } let ctor_obj = unsafe { &*ctor_ptr }; if !ctor_obj.is_function() { - throw_err!( - self, - TypeError, - "NEW_EXPRESSION: constructor is not a function" - ); + throw_err!(self, TypeError, "NEW_EXPRESSION: constructor is not a function"); } // Arrow functions cannot be used as constructors (D-03) if ctor_obj.is_arrow() { - throw_err!( - self, - TypeError, - "arrow functions cannot be used as constructors" - ); + throw_err!(self, TypeError, "arrow functions cannot be used as constructors"); } // Read extension word for arg_count @@ -940,10 +841,9 @@ impl Vm { // Create new empty object let proto_ptr = &*self.object_prototype as *const JsObject as *mut JsObject; - let new_obj = self.epoch.alloc(JsObject::new_empty( - EMPTY_SHAPE_ID, - JsValue::from_js_object(proto_ptr), - )); + let new_obj = self + .epoch + .alloc(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(proto_ptr))); // Look up constructor.prototype and set as proto of new object let proto_si = self.kernel.string_forge().intern("prototype").0; @@ -967,8 +867,7 @@ impl Vm { } let args_slice = &args_buf[..arg_count + 1]; - let func: NativeFn = - unsafe { std::mem::transmute(ctor_obj.native_fn().unwrap()) }; + let func: NativeFn = unsafe { std::mem::transmute(ctor_obj.native_fn().unwrap()) }; self.regs[254] = constructor; match func(self, args_slice) { Ok(val) => { @@ -1036,16 +935,14 @@ impl Vm { OpCode::NEW_OBJECT => { let proto_ptr = &*self.object_prototype as *const JsObject as *mut JsObject; - let obj = self.epoch.alloc(JsObject::new_empty( - EMPTY_SHAPE_ID, - JsValue::from_js_object(proto_ptr), - )); + let obj = self + .epoch + .alloc(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(proto_ptr))); self.regs[rd] = JsValue::object(obj as *mut u8); } OpCode::NEW_ARRAY => { - let proto_ptr = - self.kernel.builtin_world().array_proto.as_ptr() as *mut JsObject; + let proto_ptr = self.kernel.builtin_world().array_proto.as_ptr() as *mut JsObject; let n = opcode::imm16(instr) as usize; let bump = self.epoch.bump(); let obj = self.epoch.alloc(JsObject::new_array( @@ -1119,10 +1016,7 @@ impl Vm { let reg = (seg & 0x7F) as u8; let val = self.regs[reg as usize]; let s = if val.is_string() { - self.kernel() - .string_forge() - .lookup(val.as_string_index()) - .unwrap_or_default() + self.kernel().string_forge().lookup(val.as_string_index()).unwrap_or_default() } else { format!("{}", val) }; @@ -1133,11 +1027,8 @@ impl Vm { if const_idx < self.constants.len() { let val = self.constants[const_idx]; if val.is_string() { - let s = self - .kernel() - .string_forge() - .lookup(val.as_string_index()) - .unwrap_or_default(); + let s = + self.kernel().string_forge().lookup(val.as_string_index()).unwrap_or_default(); result.push_str(&s); } } @@ -1164,11 +1055,7 @@ impl Vm { let rhs_val = self.regs[b]; if !rhs_val.is_object() { - throw_err!( - self, - TypeError, - "INSTANCEOF right-hand side is not callable" - ); + throw_err!(self, TypeError, "INSTANCEOF right-hand side is not callable"); } if !lhs_val.is_object() { self.regs[rd] = JsValue::bool(false); @@ -1286,14 +1173,8 @@ impl Vm { break; } if let Some(shape) = self.kernel.shape_forge().get_shape(id) { - if shape.property_name != u32::MAX - && seen.insert(shape.property_name) - { - let hash = self - .kernel - .string_forge() - .get_hash(shape.property_name) - .unwrap_or(0); + if shape.property_name != u32::MAX && seen.insert(shape.property_name) { + let hash = self.kernel.string_forge().get_hash(shape.property_name).unwrap_or(0); keys_vec.push(JsValue::string(shape.property_name, hash)); } cursor = shape.parent; @@ -1304,10 +1185,7 @@ impl Vm { current = cur.proto(); } - let iter = self.epoch.alloc(ForInIter { - keys: keys_vec, - index: 0, - }); + let iter = self.epoch.alloc(ForInIter { keys: keys_vec, index: 0 }); self.for_in_iters.push(iter as *mut u8); } @@ -1480,35 +1358,18 @@ mod tests { #[test] fn for_of_opcodes_fail_explicitly() { for (op, expected) in [ - ( - opcode::OpCode::FOR_OF_INIT, - "opcode FOR_OF_INIT not yet implemented", - ), - ( - opcode::OpCode::FOR_OF_NEXT, - "opcode FOR_OF_NEXT not yet implemented", - ), - ( - opcode::OpCode::FOR_OF_DONE, - "opcode FOR_OF_DONE not yet implemented", - ), - ( - opcode::OpCode::FOR_OF_CLOSE, - "opcode FOR_OF_CLOSE not yet implemented", - ), + (opcode::OpCode::FOR_OF_INIT, "opcode FOR_OF_INIT not yet implemented"), + (opcode::OpCode::FOR_OF_NEXT, "opcode FOR_OF_NEXT not yet implemented"), + (opcode::OpCode::FOR_OF_DONE, "opcode FOR_OF_DONE not yet implemented"), + (opcode::OpCode::FOR_OF_CLOSE, "opcode FOR_OF_CLOSE not yet implemented"), ] { let module = CompiledModule { - bytecode: vec![ - opcode::encode(op, 0, 0, 0), - opcode::encode(opcode::OpCode::HALT, 0, 0, 0), - ], + bytecode: vec![opcode::encode(op, 0, 0, 0), opcode::encode(opcode::OpCode::HALT, 0, 0, 0)], n_registers: 1, ..CompiledModule::new() }; let mut vm = Vm::new(); - let err = vm - .run(&module) - .expect_err("FOR_OF opcode should fail explicitly"); + let err = vm.run(&module).expect_err("FOR_OF opcode should fail explicitly"); assert_eq!(err, expected); } } @@ -1522,13 +1383,8 @@ mod tests { ..CompiledModule::new() }; let mut vm = Vm::new(); - let err = vm - .run(&module) - .expect_err("invalid RegExp constant should fail explicitly"); - assert!( - err.contains("SyntaxError: Invalid regular expression"), - "unexpected error: {err}" - ); + let err = vm.run(&module).expect_err("invalid RegExp constant should fail explicitly"); + assert!(err.contains("SyntaxError: Invalid regular expression"), "unexpected error: {err}"); } #[test] @@ -1556,10 +1412,7 @@ mod tests { let err = vm .run(&module) .expect_err("invalid submodule RegExp constant should fail explicitly"); - assert!( - err.contains("SyntaxError: Invalid regular expression"), - "unexpected error: {err}" - ); + assert!(err.contains("SyntaxError: Invalid regular expression"), "unexpected error: {err}"); } #[test] @@ -1586,9 +1439,7 @@ mod tests { ..CompiledModule::new() }; let mut vm = Vm::new(); - let err = vm - .run(&module) - .expect_err("unimplemented opcode should fail explicitly"); + let err = vm.run(&module).expect_err("unimplemented opcode should fail explicitly"); assert_eq!(err, "opcode PROFILE_TYPE not yet implemented"); } } diff --git a/crates/oxide_vm/src/vm_pool.rs b/crates/oxide_vm/src/vm_pool.rs index f49a3f5..2a533b9 100644 --- a/crates/oxide_vm/src/vm_pool.rs +++ b/crates/oxide_vm/src/vm_pool.rs @@ -27,11 +27,7 @@ pub struct VmGuard { } impl VmPool { - pub fn new( - kernel: Arc, - #[allow(dead_code)] min_size: usize, - max_size: Option, - ) -> Arc { + pub fn new(kernel: Arc, #[allow(dead_code)] min_size: usize, max_size: Option) -> Arc { let pool = Arc::new(Self { kernel, inner: Mutex::new(VmPoolInner { diff --git a/crates/oxide_vm/tests/arrow_tests.rs b/crates/oxide_vm/tests/arrow_tests.rs index 8e0bf4f..999d969 100644 --- a/crates/oxide_vm/tests/arrow_tests.rs +++ b/crates/oxide_vm/tests/arrow_tests.rs @@ -37,10 +37,7 @@ fn eval_val(source: &str) -> (Vm, Result) { fn to_str(vm: &Vm, val: JsValue) -> String { if val.is_string() { - vm.kernel() - .string_forge() - .lookup(val.as_string_index()) - .unwrap_or_default() + vm.kernel().string_forge().lookup(val.as_string_index()).unwrap_or_default() } else { format!("{}", val) } diff --git a/crates/oxide_vm/tests/bench_tests.rs b/crates/oxide_vm/tests/bench_tests.rs index df94888..d61cbba 100644 --- a/crates/oxide_vm/tests/bench_tests.rs +++ b/crates/oxide_vm/tests/bench_tests.rs @@ -24,11 +24,7 @@ fn bench_1m_property_reads() { } let elapsed = start.elapsed(); let ns_per = elapsed.as_nanos() as f64 / N as f64; - println!( - "1M IC property reads: {:.2}ms ({:.0} ns/read)", - elapsed.as_secs_f64() * 1000.0, - ns_per - ); + println!("1M IC property reads: {:.2}ms ({:.0} ns/read)", elapsed.as_secs_f64() * 1000.0, ns_per); if cfg!(debug_assertions) { println!(" (debug build -- skipping timing assertion)"); } else { diff --git a/crates/oxide_vm/tests/builtins_array_tests.rs b/crates/oxide_vm/tests/builtins_array_tests.rs index 4ffb8c1..5c3790c 100644 --- a/crates/oxide_vm/tests/builtins_array_tests.rs +++ b/crates/oxide_vm/tests/builtins_array_tests.rs @@ -5,11 +5,8 @@ use oxide_vm::vm::Vm; fn eval(source: &str) -> Result<(Vm, JsValue), String> { let allocator = oxide_parser::Allocator::default(); - let program = - oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse error: {:?}", e))?; - let module = Compiler::new() - .compile(&program) - .map_err(|e| format!("Compile error: {}", e))?; + let program = oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse error: {:?}", e))?; + let module = Compiler::new().compile(&program).map_err(|e| format!("Compile error: {}", e))?; let mut vm = Vm::new(); let result = vm.run(&module)?; Ok((vm, result)) diff --git a/crates/oxide_vm/tests/builtins_boolean_tests.rs b/crates/oxide_vm/tests/builtins_boolean_tests.rs index 16c986f..ba12993 100644 --- a/crates/oxide_vm/tests/builtins_boolean_tests.rs +++ b/crates/oxide_vm/tests/builtins_boolean_tests.rs @@ -1,28 +1,20 @@ use oxide_compiler::compiler::Compiler; use oxide_types::object::JsObject; use oxide_types::value::JsValue; -use oxide_vm::builtins::boolean::{ - boolean_constructor, boolean_prototype_to_string, boolean_prototype_value_of, -}; +use oxide_vm::builtins::boolean::{boolean_constructor, boolean_prototype_to_string, boolean_prototype_value_of}; use oxide_vm::vm::Vm; use oxide_kernel::shape_forge::EMPTY_SHAPE_ID; fn eval(vm: &mut Vm, source: &str) -> Result { let allocator = oxide_parser::Allocator::default(); - let program = - oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse error: {:?}", e))?; - let module = Compiler::new() - .compile(&program) - .map_err(|e| format!("Compile error: {}", e))?; + let program = oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse error: {:?}", e))?; + let module = Compiler::new().compile(&program).map_err(|e| format!("Compile error: {}", e))?; vm.run(&module) } fn str_val(vm: &Vm, val: JsValue) -> String { - vm.kernel() - .string_forge() - .lookup(val.as_string_index()) - .unwrap_or_default() + vm.kernel().string_forge().lookup(val.as_string_index()).unwrap_or_default() } // -- direct native fn tests -- diff --git a/crates/oxide_vm/tests/builtins_date_tests.rs b/crates/oxide_vm/tests/builtins_date_tests.rs index adffa66..6813e04 100644 --- a/crates/oxide_vm/tests/builtins_date_tests.rs +++ b/crates/oxide_vm/tests/builtins_date_tests.rs @@ -3,19 +3,13 @@ use oxide_vm::vm::Vm; fn eval(vm: &mut Vm, source: &str) -> Result { let allocator = oxide_parser::Allocator::default(); - let program = - oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse error: {:?}", e))?; - let module = Compiler::new() - .compile(&program) - .map_err(|e| format!("Compile error: {}", e))?; + let program = oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse error: {:?}", e))?; + let module = Compiler::new().compile(&program).map_err(|e| format!("Compile error: {}", e))?; vm.run(&module) } fn str_val(vm: &Vm, val: oxide_types::value::JsValue) -> String { - vm.kernel() - .string_forge() - .lookup(val.as_string_index()) - .unwrap_or_default() + vm.kernel().string_forge().lookup(val.as_string_index()).unwrap_or_default() } // -- static methods -- @@ -92,11 +86,7 @@ fn date_set_time() { #[test] fn date_set_full_year() { let mut vm = Vm::new(); - let r = eval( - &mut vm, - "var d = new Date(2020, 0, 1); d.setFullYear(2025); d.getFullYear()", - ) - .unwrap(); + let r = eval(&mut vm, "var d = new Date(2020, 0, 1); d.setFullYear(2025); d.getFullYear()").unwrap(); assert_eq!(r.as_double(), 2025.0); } diff --git a/crates/oxide_vm/tests/builtins_error_tests.rs b/crates/oxide_vm/tests/builtins_error_tests.rs index 1e9cf01..3ddab65 100644 --- a/crates/oxide_vm/tests/builtins_error_tests.rs +++ b/crates/oxide_vm/tests/builtins_error_tests.rs @@ -10,9 +10,7 @@ fn make_vm() -> Vm { fn eval(source: &str) -> Result { let allocator = oxide_parser::Allocator::default(); let program = oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse: {:?}", e))?; - let module = Compiler::new() - .compile(&program) - .map_err(|e| format!("Compile: {}", e))?; + let module = Compiler::new().compile(&program).map_err(|e| format!("Compile: {}", e))?; let mut vm = make_vm(); vm.run(&module) } @@ -140,22 +138,7 @@ fn reference_error_is_defined() { #[test] fn error_subtype_constructors_produce_named_objects() { - assert_eq!( - format!("{}", eval("new Error('boom').name == 'Error'").unwrap()), - "true" - ); - assert_eq!( - format!( - "{}", - eval("new TypeError('boom').name == 'TypeError'").unwrap() - ), - "true" - ); - assert_eq!( - format!( - "{}", - eval("new SyntaxError('boom').name == 'SyntaxError'").unwrap() - ), - "true" - ); + assert_eq!(format!("{}", eval("new Error('boom').name == 'Error'").unwrap()), "true"); + assert_eq!(format!("{}", eval("new TypeError('boom').name == 'TypeError'").unwrap()), "true"); + assert_eq!(format!("{}", eval("new SyntaxError('boom').name == 'SyntaxError'").unwrap()), "true"); } diff --git a/crates/oxide_vm/tests/builtins_function_tests.rs b/crates/oxide_vm/tests/builtins_function_tests.rs index 746a93d..0624041 100644 --- a/crates/oxide_vm/tests/builtins_function_tests.rs +++ b/crates/oxide_vm/tests/builtins_function_tests.rs @@ -4,11 +4,8 @@ use oxide_vm::vm::Vm; fn eval(vm: &mut Vm, source: &str) -> Result { let allocator = oxide_parser::Allocator::default(); - let program = - oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse error: {:?}", e))?; - let module = Compiler::new() - .compile(&program) - .map_err(|e| format!("Compile error: {}", e))?; + let program = oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse error: {:?}", e))?; + let module = Compiler::new().compile(&program).map_err(|e| format!("Compile error: {}", e))?; vm.run(&module) } @@ -38,11 +35,7 @@ fn function_to_string_includes_function() { let mut vm = Vm::new(); let result = eval(&mut vm, "Math.max.toString()").unwrap(); assert!(result.is_string()); - let rendered = vm - .kernel() - .string_forge() - .lookup(result.as_string_index()) - .unwrap_or_default(); + let rendered = vm.kernel().string_forge().lookup(result.as_string_index()).unwrap_or_default(); assert!(rendered.contains("function"), "got: {}", rendered); } diff --git a/crates/oxide_vm/tests/builtins_globals_tests.rs b/crates/oxide_vm/tests/builtins_globals_tests.rs index 177078b..37032e5 100644 --- a/crates/oxide_vm/tests/builtins_globals_tests.rs +++ b/crates/oxide_vm/tests/builtins_globals_tests.rs @@ -4,11 +4,8 @@ use oxide_vm::vm::Vm; fn eval(source: &str) -> Result { let allocator = Allocator::default(); - let program = - oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse error: {:?}", e))?; - let module = Compiler::new() - .compile(&program) - .map_err(|e| format!("Compile error: {}", e))?; + let program = oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse error: {:?}", e))?; + let module = Compiler::new().compile(&program).map_err(|e| format!("Compile error: {}", e))?; let mut vm = Vm::new(); vm.run(&module) } diff --git a/crates/oxide_vm/tests/builtins_map_tests.rs b/crates/oxide_vm/tests/builtins_map_tests.rs index 9d4b2e7..d06181a 100644 --- a/crates/oxide_vm/tests/builtins_map_tests.rs +++ b/crates/oxide_vm/tests/builtins_map_tests.rs @@ -1,25 +1,17 @@ use oxide_compiler::compiler::Compiler; use oxide_types::value::JsValue; -use oxide_vm::builtins::map::{ - map_clear, map_constructor as new_map, map_delete, map_get, map_has, map_set, map_size, -}; +use oxide_vm::builtins::map::{map_clear, map_constructor as new_map, map_delete, map_get, map_has, map_set, map_size}; use oxide_vm::vm::Vm; fn eval(vm: &mut Vm, source: &str) -> Result { let allocator = oxide_parser::Allocator::default(); - let program = - oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse error: {:?}", e))?; - let module = Compiler::new() - .compile(&program) - .map_err(|e| format!("Compile error: {}", e))?; + let program = oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse error: {:?}", e))?; + let module = Compiler::new().compile(&program).map_err(|e| format!("Compile error: {}", e))?; vm.run(&module) } fn str_val(vm: &Vm, val: JsValue) -> String { - vm.kernel() - .string_forge() - .lookup(val.as_string_index()) - .unwrap_or_default() + vm.kernel().string_forge().lookup(val.as_string_index()).unwrap_or_default() } // -- direct native fn tests -- @@ -101,10 +93,6 @@ fn map_new_has() { #[test] fn map_new_delete() { let mut vm = Vm::new(); - let r = eval( - &mut vm, - "var m = new Map(); m.set('x', 10); m.delete('x'); m.has('x')", - ) - .unwrap(); + let r = eval(&mut vm, "var m = new Map(); m.set('x', 10); m.delete('x'); m.has('x')").unwrap(); assert!(!r.as_bool()); } diff --git a/crates/oxide_vm/tests/builtins_math_tests.rs b/crates/oxide_vm/tests/builtins_math_tests.rs index d538861..3aba0b2 100644 --- a/crates/oxide_vm/tests/builtins_math_tests.rs +++ b/crates/oxide_vm/tests/builtins_math_tests.rs @@ -4,11 +4,8 @@ use oxide_vm::vm::Vm; fn eval(vm: &mut Vm, source: &str) -> Result { let allocator = oxide_parser::Allocator::default(); - let program = - oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse error: {:?}", e))?; - let module = Compiler::new() - .compile(&program) - .map_err(|e| format!("Compile error: {}", e))?; + let program = oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse error: {:?}", e))?; + let module = Compiler::new().compile(&program).map_err(|e| format!("Compile error: {}", e))?; vm.run(&module) } diff --git a/crates/oxide_vm/tests/builtins_number_tests.rs b/crates/oxide_vm/tests/builtins_number_tests.rs index f7252f7..b4110aa 100644 --- a/crates/oxide_vm/tests/builtins_number_tests.rs +++ b/crates/oxide_vm/tests/builtins_number_tests.rs @@ -4,11 +4,8 @@ use oxide_vm::vm::Vm; fn eval(vm: &mut Vm, source: &str) -> Result { let allocator = oxide_parser::Allocator::default(); - let program = - oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse error: {:?}", e))?; - let module = Compiler::new() - .compile(&program) - .map_err(|e| format!("Compile error: {}", e))?; + let program = oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse error: {:?}", e))?; + let module = Compiler::new().compile(&program).map_err(|e| format!("Compile error: {}", e))?; vm.run(&module) } @@ -79,11 +76,7 @@ fn number_constructor() { fn to_string_of_number() { let mut vm = Vm::new(); let result = eval(&mut vm, "var n = 42; n.toString()").unwrap(); - let s = vm - .kernel() - .string_forge() - .lookup(result.as_string_index()) - .unwrap_or_default(); + let s = vm.kernel().string_forge().lookup(result.as_string_index()).unwrap_or_default(); assert_eq!(s, "42"); } @@ -91,11 +84,7 @@ fn to_string_of_number() { fn to_fixed_of_number() { let mut vm = Vm::new(); let result = eval(&mut vm, "var n = 3.14159; n.toFixed(2)").unwrap(); - let s = vm - .kernel() - .string_forge() - .lookup(result.as_string_index()) - .unwrap_or_default(); + let s = vm.kernel().string_forge().lookup(result.as_string_index()).unwrap_or_default(); assert_eq!(s, "3.14"); } @@ -124,24 +113,13 @@ fn number_epsilon_is_positive() { fn number_to_exponential() { let mut vm = Vm::new(); let result = eval(&mut vm, "var n = 123.456; n.toExponential(2)").unwrap(); - let s = vm - .kernel() - .string_forge() - .lookup(result.as_string_index()) - .unwrap_or_default(); + let s = vm.kernel().string_forge().lookup(result.as_string_index()).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()); + assert_eq!(eval(&mut vm, "Number.MAX_SAFE_INTEGER").unwrap().as_double(), 9007199254740991f64); + assert!(eval(&mut vm, "Number.POSITIVE_INFINITY > 0").unwrap().as_bool()); } diff --git a/crates/oxide_vm/tests/builtins_object_tests.rs b/crates/oxide_vm/tests/builtins_object_tests.rs index a8e278c..81c6c78 100644 --- a/crates/oxide_vm/tests/builtins_object_tests.rs +++ b/crates/oxide_vm/tests/builtins_object_tests.rs @@ -4,11 +4,8 @@ use oxide_vm::vm::Vm; fn eval(source: &str) -> Result<(Vm, JsValue), String> { let allocator = oxide_parser::Allocator::default(); - let program = - oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse error: {:?}", e))?; - let module = Compiler::new() - .compile(&program) - .map_err(|e| format!("Compile error: {}", e))?; + let program = oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse error: {:?}", e))?; + let module = Compiler::new().compile(&program).map_err(|e| format!("Compile error: {}", e))?; let mut vm = Vm::new(); let result = vm.run(&module)?; Ok((vm, result)) diff --git a/crates/oxide_vm/tests/builtins_regexp_tests.rs b/crates/oxide_vm/tests/builtins_regexp_tests.rs index ea0da4f..169d94e 100644 --- a/crates/oxide_vm/tests/builtins_regexp_tests.rs +++ b/crates/oxide_vm/tests/builtins_regexp_tests.rs @@ -4,19 +4,13 @@ use oxide_vm::vm::Vm; fn eval(vm: &mut Vm, source: &str) -> Result { let allocator = oxide_parser::Allocator::default(); - let program = - oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse error: {:?}", e))?; - let module = Compiler::new() - .compile(&program) - .map_err(|e| format!("Compile error: {}", e))?; + let program = oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse error: {:?}", e))?; + let module = Compiler::new().compile(&program).map_err(|e| format!("Compile error: {}", e))?; vm.run(&module) } fn to_str(vm: &Vm, val: JsValue) -> String { - vm.kernel() - .string_forge() - .lookup(val.as_string_index()) - .unwrap_or_default() + vm.kernel().string_forge().lookup(val.as_string_index()).unwrap_or_default() } // --- RegExp constructor --- @@ -154,11 +148,7 @@ fn regexp_exec_global_last_index_advances() { #[test] fn regexp_exec_global_resets_on_exhaustion() { let mut vm = Vm::new(); - let result = eval( - &mut vm, - "var re = /a/g; re.exec('a'); re.exec('a') === null", - ) - .unwrap(); + let result = eval(&mut vm, "var re = /a/g; re.exec('a'); re.exec('a') === null").unwrap(); assert!(result.as_bool()); } diff --git a/crates/oxide_vm/tests/builtins_set_tests.rs b/crates/oxide_vm/tests/builtins_set_tests.rs index f742e1a..db4606a 100644 --- a/crates/oxide_vm/tests/builtins_set_tests.rs +++ b/crates/oxide_vm/tests/builtins_set_tests.rs @@ -1,17 +1,12 @@ use oxide_compiler::compiler::Compiler; use oxide_types::value::JsValue; -use oxide_vm::builtins::set::{ - set_add, set_clear, set_constructor as new_set, set_delete, set_has, set_size, -}; +use oxide_vm::builtins::set::{set_add, set_clear, set_constructor as new_set, set_delete, set_has, set_size}; use oxide_vm::vm::Vm; fn eval(vm: &mut Vm, source: &str) -> Result { let allocator = oxide_parser::Allocator::default(); - let program = - oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse error: {:?}", e))?; - let module = Compiler::new() - .compile(&program) - .map_err(|e| format!("Compile error: {}", e))?; + let program = oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse error: {:?}", e))?; + let module = Compiler::new().compile(&program).map_err(|e| format!("Compile error: {}", e))?; vm.run(&module) } @@ -119,10 +114,6 @@ fn set_new_has_missing() { #[test] fn set_new_delete() { let mut vm = Vm::new(); - let r = eval( - &mut vm, - "var s = new Set(); s.add(1); s.add(2); s.delete(1); s.has(1)", - ) - .unwrap(); + let r = eval(&mut vm, "var s = new Set(); s.add(1); s.add(2); s.delete(1); s.has(1)").unwrap(); assert!(!r.as_bool()); } diff --git a/crates/oxide_vm/tests/builtins_string_tests.rs b/crates/oxide_vm/tests/builtins_string_tests.rs index 452ea45..8b3aa42 100644 --- a/crates/oxide_vm/tests/builtins_string_tests.rs +++ b/crates/oxide_vm/tests/builtins_string_tests.rs @@ -4,19 +4,13 @@ use oxide_vm::vm::Vm; fn eval(vm: &mut Vm, source: &str) -> Result { let allocator = oxide_parser::Allocator::default(); - let program = - oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse error: {:?}", e))?; - let module = Compiler::new() - .compile(&program) - .map_err(|e| format!("Compile error: {}", e))?; + let program = oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse error: {:?}", e))?; + let module = Compiler::new().compile(&program).map_err(|e| format!("Compile error: {}", e))?; vm.run(&module) } fn to_str(vm: &Vm, val: JsValue) -> String { - vm.kernel() - .string_forge() - .lookup(val.as_string_index()) - .unwrap_or_default() + vm.kernel().string_forge().lookup(val.as_string_index()).unwrap_or_default() } #[test] diff --git a/crates/oxide_vm/tests/builtins_symbol_tests.rs b/crates/oxide_vm/tests/builtins_symbol_tests.rs index 05503e1..48ecba3 100644 --- a/crates/oxide_vm/tests/builtins_symbol_tests.rs +++ b/crates/oxide_vm/tests/builtins_symbol_tests.rs @@ -4,19 +4,13 @@ use oxide_vm::vm::Vm; fn eval(vm: &mut Vm, source: &str) -> Result { let allocator = oxide_parser::Allocator::default(); - let program = - oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse error: {:?}", e))?; - let module = Compiler::new() - .compile(&program) - .map_err(|e| format!("Compile error: {}", e))?; + let program = oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse error: {:?}", e))?; + let module = Compiler::new().compile(&program).map_err(|e| format!("Compile error: {}", e))?; vm.run(&module) } fn to_str(vm: &Vm, val: JsValue) -> String { - vm.kernel() - .string_forge() - .lookup(val.as_string_index()) - .unwrap_or_default() + vm.kernel().string_forge().lookup(val.as_string_index()).unwrap_or_default() } // --- Symbol constructor --- diff --git a/crates/oxide_vm/tests/coercion_tests.rs b/crates/oxide_vm/tests/coercion_tests.rs index d093979..4be136b 100644 --- a/crates/oxide_vm/tests/coercion_tests.rs +++ b/crates/oxide_vm/tests/coercion_tests.rs @@ -38,26 +38,17 @@ fn eval_not_falsy() { #[test] fn test_same_value_signed_zero() { - assert!(!coercion::same_value( - JsValue::float(0.0), - JsValue::float(-0.0) - )); + assert!(!coercion::same_value(JsValue::float(0.0), JsValue::float(-0.0))); } #[test] fn test_strict_equality_signed_zero() { - assert!(coercion::strict_equality( - JsValue::float(0.0), - JsValue::float(-0.0) - )); + assert!(coercion::strict_equality(JsValue::float(0.0), JsValue::float(-0.0))); } #[test] fn test_same_value_nan() { - assert!(coercion::same_value( - JsValue::float(f64::NAN), - JsValue::float(f64::NAN) - )); + assert!(coercion::same_value(JsValue::float(f64::NAN), JsValue::float(f64::NAN))); } #[test] @@ -73,36 +64,21 @@ fn test_same_value_int_float_equal() { #[test] fn test_strict_equality_nan() { - assert!(!coercion::strict_equality( - JsValue::float(f64::NAN), - JsValue::float(f64::NAN) - )); + assert!(!coercion::strict_equality(JsValue::float(f64::NAN), JsValue::float(f64::NAN))); } #[test] fn test_strict_equality_type_mismatch() { - assert!(!coercion::strict_equality( - JsValue::int(1), - JsValue::bool(true) - )); + assert!(!coercion::strict_equality(JsValue::int(1), JsValue::bool(true))); } #[test] fn test_strict_equality_int_float_equal() { - assert!(coercion::strict_equality( - JsValue::int(1), - JsValue::float(1.0) - )); - assert!(!coercion::strict_equality( - JsValue::int(1), - JsValue::float(2.0) - )); + assert!(coercion::strict_equality(JsValue::int(1), JsValue::float(1.0))); + assert!(!coercion::strict_equality(JsValue::int(1), JsValue::float(2.0))); } #[test] fn test_strict_equality_null_undefined() { - assert!(!coercion::strict_equality( - JsValue::null(), - JsValue::undefined() - )); + assert!(!coercion::strict_equality(JsValue::null(), JsValue::undefined())); } diff --git a/crates/oxide_vm/tests/control_flow_tests.rs b/crates/oxide_vm/tests/control_flow_tests.rs index 40b65d0..01f5e99 100644 --- a/crates/oxide_vm/tests/control_flow_tests.rs +++ b/crates/oxide_vm/tests/control_flow_tests.rs @@ -61,18 +61,12 @@ fn eval_while_result_undefined() { #[test] fn eval_for_basic() { - assert_eq!( - eval("var r = 0; for (i = 0; i < 3; i = i + 1) { r = r + i; } r"), - "3" - ); + assert_eq!(eval("var r = 0; for (i = 0; i < 3; i = i + 1) { r = r + i; } r"), "3"); } #[test] fn eval_for_no_test() { - assert_eq!( - eval("var r = 0; for (i = 0; ; i = i + 1) { if (i >= 3) { break; } r = r + i; } r"), - "3" - ); + assert_eq!(eval("var r = 0; for (i = 0; ; i = i + 1) { if (i >= 3) { break; } r = r + i; } r"), "3"); } #[test] @@ -97,10 +91,7 @@ fn eval_ternary_nested() { #[test] fn eval_break_in_while() { - assert_eq!( - eval("var i = 0; while (true) { i = i + 1; if (i >= 3) { break; } } i"), - "3" - ); + assert_eq!(eval("var i = 0; while (true) { i = i + 1; if (i >= 3) { break; } } i"), "3"); } #[test] @@ -155,10 +146,7 @@ fn eval_do_while_multi_iteration() { #[test] fn eval_do_while_break() { - assert_eq!( - eval("var i = 0; do { i = i + 1; if (i >= 3) break; } while (true); i"), - "3" - ); + assert_eq!(eval("var i = 0; do { i = i + 1; if (i >= 3) break; } while (true); i"), "3"); } #[test] @@ -182,34 +170,22 @@ fn eval_for_in_empty_object() { #[test] fn eval_for_in_non_object_throws() { let result = eval("for (k in 42) {}"); - assert!( - result.contains("TypeError"), - "expected TypeError, got: {result}" - ); + assert!(result.contains("TypeError"), "expected TypeError, got: {result}"); } #[test] fn eval_for_in_nested() { - assert_eq!( - eval("var r=0; for (k in {a:{x:1}}) { for (j in {y:2}) { r=r+1; } } r"), - "2" - ); + assert_eq!(eval("var r=0; for (k in {a:{x:1}}) { for (j in {y:2}) { r=r+1; } } r"), "2"); } #[test] fn eval_for_in_break() { - assert_eq!( - eval("var r=0; for (k in {a:1,b:2,c:3}) { if (k=='b') break; r=r+1; } r"), - "1" - ); + assert_eq!(eval("var r=0; for (k in {a:1,b:2,c:3}) { if (k=='b') break; r=r+1; } r"), "1"); } #[test] fn eval_for_in_continue() { - assert_eq!( - eval("var r=0; for (k in {a:1,b:2}) { if (k=='a') continue; r=r+1; } r"), - "2" - ); + assert_eq!(eval("var r=0; for (k in {a:1,b:2}) { if (k=='a') continue; r=r+1; } r"), "2"); } #[test] @@ -220,10 +196,7 @@ fn eval_for_in_let_scoping() { #[test] fn eval_switch_basic_match() { - assert_eq!( - eval("var x=0;switch(2){case 1:x=10;case 2:x=20;break;default:x=30;}x"), - "20" - ); + assert_eq!(eval("var x=0;switch(2){case 1:x=10;case 2:x=20;break;default:x=30;}x"), "20"); } #[test] @@ -243,18 +216,12 @@ fn eval_switch_no_match_no_default() { #[test] fn eval_switch_break() { - assert_eq!( - eval("var x=0;switch(1){case 1:x=10;break;case 2:x=20;}x"), - "10" - ); + assert_eq!(eval("var x=0;switch(1){case 1:x=10;break;case 2:x=20;}x"), "10"); } #[test] fn eval_break_in_switch_in_loop() { - assert_eq!( - eval("var r=0;while(true){switch(1){case 1:r=1;break;}r=2;break;}r"), - "2" - ); + assert_eq!(eval("var r=0;while(true){switch(1){case 1:r=1;break;}r=2;break;}r"), "2"); } #[test] diff --git a/crates/oxide_vm/tests/function_tests.rs b/crates/oxide_vm/tests/function_tests.rs index 7aaad7e..9e16650 100644 --- a/crates/oxide_vm/tests/function_tests.rs +++ b/crates/oxide_vm/tests/function_tests.rs @@ -4,11 +4,8 @@ use oxide_vm::vm::Vm; fn eval(vm: &mut Vm, source: &str) -> Result { let allocator = oxide_parser::Allocator::default(); - let program = - oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse error: {:?}", e))?; - let module = Compiler::new() - .compile(&program) - .map_err(|e| format!("Compile error: {}", e))?; + let program = oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse error: {:?}", e))?; + let module = Compiler::new().compile(&program).map_err(|e| format!("Compile error: {}", e))?; vm.run(&module) } @@ -61,11 +58,7 @@ fn fe_basic() { #[test] fn fe_with_params() { let mut vm = Vm::new(); - let result = eval( - &mut vm, - "var mul = function(x,y) { return x * y; }; mul(6, 7)", - ) - .unwrap(); + let result = eval(&mut vm, "var mul = function(x,y) { return x * y; }; mul(6, 7)").unwrap(); assert!((result.as_double() - 42.0).abs() < 0.0001); } @@ -74,22 +67,14 @@ fn fe_with_params() { #[test] fn cross_func_call() { let mut vm = Vm::new(); - let result = eval( - &mut vm, - "function a() { return 1; } function b() { return a() + 2; } b()", - ) - .unwrap(); + let result = eval(&mut vm, "function a() { return 1; } function b() { return a() + 2; } b()").unwrap(); assert!((result.as_double() - 3.0).abs() < 0.0001); } #[test] fn two_funcs_called_from_global() { let mut vm = Vm::new(); - let result = eval( - &mut vm, - "function a() { return 1; } function b() { return 2; } a() + b()", - ) - .unwrap(); + let result = eval(&mut vm, "function a() { return 1; } function b() { return 2; } a() + b()").unwrap(); assert!(result.is_double(), "expected double, got: {:?}", result); assert!((result.as_double() - 3.0).abs() < 0.0001); } @@ -147,11 +132,7 @@ fn fd_calls_builtin_two_args() { #[test] fn fd_chain_call() { let mut vm = Vm::new(); - let result = eval( - &mut vm, - "function a() { return 10; } function b() { return a(); } b()", - ) - .unwrap(); + let result = eval(&mut vm, "function a() { return 10; } function b() { return a(); } b()").unwrap(); assert_eq!(result.as_int(), 10); } @@ -177,11 +158,7 @@ fn fd_returns_new_array() { fn this_in_function_reads_value() { let mut vm = Vm::new(); let result = eval(&mut vm, "function f() { return this; } f()").unwrap(); - assert!( - result.is_object(), - "expected object (function as this), got: {:?}", - result - ); + assert!(result.is_object(), "expected object (function as this), got: {:?}", result); } #[test] @@ -201,10 +178,6 @@ fn this_member_access() { #[test] fn this_in_constructor_sets_proto() { let mut vm = Vm::new(); - let result = eval( - &mut vm, - "function Ctor(m) { this.message = m; } Ctor.prototype = new Object(); 1", - ) - .unwrap(); + let result = eval(&mut vm, "function Ctor(m) { this.message = m; } Ctor.prototype = new Object(); 1").unwrap(); assert_eq!(result.as_int(), 1); } diff --git a/crates/oxide_vm/tests/json_tests.rs b/crates/oxide_vm/tests/json_tests.rs index 6204c80..d07beab 100644 --- a/crates/oxide_vm/tests/json_tests.rs +++ b/crates/oxide_vm/tests/json_tests.rs @@ -4,19 +4,13 @@ use oxide_vm::vm::Vm; fn eval(vm: &mut Vm, source: &str) -> Result { let allocator = oxide_parser::Allocator::default(); - let program = - oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse error: {:?}", e))?; - let module = Compiler::new() - .compile(&program) - .map_err(|e| format!("Compile error: {}", e))?; + let program = oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse error: {:?}", e))?; + let module = Compiler::new().compile(&program).map_err(|e| format!("Compile error: {}", e))?; vm.run(&module) } fn string_value(vm: &Vm, val: JsValue) -> String { - vm.kernel() - .string_forge() - .lookup(val.as_string_index()) - .unwrap_or_default() + vm.kernel().string_forge().lookup(val.as_string_index()).unwrap_or_default() } // -- JSON.parse -- @@ -90,11 +84,7 @@ fn json_parse_null() { #[test] fn json_parse_nested() { let mut vm = Vm::new(); - let result = eval( - &mut vm, - "JSON.parse('{\"a\":1,\"b\":[1,2],\"c\":{\"d\":\"hello\"}}')", - ) - .unwrap(); + let result = eval(&mut vm, "JSON.parse('{\"a\":1,\"b\":[1,2],\"c\":{\"d\":\"hello\"}}')").unwrap(); assert!(result.is_object()); } @@ -200,11 +190,7 @@ fn json_parse_stringify_roundtrip() { #[test] fn json_roundtrip_array() { let mut vm = Vm::new(); - let _ = eval( - &mut vm, - "var arr = JSON.parse(JSON.stringify([1,2,3])); arr", - ) - .unwrap(); + let _ = eval(&mut vm, "var arr = JSON.parse(JSON.stringify([1,2,3])); arr").unwrap(); } // -- Edge cases -- diff --git a/crates/oxide_vm/tests/mem_tests.rs b/crates/oxide_vm/tests/mem_tests.rs index 41754e9..ae7eedc 100644 --- a/crates/oxide_vm/tests/mem_tests.rs +++ b/crates/oxide_vm/tests/mem_tests.rs @@ -43,10 +43,7 @@ fn epoch_benchmark_1m_allocations() { let elapsed = start.elapsed(); if cfg!(debug_assertions) { - println!( - "1M allocations took {}ms (debug build - skipping timing assertion)", - elapsed.as_millis() - ); + println!("1M allocations took {}ms (debug build - skipping timing assertion)", elapsed.as_millis()); } else { assert!( elapsed.as_millis() < 200, diff --git a/crates/oxide_vm/tests/proto_chain_tests.rs b/crates/oxide_vm/tests/proto_chain_tests.rs index 8737100..023e729 100644 --- a/crates/oxide_vm/tests/proto_chain_tests.rs +++ b/crates/oxide_vm/tests/proto_chain_tests.rs @@ -5,9 +5,7 @@ use oxide_vm::vm::Vm; fn eval(source: &str) -> Result { let allocator = oxide_parser::Allocator::default(); let program = oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse: {:?}", e))?; - let module = Compiler::new() - .compile(&program) - .map_err(|e| format!("Compile: {}", e))?; + let module = Compiler::new().compile(&program).map_err(|e| format!("Compile: {}", e))?; let mut vm = Vm::new(); vm.run(&module) } @@ -15,36 +13,21 @@ fn eval(source: &str) -> Result { macro_rules! assert_bool { ($expr:expr, $expected:expr, $msg:expr) => { let r = $expr.unwrap(); - assert!( - r.is_bool() && r.as_bool() == $expected, - "{}: expected {}, got {:?}", - $msg, - $expected, - r - ); + assert!(r.is_bool() && r.as_bool() == $expected, "{}: expected {}, got {:?}", $msg, $expected, r); }; } macro_rules! assert_undefined { ($expr:expr, $msg:expr) => { let r = $expr.unwrap(); - assert!( - r.is_undefined(), - "{}: expected undefined, got {:?}", - $msg, - r - ); + assert!(r.is_undefined(), "{}: expected undefined, got {:?}", $msg, r); }; } // -- Proto chains: every (non-Object) constructor.prototype should inherit from Object.prototype -- #[test] fn array_proto_chain() { - assert_bool!( - eval("Object.getPrototypeOf(Array.prototype) === Object.prototype"), - true, - "Array proto" - ); + assert_bool!(eval("Object.getPrototypeOf(Array.prototype) === Object.prototype"), true, "Array proto"); } #[test] @@ -57,20 +40,12 @@ fn function_proto_chain() { #[test] fn string_proto_chain() { - assert_bool!( - eval("Object.getPrototypeOf(String.prototype) === Object.prototype"), - true, - "String proto" - ); + assert_bool!(eval("Object.getPrototypeOf(String.prototype) === Object.prototype"), true, "String proto"); } #[test] fn number_proto_chain() { - assert_bool!( - eval("Object.getPrototypeOf(Number.prototype) === Object.prototype"), - true, - "Number proto" - ); + assert_bool!(eval("Object.getPrototypeOf(Number.prototype) === Object.prototype"), true, "Number proto"); } #[test] @@ -84,56 +59,32 @@ fn boolean_proto_chain() { #[test] fn error_proto_chain() { - assert_bool!( - eval("Object.getPrototypeOf(Error.prototype) === Object.prototype"), - true, - "Error proto" - ); + assert_bool!(eval("Object.getPrototypeOf(Error.prototype) === Object.prototype"), true, "Error proto"); } #[test] fn symbol_proto_chain() { - assert_bool!( - eval("Object.getPrototypeOf(Symbol.prototype) === Object.prototype"), - true, - "Symbol proto" - ); + assert_bool!(eval("Object.getPrototypeOf(Symbol.prototype) === Object.prototype"), true, "Symbol proto"); } #[test] fn date_proto_chain() { - assert_bool!( - eval("Object.getPrototypeOf(Date.prototype) === Object.prototype"), - true, - "Date proto" - ); + assert_bool!(eval("Object.getPrototypeOf(Date.prototype) === Object.prototype"), true, "Date proto"); } #[test] fn set_proto_chain() { - assert_bool!( - eval("Object.getPrototypeOf(Set.prototype) === Object.prototype"), - true, - "Set proto" - ); + assert_bool!(eval("Object.getPrototypeOf(Set.prototype) === Object.prototype"), true, "Set proto"); } #[test] fn map_proto_chain() { - assert_bool!( - eval("Object.getPrototypeOf(Map.prototype) === Object.prototype"), - true, - "Map proto" - ); + assert_bool!(eval("Object.getPrototypeOf(Map.prototype) === Object.prototype"), true, "Map proto"); } #[test] fn regexp_proto_chain() { - assert_bool!( - eval("Object.getPrototypeOf(RegExp.prototype) === Object.prototype"), - true, - "RegExp proto" - ); + assert_bool!(eval("Object.getPrototypeOf(RegExp.prototype) === Object.prototype"), true, "RegExp proto"); } // -- Object.prototype is the root, its __proto__ is null -- @@ -147,20 +98,12 @@ fn object_proto_is_root() { #[test] fn array_instanceof_object() { assert_bool!(eval("[] instanceof Object"), true, "[] instanceof Object"); - assert_bool!( - eval("new Array() instanceof Object"), - true, - "new Array instanceof Object" - ); + assert_bool!(eval("new Array() instanceof Object"), true, "new Array instanceof Object"); } #[test] fn function_instanceof_object() { - assert_bool!( - eval("(function() {}) instanceof Object"), - true, - "function instanceof Object" - ); + assert_bool!(eval("(function() {}) instanceof Object"), true, "function instanceof Object"); } #[test] @@ -179,110 +122,62 @@ fn boolean_not_instanceof_function() { #[test] fn number_instanceof_object() { - assert_bool!( - eval("new Number(1) instanceof Object"), - true, - "new Number instanceof Object" - ); + assert_bool!(eval("new Number(1) instanceof Object"), true, "new Number instanceof Object"); } #[test] fn boolean_instanceof_object() { - assert_bool!( - eval("new Boolean(true) instanceof Object"), - true, - "new Boolean instanceof Object" - ); + assert_bool!(eval("new Boolean(true) instanceof Object"), true, "new Boolean instanceof Object"); } #[test] fn error_instanceof_object() { - assert_bool!( - eval("new Error() instanceof Object"), - true, - "new Error instanceof Object" - ); + assert_bool!(eval("new Error() instanceof Object"), true, "new Error instanceof Object"); } #[test] fn date_instanceof_object() { - assert_bool!( - eval("new Date() instanceof Object"), - true, - "new Date instanceof Object" - ); + assert_bool!(eval("new Date() instanceof Object"), true, "new Date instanceof Object"); } #[test] fn set_instanceof_object() { - assert_bool!( - eval("new Set() instanceof Object"), - true, - "new Set instanceof Object" - ); + assert_bool!(eval("new Set() instanceof Object"), true, "new Set instanceof Object"); } #[test] fn map_instanceof_object() { - assert_bool!( - eval("new Map() instanceof Object"), - true, - "new Map instanceof Object" - ); + assert_bool!(eval("new Map() instanceof Object"), true, "new Map instanceof Object"); } #[test] fn regexp_instanceof_object() { assert_bool!(eval("/a/ instanceof Object"), true, "/a/ instanceof Object"); - assert_bool!( - eval("new RegExp('a') instanceof Object"), - true, - "new RegExp instanceof Object" - ); + assert_bool!(eval("new RegExp('a') instanceof Object"), true, "new RegExp instanceof Object"); } #[test] fn object_instanceof_object() { - assert_bool!( - eval("({}) instanceof Object"), - true, - "({}) instanceof Object" - ); + assert_bool!(eval("({}) instanceof Object"), true, "({}) instanceof Object"); } // -- instanceof for native types should NOT respond to their own false positives -- #[test] fn number_not_instanceof_array() { - assert_bool!( - eval("new Number(1) instanceof Array"), - false, - "Number instanceof Array" - ); + assert_bool!(eval("new Number(1) instanceof Array"), false, "Number instanceof Array"); } #[test] fn object_not_instanceof_regexp() { - assert_bool!( - eval("({}) instanceof RegExp"), - false, - "({}) instanceof RegExp" - ); + assert_bool!(eval("({}) instanceof RegExp"), false, "({}) instanceof RegExp"); } // -- Primitives should NOT be instanceof their wrapper constructors (no autoboxing) -- #[test] fn primitives_not_instanceof() { assert_bool!(eval("1 instanceof Number"), false, "1 instanceof Number"); - assert_bool!( - eval("'hi' instanceof String"), - false, - "'hi' instanceof String" - ); - assert_bool!( - eval("true instanceof Boolean"), - false, - "true instanceof Boolean" - ); + assert_bool!(eval("'hi' instanceof String"), false, "'hi' instanceof String"); + assert_bool!(eval("true instanceof Boolean"), false, "true instanceof Boolean"); } // -- VOID regression -- diff --git a/crates/oxide_vm/tests/regression_tests.rs b/crates/oxide_vm/tests/regression_tests.rs index d1a63ab..017f282 100644 --- a/crates/oxide_vm/tests/regression_tests.rs +++ b/crates/oxide_vm/tests/regression_tests.rs @@ -42,11 +42,7 @@ fn eval_with_kernel(source: &str, kernel: Arc) -> String { #[test] fn regression_to_boolean_empty_string() { assert_eq!(eval("!''"), "true", "NOT empty string should be true"); - assert_eq!( - eval("if ('') { 1 } else { 2 }"), - "2", - "empty string should be falsy" - ); + assert_eq!(eval("if ('') { 1 } else { 2 }"), "2", "empty string should be falsy"); } #[test] @@ -71,19 +67,13 @@ fn regression_rerun_clears_ic_cache() { #[test] fn regression_recursion_depth_limit() { - assert_eq!( - eval("function f(){f()} f()"), - "vm error: RangeError: Maximum call stack size exceeded" - ); + assert_eq!(eval("function f(){f()} f()"), "vm error: RangeError: Maximum call stack size exceeded"); } #[test] fn regression_throw_statement_errors() { let result = eval("throw 'error'"); - assert!( - result.contains("uncaught"), - "expected uncaught, got: {result}" - ); + assert!(result.contains("uncaught"), "expected uncaught, got: {result}"); assert!( result.contains("uncaught Error"), "expected string throw to default to Error, got: {result}" @@ -92,14 +82,8 @@ fn regression_throw_statement_errors() { #[test] fn regression_throw_statement_preserves_type_error_kind() { - assert_eq!( - eval("try { throw new TypeError('boom') } catch (e) { e.name == 'TypeError' }"), - "true" - ); - assert_eq!( - eval("throw new TypeError('boom')"), - "vm error: uncaught TypeError: {object}" - ); + assert_eq!(eval("try { throw new TypeError('boom') } catch (e) { e.name == 'TypeError' }"), "true"); + assert_eq!(eval("throw new TypeError('boom')"), "vm error: uncaught TypeError: {object}"); } #[test] @@ -108,10 +92,7 @@ fn regression_throw_statement_preserves_syntax_error_kind() { eval("try { throw new SyntaxError('boom') } catch (e) { e.name == 'SyntaxError' }"), "true" ); - assert_eq!( - eval("throw new SyntaxError('boom')"), - "vm error: uncaught SyntaxError: {object}" - ); + assert_eq!(eval("throw new SyntaxError('boom')"), "vm error: uncaught SyntaxError: {object}"); } #[test] @@ -155,24 +136,12 @@ fn regression_new_expression_bytecode_constructor_error_is_catchable() { #[test] fn regression_delete_static_property_throws_type_error() { - assert_eq!( - eval("try { var o={x:1}; delete o.x; 0 } catch (e) { e.name == 'TypeError' }"), - "true" - ); - assert_eq!( - eval("var o={x:1}; delete o.x"), - "vm error: uncaught TypeError: {object}" - ); + assert_eq!(eval("try { var o={x:1}; delete o.x; 0 } catch (e) { e.name == 'TypeError' }"), "true"); + assert_eq!(eval("var o={x:1}; delete o.x"), "vm error: uncaught TypeError: {object}"); } #[test] fn regression_delete_dynamic_property_throws_type_error() { - assert_eq!( - eval("try { var o={x:1}; delete o['x']; 0 } catch (e) { e.name == 'TypeError' }"), - "true" - ); - assert_eq!( - eval("var o={x:1}; var k='x'; delete o[k]"), - "vm error: uncaught TypeError: {object}" - ); + assert_eq!(eval("try { var o={x:1}; delete o['x']; 0 } catch (e) { e.name == 'TypeError' }"), "true"); + assert_eq!(eval("var o={x:1}; var k='x'; delete o[k]"), "vm error: uncaught TypeError: {object}"); } diff --git a/crates/oxide_vm/tests/scoping_tests.rs b/crates/oxide_vm/tests/scoping_tests.rs index 0d5b9a4..2bb0e25 100644 --- a/crates/oxide_vm/tests/scoping_tests.rs +++ b/crates/oxide_vm/tests/scoping_tests.rs @@ -5,9 +5,7 @@ use oxide_vm::vm::Vm; fn eval(source: &str) -> Result { let allocator = oxide_parser::Allocator::default(); let program = oxide_parser::parse(&allocator, source).map_err(|e| format!("Parse: {:?}", e))?; - let module = Compiler::new() - .compile(&program) - .map_err(|e| format!("Compile: {}", e))?; + let module = Compiler::new().compile(&program).map_err(|e| format!("Compile: {}", e))?; let mut vm = Vm::new(); vm.run(&module) } @@ -23,11 +21,7 @@ fn const_reassignment_throws() { let result = eval("const x = 1; x = 2"); assert!(result.is_err()); let err = result.unwrap_err(); - assert!( - err.contains("TypeError") || err.contains("constant"), - "got: {}", - err - ); + assert!(err.contains("TypeError") || err.contains("constant"), "got: {}", err); } #[test] diff --git a/crates/oxide_vm/tests/template_tests.rs b/crates/oxide_vm/tests/template_tests.rs index b9ec248..f83e8e3 100644 --- a/crates/oxide_vm/tests/template_tests.rs +++ b/crates/oxide_vm/tests/template_tests.rs @@ -37,10 +37,7 @@ fn eval_val(source: &str) -> (Vm, Result) { fn to_str(vm: &Vm, val: JsValue) -> String { if val.is_string() { - vm.kernel() - .string_forge() - .lookup(val.as_string_index()) - .unwrap_or_default() + vm.kernel().string_forge().lookup(val.as_string_index()).unwrap_or_default() } else { format!("{}", val) } @@ -99,11 +96,7 @@ fn tagged_template_basic() { // This avoids bytecode function call complexity. let result = eval("Math.max`hello ${42} world`"); // Math.max on the args should work - just verify it doesn't crash - assert!( - !result.starts_with("vm error:"), - "Tagged template should not crash, got: {}", - result - ); + assert!(!result.starts_with("vm error:"), "Tagged template should not crash, got: {}", result); } #[test] @@ -111,8 +104,5 @@ fn tagged_template_compiles_no_error() { // Verify that tagged templates compile without error (even if the tag // function behavior isn't fully tested) let result = eval("function t(s,v){ return s[0]+v; } t`x${1}`"); - assert!( - !result.starts_with("compile error:"), - "Tagged template should compile" - ); + assert!(!result.starts_with("compile error:"), "Tagged template should compile"); } diff --git a/crates/oxide_vm/tests/value_tests.rs b/crates/oxide_vm/tests/value_tests.rs index 710b1bc..fbb6877 100644 --- a/crates/oxide_vm/tests/value_tests.rs +++ b/crates/oxide_vm/tests/value_tests.rs @@ -121,9 +121,7 @@ fn as_js_object_ptr_non_object_returns_null() { assert!(JsValue::null().as_js_object_ptr().is_null()); assert!(JsValue::undefined().as_js_object_ptr().is_null()); let x = 42u8; - assert!(!JsValue::object(&x as *const u8) - .as_js_object_ptr() - .is_null()); + assert!(!JsValue::object(&x as *const u8).as_js_object_ptr().is_null()); } #[test] diff --git a/crates/oxide_vm/tests/vm_tests.rs b/crates/oxide_vm/tests/vm_tests.rs index e761e1b..9bf86c5 100644 --- a/crates/oxide_vm/tests/vm_tests.rs +++ b/crates/oxide_vm/tests/vm_tests.rs @@ -27,10 +27,7 @@ fn test_throw_caught_by_catch() { #[test] fn test_throw_without_catch() { let result = eval("throw 'err';"); - assert!( - result.contains("uncaught"), - "expected uncaught, got: {result}" - ); + assert!(result.contains("uncaught"), "expected uncaught, got: {result}"); } #[test] @@ -41,34 +38,22 @@ fn test_try_finally_normal_path() { #[test] fn test_try_finally_exception_path() { let result = eval("var x = 0; try { throw 1; } finally { x = 2; }"); - assert!( - result.contains("uncaught"), - "expected uncaught, got: {result}" - ); + assert!(result.contains("uncaught"), "expected uncaught, got: {result}"); } #[test] fn test_nested_try_inner_catches() { - assert_eq!( - eval("try { try { throw 1; } catch(e) { e; } } catch(e) { 2; }"), - "1" - ); + assert_eq!(eval("try { try { throw 1; } catch(e) { e; } } catch(e) { 2; }"), "1"); } #[test] fn test_nested_try_outer_catches() { - assert_eq!( - eval("try { try { throw 1; } catch(e) { throw 2; } } catch(e) { e; }"), - "2" - ); + assert_eq!(eval("try { try { throw 1; } catch(e) { throw 2; } } catch(e) { e; }"), "2"); } #[test] fn test_try_catch_finally() { - assert_eq!( - eval("var x = 0; try { x = 1; } catch(e) { x = 2; } finally { x = 3; } x;"), - "3" - ); + assert_eq!(eval("var x = 0; try { x = 1; } catch(e) { x = 2; } finally { x = 3; } x;"), "3"); } #[test] @@ -92,8 +77,5 @@ fn test_throw_err_type_error_is_object() { #[test] fn test_uncaught_type_error_message() { let result = eval("null.prop;"); - assert!( - result.contains("TypeError"), - "expected TypeError in message, got: {result}" - ); + assert!(result.contains("TypeError"), "expected TypeError in message, got: {result}"); } diff --git a/rustfmt.toml b/rustfmt.toml index 758d417..5c05ba4 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -1 +1,16 @@ -max_width = 100 +max_width = 120 +use_small_heuristics = "Max" + +fn_call_width = 90 +attr_fn_like_width = 90 +struct_lit_width = 30 +struct_variant_width = 50 +array_width = 90 +chain_width = 80 + +single_line_if_else_max_width = 80 +single_line_let_else_max_width = 80 +fn_params_layout = "Compressed" + +edition = "2021" +style_edition = "2021"