Commit Graph

7 Commits

Author SHA1 Message Date
Andreas Kling
8a9d5ee1a1 LibJS: Separate raw and capturing native functions
NativeFunction previously stored an AK::Function for every builtin,
even when the callable was just a plain C++ entry point. That mixed
together two different representations, made simple builtins carry
capture storage they did not need, and forced the GC to treat every
native function as if it might contain captured JS values.

Introduce RawNativeFunction for plain NativeFunctionPointer callees
and keep AK::Function-backed callables on a CapturingNativeFunction
subclass. Update the straightforward native registrations in LibJS
and LibWeb to use the raw representation, while leaving exported
Wasm functions on the capturing path because they still capture
state.

Wrap UniversalGlobalScope's byte-length strategy lambda in
Function<...> explicitly so it keeps selecting the capturing
NativeFunction::create overload.
2026-04-15 15:57:48 +02:00
Ollie Hensman-Crook
df8ead1f12 LibJS: Treat concise methods as non-constructors 2026-03-20 15:58:05 -05:00
Andreas Kling
3efd1a1bb5 LibJS: Reject duplicate params across destructuring patterns in C++
The C++ parser was not rejecting duplicate parameter names across
destructuring patterns in non-simple parameter lists. For example,
`function f({ bar, ...a }, { bar, ...b }) {}` was accepted despite
being a syntax error per spec.

The existing inline duplicate check only ran for identifier parameters,
missing the case where both parameters are binding patterns. Add a
post-parse pass that collects all bound names and checks for duplicates
when the parameter list is non-simple (or in strict mode/arrows).

Also fix existing tests that relied on the incorrect behavior and add
new test coverage for destructuring duplicate detection.
2026-03-19 09:43:11 +01:00
Andreas Kling
af57184627 LibJS: Fix scoping of function declarations with destructured params
When a function has parameter expressions (e.g. destructured params with
defaults), CreateVariableEnvironment creates a separate variable
environment for function declarations and sets it as the current lexical
environment at runtime. However, the bytecode generator's
m_lexical_environment_register_stack was not updated to reflect this, so
subsequent CreateLexicalEnvironment ops would parent themselves to the
old (pre-variable-environment) lexical environment, skipping the
variable environment entirely.

This meant function declarations hoisted into the variable environment
were invisible to closures created in the function body.

Fix this by capturing the new lexical environment into a register after
CreateVariableEnvironment and pushing it onto the environment register
stack.

This fixes a problem where https://tumblr.com/ wouldn't load the feed.
2026-02-12 16:59:47 +01:00
Andreas Kling
755a0a1d1e Tests/LibJS: Add test for rest-only param with arguments object access
Test that a function whose only parameter is a rest parameter correctly
receives its value even when the function also accesses the arguments
object.
2026-02-10 02:05:20 +01:00
Andreas Kling
5238841da2 LibJS: Mark named function expression identifiers at individual level
Previously, when parsing a named function expression like
`Oops = function Oops() { Oops }`, the parser set a group-level flag
`might_be_variable_in_lexical_scope_in_named_function_assignment` that
propagated to the parent scope. This incorrectly prevented ALL `Oops`
identifiers from being marked as global, including those outside the
function expression.

Fix this by marking identifiers individually using
`set_is_inside_scope_with_eval()` only for identifiers inside the
function scope. This allows identifiers outside the function expression
to correctly use GetGlobal/SetGlobal while identifiers inside still
use GetBinding (since they may refer to the function's name binding).
2026-01-27 10:58:39 +01:00
Jelle Raaijmakers
e3faa9b5ad LibJS: Move tests to /Tests/LibJS 2026-01-22 07:46:48 -05:00