diff --git a/boa_engine/src/vm/code_block.rs b/boa_engine/src/vm/code_block.rs index 41832e3c1a0..4f0500efa4c 100644 --- a/boa_engine/src/vm/code_block.rs +++ b/boa_engine/src/vm/code_block.rs @@ -1004,7 +1004,7 @@ impl JsObject { this: &JsValue, args: &[JsValue], context: &mut Context<'_>, - ) -> JsResult> { + ) -> JsResult { let this_function_object = self.clone(); let object = self.borrow(); let function_object = object.as_function().expect("not a function"); @@ -1032,7 +1032,9 @@ impl JsObject { context.vm.native_active_function = None; context.swap_realm(&mut realm); - return result.map(Some); + context.vm.push(result?); + + return Ok(true); } FunctionKind::Ordinary { code, @@ -1089,7 +1091,7 @@ impl JsObject { let argument_count = args.len(); let parameters_count = code.params.as_ref().len(); - let frame = CallFrame::new( + let mut frame = CallFrame::new( code.clone(), script_or_module, Some(self.clone()), @@ -1099,6 +1101,8 @@ impl JsObject { .with_argument_count(argument_count as u32) .with_env_fp(env_fp); + frame.exit_early = false; + context.vm.push_frame(frame); let lexical_this_mode = code.this_mode == ThisMode::Lexical; @@ -1194,7 +1198,7 @@ impl JsObject { } context.vm.stack.extend(args.iter().rev().cloned()); - Ok(None) + Ok(false) } pub(crate) fn call_internal( @@ -1203,10 +1207,12 @@ impl JsObject { args: &[JsValue], context: &mut Context<'_>, ) -> JsResult { - if let Some(value) = self.prepare_call_internal(this, args, context)? { - return Ok(value); + if self.prepare_call_internal(this, args, context)? { + return Ok(context.vm.pop()); } + context.vm.frame_mut().exit_early = true; + let result = context .run() .consume() diff --git a/boa_engine/src/vm/opcode/call/mod.rs b/boa_engine/src/vm/opcode/call/mod.rs index 71a51c75211..e488642a4e5 100644 --- a/boa_engine/src/vm/opcode/call/mod.rs +++ b/boa_engine/src/vm/opcode/call/mod.rs @@ -68,6 +68,12 @@ impl Operation for CallEval { context.vm.push(JsValue::Undefined); } } else { + if object.has_function_call_internal() { + object.prepare_call_internal(&this, &arguments, context)?; + + return Ok(CompletionType::Normal); + } + let result = object.__call__(&this, &arguments, context)?; context.vm.push(result); } @@ -142,6 +148,12 @@ impl Operation for CallEvalSpread { context.vm.push(JsValue::Undefined); } } else { + if object.has_function_call_internal() { + object.prepare_call_internal(&this, &arguments, context)?; + + return Ok(CompletionType::Normal); + } + let result = object.__call__(&this, &arguments, context)?; context.vm.push(result); } @@ -194,12 +206,7 @@ impl Operation for Call { }; if object.has_function_call_internal() { - if let Some(value) = object.prepare_call_internal(&this, &arguments, context)? { - context.vm.push(value); - return Ok(CompletionType::Normal); - } - - context.vm.frame_mut().exit_early = false; + object.prepare_call_internal(&this, &arguments, context)?; return Ok(CompletionType::Normal); } @@ -257,6 +264,12 @@ impl Operation for CallSpread { } }; + if object.has_function_call_internal() { + object.prepare_call_internal(&this, &arguments, context)?; + + return Ok(CompletionType::Normal); + } + let result = object.__call__(&this, &arguments, context)?; context.vm.push(result);