Skip to content

Commit

Permalink
Merge branch 'mozilla:master' into nullable-parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
drubanovich-soti authored Jan 27, 2025
2 parents d3437ed + ab43fc9 commit abf36e7
Show file tree
Hide file tree
Showing 18 changed files with 635 additions and 392 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public void create() {
public Object embeddedInsert1Key(EmbeddedState state) {
Slot newSlot = null;
for (int i = 0; i < 100; i++) {
newSlot = state.emptyMap.modify(state.randomKeys[i], 0, 0);
newSlot = state.emptyMap.modify(null, state.randomKeys[i], 0, 0);
}
if (newSlot == null) {
throw new AssertionError();
Expand Down Expand Up @@ -109,7 +109,7 @@ public void create() {
public Object hashInsert1Key(HashState state) {
Slot newSlot = null;
for (int i = 0; i < 100; i++) {
newSlot = state.emptyMap.modify(state.randomKeys[i], 0, 0);
newSlot = state.emptyMap.modify(null, state.randomKeys[i], 0, 0);
}
if (newSlot == null) {
throw new AssertionError();
Expand Down Expand Up @@ -156,7 +156,7 @@ private static String makeRandomString() {
/** Insert a random key and value into the map */
private static String insertRandomEntry(SlotMap map) {
String key = makeRandomString();
Slot slot = map.modify(key, 0, 0);
Slot slot = map.modify(null, key, 0, 0);
slot.setValue(key, null, null);
return key;
}
Expand Down
3 changes: 3 additions & 0 deletions rhino-xml/src/main/java/module-info.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
module org.mozilla.javascript.xml {
exports org.mozilla.javascript.xmlimpl;

provides org.mozilla.javascript.xml.XMLLoader with
org.mozilla.javascript.xmlimpl.XMLLoaderImpl;

requires transitive org.mozilla.rhino;
requires transitive java.xml;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.mozilla.javascript.xmlimpl;

import org.mozilla.javascript.LazilyLoadedCtor;
import org.mozilla.javascript.ScriptableObject;
import org.mozilla.javascript.xml.XMLLib;
import org.mozilla.javascript.xml.XMLLoader;

public class XMLLoaderImpl implements XMLLoader {
@Override
public void load(ScriptableObject scope, boolean sealed) {
String implClass = XMLLibImpl.class.getName();
new LazilyLoadedCtor(scope, "XML", implClass, sealed, true);
new LazilyLoadedCtor(scope, "XMLList", implClass, sealed, true);
new LazilyLoadedCtor(scope, "Namespace", implClass, sealed, true);
new LazilyLoadedCtor(scope, "QName", implClass, sealed, true);
}

@Override
public XMLLib.Factory getFactory() {
return XMLLib.Factory.create(XMLLibImpl.class.getName());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
org.mozilla.javascript.xmlimpl.XMLLoaderImpl
6 changes: 6 additions & 0 deletions rhino/src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@
exports org.mozilla.javascript.typedarrays;
exports org.mozilla.javascript.xml;

uses org.mozilla.javascript.RegExpProxy;
uses org.mozilla.javascript.xml.XMLLoader;

provides org.mozilla.javascript.RegExpProxy with
org.mozilla.javascript.regexp.RegExpImpl;

requires java.compiler;
requires jdk.dynalink;
requires transitive java.desktop;
Expand Down
16 changes: 11 additions & 5 deletions rhino/src/main/java/org/mozilla/javascript/Context.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import org.mozilla.javascript.debug.DebuggableScript;
import org.mozilla.javascript.debug.Debugger;
import org.mozilla.javascript.xml.XMLLib;
import org.mozilla.javascript.xml.XMLLoader;

/**
* This class represents the runtime context of an executing script.
Expand Down Expand Up @@ -2318,11 +2319,19 @@ public boolean hasFeature(int featureIndex) {
* <p>The default implementation uses the implementation provided by this <code>Context</code>'s
* {@link ContextFactory}.
*
* <p>This is no longer used in E4X -- an implementation is only provided for backward
* compatibility.
*
* @return An XMLLib.Factory. Should not return <code>null</code> if {@link #FEATURE_E4X} is
* enabled. See {@link #hasFeature}.
*/
@Deprecated
public XMLLib.Factory getE4xImplementationFactory() {
return getFactory().getE4xImplementationFactory();
XMLLoader loader = ScriptRuntime.loadOneServiceImplementation(XMLLoader.class);
if (loader != null) {
return loader.getFactory();
}
return null;
}

/**
Expand Down Expand Up @@ -2682,10 +2691,7 @@ private static boolean frameMatches(StackTraceElement e) {

RegExpProxy getRegExpProxy() {
if (regExpProxy == null) {
Class<?> cl = Kit.classOrNull("org.mozilla.javascript.regexp.RegExpImpl");
if (cl != null) {
regExpProxy = (RegExpProxy) Kit.newInstanceOrNull(cl);
}
regExpProxy = ScriptRuntime.loadOneServiceImplementation(RegExpProxy.class);
}
return regExpProxy;
}
Expand Down
36 changes: 0 additions & 36 deletions rhino/src/main/java/org/mozilla/javascript/ContextFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -295,42 +295,6 @@ protected boolean hasFeature(Context cx, int featureIndex) {
throw new IllegalArgumentException(String.valueOf(featureIndex));
}

private static boolean isDom3Present() {
Class<?> nodeClass = Kit.classOrNull("org.w3c.dom.Node");
if (nodeClass == null) return false;
// Check to see whether DOM3 is present; use a new method defined in
// DOM3 that is vital to our implementation
try {
nodeClass.getMethod("getUserData", String.class);
return true;
} catch (NoSuchMethodException e) {
return false;
}
}

/**
* Provides a default {@link org.mozilla.javascript.xml.XMLLib.Factory XMLLib.Factory} to be
* used by the <code>Context</code> instances produced by this factory. See {@link
* Context#getE4xImplementationFactory} for details.
*
* <p>May return null, in which case E4X functionality is not supported in Rhino.
*
* <p>The default implementation now prefers the DOM3 E4X implementation.
*/
protected org.mozilla.javascript.xml.XMLLib.Factory getE4xImplementationFactory() {
// Must provide default implementation, rather than abstract method,
// so that past implementors of ContextFactory do not fail at runtime
// upon invocation of this method.
// Note that the default implementation returns null if we
// neither have XMLBeans nor a DOM3 implementation present.

if (isDom3Present()) {
return org.mozilla.javascript.xml.XMLLib.Factory.create(
"org.mozilla.javascript.xmlimpl.XMLLibImpl");
}
return null;
}

/**
* Create class loader for generated classes. This method creates an instance of the default
* implementation of {@link GeneratedClassLoader}. Rhino uses this interface to load generated
Expand Down
93 changes: 53 additions & 40 deletions rhino/src/main/java/org/mozilla/javascript/EmbeddedSlotMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ public Slot query(Object key, int index) {
* @param index index or 0 if slot holds property name.
*/
@Override
public Slot modify(Object key, int index, int attributes) {
public Slot modify(SlotMapOwner owner, Object key, int index, int attributes) {
final int indexOrHash = (key != null ? key.hashCode() : index);
Slot slot;

Expand All @@ -110,13 +110,12 @@ public Slot modify(Object key, int index, int attributes) {
}
}

// A new slot has to be inserted.
Slot newSlot = new Slot(key, index, attributes);
createNewSlot(newSlot);
createNewSlot(owner, newSlot);
return newSlot;
}

private void createNewSlot(Slot newSlot) {
private void createNewSlot(SlotMapOwner owner, Slot newSlot) {
if (count == 0) {
// Always throw away old slots if any on empty insert.
slots = new Slot[INITIAL_SLOT_SIZE];
Expand All @@ -125,6 +124,11 @@ private void createNewSlot(Slot newSlot) {
// Check if the table is not too full before inserting.
if (4 * (count + 1) > 3 * slots.length) {
// table size must be a power of 2 -- always grow by x2!
if (count > SlotMapContainer.LARGE_HASH_SIZE) {
var newMap = new HashSlotMap(this, newSlot);
owner.setMap(newMap);
return;
}
Slot[] newSlots = new Slot[slots.length * 2];
copyTable(slots, newSlots);
slots = newSlots;
Expand All @@ -134,7 +138,8 @@ private void createNewSlot(Slot newSlot) {
}

@Override
public <S extends Slot> S compute(Object key, int index, SlotComputer<S> c) {
public <S extends Slot> S compute(
SlotMapOwner owner, Object key, int index, SlotComputer<S> c) {
final int indexOrHash = (key != null ? key.hashCode() : index);

if (slots != null) {
Expand All @@ -148,54 +153,62 @@ public <S extends Slot> S compute(Object key, int index, SlotComputer<S> c) {
prev = slot;
}
if (slot != null) {
// Modify or remove existing slot
S newSlot = c.compute(key, index, slot);
if (newSlot == null) {
// Need to delete this slot actually
removeSlot(slot, prev, slotIndex, key);
} else if (!Objects.equals(slot, newSlot)) {
// Replace slot in hash table
if (prev == slot) {
slots[slotIndex] = newSlot;
} else {
prev.next = newSlot;
}
newSlot.next = slot.next;
// Replace new slot in linked list, keeping same order
if (slot == firstAdded) {
firstAdded = newSlot;
} else {
Slot ps = firstAdded;
while ((ps != null) && (ps.orderedNext != slot)) {
ps = ps.orderedNext;
}
if (ps != null) {
ps.orderedNext = newSlot;
}
}
newSlot.orderedNext = slot.orderedNext;
if (slot == lastAdded) {
lastAdded = newSlot;
}
}
return newSlot;
return computeExisting(key, index, c, slot, prev, slotIndex);
}
}
return computeNew(owner, key, index, c);
}

// If we get here, we know we are potentially adding a new slot
private <S extends Slot> S computeNew(
SlotMapOwner owner, Object key, int index, SlotComputer<S> c) {
S newSlot = c.compute(key, index, null);
if (newSlot != null) {
createNewSlot(newSlot);
createNewSlot(owner, newSlot);
}
return newSlot;
}

private <S extends Slot> S computeExisting(
Object key, int index, SlotComputer<S> c, Slot slot, Slot prev, int slotIndex) {
// Modify or remove existing slot
S newSlot = c.compute(key, index, slot);
if (newSlot == null) {
// Need to delete this slot actually
removeSlot(slot, prev, slotIndex, key);
} else if (!Objects.equals(slot, newSlot)) {
// Replace slot in hash table
if (prev == slot) {
slots[slotIndex] = newSlot;
} else {
prev.next = newSlot;
}
newSlot.next = slot.next;
// Replace new slot in linked list, keeping same order
if (slot == firstAdded) {
firstAdded = newSlot;
} else {
Slot ps = firstAdded;
while ((ps != null) && (ps.orderedNext != slot)) {
ps = ps.orderedNext;
}
if (ps != null) {
ps.orderedNext = newSlot;
}
}
newSlot.orderedNext = slot.orderedNext;
if (slot == lastAdded) {
lastAdded = newSlot;
}
}
return newSlot;
}

@Override
public void add(Slot newSlot) {
public void add(SlotMapOwner owner, Slot newSlot) {
if (slots == null) {
slots = new Slot[INITIAL_SLOT_SIZE];
}
insertNewSlot(newSlot);
createNewSlot(owner, newSlot);
}

private void insertNewSlot(Slot newSlot) {
Expand Down
17 changes: 13 additions & 4 deletions rhino/src/main/java/org/mozilla/javascript/HashSlotMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,18 @@ public HashSlotMap() {
public HashSlotMap(SlotMap oldMap) {
map = new LinkedHashMap<>(oldMap.size());
for (Slot n : oldMap) {
add(n.copySlot());
add(null, n.copySlot());
}
}

public HashSlotMap(SlotMap oldMap, Slot newSlot) {
map = new LinkedHashMap<>(oldMap.dirtySize() + 1);
for (Slot n : oldMap) {
add(null, n.copySlot());
}
add(null, newSlot);
}

@Override
public int size() {
return map.size();
Expand All @@ -47,21 +55,22 @@ public Slot query(Object key, int index) {
}

@Override
public Slot modify(Object key, int index, int attributes) {
public Slot modify(SlotMapOwner owner, Object key, int index, int attributes) {
Object name = makeKey(key, index);
return map.computeIfAbsent(name, n -> new Slot(key, index, attributes));
}

@SuppressWarnings("unchecked")
@Override
public <S extends Slot> S compute(Object key, int index, SlotComputer<S> c) {
public <S extends Slot> S compute(
SlotMapOwner owner, Object key, int index, SlotComputer<S> c) {
Object name = makeKey(key, index);
Slot ret = map.compute(name, (n, existing) -> c.compute(key, index, existing));
return (S) ret;
}

@Override
public void add(Slot newSlot) {
public void add(SlotMapOwner owner, Slot newSlot) {
Object name = makeKey(newSlot);
map.put(name, newSlot);
}
Expand Down
Loading

0 comments on commit abf36e7

Please sign in to comment.