Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
3b3bd3b
Tidy up serial version ids.
aardvark179 Apr 29, 2026
24e001c
Convert `BaseFunction` to descriptor.
aardvark179 Feb 2, 2026
2cd3223
Convert `NativeString` to descriptors.
aardvark179 Jan 15, 2026
b063232
Convert `NativeNumber` to descriptors.
aardvark179 Jan 15, 2026
a8cf801
Move `NativeMath` to descriptors.
aardvark179 Jan 16, 2026
2b5eb30
Convert `NativeJSON` to descriptors.
aardvark179 Jan 16, 2026
be87070
Convert `NativeScript` to descriptors.
aardvark179 Jan 16, 2026
8e63d99
Move `NativeIterator` to be based on descriptors.
aardvark179 Jan 19, 2026
c9b3cba
Convert `NativeGlobal` to descriptor.
aardvark179 Jan 21, 2026
5536539
Convert error initialisation to descriptors.
aardvark179 Jan 21, 2026
5d35c3b
Global fixup.
aardvark179 Feb 6, 2026
3a20357
Convert `ArrayBuffer` to descriptors.
aardvark179 Jan 27, 2026
89b3b78
Move typed array to descriptor.
aardvark179 Jan 28, 2026
fbae861
Update test 262 properties.
aardvark179 Feb 3, 2026
270fdbe
Move `NativeDataView` to descriptors.
aardvark179 Jan 28, 2026
ffa461f
Removing unused methods
aardvark179 Jan 29, 2026
6067007
Convert `NativeMap` to descriptor.
aardvark179 Jan 29, 2026
a65d0ba
Move `NativeSet` to descriptors.
aardvark179 Jan 29, 2026
c63941f
Move `NativePromise` to descriptors.
aardvark179 Jan 29, 2026
34c5e10
Move `NativeWeakMap` to descriptor.
aardvark179 Jan 29, 2026
534b483
Move `NativeWeakSet` to descriptors.
aardvark179 Jan 29, 2026
a0a805e
Convert `NativeBigInt` to descriptor.
aardvark179 Jan 30, 2026
7b8fd85
Convert `NativeProxy` to descriptor.
aardvark179 Jan 30, 2026
df28ed5
Convert `NativeReflect` to descriptors.
aardvark179 Jan 30, 2026
588f159
Convert `NativeContinuation` to descriptor.
aardvark179 Feb 4, 2026
e02fa8b
Convert `NativeGenerator` to descriptor.
aardvark179 Feb 4, 2026
b58dbb7
Spotless.
aardvark179 Feb 18, 2026
aa1859e
Convert `NativeCallSite` to descriptors.
aardvark179 Feb 26, 2026
b382321
Convert `ES6Iteratorz` to descriptors.
aardvark179 Feb 4, 2026
dd15954
Update 262 properties.
aardvark179 Mar 19, 2026
e7348ee
Convert `thisObj` to be `Object` not `Scriptable`.
aardvark179 Feb 12, 2026
7b81285
Update test 262 properties.
aardvark179 Mar 11, 2026
9ed50e2
Implement runtime semantics of new target.
aardvark179 Feb 12, 2026
8072143
Expose `new.target` in the language.
aardvark179 Mar 3, 2026
ff66b9c
Enable `new.target` in 262 tests.
aardvark179 Mar 11, 2026
2f0c95a
Fix new.target binding in arrow functions.
aardvark179 May 7, 2026
760f30e
Update 262 properties.
aardvark179 May 7, 2026
497614b
Expose $262 in shell for ease of exploratory testing.
aardvark179 Feb 19, 2026
66c23ec
Refactor away from `WithScope` for catching exceptions.
aardvark179 Mar 2, 2026
6edf538
Update 262 properties.
aardvark179 Mar 11, 2026
9020695
Fix up scoping in the compiler.
aardvark179 Mar 13, 2026
f8e328f
Update test 262 properties.
aardvark179 Mar 17, 2026
6b595d1
Improve spec compliance with strict mode block function declarations.
aardvark179 Mar 31, 2026
6c7fa44
Update 262 properties.
aardvark179 Mar 31, 2026
414f566
Separate out legacy behaviour for symbol definitions.
aardvark179 Apr 1, 2026
15eec8b
Add scope tests and some fixup round moving symbols between scopes.
aardvark179 May 5, 2026
f4fcf63
Fix spotless issues.
aardvark179 May 12, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -334,12 +334,11 @@ public Object dumbLambdaClassMethods(DumbLambdaState state) {

private static class DumbLambdaClass extends ScriptableObject {

private static Object noop(Context cx, VarScope scope, Scriptable thisObj, Object[] args) {
private static Object noop(Context cx, VarScope scope, Object thisObj, Object[] args) {
return Undefined.instance;
}

private static Object setValue(
Context cx, VarScope scope, Scriptable thisObj, Object[] args) {
private static Object setValue(Context cx, VarScope scope, Object thisObj, Object[] args) {
if (args.length < 1) {
throw ScriptRuntime.throwError(cx, scope, "Not enough args");
}
Expand All @@ -349,8 +348,7 @@ private static Object setValue(
return Undefined.instance;
}

private static Object getValue(
Context cx, VarScope scope, Scriptable thisObj, Object[] args) {
private static Object getValue(Context cx, VarScope scope, Object thisObj, Object[] args) {
DumbLambdaClass self =
LambdaConstructor.convertThisObject(thisObj, DumbLambdaClass.class);
return self.value;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import javax.script.ScriptContext;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.ScriptRuntime;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
import org.mozilla.javascript.TopLevel;
import org.mozilla.javascript.Undefined;
Expand Down Expand Up @@ -48,7 +47,7 @@ void register(Context cx, TopLevel scope, ScriptContext sc) {
ScriptableObject.DONTENUM | ScriptableObject.READONLY);
}

private static Object print(Context cx, VarScope scope, Scriptable thisObj, Object[] args) {
private static Object print(Context cx, VarScope scope, Object thisObj, Object[] args) {
try {
Builtins self = getSelf(scope);
for (Object arg : args) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -980,7 +980,7 @@ public static class StackFrame implements DebugFrame {
private VarScope scope;

/** The 'this' object. */
private Scriptable thisObj;
private Object thisObj;

/** Whether this frame represents a function (vs a top-level script). */
private boolean isFunction;
Expand All @@ -1006,7 +1006,7 @@ private StackFrame(Context cx, Dim dim, FunctionSource fsource, boolean isFuncti

/** Called when the stack frame is entered. */
@Override
public void onEnter(Context cx, VarScope scope, Scriptable thisObj, Object[] args) {
public void onEnter(Context cx, VarScope scope, Object thisObj, Object[] args) {
contextData.pushFrame(this);
this.scope = scope;
this.thisObj = thisObj;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,10 @@ public void init(Context cx) {
history = (NativeArray) cx.newArray(this, 0);
defineProperty("history", history, ScriptableObject.DONTENUM);

// Initialize Test262 support
Test262 proto262 = Test262.init(cx, this, Test262.RealmMode.STANDARD);
Test262.install(this, proto262, Test262.RealmMode.STANDARD);

initialized = true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import org.mozilla.javascript.Context;
import org.mozilla.javascript.GeneratedClassLoader;
import org.mozilla.javascript.Script;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.VarScope;

public class JavaPolicySecurity extends SecurityProxy {
Expand Down Expand Up @@ -205,7 +204,7 @@ public Object callWithDomain(
Context cx,
Callable callable,
VarScope scope,
Scriptable thisObj,
Object thisObj,
Object[] args) {
return doAction(securityDomain, () -> callable.call(cx, scope, thisObj, args));
}
Expand All @@ -216,7 +215,7 @@ public Object callWithDomain(
Context cx,
Script script,
VarScope scope,
Scriptable thisObj,
Object thisObj,
Object[] args) {
return doAction(securityDomain, () -> script.exec(cx, scope, thisObj));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

package org.mozilla.javascript.tools.shell;

import org.mozilla.javascript.Context;
import org.mozilla.javascript.ScopeObject;
import org.mozilla.javascript.ScriptRuntime;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
import org.mozilla.javascript.SymbolKey;
import org.mozilla.javascript.TopLevel;
import org.mozilla.javascript.Undefined;
import org.mozilla.javascript.VarScope;
import org.mozilla.javascript.typedarrays.NativeArrayBuffer;

/**
* Implements the $262 object required by the Test262 ECMAScript conformance test suite.
*
* <p>This class provides the host-defined functions specified by Test262 for testing ECMAScript
* implementations. It supports creating new realms, evaluating scripts, and accessing global
* objects.
*
* @see <a href="https://github.com/tc39/test262/blob/main/INTERPRETING.md#host-defined-functions">
* Test262 Host-Defined Functions</a>
*/
public class Test262 extends ScriptableObject {

/** Enum to control how realms are initialized. */
public enum RealmMode {
/** Uses initSafeStandardObjects - restricts Java access for sandboxing (used in tests) */
SAFE,
/** Uses initStandardObjects - full access to Java integration (used in shell) */
STANDARD
}

private RealmMode realmMode;

public Test262() {
super();
}

Test262(VarScope scope, Scriptable prototype, RealmMode mode) {
super(scope, prototype);
this.realmMode = mode;
}

/**
* Initialize the $262 prototype object with all Test262 host-defined functions.
*
* @param cx the current Context
* @param scope the scope to install the prototype in
* @param mode the realm mode (SAFE for tests, STANDARD for shell)
* @return the initialized $262 prototype
*/
public static Test262 init(Context cx, VarScope scope, RealmMode mode) {
Test262 proto = new Test262();
proto.realmMode = mode;
proto.setPrototype(getObjectPrototype(scope));
proto.setParentScope(scope);

proto.defineProperty(scope, "gc", 0, Test262::gc);
proto.defineProperty(scope, "createRealm", 0, Test262::createRealm);
proto.defineProperty(scope, "evalScript", 1, Test262::evalScript);
proto.defineProperty(scope, "detachArrayBuffer", 0, Test262::detachArrayBuffer);

proto.defineProperty(cx, scope, "global", Test262::getGlobal, null, DONTENUM | READONLY);
proto.defineProperty(cx, scope, "agent", Test262::getAgent, null, DONTENUM | READONLY);

proto.defineProperty(SymbolKey.TO_STRING_TAG, "__262__", DONTENUM | READONLY);

ScriptableObject.defineProperty(scope, "__262__", proto, DONTENUM);
return proto;
}

/**
* Install a $262 instance into a scope.
*
* @param scope the scope to install into
* @param parentScope the parent scope for the $262 instance
* @param mode the realm mode
* @return the installed $262 instance
*/
public static Test262 install(ScopeObject scope, Scriptable parentScope, RealmMode mode) {
Test262 instance = new Test262(scope, parentScope, mode);

scope.put("$262", scope, instance);
scope.setAttributes("$262", ScriptableObject.DONTENUM);

return instance;
}

private static Object gc(Context cx, VarScope scope, Object thisObj, Object[] args) {
System.gc();
return Undefined.instance;
}

public static Object evalScript(Context cx, VarScope scope, Object thisObj, Object[] args) {
if (args.length == 0) {
throw ScriptRuntime.throwError(cx, scope, "not enough args");
}
String source = Context.toString(args[0]);
return cx.evaluateString(scope, source, "<evalScript>", 1, null);
}

public static Object getGlobal(Scriptable scriptable) {
return ((TopLevel) scriptable.getParentScope()).getGlobalThis();
}

public static Test262 createRealm(Context cx, VarScope scope, Object thisObj, Object[] args) {
// Get the realm mode from the parent $262 instance
Test262 parent = (Test262) ScriptRuntime.toObject(scope, thisObj);
RealmMode mode = parent.realmMode;

// Create realm based on mode
TopLevel realm;
if (mode == RealmMode.SAFE) {
realm = cx.initSafeStandardObjects(new TopLevel());
} else {
realm = cx.initStandardObjects(new TopLevel());
}

return install(realm, ScriptRuntime.toObject(realm, thisObj).getPrototype(), mode);
}

public static Object detachArrayBuffer(
Context cx, VarScope scope, Object thisObj, Object[] args) {
Scriptable buf = ScriptRuntime.toObject(scope, args[0]);
if (buf instanceof NativeArrayBuffer) {
((NativeArrayBuffer) buf).detach();
}
return Undefined.instance;
}

public static Object getAgent(Scriptable scriptable) {
throw new UnsupportedOperationException("$262.agent property not yet implemented");
}

@Override
public String getClassName() {
return "__262__";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import org.mozilla.javascript.Function;
import org.mozilla.javascript.LambdaFunction;
import org.mozilla.javascript.ScriptRuntime;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
import org.mozilla.javascript.Undefined;
import org.mozilla.javascript.VarScope;
Expand All @@ -29,19 +28,14 @@ public class Timers {
public void install(VarScope scope) {
LambdaFunction setTimeout =
new LambdaFunction(
scope,
"setTimeout",
1,
(Context lcx, VarScope lscope, Scriptable thisObj, Object[] args) ->
setTimeout(args));
scope, "setTimeout", 1, (lcx, lscope, thisObj, args) -> setTimeout(args));
ScriptableObject.defineProperty(scope, "setTimeout", setTimeout, ScriptableObject.DONTENUM);
LambdaFunction clearTimeout =
new LambdaFunction(
scope,
"clearTimeout",
1,
(Context lcx, VarScope lscope, Scriptable thisObj, Object[] args) ->
clearTimeout(args));
(lcx, lscope, thisObj, args) -> clearTimeout(args));
ScriptableObject.defineProperty(
scope, "clearTimeout", clearTimeout, ScriptableObject.DONTENUM);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public final class XMLLibImpl extends XMLLib implements Serializable {
// EXPERIMENTAL Java interface
//

private static final long serialVersionUID = 1L;
private static final long serialVersionUID = -6301237868232033480L;

/** This experimental interface is undocumented. */
public static org.w3c.dom.Node toDomNode(Object xmlObject) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -765,7 +765,7 @@ private XMLList getPropertyList(XMLName name) {
}

private Object applyOrCall(
boolean isApply, Context cx, VarScope scope, Scriptable thisObj, Object[] args) {
boolean isApply, Context cx, VarScope scope, Object thisObj, Object[] args) {
String methodName = isApply ? "apply" : "call";
if (!(thisObj instanceof XMLList) || ((XMLList) thisObj).targetProperty == null)
throw ScriptRuntime.typeErrorById("msg.isnt.function", methodName);
Expand Down Expand Up @@ -797,7 +797,7 @@ public Scriptable getExtraMethodSource(Context cx) {
}

@Override
public Object call(Context cx, VarScope scope, Scriptable thisObj, Object[] args) {
public Object call(Context cx, VarScope scope, Object thisObj, Object[] args) {
// This XMLList is being called as a Function.
// Let's find the real Function object.
if (targetProperty == null) throw ScriptRuntime.notFunctionError(this);
Expand All @@ -812,7 +812,7 @@ public Object call(Context cx, VarScope scope, Scriptable thisObj, Object[] args
throw ScriptRuntime.typeErrorById("msg.incompat.call", methodName);
}
Object func = null;
Scriptable sobj = thisObj;
Scriptable sobj = ScriptRuntime.toObject(getDeclarationScope(), thisObj);

while (sobj instanceof XMLObject) {
XMLObject xmlObject = (XMLObject) sobj;
Expand All @@ -839,4 +839,9 @@ public Object call(Context cx, VarScope scope, Scriptable thisObj, Object[] args
public Scriptable construct(Context cx, VarScope scope, Object[] args) {
throw ScriptRuntime.typeErrorById("msg.not.ctor", "XMLList");
}

@Override
public Scriptable construct(Context cx, Object nt, VarScope s, Object thisObj, Object[] args) {
throw ScriptRuntime.typeErrorById("msg.not.ctor", "XMLList");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import org.w3c.dom.UserDataHandler;

class XmlNode implements Serializable {
private static final long serialVersionUID = 1L;
private static final long serialVersionUID = 7498300745525888082L;

private static final String XML_NAMESPACES_NAMESPACE_URI = "http://www.w3.org/2000/xmlns/";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,59 +31,6 @@ public interface LengthAccessor {
public long getLength(Context cx, Scriptable o);
}

/**
* Implements the methods "every", "filter", "forEach", "map", and "some" without using an
* IdFunctionObject.
*/
public static Object iterativeMethod(
Context cx,
IterativeOperation operation,
VarScope scope,
Object thisObj,
Object[] args,
LengthAccessor lengthAccessor) {
return iterativeMethod(cx, null, operation, scope, thisObj, args, lengthAccessor, true);
}

/**
* Implements the methods "every", "filter", "forEach", "map", and "some" using an
* IdFunctionObject.
*/
public static Object iterativeMethod(
Context cx,
IdFunctionObject fun,
IterativeOperation operation,
VarScope scope,
Object thisObj,
Object[] args,
LengthAccessor lengthAccessor) {
return iterativeMethod(cx, fun, operation, scope, thisObj, args, lengthAccessor, false);
}

private static Object iterativeMethod(
Context cx,
IdFunctionObject fun,
IterativeOperation operation,
VarScope scope,
Object thisObj,
Object[] args,
LengthAccessor lengthAccessor,
boolean skipCoercibleCheck) {
Scriptable o = ScriptRuntime.toObject(cx, scope, thisObj);

if (!skipCoercibleCheck) {
if (IterativeOperation.FIND == operation
|| IterativeOperation.FIND_INDEX == operation
|| IterativeOperation.FIND_LAST == operation
|| IterativeOperation.FIND_LAST_INDEX == operation) {
requireObjectCoercible(cx, o, fun);
}
}

long length = lengthAccessor.getLength(cx, o);
return coercibleIterativeMethod(cx, operation, scope, o, args, length);
}

public static Object iterativeMethod(
Context cx,
Object tag,
Expand Down
Loading