< prev index next >
src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CodeGenerator.java
Print this page
@@ -2484,15 +2484,10 @@
public boolean enterFunctionNode(final FunctionNode functionNode) {
return false;
}
@Override
- public boolean enterObjectNode(final ObjectNode objectNode) {
- return false;
- }
-
- @Override
public boolean enterDefault(final Node node) {
if (contains) {
return false;
}
if (node instanceof Optimistic && ((Optimistic)node).getProgramPoint() == pp) {
@@ -2560,11 +2555,12 @@
oc = new SpillObjectCreator(this, tuples);
} else {
oc = new FieldObjectCreator<Expression>(this, tuples) {
@Override
protected void loadValue(final Expression node, final Type type) {
- loadExpressionAsType(node, type);
+ // Use generic type in order to avoid conversion between object types
+ loadExpressionAsType(node, Type.generic(type));
}};
}
if (ranges != null) {
oc.createObject(method);
@@ -2576,14 +2572,11 @@
//if this is a rest of method and our continuation point was found as one of the values
//in the properties above, we need to reset the map to oc.getMap() in the continuation
//handler
if (restOfProperty) {
final ContinuationInfo ci = getContinuationInfo();
- // Can be set at most once for a single rest-of method
- assert ci.getObjectLiteralMap() == null;
- ci.setObjectLiteralMap(oc.getMap());
- ci.setObjectLiteralStackDepth(method.getStackSize());
+ ci.setObjectLiteralMap(method.getStackSize(), oc.getMap());
}
method.dup();
if (protoNode != null) {
loadExpressionAsObject(protoNode);
@@ -5307,14 +5300,12 @@
private int[] stackStoreSpec;
// Types of values loaded on the stack
private Type[] stackTypes;
// If non-null, this node should perform the requisite type conversion
private Type returnValueType;
- // If we are in the middle of an object literal initialization, we need to update the map
- private PropertyMap objectLiteralMap;
- // Object literal stack depth for object literal - not necessarily top if property is a tree
- private int objectLiteralStackDepth = -1;
+ // If we are in the middle of an object literal initialization, we need to update the property maps
+ private Map<Integer, PropertyMap> objectLiteralMaps;
// The line number at the continuation point
private int lineNumber;
// The active catch label, in case the continuation point is in a try/catch block
private Label catchLabel;
// The number of scopes that need to be popped before control is transferred to the catch label.
@@ -5362,24 +5353,19 @@
void setReturnValueType(final Type returnValueType) {
this.returnValueType = returnValueType;
}
- int getObjectLiteralStackDepth() {
- return objectLiteralStackDepth;
+ void setObjectLiteralMap(final int objectLiteralStackDepth, final PropertyMap objectLiteralMap) {
+ if (objectLiteralMaps == null) {
+ objectLiteralMaps = new HashMap<>();
}
-
- void setObjectLiteralStackDepth(final int objectLiteralStackDepth) {
- this.objectLiteralStackDepth = objectLiteralStackDepth;
- }
-
- PropertyMap getObjectLiteralMap() {
- return objectLiteralMap;
+ objectLiteralMaps.put(objectLiteralStackDepth, objectLiteralMap);
}
- void setObjectLiteralMap(final PropertyMap objectLiteralMap) {
- this.objectLiteralMap = objectLiteralMap;
+ PropertyMap getObjectLiteralMap(final int stackDepth) {
+ return objectLiteralMaps == null ? null : objectLiteralMaps.get(stackDepth);
}
@Override
public String toString() {
return "[localVariableTypes=" + targetLabel.getStack().getLocalVariableTypesCopy() + ", stackStoreSpec=" +
@@ -5465,33 +5451,32 @@
}
final int[] stackStoreSpec = ci.getStackStoreSpec();
final Type[] stackTypes = ci.getStackTypes();
final boolean isStackEmpty = stackStoreSpec.length == 0;
- boolean replacedObjectLiteralMap = false;
+ int replacedObjectLiteralMaps = 0;
if(!isStackEmpty) {
// Load arguments on the stack
- final int objectLiteralStackDepth = ci.getObjectLiteralStackDepth();
for(int i = 0; i < stackStoreSpec.length; ++i) {
final int slot = stackStoreSpec[i];
method.load(lvarTypes.get(slot), slot);
method.convert(stackTypes[i]);
// stack: s0=object literal being initialized
// change map of s0 so that the property we are initializing when we failed
// is now ci.returnValueType
- if (i == objectLiteralStackDepth) {
+ final PropertyMap map = ci.getObjectLiteralMap(i);
+ if (map != null) {
method.dup();
- assert ci.getObjectLiteralMap() != null;
assert ScriptObject.class.isAssignableFrom(method.peekType().getTypeClass()) : method.peekType().getTypeClass() + " is not a script object";
- loadConstant(ci.getObjectLiteralMap());
+ loadConstant(map);
method.invoke(ScriptObject.SET_MAP);
- replacedObjectLiteralMap = true;
+ replacedObjectLiteralMaps++;
}
}
}
- // Must have emitted the code for replacing the map of an object literal if we have a set object literal stack depth
- assert ci.getObjectLiteralStackDepth() == -1 || replacedObjectLiteralMap;
+ // Must have emitted the code for replacing all object literal maps
+ assert ci.objectLiteralMaps == null || ci.objectLiteralMaps.size() == replacedObjectLiteralMaps;
// Load RewriteException back.
method.load(rewriteExceptionType, lvarCount);
// Get rid of the stored reference
method.loadNull();
method.storeHidden(Type.OBJECT, lvarCount);
< prev index next >