8144020: Remove long as an internal numeric type

Reviewed-by: attila, sundar, lagergren
This commit is contained in:
Hannes Wallnöfer 2015-12-14 14:27:46 +01:00
parent 64634dc9a4
commit 67fe9c8efe
72 changed files with 475 additions and 2407 deletions

View File

@ -314,7 +314,7 @@
classpath="${run.test.classpath}"
fork="true"
dir=".">
<jvmarg line="${ext.class.path}"/>
<jvmarg line="${boot.class.path}"/>
<jvmarg line="${run.test.jvmargs.octane} -Xms${run.test.xms} -Xmx${run.test.xmx}"/>
<!-- pass on all properties prefixed with 'nashorn' to the runtime -->
<syspropertyset>
@ -387,7 +387,7 @@
classpath="${run.test.classpath}"
fork="true"
dir=".">
<jvmarg line="${ext.class.path}"/>
<jvmarg line="${boot.class.path}"/>
<jvmarg line="${run.test.jvmargs} -Xmx${run.test.xmx}"/>
<arg value="-timezone=PST"/>
<arg value="--class-cache-size=50"/>

View File

@ -188,8 +188,6 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
private static final Call ENSURE_INT = CompilerConstants.staticCallNoLookup(OptimisticReturnFilters.class,
"ensureInt", int.class, Object.class, int.class);
private static final Call ENSURE_LONG = CompilerConstants.staticCallNoLookup(OptimisticReturnFilters.class,
"ensureLong", long.class, Object.class, int.class);
private static final Call ENSURE_NUMBER = CompilerConstants.staticCallNoLookup(OptimisticReturnFilters.class,
"ensureNumber", double.class, Object.class, int.class);
@ -1726,7 +1724,7 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
enterStatement(expressionStatement);
loadAndDiscard(expressionStatement.getExpression());
assert method.getStackSize() == 0;
assert method.getStackSize() == 0 : "stack not empty in " + expressionStatement;
return false;
}
@ -2241,7 +2239,7 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
* @param arrayType the type of the array, e.g. ARRAY_NUMBER or ARRAY_OBJECT
*/
private void loadArray(final ArrayLiteralNode arrayLiteralNode, final ArrayType arrayType) {
assert arrayType == Type.INT_ARRAY || arrayType == Type.LONG_ARRAY || arrayType == Type.NUMBER_ARRAY || arrayType == Type.OBJECT_ARRAY;
assert arrayType == Type.INT_ARRAY || arrayType == Type.NUMBER_ARRAY || arrayType == Type.OBJECT_ARRAY;
final Expression[] nodes = arrayLiteralNode.getValue();
final Object presets = arrayLiteralNode.getPresets();
@ -2389,20 +2387,9 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
method.convert(Type.OBJECT);
} else if(!resultBounds.canBeNarrowerThan(Type.NUMBER)) {
method.load(((Integer)value).doubleValue());
} else if(!resultBounds.canBeNarrowerThan(Type.LONG)) {
method.load(((Integer)value).longValue());
} else {
method.load((Integer)value);
}
} else if (value instanceof Long) {
if(!resultBounds.canBeNarrowerThan(Type.OBJECT)) {
method.load((Long)value);
method.convert(Type.OBJECT);
} else if(!resultBounds.canBeNarrowerThan(Type.NUMBER)) {
method.load(((Long)value).doubleValue());
} else {
method.load((Long)value);
}
} else if (value instanceof Double) {
if(!resultBounds.canBeNarrowerThan(Type.OBJECT)) {
method.load((Double)value);
@ -3650,8 +3637,6 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
private void loadMinusOne() {
if (type.isInteger()) {
method.load(isIncrement ? 1 : -1);
} else if (type.isLong()) {
method.load(isIncrement ? 1L : -1L);
} else {
method.load(isIncrement ? 1.0 : -1.0);
}
@ -4033,23 +4018,66 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
}
private void loadASSIGN_SHR(final BinaryNode binaryNode) {
new BinarySelfAssignment(binaryNode) {
new SelfModifyingStore<BinaryNode>(binaryNode, binaryNode.lhs()) {
@Override
protected void op() {
doSHR();
}
protected void evaluate() {
new OptimisticOperation(assignNode, new TypeBounds(Type.INT, Type.NUMBER)) {
@Override
void loadStack() {
assert assignNode.getWidestOperandType() == Type.INT;
if (isRhsZero(binaryNode)) {
loadExpressionAsType(binaryNode.lhs(), Type.INT);
} else {
loadBinaryOperands(binaryNode.lhs(), binaryNode.rhs(), TypeBounds.INT, true, false);
method.shr();
}
}
@Override
void consumeStack() {
if (isOptimistic(binaryNode)) {
toUint32Optimistic(binaryNode.getProgramPoint());
} else {
toUint32Double();
}
}
}.emit(getOptimisticIgnoreCountForSelfModifyingExpression(binaryNode.lhs()));
method.convert(assignNode.getType());
}
}.store();
}
private void doSHR() {
// TODO: make SHR optimistic
method.shr();
toUint();
private void doSHR(final BinaryNode binaryNode) {
new OptimisticOperation(binaryNode, new TypeBounds(Type.INT, Type.NUMBER)) {
@Override
void loadStack() {
if (isRhsZero(binaryNode)) {
loadExpressionAsType(binaryNode.lhs(), Type.INT);
} else {
loadBinaryOperands(binaryNode);
method.shr();
}
}
@Override
void consumeStack() {
if (isOptimistic(binaryNode)) {
toUint32Optimistic(binaryNode.getProgramPoint());
} else {
toUint32Double();
}
}
}.emit();
}
private void toUint() {
JSType.TO_UINT32_I.invoke(method);
private void toUint32Optimistic(final int programPoint) {
method.load(programPoint);
JSType.TO_UINT32_OPTIMISTIC.invoke(method);
}
private void toUint32Double() {
JSType.TO_UINT32_DOUBLE.invoke(method);
}
private void loadASSIGN_SUB(final BinaryNode binaryNode) {
@ -4087,7 +4115,7 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
// Non-optimistic, non-FP subtraction or multiplication. Allow them to overflow.
operandBounds = new TypeBounds(Type.narrowest(node.getWidestOperandType(),
numericBounds.widest), Type.NUMBER);
forceConversionSeparation = node.getWidestOperationType().narrowerThan(numericBounds.widest);
forceConversionSeparation = true;
}
}
loadBinaryOperands(node.lhs(), node.rhs(), operandBounds, false, forceConversionSeparation);
@ -4189,14 +4217,7 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
}
private void loadSHR(final BinaryNode binaryNode) {
// Optimize x >>> 0 to (uint)x
if (isRhsZero(binaryNode)) {
loadExpressionAsType(binaryNode.lhs(), Type.INT);
toUint();
} else {
loadBinaryOperands(binaryNode);
doSHR();
}
doSHR(binaryNode);
}
private void loadSUB(final BinaryNode binaryNode, final TypeBounds resultBounds) {
@ -4467,6 +4488,7 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
}
} else {
final Type storeType = assignNode.getType();
assert storeType != Type.LONG;
if (symbol.hasSlotFor(storeType)) {
// Only emit a convert for a store known to be live; converts for dead stores can
// give us an unnecessary ClassCastException.
@ -4851,8 +4873,6 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
method.load(optimistic.getProgramPoint());
if(optimisticType.isInteger()) {
method.invoke(ENSURE_INT);
} else if(optimisticType.isLong()) {
method.invoke(ENSURE_LONG);
} else if(optimisticType.isNumber()) {
method.invoke(ENSURE_NUMBER);
} else {

View File

@ -167,8 +167,7 @@ public abstract class FieldObjectCreator<T> extends ObjectCreator<T> {
assert fieldName.equals(getFieldName(fieldIndex, PRIMITIVE_FIELD_TYPE)) || fieldType.isObject() : key + " object keys must store to L*-fields";
assert fieldName.equals(getFieldName(fieldIndex, Type.OBJECT)) || fieldType.isPrimitive() : key + " primitive keys must store to J*-fields";
loadTuple(method, tuple);
loadTuple(method, tuple, true);
method.putField(fieldClass, fieldName, fieldDesc);
}
@ -180,11 +179,7 @@ public abstract class FieldObjectCreator<T> extends ObjectCreator<T> {
* @param tuple Tuple to store.
*/
private void putSlot(final MethodEmitter method, final long index, final MapTuple<T> tuple) {
if (JSType.isRepresentableAsInt(index)) {
method.load((int)index);
} else {
method.load(index);
}
loadIndex(method, index);
loadTuple(method, tuple, false); //we don't pack array like objects
method.dynamicSetIndex(callSiteFlags);
}

View File

@ -307,9 +307,7 @@ final class FoldConstants extends SimpleNodeVisitor implements Loggable {
final Type widest = Type.widest(lhs.getType(), rhs.getType());
boolean isInteger = widest.isInteger();
boolean isLong = widest.isLong();
double value;
final double value;
switch (parent.tokenType()) {
case DIV:
@ -336,7 +334,8 @@ final class FoldConstants extends SimpleNodeVisitor implements Loggable {
value = lhs.getNumber() - rhs.getNumber();
break;
case SHR:
return LiteralNode.newInstance(token, finish, JSType.toUint32(lhs.getInt32() >>> rhs.getInt32()));
final long result = JSType.toUint32(lhs.getInt32() >>> rhs.getInt32());
return LiteralNode.newInstance(token, finish, JSType.isRepresentableAsInt(result) ? (int) result : (double) result);
case SAR:
return LiteralNode.newInstance(token, finish, lhs.getInt32() >> rhs.getInt32());
case SHL:
@ -368,12 +367,9 @@ final class FoldConstants extends SimpleNodeVisitor implements Loggable {
}
isInteger &= JSType.isStrictlyRepresentableAsInt(value);
isLong &= JSType.isStrictlyRepresentableAsLong(value);
if (isInteger) {
return LiteralNode.newInstance(token, finish, (int)value);
} else if (isLong) {
return LiteralNode.newInstance(token, finish, (long)value);
}
return LiteralNode.newInstance(token, finish, value);

View File

@ -131,7 +131,6 @@ final class LocalVariableTypesCalculator extends SimpleNodeVisitor {
UNDEFINED(Type.UNDEFINED),
BOOLEAN(Type.BOOLEAN),
INT(Type.INT),
LONG(Type.LONG),
DOUBLE(Type.NUMBER),
OBJECT(Type.OBJECT);
@ -272,12 +271,9 @@ final class LocalVariableTypesCalculator extends SimpleNodeVisitor {
}
private static class SymbolConversions {
private static final byte I2L = 1 << 0;
private static final byte I2D = 1 << 1;
private static final byte I2O = 1 << 2;
private static final byte L2D = 1 << 3;
private static final byte L2O = 1 << 4;
private static final byte D2O = 1 << 5;
private static final byte I2D = 1 << 0;
private static final byte I2O = 1 << 1;
private static final byte D2O = 1 << 2;
private byte conversions;
@ -288,9 +284,6 @@ final class LocalVariableTypesCalculator extends SimpleNodeVisitor {
case INT:
case BOOLEAN:
switch (to) {
case LONG:
recordConversion(I2L);
return;
case DOUBLE:
recordConversion(I2D);
return;
@ -301,18 +294,6 @@ final class LocalVariableTypesCalculator extends SimpleNodeVisitor {
illegalConversion(from, to);
return;
}
case LONG:
switch (to) {
case DOUBLE:
recordConversion(L2D);
return;
case OBJECT:
recordConversion(L2O);
return;
default:
illegalConversion(from, to);
return;
}
case DOUBLE:
if(to == LvarType.OBJECT) {
recordConversion(D2O);
@ -340,26 +321,15 @@ final class LocalVariableTypesCalculator extends SimpleNodeVisitor {
if(hasConversion(D2O)) {
symbol.setHasSlotFor(Type.NUMBER);
}
if(hasConversion(L2O)) {
symbol.setHasSlotFor(Type.LONG);
}
if(hasConversion(I2O)) {
symbol.setHasSlotFor(Type.INT);
}
}
if(symbol.hasSlotFor(Type.NUMBER)) {
if(hasConversion(L2D)) {
symbol.setHasSlotFor(Type.LONG);
}
if(hasConversion(I2D)) {
symbol.setHasSlotFor(Type.INT);
}
}
if(symbol.hasSlotFor(Type.LONG)) {
if(hasConversion(I2L)) {
symbol.setHasSlotFor(Type.INT);
}
}
}
}
@ -378,7 +348,7 @@ final class LocalVariableTypesCalculator extends SimpleNodeVisitor {
if(lvarType != null) {
return lvarType;
}
assert type.isObject();
assert type.isObject() : "Unsupported primitive type: " + type;
return LvarType.OBJECT;
}
private static LvarType widestLvarType(final LvarType t1, final LvarType t2) {

View File

@ -544,7 +544,6 @@ public class MethodEmitter {
} else {
assert false : type + " cannot be packed!";
}
//all others are nops, objects aren't packed
}
/**

View File

@ -41,7 +41,6 @@ import static jdk.nashorn.internal.runtime.JSType.CONVERT_OBJECT_OPTIMISTIC;
import static jdk.nashorn.internal.runtime.JSType.GET_UNDEFINED;
import static jdk.nashorn.internal.runtime.JSType.TYPE_DOUBLE_INDEX;
import static jdk.nashorn.internal.runtime.JSType.TYPE_INT_INDEX;
import static jdk.nashorn.internal.runtime.JSType.TYPE_LONG_INDEX;
import static jdk.nashorn.internal.runtime.JSType.TYPE_OBJECT_INDEX;
import static jdk.nashorn.internal.runtime.JSType.TYPE_UNDEFINED_INDEX;
import static jdk.nashorn.internal.runtime.JSType.getAccessorTypeIndex;
@ -535,8 +534,6 @@ public final class ObjectClassGenerator implements Loggable {
switch (getAccessorTypeIndex(forType)) {
case TYPE_INT_INDEX:
return MH.explicitCastArguments(primitiveGetter, primitiveGetter.type().changeReturnType(int.class));
case TYPE_LONG_INDEX:
return primitiveGetter;
case TYPE_DOUBLE_INDEX:
return MH.filterReturnValue(primitiveGetter, UNPACK_DOUBLE);
case TYPE_OBJECT_INDEX:
@ -623,7 +620,7 @@ public final class ObjectClassGenerator implements Loggable {
}
assert !isOptimistic;
//freely coerce the result to whatever you asked for, this is e.g. Object->int for a & b
// freely coerce the result to whatever you asked for, this is e.g. Object->int for a & b
final MethodHandle tgetter = getterForType(forType, primitiveGetter, objectGetter);
if (fti == TYPE_OBJECT_INDEX) {
if (fti != ti) {
@ -638,22 +635,10 @@ public final class ObjectClassGenerator implements Loggable {
case TYPE_INT_INDEX: {
return MH.asType(tgetter, tgetterType.changeReturnType(type));
}
case TYPE_LONG_INDEX:
switch (ti) {
case TYPE_INT_INDEX:
//get int while an int, truncating cast of long value
return MH.filterReturnValue(tgetter, JSType.TO_INT32_L.methodHandle);
case TYPE_LONG_INDEX:
return primitiveGetter;
default:
return MH.asType(tgetter, tgetterType.changeReturnType(type));
}
case TYPE_DOUBLE_INDEX:
switch (ti) {
case TYPE_INT_INDEX:
return MH.filterReturnValue(tgetter, JSType.TO_INT32_D.methodHandle);
case TYPE_LONG_INDEX:
return MH.explicitCastArguments(tgetter, tgetterType.changeReturnType(type));
case TYPE_DOUBLE_INDEX:
assert tgetterType.returnType() == double.class;
return tgetter;
@ -734,12 +719,9 @@ public final class ObjectClassGenerator implements Loggable {
switch (fti) {
case TYPE_INT_INDEX:
case TYPE_LONG_INDEX:
switch (ti) {
case TYPE_INT_INDEX:
return MH.asType(primitiveSetter, pmt.changeParameterType(1, int.class));
case TYPE_LONG_INDEX:
return primitiveSetter;
case TYPE_DOUBLE_INDEX:
return MH.filterArguments(primitiveSetter, 1, PACK_DOUBLE);
default:

View File

@ -29,6 +29,7 @@ import static jdk.nashorn.internal.codegen.CompilerConstants.SCOPE;
import java.util.List;
import jdk.nashorn.internal.codegen.types.Type;
import jdk.nashorn.internal.runtime.JSType;
import jdk.nashorn.internal.runtime.PropertyMap;
import jdk.nashorn.internal.runtime.ScriptObject;
@ -156,15 +157,15 @@ public abstract class ObjectCreator<T> implements CodeGenerator.SplitLiteralCrea
MethodEmitter loadTuple(final MethodEmitter method, final MapTuple<T> tuple, final boolean pack) {
loadValue(tuple.value, tuple.type);
if (pack && codegen.useDualFields() && tuple.isPrimitive()) {
method.pack();
} else {
if (!codegen.useDualFields() || !tuple.isPrimitive()) {
method.convert(Type.OBJECT);
} else if (pack) {
method.pack();
}
return method;
}
MethodEmitter loadTuple(final MethodEmitter method, final MapTuple<T> tuple) {
return loadTuple(method, tuple, true);
MethodEmitter loadIndex(final MethodEmitter method, final long index) {
return JSType.isRepresentableAsInt(index) ? method.load((int) index) : method.load((double) index);
}
}

View File

@ -109,8 +109,6 @@ public final class SpillObjectCreator extends ObjectCreator<Expression> {
//avoid blowing up the array if we can
if (constantValue instanceof Integer) {
arrayData = arrayData.set(index, ((Integer)constantValue).intValue(), false);
} else if (constantValue instanceof Long) {
arrayData = arrayData.set(index, ((Long)constantValue).longValue(), false);
} else if (constantValue instanceof Double) {
arrayData = arrayData.set(index, ((Double)constantValue).doubleValue(), false);
} else {
@ -169,13 +167,13 @@ public final class SpillObjectCreator extends ObjectCreator<Expression> {
final int index = ArrayIndex.getArrayIndex(tuple.key);
assert ArrayIndex.isValidArrayIndex(index);
method.dup();
method.load(ArrayIndex.toLongIndex(index));
loadTuple(method, tuple);
loadIndex(method, ArrayIndex.toLongIndex(index));
loadTuple(method, tuple, false);
method.dynamicSetIndex(callSiteFlags);
} else {
assert property.getKey() instanceof String; // symbol keys not yet supported in object literals
method.dup();
loadTuple(method, tuple);
loadTuple(method, tuple, false);
method.dynamicSet((String) property.getKey(), codegen.getCallSiteFlags(), false);
}
}

View File

@ -239,7 +239,7 @@ final class TypeEvaluator {
// currently deoptimize all the way to Object.
return Type.OBJECT;
}
assert returnType == Type.INT || returnType == Type.LONG || returnType == Type.NUMBER || returnType == Type.OBJECT;
assert returnType == Type.INT || returnType == Type.NUMBER || returnType == Type.OBJECT;
return returnType;
}
}

View File

@ -72,7 +72,7 @@ class IntType extends BitwiseType {
@Override
public Type nextWider() {
return LONG;
return NUMBER;
}
@Override

View File

@ -28,20 +28,11 @@ package jdk.nashorn.internal.codegen.types;
import static jdk.internal.org.objectweb.asm.Opcodes.L2D;
import static jdk.internal.org.objectweb.asm.Opcodes.L2I;
import static jdk.internal.org.objectweb.asm.Opcodes.LADD;
import static jdk.internal.org.objectweb.asm.Opcodes.LAND;
import static jdk.internal.org.objectweb.asm.Opcodes.LCMP;
import static jdk.internal.org.objectweb.asm.Opcodes.LCONST_0;
import static jdk.internal.org.objectweb.asm.Opcodes.LCONST_1;
import static jdk.internal.org.objectweb.asm.Opcodes.LLOAD;
import static jdk.internal.org.objectweb.asm.Opcodes.LMUL;
import static jdk.internal.org.objectweb.asm.Opcodes.LOR;
import static jdk.internal.org.objectweb.asm.Opcodes.LRETURN;
import static jdk.internal.org.objectweb.asm.Opcodes.LSHL;
import static jdk.internal.org.objectweb.asm.Opcodes.LSHR;
import static jdk.internal.org.objectweb.asm.Opcodes.LSTORE;
import static jdk.internal.org.objectweb.asm.Opcodes.LSUB;
import static jdk.internal.org.objectweb.asm.Opcodes.LUSHR;
import static jdk.internal.org.objectweb.asm.Opcodes.LXOR;
import static jdk.nashorn.internal.codegen.CompilerConstants.staticCallNoLookup;
import static jdk.nashorn.internal.runtime.JSType.UNDEFINED_LONG;
import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT;
@ -53,7 +44,7 @@ import jdk.nashorn.internal.runtime.JSType;
/**
* Type class: LONG
*/
class LongType extends BitwiseType {
class LongType extends Type {
private static final long serialVersionUID = 1L;
private static final CompilerConstants.Call VALUE_OF = staticCallNoLookup(Long.class, "valueOf", Long.class, long.class);
@ -81,12 +72,6 @@ class LongType extends BitwiseType {
return 'J';
}
@Override
public Type cmp(final MethodVisitor method) {
method.visitInsn(LCMP);
return INT;
}
@Override
public Type load(final MethodVisitor method, final int slot) {
assert slot != -1;
@ -148,88 +133,6 @@ class LongType extends BitwiseType {
return LONG;
}
@Override
public Type sub(final MethodVisitor method, final int programPoint) {
if(programPoint == INVALID_PROGRAM_POINT) {
method.visitInsn(LSUB);
} else {
method.visitInvokeDynamicInsn("lsub", "(JJ)J", MATHBOOTSTRAP, programPoint);
}
return LONG;
}
@Override
public Type mul(final MethodVisitor method, final int programPoint) {
if(programPoint == INVALID_PROGRAM_POINT) {
method.visitInsn(LMUL);
} else {
method.visitInvokeDynamicInsn("lmul", "(JJ)J", MATHBOOTSTRAP, programPoint);
}
return LONG;
}
@Override
public Type div(final MethodVisitor method, final int programPoint) {
if (programPoint == INVALID_PROGRAM_POINT) {
JSType.DIV_ZERO_LONG.invoke(method);
} else {
method.visitInvokeDynamicInsn("ldiv", "(JJ)J", MATHBOOTSTRAP, programPoint);
}
return LONG;
}
@Override
public Type rem(final MethodVisitor method, final int programPoint) {
if (programPoint == INVALID_PROGRAM_POINT) {
JSType.REM_ZERO_LONG.invoke(method);
} else {
method.visitInvokeDynamicInsn("lrem", "(JJ)J", MATHBOOTSTRAP, programPoint);
}
return LONG;
}
@Override
public Type shr(final MethodVisitor method) {
method.visitInsn(LUSHR);
return LONG;
}
@Override
public Type sar(final MethodVisitor method) {
method.visitInsn(LSHR);
return LONG;
}
@Override
public Type shl(final MethodVisitor method) {
method.visitInsn(LSHL);
return LONG;
}
@Override
public Type and(final MethodVisitor method) {
method.visitInsn(LAND);
return LONG;
}
@Override
public Type or(final MethodVisitor method) {
method.visitInsn(LOR);
return LONG;
}
@Override
public Type xor(final MethodVisitor method) {
method.visitInsn(LXOR);
return LONG;
}
@Override
public Type neg(final MethodVisitor method, final int programPoint) {
method.visitInvokeDynamicInsn("lneg", "(J)J", MATHBOOTSTRAP, programPoint);
return LONG;
}
@Override
public void _return(final MethodVisitor method) {
method.visitInsn(LRETURN);
@ -246,9 +149,4 @@ class LongType extends BitwiseType {
method.visitInsn(LCONST_0);
return LONG;
}
@Override
public Type cmp(final MethodVisitor method, final boolean isCmpG) {
return cmp(method);
}
}

View File

@ -914,7 +914,7 @@ public abstract class Type implements Comparable<Type>, BytecodeOps, Serializabl
/**
* This is the long singleton, used for all long types
*/
public static final BitwiseType LONG = putInCache(new LongType());
public static final Type LONG = putInCache(new LongType());
/**
* A string singleton

View File

@ -70,7 +70,9 @@ public final class BinaryNode extends Expression implements Assignment<Expressio
TokenType.ASSIGN_DIV,
TokenType.ASSIGN_MOD,
TokenType.ASSIGN_MUL,
TokenType.ASSIGN_SUB
TokenType.ASSIGN_SUB,
TokenType.SHR,
TokenType.ASSIGN_SHR
})));
/**
@ -196,9 +198,7 @@ public final class BinaryNode extends Expression implements Assignment<Expressio
return Type.CHARSEQUENCE;
}
final Type widestOperandType = Type.widest(undefinedToNumber(booleanToInt(lhsType)), undefinedToNumber(booleanToInt(rhsType)));
if(widestOperandType == Type.INT) {
return Type.LONG;
} else if (widestOperandType.isNumeric()) {
if (widestOperandType.isNumeric()) {
return Type.NUMBER;
}
// We pretty much can't know what it will be statically. Must presume OBJECT conservatively, as we can end
@ -210,7 +210,7 @@ public final class BinaryNode extends Expression implements Assignment<Expressio
}
case SHR:
case ASSIGN_SHR:
return Type.LONG;
return Type.NUMBER;
case ASSIGN_SAR:
case ASSIGN_SHL:
case BIT_AND:
@ -239,10 +239,6 @@ public final class BinaryNode extends Expression implements Assignment<Expressio
if(lhsType == Type.BOOLEAN && rhsType == Type.BOOLEAN) {
return Type.INT;
}
final Type widestOperandType = Type.widest(booleanToInt(lhsType), booleanToInt(rhsType));
if(widestOperandType == Type.INT) {
return Type.LONG;
}
return Type.NUMBER;
}
case VOID: {
@ -565,6 +561,9 @@ public final class BinaryNode extends Expression implements Assignment<Expressio
if(type == null) {
return widest;
}
if (tokenType() == TokenType.ASSIGN_SHR || tokenType() == TokenType.SHR) {
return type;
}
return Type.narrowest(widest, Type.widest(type, Type.widest(lhs.getType(), rhs.getType())));
}

View File

@ -386,8 +386,6 @@ public abstract class LiteralNode<T> extends Expression implements PropertyKey {
private static Type numberGetType(final Number number) {
if (number instanceof Integer) {
return Type.INT;
} else if (number instanceof Long) {
return Type.LONG;
} else if (number instanceof Double) {
return Type.NUMBER;
} else {
@ -418,6 +416,7 @@ public abstract class LiteralNode<T> extends Expression implements PropertyKey {
* @return the new literal node
*/
public static LiteralNode<Number> newInstance(final long token, final int finish, final Number value) {
assert !(value instanceof Long);
return new NumberLiteralNode(token, finish, value);
}
@ -776,8 +775,6 @@ public abstract class LiteralNode<T> extends Expression implements PropertyKey {
assert !elementType.isUnknown();
if (elementType.isInteger()) {
return presetIntArray(value, postsets);
} else if (elementType.isLong()) {
return presetLongArray(value, postsets);
} else if (elementType.isNumeric()) {
return presetDoubleArray(value, postsets);
} else {
@ -847,8 +844,6 @@ public abstract class LiteralNode<T> extends Expression implements PropertyKey {
private static ArrayType getArrayType(final Type elementType) {
if (elementType.isInteger()) {
return Type.INT_ARRAY;
} else if (elementType.isLong()) {
return Type.LONG_ARRAY;
} else if (elementType.isNumeric()) {
return Type.NUMBER_ARRAY;
} else {
@ -883,8 +878,6 @@ public abstract class LiteralNode<T> extends Expression implements PropertyKey {
private boolean presetsMatchElementType() {
if (elementType == Type.INT) {
return presets instanceof int[];
} else if (elementType == Type.LONG) {
return presets instanceof long[];
} else if (elementType == Type.NUMBER) {
return presets instanceof double[];
} else {

View File

@ -82,14 +82,12 @@ public final class Symbol implements Comparable<Symbol>, Cloneable, Serializable
public static final int HAS_SLOT = 1 << 10;
/** Is this symbol known to store an int value ? */
public static final int HAS_INT_VALUE = 1 << 11;
/** Is this symbol known to store a long value ? */
public static final int HAS_LONG_VALUE = 1 << 12;
/** Is this symbol known to store a double value ? */
public static final int HAS_DOUBLE_VALUE = 1 << 13;
public static final int HAS_DOUBLE_VALUE = 1 << 12;
/** Is this symbol known to store an object value ? */
public static final int HAS_OBJECT_VALUE = 1 << 14;
public static final int HAS_OBJECT_VALUE = 1 << 13;
/** Is this symbol seen a declaration? Used for block scoped LET and CONST symbols only. */
public static final int HAS_BEEN_DECLARED = 1 << 15;
public static final int HAS_BEEN_DECLARED = 1 << 14;
/** Null or name identifying symbol. */
private final String name;
@ -256,7 +254,6 @@ public final class Symbol implements Comparable<Symbol>, Cloneable, Serializable
*/
public int slotCount() {
return ((flags & HAS_INT_VALUE) == 0 ? 0 : 1) +
((flags & HAS_LONG_VALUE) == 0 ? 0 : 2) +
((flags & HAS_DOUBLE_VALUE) == 0 ? 0 : 2) +
((flags & HAS_OBJECT_VALUE) == 0 ? 0 : 1);
}
@ -278,7 +275,6 @@ public final class Symbol implements Comparable<Symbol>, Cloneable, Serializable
append("slot=").
append(firstSlot).append(' ');
if((flags & HAS_INT_VALUE) != 0) { sb.append('I'); }
if((flags & HAS_LONG_VALUE) != 0) { sb.append('J'); }
if((flags & HAS_DOUBLE_VALUE) != 0) { sb.append('D'); }
if((flags & HAS_OBJECT_VALUE) != 0) { sb.append('O'); }
sb.append(')');
@ -573,11 +569,6 @@ public final class Symbol implements Comparable<Symbol>, Cloneable, Serializable
return typeSlot;
}
typeSlot += ((flags & HAS_INT_VALUE) == 0 ? 0 : 1);
if(type.isLong()) {
assert (flags & HAS_LONG_VALUE) != 0;
return typeSlot;
}
typeSlot += ((flags & HAS_LONG_VALUE) == 0 ? 0 : 2);
if(type.isNumber()) {
assert (flags & HAS_DOUBLE_VALUE) != 0;
return typeSlot;
@ -595,8 +586,6 @@ public final class Symbol implements Comparable<Symbol>, Cloneable, Serializable
public boolean hasSlotFor(final Type type) {
if(type.isBoolean() || type.isInteger()) {
return (flags & HAS_INT_VALUE) != 0;
} else if(type.isLong()) {
return (flags & HAS_LONG_VALUE) != 0;
} else if(type.isNumber()) {
return (flags & HAS_DOUBLE_VALUE) != 0;
}
@ -611,8 +600,6 @@ public final class Symbol implements Comparable<Symbol>, Cloneable, Serializable
public void setHasSlotFor(final Type type) {
if(type.isBoolean() || type.isInteger()) {
setFlag(HAS_INT_VALUE);
} else if(type.isLong()) {
setFlag(HAS_LONG_VALUE);
} else if(type.isNumber()) {
setFlag(HAS_DOUBLE_VALUE);
} else {

View File

@ -25,9 +25,6 @@
package jdk.nashorn.internal.ir.debug;
import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_PROGRAM_POINT_SHIFT;
import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.FLAGS_MASK;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
@ -502,6 +499,7 @@ public final class NashornTextifier extends Printer {
appendOpcode(sb, Opcodes.INVOKEDYNAMIC).append(' ');
final boolean isNashornBootstrap = isNashornBootstrap(bsm);
final boolean isNashornMathBootstrap = isNashornMathBootstrap(bsm);
if (isNashornBootstrap) {
sb.append(NashornCallSiteDescriptor.getOperationName((Integer)bsmArgs[0]));
final String decodedName = NameCodec.decode(name);
@ -529,12 +527,9 @@ public final class NashornTextifier extends Printer {
} else if (cst instanceof Handle) {
appendHandle(sb, (Handle)cst);
} else if (cst instanceof Integer && isNashornBootstrap) {
final int c = (Integer)cst;
final int pp = c >> CALLSITE_PROGRAM_POINT_SHIFT;
if (pp != 0) {
sb.append(" pp=").append(pp);
}
sb.append(NashornCallSiteDescriptor.toString(c & FLAGS_MASK));
NashornCallSiteDescriptor.appendFlags((Integer) cst, sb);
} else if (cst instanceof Integer && isNashornMathBootstrap) {
sb.append(" pp=").append(cst);
} else {
sb.append(cst);
}
@ -551,6 +546,10 @@ public final class NashornTextifier extends Printer {
return "bootstrap".equals(bsm.getName()) && BOOTSTRAP_CLASS_NAME.equals(bsm.getOwner());
}
private static boolean isNashornMathBootstrap(final Handle bsm) {
return "mathBootstrap".equals(bsm.getName()) && BOOTSTRAP_CLASS_NAME.equals(bsm.getOwner());
}
private static boolean noFallThru(final int opcode) {
switch (opcode) {
case Opcodes.GOTO:

View File

@ -1106,8 +1106,6 @@ public final class Global extends Scope {
return new NativeArray(ArrayData.allocate((Object[])obj), this);
} else if (obj instanceof double[]) { // extension
return new NativeArray(ArrayData.allocate((double[])obj), this);
} else if (obj instanceof long[]) {
return new NativeArray(ArrayData.allocate((long[])obj), this);
} else if (obj instanceof int[]) {
return new NativeArray(ArrayData.allocate((int[]) obj), this);
} else if (obj instanceof ArrayData) {
@ -1993,16 +1991,6 @@ public final class Global extends Scope {
return new NativeArray(ArrayData.allocate(initial));
}
/**
* Allocate a new long array.
*
* @param initial number values.
* @return the new array
*/
public static NativeArray allocate(final long[] initial) {
return new NativeArray(ArrayData.allocate(initial));
}
/**
* Allocate a new integer array.
*
@ -2291,7 +2279,6 @@ public final class Global extends Scope {
new Specialization[] {
new Specialization(GlobalFunctions.PARSEINT_Z),
new Specialization(GlobalFunctions.PARSEINT_I),
new Specialization(GlobalFunctions.PARSEINT_J),
new Specialization(GlobalFunctions.PARSEINT_OI),
new Specialization(GlobalFunctions.PARSEINT_O) });
this.parseFloat = ScriptFunction.createBuiltin("parseFloat", GlobalFunctions.PARSEFLOAT);

View File

@ -127,12 +127,6 @@ public final class NativeArguments extends ScriptObject {
return isMapped(index) ? deleteMapped(index, strict) : super.delete(key, strict);
}
@Override
public boolean delete(final long key, final boolean strict) {
final int index = ArrayIndex.getArrayIndex(key);
return isMapped(index) ? deleteMapped(index, strict) : super.delete(key, strict);
}
@Override
public boolean delete(final double key, final boolean strict) {
final int index = ArrayIndex.getArrayIndex(key);

View File

@ -100,20 +100,38 @@ public final class NativeArray extends ScriptObject implements OptimisticBuiltin
}
NativeArray(final long length) {
// TODO assert valid index in long before casting
this(ArrayData.allocate((int)length));
this(ArrayData.allocate(length));
}
NativeArray(final int[] array) {
this(ArrayData.allocate(array));
}
NativeArray(final long[] array) {
NativeArray(final double[] array) {
this(ArrayData.allocate(array));
}
NativeArray(final double[] array) {
this(ArrayData.allocate(array));
NativeArray(final long[] array) {
this(ArrayData.allocate(array.length));
ArrayData arrayData = this.getArray();
Class<?> widest = int.class;
for (int index = 0; index < array.length; index++) {
final long value = array[index];
if (widest == int.class && JSType.isRepresentableAsInt(value)) {
arrayData = arrayData.set(index, (int) value, false);
} else if (widest != Object.class && JSType.isRepresentableAsDouble(value)) {
arrayData = arrayData.set(index, (double) value, false);
widest = double.class;
} else {
arrayData = arrayData.set(index, (Object) value, false);
widest = Object.class;
}
}
this.setArray(arrayData);
}
NativeArray(final Object[] array) {
@ -179,7 +197,7 @@ public final class NativeArray extends ScriptObject implements OptimisticBuiltin
@Override
public MethodHandle call() {
return Bootstrap.createDynamicCallInvoker(rtype, Object.class, Object.class, Object.class,
long.class, Object.class);
double.class, Object.class);
}
});
}
@ -210,7 +228,7 @@ public final class NativeArray extends ScriptObject implements OptimisticBuiltin
@Override
public MethodHandle call() {
return Bootstrap.createDynamicCallInvoker(Object.class, Object.class,
Undefined.class, Object.class, Object.class, long.class, Object.class);
Undefined.class, Object.class, Object.class, double.class, Object.class);
}
});
}
@ -246,8 +264,9 @@ public final class NativeArray extends ScriptObject implements OptimisticBuiltin
@Override
public Object getLength() {
final long length = JSType.toUint32(getArray().length());
if (length < Integer.MAX_VALUE) {
final long length = getArray().length();
assert length >= 0L;
if (length <= Integer.MAX_VALUE) {
return (int)length;
}
return length;
@ -445,7 +464,13 @@ public final class NativeArray extends ScriptObject implements OptimisticBuiltin
@Getter(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_CONFIGURABLE)
public static Object length(final Object self) {
if (isArray(self)) {
return JSType.toUint32(((ScriptObject) self).getArray().length());
final long length = ((ScriptObject) self).getArray().length();
assert length >= 0L;
// Cast to the narrowest supported numeric type to help optimistic type calculator
if (length <= Integer.MAX_VALUE) {
return (int) length;
}
return (double) length;
}
return 0;
@ -1553,7 +1578,7 @@ public final class NativeArray extends ScriptObject implements OptimisticBuiltin
private final MethodHandle everyInvoker = getEVERY_CALLBACK_INVOKER();
@Override
protected boolean forEach(final Object val, final long i) throws Throwable {
protected boolean forEach(final Object val, final double i) throws Throwable {
return result = (boolean)everyInvoker.invokeExact(callbackfn, thisArg, val, i, self);
}
}.apply();
@ -1573,7 +1598,7 @@ public final class NativeArray extends ScriptObject implements OptimisticBuiltin
private final MethodHandle someInvoker = getSOME_CALLBACK_INVOKER();
@Override
protected boolean forEach(final Object val, final long i) throws Throwable {
protected boolean forEach(final Object val, final double i) throws Throwable {
return !(result = (boolean)someInvoker.invokeExact(callbackfn, thisArg, val, i, self));
}
}.apply();
@ -1593,7 +1618,7 @@ public final class NativeArray extends ScriptObject implements OptimisticBuiltin
private final MethodHandle forEachInvoker = getFOREACH_CALLBACK_INVOKER();
@Override
protected boolean forEach(final Object val, final long i) throws Throwable {
protected boolean forEach(final Object val, final double i) throws Throwable {
forEachInvoker.invokeExact(callbackfn, thisArg, val, i, self);
return true;
}
@ -1614,7 +1639,7 @@ public final class NativeArray extends ScriptObject implements OptimisticBuiltin
private final MethodHandle mapInvoker = getMAP_CALLBACK_INVOKER();
@Override
protected boolean forEach(final Object val, final long i) throws Throwable {
protected boolean forEach(final Object val, final double i) throws Throwable {
final Object r = mapInvoker.invokeExact(callbackfn, thisArg, val, i, self);
result.defineOwnProperty(ArrayIndex.getArrayIndex(index), r);
return true;
@ -1644,7 +1669,7 @@ public final class NativeArray extends ScriptObject implements OptimisticBuiltin
private final MethodHandle filterInvoker = getFILTER_CALLBACK_INVOKER();
@Override
protected boolean forEach(final Object val, final long i) throws Throwable {
protected boolean forEach(final Object val, final double i) throws Throwable {
if ((boolean)filterInvoker.invokeExact(callbackfn, thisArg, val, i, self)) {
result.defineOwnProperty(ArrayIndex.getArrayIndex(to++), val);
}
@ -1676,7 +1701,7 @@ public final class NativeArray extends ScriptObject implements OptimisticBuiltin
private final MethodHandle reduceInvoker = getREDUCE_CALLBACK_INVOKER();
@Override
protected boolean forEach(final Object val, final long i) throws Throwable {
protected boolean forEach(final Object val, final double i) throws Throwable {
// TODO: why can't I declare the second arg as Undefined.class?
result = reduceInvoker.invokeExact(callbackfn, ScriptRuntime.UNDEFINED, result, val, i, self);
return true;

View File

@ -124,7 +124,7 @@ public final class NativeFloat32Array extends ArrayBufferView {
@Override
public MethodHandle getElementGetter(final Class<?> returnType, final int programPoint) {
if (returnType == int.class || returnType == long.class) {
if (returnType == int.class) {
return null;
}
return getContinuousElementGetter(getClass(), GET_ELEM, returnType, programPoint);
@ -135,11 +135,6 @@ public final class NativeFloat32Array extends ArrayBufferView {
return (int)getDouble(index);
}
@Override
public long getLong(final int index) {
return (long)getDouble(index);
}
@Override
public double getDouble(final int index) {
return getElem(index);
@ -165,11 +160,6 @@ public final class NativeFloat32Array extends ArrayBufferView {
return set(index, (double)value, strict);
}
@Override
public ArrayData set(final int index, final long value, final boolean strict) {
return set(index, (double)value, strict);
}
@Override
public ArrayData set(final int index, final double value, final boolean strict) {
setElem(index, value);

View File

@ -124,7 +124,7 @@ public final class NativeFloat64Array extends ArrayBufferView {
@Override
public MethodHandle getElementGetter(final Class<?> returnType, final int programPoint) {
if (returnType == int.class || returnType == long.class) {
if (returnType == int.class) {
return null;
}
return getContinuousElementGetter(getClass(), GET_ELEM, returnType, programPoint);
@ -135,11 +135,6 @@ public final class NativeFloat64Array extends ArrayBufferView {
return (int)getDouble(index);
}
@Override
public long getLong(final int index) {
return (long)getDouble(index);
}
@Override
public double getDouble(final int index) {
return getElem(index);
@ -165,11 +160,6 @@ public final class NativeFloat64Array extends ArrayBufferView {
return set(index, (double)value, strict);
}
@Override
public ArrayData set(final int index, final long value, final boolean strict) {
return set(index, (double)value, strict);
}
@Override
public ArrayData set(final int index, final double value, final boolean strict) {
setElem(index, value);

View File

@ -133,16 +133,6 @@ public final class NativeInt16Array extends ArrayBufferView {
return getElem(index);
}
@Override
public long getLong(final int index) {
return getInt(index);
}
@Override
public long getLongOptimistic(final int index, final int programPoint) {
return getElem(index);
}
@Override
public double getDouble(final int index) {
return getInt(index);
@ -169,11 +159,6 @@ public final class NativeInt16Array extends ArrayBufferView {
return this;
}
@Override
public ArrayData set(final int index, final long value, final boolean strict) {
return set(index, (int)value, strict);
}
@Override
public ArrayData set(final int index, final double value, final boolean strict) {
return set(index, (int)value, strict);

View File

@ -132,16 +132,6 @@ public final class NativeInt32Array extends ArrayBufferView {
return getElem(index);
}
@Override
public long getLong(final int index) {
return getInt(index);
}
@Override
public long getLongOptimistic(final int index, final int programPoint) {
return getElem(index);
}
@Override
public double getDouble(final int index) {
return getInt(index);
@ -168,11 +158,6 @@ public final class NativeInt32Array extends ArrayBufferView {
return this;
}
@Override
public ArrayData set(final int index, final long value, final boolean strict) {
return set(index, (int)value, strict);
}
@Override
public ArrayData set(final int index, final double value, final boolean strict) {
return set(index, (int)value, strict);

View File

@ -131,16 +131,6 @@ public final class NativeInt8Array extends ArrayBufferView {
return getElem(index);
}
@Override
public long getLong(final int index) {
return getInt(index);
}
@Override
public long getLongOptimistic(final int index, final int programPoint) {
return getElem(index);
}
@Override
public double getDouble(final int index) {
return getInt(index);
@ -167,11 +157,6 @@ public final class NativeInt8Array extends ArrayBufferView {
return this;
}
@Override
public ArrayData set(final int index, final long value, final boolean strict) {
return set(index, (int)value, strict);
}
@Override
public ArrayData set(final int index, final double value, final boolean strict) {
return set(index, (int)value, strict);

View File

@ -184,36 +184,11 @@ public final class NativeJSAdapter extends ScriptObject {
return (overrides && super.hasOwnProperty(key)) ? super.getInt(key, programPoint) : callAdapteeInt(programPoint, __get__, key);
}
@Override
public int getInt(final long key, final int programPoint) {
return (overrides && super.hasOwnProperty(key)) ? super.getInt(key, programPoint) : callAdapteeInt(programPoint, __get__, key);
}
@Override
public int getInt(final int key, final int programPoint) {
return (overrides && super.hasOwnProperty(key)) ? super.getInt(key, programPoint) : callAdapteeInt(programPoint, __get__, key);
}
@Override
public long getLong(final Object key, final int programPoint) {
return (overrides && super.hasOwnProperty(key)) ? super.getLong(key, programPoint) : callAdapteeLong(programPoint, __get__, key);
}
@Override
public long getLong(final double key, final int programPoint) {
return (overrides && super.hasOwnProperty(key)) ? super.getLong(key, programPoint) : callAdapteeLong(programPoint, __get__, key);
}
@Override
public long getLong(final long key, final int programPoint) {
return (overrides && super.hasOwnProperty(key)) ? super.getLong(key, programPoint) : callAdapteeLong(programPoint, __get__, key);
}
@Override
public long getLong(final int key, final int programPoint) {
return (overrides && super.hasOwnProperty(key)) ? super.getLong(key, programPoint) : callAdapteeLong(programPoint, __get__, key);
}
@Override
public double getDouble(final Object key, final int programPoint) {
return (overrides && super.hasOwnProperty(key)) ? super.getDouble(key, programPoint) : callAdapteeDouble(programPoint, __get__, key);
@ -224,11 +199,6 @@ public final class NativeJSAdapter extends ScriptObject {
return (overrides && super.hasOwnProperty(key)) ? super.getDouble(key, programPoint) : callAdapteeDouble(programPoint, __get__, key);
}
@Override
public double getDouble(final long key, final int programPoint) {
return (overrides && super.hasOwnProperty(key)) ? super.getDouble(key, programPoint) : callAdapteeDouble(programPoint, __get__, key);
}
@Override
public double getDouble(final int key, final int programPoint) {
return (overrides && super.hasOwnProperty(key)) ? super.getDouble(key, programPoint) : callAdapteeDouble(programPoint, __get__, key);
@ -244,11 +214,6 @@ public final class NativeJSAdapter extends ScriptObject {
return (overrides && super.hasOwnProperty(key)) ? super.get(key) : callAdaptee(__get__, key);
}
@Override
public Object get(final long key) {
return (overrides && super.hasOwnProperty(key)) ? super.get(key) : callAdaptee(__get__, key);
}
@Override
public Object get(final int key) {
return (overrides && super.hasOwnProperty(key)) ? super.get(key) : callAdaptee(__get__, key);
@ -263,15 +228,6 @@ public final class NativeJSAdapter extends ScriptObject {
}
}
@Override
public void set(final Object key, final long value, final int flags) {
if (overrides && super.hasOwnProperty(key)) {
super.set(key, value, flags);
} else {
callAdaptee(__put__, key, value, flags);
}
}
@Override
public void set(final Object key, final double value, final int flags) {
if (overrides && super.hasOwnProperty(key)) {
@ -299,15 +255,6 @@ public final class NativeJSAdapter extends ScriptObject {
}
}
@Override
public void set(final double key, final long value, final int flags) {
if (overrides && super.hasOwnProperty(key)) {
super.set(key, value, flags);
} else {
callAdaptee(__put__, key, value, flags);
}
}
@Override
public void set(final double key, final double value, final int flags) {
if (overrides && super.hasOwnProperty(key)) {
@ -326,42 +273,6 @@ public final class NativeJSAdapter extends ScriptObject {
}
}
@Override
public void set(final long key, final int value, final int flags) {
if (overrides && super.hasOwnProperty(key)) {
super.set(key, value, flags);
} else {
callAdaptee(__put__, key, value, flags);
}
}
@Override
public void set(final long key, final long value, final int flags) {
if (overrides && super.hasOwnProperty(key)) {
super.set(key, value, flags);
} else {
callAdaptee(__put__, key, value, flags);
}
}
@Override
public void set(final long key, final double value, final int flags) {
if (overrides && super.hasOwnProperty(key)) {
super.set(key, value, flags);
} else {
callAdaptee(__put__, key, value, flags);
}
}
@Override
public void set(final long key, final Object value, final int flags) {
if (overrides && super.hasOwnProperty(key)) {
super.set(key, value, flags);
} else {
callAdaptee(__put__, key, value, flags);
}
}
@Override
public void set(final int key, final int value, final int flags) {
if (overrides && super.hasOwnProperty(key)) {
@ -371,15 +282,6 @@ public final class NativeJSAdapter extends ScriptObject {
}
}
@Override
public void set(final int key, final long value, final int flags) {
if (overrides && super.hasOwnProperty(key)) {
super.set(key, value, flags);
} else {
callAdaptee(__put__, key, value, flags);
}
}
@Override
public void set(final int key, final double value, final int flags) {
if (overrides && super.hasOwnProperty(key)) {
@ -416,15 +318,6 @@ public final class NativeJSAdapter extends ScriptObject {
return JSType.toBoolean(callAdaptee(Boolean.FALSE, __has__, key));
}
@Override
public boolean has(final long key) {
if (overrides && super.hasOwnProperty(key)) {
return true;
}
return JSType.toBoolean(callAdaptee(Boolean.FALSE, __has__, key));
}
@Override
public boolean has(final double key) {
if (overrides && super.hasOwnProperty(key)) {
@ -443,15 +336,6 @@ public final class NativeJSAdapter extends ScriptObject {
return JSType.toBoolean(callAdaptee(Boolean.TRUE, __delete__, key, strict));
}
@Override
public boolean delete(final long key, final boolean strict) {
if (overrides && super.hasOwnProperty(key)) {
return super.delete(key, strict);
}
return JSType.toBoolean(callAdaptee(Boolean.TRUE, __delete__, key, strict));
}
@Override
public boolean delete(final double key, final boolean strict) {
if (overrides && super.hasOwnProperty(key)) {
@ -669,10 +553,6 @@ public final class NativeJSAdapter extends ScriptObject {
return JSType.toNumberMaybeOptimistic(callAdaptee(name, args), programPoint);
}
private long callAdapteeLong(final int programPoint, final String name, final Object... args) {
return JSType.toLongMaybeOptimistic(callAdaptee(name, args), programPoint);
}
private int callAdapteeInt(final int programPoint, final String name, final Object... args) {
return JSType.toInt32MaybeOptimistic(callAdaptee(name, args), programPoint);
}

View File

@ -33,8 +33,6 @@ import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.math.RoundingMode;
import java.text.NumberFormat;
import java.util.Locale;
import jdk.dynalink.linker.GuardedInvocation;
import jdk.dynalink.linker.LinkRequest;

View File

@ -209,14 +209,6 @@ public final class NativeString extends ScriptObject implements OptimisticBuilti
return super.get(key);
}
@Override
public Object get(final long key) {
if (key >= 0 && key < value.length()) {
return String.valueOf(value.charAt((int)key));
}
return super.get(key);
}
@Override
public Object get(final int key) {
if (key >= 0 && key < value.length()) {
@ -235,36 +227,11 @@ public final class NativeString extends ScriptObject implements OptimisticBuilti
return JSType.toInt32MaybeOptimistic(get(key), programPoint);
}
@Override
public int getInt(final long key, final int programPoint) {
return JSType.toInt32MaybeOptimistic(get(key), programPoint);
}
@Override
public int getInt(final int key, final int programPoint) {
return JSType.toInt32MaybeOptimistic(get(key), programPoint);
}
@Override
public long getLong(final Object key, final int programPoint) {
return JSType.toLongMaybeOptimistic(get(key), programPoint);
}
@Override
public long getLong(final double key, final int programPoint) {
return JSType.toLongMaybeOptimistic(get(key), programPoint);
}
@Override
public long getLong(final long key, final int programPoint) {
return JSType.toLongMaybeOptimistic(get(key), programPoint);
}
@Override
public long getLong(final int key, final int programPoint) {
return JSType.toLongMaybeOptimistic(get(key), programPoint);
}
@Override
public double getDouble(final Object key, final int programPoint) {
return JSType.toNumberMaybeOptimistic(get(key), programPoint);
@ -275,11 +242,6 @@ public final class NativeString extends ScriptObject implements OptimisticBuilti
return JSType.toNumberMaybeOptimistic(get(key), programPoint);
}
@Override
public double getDouble(final long key, final int programPoint) {
return JSType.toNumberMaybeOptimistic(get(key), programPoint);
}
@Override
public double getDouble(final int key, final int programPoint) {
return JSType.toNumberMaybeOptimistic(get(key), programPoint);
@ -297,12 +259,6 @@ public final class NativeString extends ScriptObject implements OptimisticBuilti
return isValidStringIndex(key) || super.has(key);
}
@Override
public boolean has(final long key) {
final int index = ArrayIndex.getArrayIndex(key);
return isValidStringIndex(index) || super.has(key);
}
@Override
public boolean has(final double key) {
final int index = ArrayIndex.getArrayIndex(key);
@ -321,12 +277,6 @@ public final class NativeString extends ScriptObject implements OptimisticBuilti
return isValidStringIndex(key) || super.hasOwnProperty(key);
}
@Override
public boolean hasOwnProperty(final long key) {
final int index = ArrayIndex.getArrayIndex(key);
return isValidStringIndex(index) || super.hasOwnProperty(key);
}
@Override
public boolean hasOwnProperty(final double key) {
final int index = ArrayIndex.getArrayIndex(key);
@ -338,12 +288,6 @@ public final class NativeString extends ScriptObject implements OptimisticBuilti
return checkDeleteIndex(key, strict)? false : super.delete(key, strict);
}
@Override
public boolean delete(final long key, final boolean strict) {
final int index = ArrayIndex.getArrayIndex(key);
return checkDeleteIndex(index, strict)? false : super.delete(key, strict);
}
@Override
public boolean delete(final double key, final boolean strict) {
final int index = ArrayIndex.getArrayIndex(key);

View File

@ -137,16 +137,6 @@ public final class NativeUint16Array extends ArrayBufferView {
return getElem(index);
}
@Override
public long getLong(final int index) {
return getInt(index);
}
@Override
public long getLongOptimistic(final int index, final int programPoint) {
return getElem(index);
}
@Override
public double getDouble(final int index) {
return getInt(index);
@ -173,11 +163,6 @@ public final class NativeUint16Array extends ArrayBufferView {
return this;
}
@Override
public ArrayData set(final int index, final long value, final boolean strict) {
return set(index, (int)value, strict);
}
@Override
public ArrayData set(final int index, final double value, final boolean strict) {
return set(index, (int)value, strict);

View File

@ -32,6 +32,7 @@ import java.lang.invoke.MethodHandles;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
import jdk.nashorn.internal.codegen.types.Type;
import jdk.nashorn.internal.objects.annotations.Attribute;
import jdk.nashorn.internal.objects.annotations.Constructor;
import jdk.nashorn.internal.objects.annotations.Function;
@ -41,6 +42,7 @@ import jdk.nashorn.internal.objects.annotations.Where;
import jdk.nashorn.internal.runtime.JSType;
import jdk.nashorn.internal.runtime.PropertyMap;
import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.UnwarrantedOptimismException;
import jdk.nashorn.internal.runtime.arrays.ArrayData;
import jdk.nashorn.internal.runtime.arrays.TypedArrayData;
@ -78,7 +80,7 @@ public final class NativeUint32Array extends ArrayBufferView {
private static final class Uint32ArrayData extends TypedArrayData<IntBuffer> {
private static final MethodHandle GET_ELEM = specialCall(MethodHandles.lookup(), Uint32ArrayData.class, "getElem", long.class, int.class).methodHandle();
private static final MethodHandle GET_ELEM = specialCall(MethodHandles.lookup(), Uint32ArrayData.class, "getElem", double.class, int.class).methodHandle();
private static final MethodHandle SET_ELEM = specialCall(MethodHandles.lookup(), Uint32ArrayData.class, "setElem", void.class, int.class, int.class).methodHandle();
private Uint32ArrayData(final IntBuffer nb, final int start, final int end) {
@ -103,14 +105,18 @@ public final class NativeUint32Array extends ArrayBufferView {
return getContinuousElementGetter(getClass(), GET_ELEM, returnType, programPoint);
}
private long getElem(final int index) {
private int getRawElem(final int index) {
try {
return JSType.toUint32(nb.get(index));
return nb.get(index);
} catch (final IndexOutOfBoundsException e) {
throw new ClassCastException(); //force relink - this works for unoptimistic too
}
}
private double getElem(final int index) {
return JSType.toUint32(getRawElem(index));
}
private void setElem(final int index, final int elem) {
try {
if (index < nb.limit()) {
@ -128,42 +134,37 @@ public final class NativeUint32Array extends ArrayBufferView {
@Override
public Class<?> getElementType() {
return long.class;
return double.class;
}
@Override
public Class<?> getBoxedElementType() {
return Integer.class;
return Double.class;
}
@Override
public int getInt(final int index) {
return (int)getLong(index);
return getRawElem(index);
}
@Override
public long getLong(final int index) {
return getElem(index);
}
@Override
public long getLongOptimistic(final int index, final int programPoint) {
return getElem(index);
public int getIntOptimistic(final int index, final int programPoint) {
return JSType.toUint32Optimistic(getRawElem(index), programPoint);
}
@Override
public double getDouble(final int index) {
return getLong(index);
return getElem(index);
}
@Override
public double getDoubleOptimistic(final int index, final int programPoint) {
return getLong(index);
return getElem(index);
}
@Override
public Object getObject(final int index) {
return getLong(index);
return getElem(index);
}
@Override
@ -177,11 +178,6 @@ public final class NativeUint32Array extends ArrayBufferView {
return this;
}
@Override
public ArrayData set(final int index, final long value, final boolean strict) {
return set(index, (int)value, strict);
}
@Override
public ArrayData set(final int index, final double value, final boolean strict) {
return set(index, (int)value, strict);

View File

@ -137,16 +137,6 @@ public final class NativeUint8Array extends ArrayBufferView {
return getElem(index);
}
@Override
public long getLong(final int index) {
return getInt(index);
}
@Override
public long getLongOptimistic(final int index, final int programPoint) {
return getElem(index);
}
@Override
public double getDouble(final int index) {
return getInt(index);
@ -173,11 +163,6 @@ public final class NativeUint8Array extends ArrayBufferView {
return this;
}
@Override
public ArrayData set(final int index, final long value, final boolean strict) {
return set(index, (int)value, strict);
}
@Override
public ArrayData set(final int index, final double value, final boolean strict) {
return set(index, (int)value, strict);

View File

@ -167,16 +167,6 @@ public final class NativeUint8ClampedArray extends ArrayBufferView {
return getElem(index);
}
@Override
public long getLong(final int index) {
return getInt(index);
}
@Override
public long getLongOptimistic(final int index, final int programPoint) {
return getElem(index);
}
@Override
public double getDouble(final int index) {
return getInt(index);
@ -203,11 +193,6 @@ public final class NativeUint8ClampedArray extends ArrayBufferView {
return this;
}
@Override
public ArrayData set(final int index, final long value, final boolean strict) {
return set(index, (int)value, strict);
}
@Override
public ArrayData set(final int index, final double value, final boolean strict) {
return set(index, rint(value), strict);

View File

@ -293,8 +293,6 @@ public class JSONParser {
private static Class<?> getType(final Object value) {
if (value instanceof Integer) {
return int.class;
} else if (value instanceof Long) {
return long.class;
} else if (value instanceof Double) {
return double.class;
} else {
@ -477,8 +475,6 @@ public class JSONParser {
final double d = Double.parseDouble(source.substring(start, pos));
if (JSType.isRepresentableAsInt(d)) {
return (int) d;
} else if (JSType.isRepresentableAsLong(d)) {
return (long) d;
}
return d;
}

View File

@ -1131,11 +1131,7 @@ public class Lexer extends Scanner {
*/
private static Number valueOf(final String valueString, final int radix) throws NumberFormatException {
try {
final long value = Long.parseLong(valueString, radix);
if(value >= MIN_INT_L && value <= MAX_INT_L) {
return (int)value;
}
return value;
return Integer.parseInt(valueString, radix);
} catch (final NumberFormatException e) {
if (radix == 10) {
return Double.valueOf(valueString);
@ -1782,8 +1778,6 @@ public class Lexer extends Scanner {
//yet we don't want e.g. 1e6 to be a double unnecessarily
if (JSType.isStrictlyRepresentableAsInt(value)) {
return (int)value;
} else if (JSType.isStrictlyRepresentableAsLong(value)) {
return (long)value;
}
return value;
case STRING:

View File

@ -221,7 +221,7 @@ public class AccessorProperty extends Property {
assert setterType == null || setterType == getterType;
if (getterType == int.class || getterType == long.class) {
if (getterType == int.class) {
primitiveGetter = MH.asType(getter, Lookup.GET_PRIMITIVE_TYPE);
primitiveSetter = setter == null ? null : MH.asType(setter, Lookup.SET_PRIMITIVE_TYPE);
} else if (getterType == double.class) {
@ -400,17 +400,6 @@ public class AccessorProperty extends Property {
}
}
@Override
public long getLongValue(final ScriptObject self, final ScriptObject owner) {
try {
return (long)getGetter(long.class).invokeExact((Object)self);
} catch (final Error | RuntimeException e) {
throw e;
} catch (final Throwable e) {
throw new RuntimeException(e);
}
}
@Override
public double getDoubleValue(final ScriptObject self, final ScriptObject owner) {
try {
@ -448,21 +437,6 @@ public class AccessorProperty extends Property {
}
}
/**
* Invoke setter for this property with a value
* @param self owner
* @param value value
*/
protected final void invokeSetter(final ScriptObject self, final long value) {
try {
getSetter(long.class, self.getMap()).invokeExact((Object)self, value);
} catch (final Error | RuntimeException e) {
throw e;
} catch (final Throwable e) {
throw new RuntimeException(e);
}
}
/**
* Invoke setter for this property with a value
* @param self owner
@ -499,12 +473,6 @@ public class AccessorProperty extends Property {
invokeSetter(self, value);
}
@Override
public void setValue(final ScriptObject self, final ScriptObject owner, final long value, final boolean strict) {
assert isConfigurable() || isWritable() : getKey() + " is not writable or configurable";
invokeSetter(self, value);
}
@Override
public void setValue(final ScriptObject self, final ScriptObject owner, final double value, final boolean strict) {
assert isConfigurable() || isWritable() : getKey() + " is not writable or configurable";
@ -533,7 +501,6 @@ public class AccessorProperty extends Property {
final int i = getAccessorTypeIndex(type);
assert type == int.class ||
type == long.class ||
type == double.class ||
type == Object.class :
"invalid getter type " + type + " for " + getKey();

View File

@ -239,7 +239,7 @@ final class DebuggerSupport {
if (ScriptObject.isArray(object)) {
sb.append('[');
final long length = object.getLong("length", INVALID_PROGRAM_POINT);
final long length = (long) object.getDouble("length", INVALID_PROGRAM_POINT);
for (long i = 0; i < length; i++) {
if (object.has(i)) {

View File

@ -43,36 +43,11 @@ public abstract class DefaultPropertyAccess implements PropertyAccess {
return getInt(JSType.toObject(key), programPoint);
}
@Override
public int getInt(final long key, final int programPoint) {
return getInt(JSType.toObject(key), programPoint);
}
@Override
public int getInt(final int key, final int programPoint) {
return getInt(JSType.toObject(key), programPoint);
}
@Override
public long getLong(final Object key, final int programPoint) {
return JSType.toLong(get(key));
}
@Override
public long getLong(final double key, final int programPoint) {
return getLong(JSType.toObject(key), programPoint);
}
@Override
public long getLong(final long key, final int programPoint) {
return getLong(JSType.toObject(key), programPoint);
}
@Override
public long getLong(final int key, final int programPoint) {
return getLong(JSType.toObject(key), programPoint);
}
@Override
public double getDouble(final Object key, final int programPoint) {
return JSType.toNumber(get(key));
@ -83,11 +58,6 @@ public abstract class DefaultPropertyAccess implements PropertyAccess {
return getDouble(JSType.toObject(key), programPoint);
}
@Override
public double getDouble(final long key, final int programPoint) {
return getDouble(JSType.toObject(key), programPoint);
}
@Override
public double getDouble(final int key, final int programPoint) {
return getDouble(JSType.toObject(key), programPoint);
@ -101,11 +71,6 @@ public abstract class DefaultPropertyAccess implements PropertyAccess {
return get(JSType.toObject(key));
}
@Override
public Object get(final long key) {
return get(JSType.toObject(key));
}
@Override
public Object get(final int key) {
return get(JSType.toObject(key));
@ -116,11 +81,6 @@ public abstract class DefaultPropertyAccess implements PropertyAccess {
set(JSType.toObject(key), JSType.toObject(value), flags);
}
@Override
public void set(final double key, final long value, final int flags) {
set(JSType.toObject(key), JSType.toObject(value), flags);
}
@Override
public void set(final double key, final double value, final int flags) {
set(JSType.toObject(key), JSType.toObject(value), flags);
@ -131,36 +91,11 @@ public abstract class DefaultPropertyAccess implements PropertyAccess {
set(JSType.toObject(key), JSType.toObject(value), flags);
}
@Override
public void set(final long key, final int value, final int flags) {
set(JSType.toObject(key), JSType.toObject(value), flags);
}
@Override
public void set(final long key, final long value, final int flags) {
set(JSType.toObject(key), JSType.toObject(value), flags);
}
@Override
public void set(final long key, final double value, final int flags) {
set(JSType.toObject(key), JSType.toObject(value), flags);
}
@Override
public void set(final long key, final Object value, final int flags) {
set(JSType.toObject(key), value, flags);
}
@Override
public void set(final int key, final int value, final int flags) {
set(JSType.toObject(key), JSType.toObject(value), flags);
}
@Override
public void set(final int key, final long value, final int flags) {
set(JSType.toObject(key), JSType.toObject(value), flags);
}
@Override
public void set(final int key, final double value, final int flags) {
set(JSType.toObject(key), JSType.toObject(value), flags);
@ -176,11 +111,6 @@ public abstract class DefaultPropertyAccess implements PropertyAccess {
set(key, JSType.toObject(value), flags);
}
@Override
public void set(final Object key, final long value, final int flags) {
set(key, JSType.toObject(value), flags);
}
@Override
public void set(final Object key, final double value, final int flags) {
set(key, JSType.toObject(value), flags);
@ -197,11 +127,6 @@ public abstract class DefaultPropertyAccess implements PropertyAccess {
return has(JSType.toObject(key));
}
@Override
public boolean has(final long key) {
return has(JSType.toObject(key));
}
@Override
public boolean has(final double key) {
return has(JSType.toObject(key));
@ -212,11 +137,6 @@ public abstract class DefaultPropertyAccess implements PropertyAccess {
return hasOwnProperty(JSType.toObject(key));
}
@Override
public boolean hasOwnProperty(final long key) {
return hasOwnProperty(JSType.toObject(key));
}
@Override
public boolean hasOwnProperty(final double key) {
return hasOwnProperty(JSType.toObject(key));
@ -230,11 +150,6 @@ public abstract class DefaultPropertyAccess implements PropertyAccess {
return delete(JSType.toObject(key), strict);
}
@Override
public boolean delete(final long key, final boolean strict) {
return delete(JSType.toObject(key), strict);
}
@Override
public boolean delete(final double key, final boolean strict) {
return delete(JSType.toObject(key), strict);

View File

@ -214,13 +214,6 @@ public final class FindProperty {
public int getIntValue() {
return property.getIntValue(getGetterReceiver(), getOwner());
}
/**
* Get the property value from self as object.
* @return the property value
*/
public long getLongValue() {
return property.getLongValue(getGetterReceiver(), getOwner());
}
/**
* Get the property value from self as object.
* @return the property value
@ -246,16 +239,6 @@ public final class FindProperty {
property.setValue(getSetterReceiver(), getOwner(), value, strict);
}
/**
* Set the property value in self.
*
* @param value the new value
* @param strict strict flag
*/
public void setValue(final long value, final boolean strict) {
property.setValue(getSetterReceiver(), getOwner(), value, strict);
}
/**
* Set the property value in self.
*

View File

@ -48,9 +48,6 @@ public final class GlobalFunctions {
/** ParseInt - identity for ints */
public static final MethodHandle PARSEINT_I = MH.dropArguments(MH.identity(int.class), 0, Object.class);
/** ParseInt - identity for longs */
public static final MethodHandle PARSEINT_J = MH.dropArguments(MH.identity(long.class), 0, Object.class);
/** Methodhandle (specialized) to implementation of ECMA 15.1.2.2, parseInt */
public static final MethodHandle PARSEINT_O = findOwnMH("parseInt", double.class, Object.class, Object.class);

View File

@ -119,14 +119,14 @@ public enum JSType {
public static final Call TO_INT32_D = staticCall(JSTYPE_LOOKUP, JSType.class, "toInt32", int.class, double.class);
/** JavaScript compliant conversion function from int to uint32 */
public static final Call TO_UINT32_I = staticCall(JSTYPE_LOOKUP, JSType.class, "toUint32", long.class, int.class);
public static final Call TO_UINT32_OPTIMISTIC = staticCall(JSTYPE_LOOKUP, JSType.class, "toUint32Optimistic", int.class, int.class, int.class);
/** JavaScript compliant conversion function from int to uint32 */
public static final Call TO_UINT32_DOUBLE = staticCall(JSTYPE_LOOKUP, JSType.class, "toUint32Double", double.class, int.class);
/** JavaScript compliant conversion function from Object to uint32 */
public static final Call TO_UINT32 = staticCall(JSTYPE_LOOKUP, JSType.class, "toUint32", long.class, Object.class);
/** JavaScript compliant conversion function from Object to long with type check */
public static final Call TO_LONG_OPTIMISTIC = staticCall(JSTYPE_LOOKUP, JSType.class, "toLongOptimistic", long.class, Object.class, int.class);
/** JavaScript compliant conversion function from number to uint32 */
public static final Call TO_UINT32_D = staticCall(JSTYPE_LOOKUP, JSType.class, "toUint32", long.class, double.class);
@ -172,36 +172,6 @@ public enum JSType {
/** Negate exact exact wrapper for potentially overflowing integer operations */
public static final Call NEGATE_EXACT = staticCall(JSTYPE_LOOKUP, JSType.class, "negateExact", int.class, int.class, int.class);
/** Add exact wrapper for potentially overflowing long operations */
public static final Call ADD_EXACT_LONG = staticCall(JSTYPE_LOOKUP, JSType.class, "addExact", long.class, long.class, long.class, int.class);
/** Sub exact wrapper for potentially overflowing long operations */
public static final Call SUB_EXACT_LONG = staticCall(JSTYPE_LOOKUP, JSType.class, "subExact", long.class, long.class, long.class, int.class);
/** Multiply exact wrapper for potentially overflowing long operations */
public static final Call MUL_EXACT_LONG = staticCall(JSTYPE_LOOKUP, JSType.class, "mulExact", long.class, long.class, long.class, int.class);
/** Div exact wrapper for potentially integer division that turns into float point */
public static final Call DIV_EXACT_LONG = staticCall(JSTYPE_LOOKUP, JSType.class, "divExact", long.class, long.class, long.class, int.class);
/** Div zero wrapper for long division that handles (0/0) &gt;&gt;&gt; 0 == 0 */
public static final Call DIV_ZERO_LONG = staticCall(JSTYPE_LOOKUP, JSType.class, "divZero", long.class, long.class, long.class);
/** Mod zero wrapper for long division that handles (0%0) &gt;&gt;&gt; 0 == 0 */
public static final Call REM_ZERO_LONG = staticCall(JSTYPE_LOOKUP, JSType.class, "remZero", long.class, long.class, long.class);
/** Mod exact wrapper for potentially integer remainders that turns into float point */
public static final Call REM_EXACT_LONG = staticCall(JSTYPE_LOOKUP, JSType.class, "remExact", long.class, long.class, long.class, int.class);
/** Decrement exact wrapper for potentially overflowing long operations */
public static final Call DECREMENT_EXACT_LONG = staticCall(JSTYPE_LOOKUP, JSType.class, "decrementExact", long.class, long.class, int.class);
/** Increment exact wrapper for potentially overflowing long operations */
public static final Call INCREMENT_EXACT_LONG = staticCall(JSTYPE_LOOKUP, JSType.class, "incrementExact", long.class, long.class, int.class);
/** Negate exact exact wrapper for potentially overflowing long operations */
public static final Call NEGATE_EXACT_LONG = staticCall(JSTYPE_LOOKUP, JSType.class, "negateExact", long.class, long.class, int.class);
/** Method handle to convert a JS Object to a Java array. */
public static final Call TO_JAVA_ARRAY = staticCall(JSTYPE_LOOKUP, JSType.class, "toJavaArray", Object.class, Object.class, Class.class);
@ -215,7 +185,6 @@ public enum JSType {
private static final List<Type> ACCESSOR_TYPES = Collections.unmodifiableList(
Arrays.asList(
Type.INT,
Type.LONG,
Type.NUMBER,
Type.OBJECT));
@ -223,17 +192,14 @@ public enum JSType {
public static final int TYPE_UNDEFINED_INDEX = -1;
/** table index for integer type - hard coded so it can be used in switches at compile time */
public static final int TYPE_INT_INDEX = 0; //getAccessorTypeIndex(int.class);
/** table index for long type - hard coded so it can be used in switches at compile time */
public static final int TYPE_LONG_INDEX = 1; //getAccessorTypeIndex(long.class);
/** table index for double type - hard coded so it can be used in switches at compile time */
public static final int TYPE_DOUBLE_INDEX = 2; //getAccessorTypeIndex(double.class);
public static final int TYPE_DOUBLE_INDEX = 1; //getAccessorTypeIndex(double.class);
/** table index for object type - hard coded so it can be used in switches at compile time */
public static final int TYPE_OBJECT_INDEX = 3; //getAccessorTypeIndex(Object.class);
public static final int TYPE_OBJECT_INDEX = 2; //getAccessorTypeIndex(Object.class);
/** object conversion quickies with JS semantics - used for return value and parameter filter */
public static final List<MethodHandle> CONVERT_OBJECT = toUnmodifiableList(
JSType.TO_INT32.methodHandle(),
JSType.TO_UINT32.methodHandle(),
JSType.TO_NUMBER.methodHandle(),
null
);
@ -244,7 +210,6 @@ public enum JSType {
*/
public static final List<MethodHandle> CONVERT_OBJECT_OPTIMISTIC = toUnmodifiableList(
JSType.TO_INT32_OPTIMISTIC.methodHandle(),
JSType.TO_LONG_OPTIMISTIC.methodHandle(),
JSType.TO_NUMBER_OPTIMISTIC.methodHandle(),
null
);
@ -256,13 +221,16 @@ public enum JSType {
/** The value of Undefined cast to a double */
public static final double UNDEFINED_DOUBLE = Double.NaN;
// Minimum and maximum range between which every long value can be precisely represented as a double.
private static final long MAX_PRECISE_DOUBLE = 1L << 53;
private static final long MIN_PRECISE_DOUBLE = -MAX_PRECISE_DOUBLE;
/**
* Method handles for getters that return undefined coerced
* to the appropriate type
*/
public static final List<MethodHandle> GET_UNDEFINED = toUnmodifiableList(
MH.constant(int.class, UNDEFINED_INT),
MH.constant(long.class, UNDEFINED_LONG),
MH.constant(double.class, UNDEFINED_DOUBLE),
MH.constant(Object.class, Undefined.getUndefined())
);
@ -428,7 +396,7 @@ public enum JSType {
/**
* Returns true if double number can be represented as a long. Note that it returns true for negative
* zero. If you need to exclude negative zero, use {@link #isStrictlyRepresentableAsLong(double)}.
* zero.
*
* @param number a double to inspect
* @return true for long representable doubles
@ -438,29 +406,12 @@ public enum JSType {
}
/**
* Returns true if double number can be represented as a long. Note that it returns false for negative
* zero. If you don't need to distinguish negative zero, use {@link #isRepresentableAsLong(double)}.
*
* @param number a double to inspect
*
* @return true for long representable doubles
* Returns true if long number can be represented as double without loss of precision.
* @param number a long number
* @return true if the double representation does not lose precision
*/
public static boolean isStrictlyRepresentableAsLong(final double number) {
return isRepresentableAsLong(number) && isNotNegativeZero(number);
}
/**
* Returns true if Object can be represented as a long
*
* @param obj an object to inspect
*
* @return true for long representable objects
*/
public static boolean isRepresentableAsLong(final Object obj) {
if (obj instanceof Number) {
return isRepresentableAsLong(((Number)obj).doubleValue());
}
return false;
public static boolean isRepresentableAsDouble(final long number) {
return MAX_PRECISE_DOUBLE >= number && number >= MIN_PRECISE_DOUBLE;
}
/**
@ -649,22 +600,6 @@ public enum JSType {
return toString(obj);
}
/**
* Check whether a string is representable as a JavaScript number
*
* @param str a string
*
* @return true if string can be represented as a number
*/
public static boolean isNumber(final String str) {
try {
Double.parseDouble(str);
return true;
} catch (final NumberFormatException e) {
return false;
}
}
/**
* Returns true if object represents a primitive JavaScript string value.
* @param obj the object
@ -1032,35 +967,6 @@ public enum JSType {
return (long)num;
}
/**
* Optimistic long conversion - throws UnwarrantedOptimismException if double or Object
*
* @param obj object to convert
* @param programPoint program point
* @return long
*/
public static long toLongOptimistic(final Object obj, final int programPoint) {
if (obj != null) {
final Class<?> clz = obj.getClass();
if (clz == Long.class || clz == Integer.class) {
return ((Number)obj).longValue();
}
}
throw new UnwarrantedOptimismException(obj, programPoint);
}
/**
* Object to int conversion that delegates to either {@link #toLong(Object)} or to
* {@link #toLongOptimistic(Object, int)} depending on whether the program point is valid or not.
* @param obj the object to convert
* @param programPoint the program point; can be invalid.
* @return the value converted to long
* @throws UnwarrantedOptimismException if the value can't be represented as long and the program point is valid.
*/
public static long toLongMaybeOptimistic(final Object obj, final int programPoint) {
return UnwarrantedOptimismException.isValid(programPoint) ? toLongOptimistic(obj, programPoint) : toLong(obj);
}
/**
* JavaScript compliant Object to int32 conversion
* See ECMA 9.5 ToInt32
@ -1098,10 +1004,6 @@ public enum JSType {
return UnwarrantedOptimismException.isValid(programPoint) ? toInt32Optimistic(obj, programPoint) : toInt32(obj);
}
// Minimum and maximum range between which every long value can be precisely represented as a double.
private static final long MAX_PRECISE_DOUBLE = 1L << 53;
private static final long MIN_PRECISE_DOUBLE = -MAX_PRECISE_DOUBLE;
/**
* JavaScript compliant long to int32 conversion
*
@ -1153,6 +1055,29 @@ public enum JSType {
return num & MAX_UINT;
}
/**
* Optimistic JavaScript compliant int to uint32 conversion
* @param num an int
* @param pp the program point
* @return the uint32 value if it can be represented by an int
* @throws UnwarrantedOptimismException if uint32 value cannot be represented by an int
*/
public static int toUint32Optimistic(final int num, final int pp) {
if (num >= 0) {
return num;
}
throw new UnwarrantedOptimismException(toUint32Double(num), pp, Type.NUMBER);
}
/**
* JavaScript compliant int to uint32 conversion with double return type
* @param num an int
* @return the uint32 value as double
*/
public static double toUint32Double(final int num) {
return (double) toUint32(num);
}
/**
* JavaScript compliant Object to uint16 conversion
* ECMA 9.7 ToUint16: (Unsigned 16 Bit Integer)
@ -1481,26 +1406,6 @@ public enum JSType {
* @throws UnwarrantedOptimismException if overflow occurs
*/
public static int addExact(final int x, final int y, final int programPoint) throws UnwarrantedOptimismException {
try {
return Math.addExact(x, y);
} catch (final ArithmeticException e) {
throw new UnwarrantedOptimismException((long)x + (long)y, programPoint);
}
}
/**
* Wrapper for addExact
*
* Catches ArithmeticException and rethrows as UnwarrantedOptimismException
* containing the result and the program point of the failure
*
* @param x first term
* @param y second term
* @param programPoint program point id
* @return the result
* @throws UnwarrantedOptimismException if overflow occurs
*/
public static long addExact(final long x, final long y, final int programPoint) throws UnwarrantedOptimismException {
try {
return Math.addExact(x, y);
} catch (final ArithmeticException e) {
@ -1521,26 +1426,6 @@ public enum JSType {
* @throws UnwarrantedOptimismException if overflow occurs
*/
public static int subExact(final int x, final int y, final int programPoint) throws UnwarrantedOptimismException {
try {
return Math.subtractExact(x, y);
} catch (final ArithmeticException e) {
throw new UnwarrantedOptimismException((long)x - (long)y, programPoint);
}
}
/**
* Wrapper for subExact
*
* Catches ArithmeticException and rethrows as UnwarrantedOptimismException
* containing the result and the program point of the failure
*
* @param x first term
* @param y second term
* @param programPoint program point id
* @return the result
* @throws UnwarrantedOptimismException if overflow occurs
*/
public static long subExact(final long x, final long y, final int programPoint) throws UnwarrantedOptimismException {
try {
return Math.subtractExact(x, y);
} catch (final ArithmeticException e) {
@ -1561,26 +1446,6 @@ public enum JSType {
* @throws UnwarrantedOptimismException if overflow occurs
*/
public static int mulExact(final int x, final int y, final int programPoint) throws UnwarrantedOptimismException {
try {
return Math.multiplyExact(x, y);
} catch (final ArithmeticException e) {
throw new UnwarrantedOptimismException((long)x * (long)y, programPoint);
}
}
/**
* Wrapper for mulExact
*
* Catches ArithmeticException and rethrows as UnwarrantedOptimismException
* containing the result and the program point of the failure
*
* @param x first term
* @param y second term
* @param programPoint program point id
* @return the result
* @throws UnwarrantedOptimismException if overflow occurs
*/
public static long mulExact(final long x, final long y, final int programPoint) throws UnwarrantedOptimismException {
try {
return Math.multiplyExact(x, y);
} catch (final ArithmeticException e) {
@ -1654,71 +1519,6 @@ public enum JSType {
}
}
/**
* Wrapper for divExact. Throws UnwarrantedOptimismException if the result of the division can't be represented as
* long.
*
* @param x first term
* @param y second term
* @param programPoint program point id
* @return the result
* @throws UnwarrantedOptimismException if the result of the division can't be represented as long.
*/
public static long divExact(final long x, final long y, final int programPoint) throws UnwarrantedOptimismException {
final long res;
try {
res = x / y;
} catch (final ArithmeticException e) {
assert y == 0L; // Only div by zero anticipated
throw new UnwarrantedOptimismException(x > 0L ? Double.POSITIVE_INFINITY : x < 0L ? Double.NEGATIVE_INFINITY : Double.NaN, programPoint);
}
final long rem = x % y;
if (rem == 0L) {
return res;
}
throw new UnwarrantedOptimismException((double)x / (double)y, programPoint);
}
/**
* Implements long division but allows {@code x / 0} to be represented as 0. Useful when division of two longs
* is coerced to long.
* @param x the dividend
* @param y the divisor
* @return the result
*/
public static long divZero(final long x, final long y) {
return y == 0L ? 0L : x / y;
}
/**
* Implements long remainder but allows {@code x % 0} to be represented as 0. Useful when remainder of two longs
* is coerced to long.
* @param x the dividend
* @param y the divisor
* @return the remainder
*/
public static long remZero(final long x, final long y) {
return y == 0L ? 0L : x % y;
}
/**
* Wrapper for modExact. Throws UnwarrantedOptimismException if the modulo can't be represented as int.
*
* @param x first term
* @param y second term
* @param programPoint program point id
* @return the result
* @throws UnwarrantedOptimismException if the modulo can't be represented as int.
*/
public static long remExact(final long x, final long y, final int programPoint) throws UnwarrantedOptimismException {
try {
return x % y;
} catch (final ArithmeticException e) {
assert y == 0L; // Only mod by zero anticipated
throw new UnwarrantedOptimismException(Double.NaN, programPoint);
}
}
/**
* Wrapper for decrementExact
*
@ -1734,26 +1534,7 @@ public enum JSType {
try {
return Math.decrementExact(x);
} catch (final ArithmeticException e) {
throw new UnwarrantedOptimismException((long)x - 1, programPoint);
}
}
/**
* Wrapper for decrementExact
*
* Catches ArithmeticException and rethrows as UnwarrantedOptimismException
* containing the result and the program point of the failure
*
* @param x number to negate
* @param programPoint program point id
* @return the result
* @throws UnwarrantedOptimismException if overflow occurs
*/
public static long decrementExact(final long x, final int programPoint) throws UnwarrantedOptimismException {
try {
return Math.decrementExact(x);
} catch (final ArithmeticException e) {
throw new UnwarrantedOptimismException((double)x - 1L, programPoint);
throw new UnwarrantedOptimismException((double)x - 1, programPoint);
}
}
@ -1772,26 +1553,7 @@ public enum JSType {
try {
return Math.incrementExact(x);
} catch (final ArithmeticException e) {
throw new UnwarrantedOptimismException((long)x + 1, programPoint);
}
}
/**
* Wrapper for incrementExact
*
* Catches ArithmeticException and rethrows as UnwarrantedOptimismException
* containing the result and the program point of the failure
*
* @param x the number to increment
* @param programPoint program point id
* @return the result
* @throws UnwarrantedOptimismException if overflow occurs
*/
public static long incrementExact(final long x, final int programPoint) throws UnwarrantedOptimismException {
try {
return Math.incrementExact(x);
} catch (final ArithmeticException e) {
throw new UnwarrantedOptimismException((double)x + 1L, programPoint);
throw new UnwarrantedOptimismException((double)x + 1, programPoint);
}
}
@ -1812,28 +1574,6 @@ public enum JSType {
throw new UnwarrantedOptimismException(-0.0, programPoint);
}
return Math.negateExact(x);
} catch (final ArithmeticException e) {
throw new UnwarrantedOptimismException(-(long)x, programPoint);
}
}
/**
* Wrapper for negateExact
*
* Catches ArithmeticException and rethrows as UnwarrantedOptimismException
* containing the result and the program point of the failure
*
* @param x the number to negate
* @param programPoint program point id
* @return the result
* @throws UnwarrantedOptimismException if overflow occurs
*/
public static long negateExact(final long x, final int programPoint) throws UnwarrantedOptimismException {
try {
if (x == 0L) {
throw new UnwarrantedOptimismException(-0.0, programPoint);
}
return Math.negateExact(x);
} catch (final ArithmeticException e) {
throw new UnwarrantedOptimismException(-(double)x, programPoint);
}
@ -1866,8 +1606,6 @@ public enum JSType {
return TYPE_UNDEFINED_INDEX;
} else if (type == int.class) {
return TYPE_INT_INDEX;
} else if (type == long.class) {
return TYPE_LONG_INDEX;
} else if (type == double.class) {
return TYPE_DOUBLE_INDEX;
} else if (!type.isPrimitive()) {
@ -1972,8 +1710,6 @@ public enum JSType {
public static Class<?> getBoxedClass(final Class<?> clazz) {
if (clazz == int.class) {
return Integer.class;
} else if (clazz == long.class) {
return Long.class;
} else if (clazz == double.class) {
return Double.class;
}
@ -1991,8 +1727,6 @@ public enum JSType {
if (o != null) {
if (o.getClass() == Integer.class) {
return MH.constant(int.class, ((Integer)o));
} else if (o.getClass() == Long.class) {
return MH.constant(long.class, ((Long)o));
} else if (o.getClass() == Double.class) {
return MH.constant(double.class, ((Double)o));
}
@ -2010,8 +1744,6 @@ public enum JSType {
return Object.class;
} else if (o.getClass() == Integer.class) {
return int.class;
} else if (o.getClass() == Long.class) {
return long.class;
} else if (o.getClass() == Double.class) {
return double.class;
} else {

View File

@ -43,52 +43,42 @@ import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
*/
public final class OptimisticReturnFilters {
private static final MethodHandle[] ENSURE_INT;
private static final MethodHandle[] ENSURE_LONG;
private static final MethodHandle[] ENSURE_NUMBER;
// These extend the type index constants in JSType
private static final int VOID_TYPE_INDEX;
private static final int BOOLEAN_TYPE_INDEX;
private static final int CHAR_TYPE_INDEX;
private static final int LONG_TYPE_INDEX;
private static final int FLOAT_TYPE_INDEX;
private static final int VOID_TYPE_INDEX;
static {
final MethodHandle INT_DOUBLE = findOwnMH("ensureInt", int.class, double.class, int.class);
ENSURE_INT = new MethodHandle[] {
null,
findOwnMH("ensureInt", int.class, long.class, int.class),
INT_DOUBLE,
findOwnMH("ensureInt", int.class, Object.class, int.class),
findOwnMH("ensureInt", int.class, int.class),
findOwnMH("ensureInt", int.class, boolean.class, int.class),
findOwnMH("ensureInt", int.class, char.class, int.class),
findOwnMH("ensureInt", int.class, long.class, int.class),
INT_DOUBLE.asType(INT_DOUBLE.type().changeParameterType(0, float.class)),
};
VOID_TYPE_INDEX = ENSURE_INT.length - 4;
BOOLEAN_TYPE_INDEX = ENSURE_INT.length - 3;
CHAR_TYPE_INDEX = ENSURE_INT.length - 2;
VOID_TYPE_INDEX = ENSURE_INT.length - 5;
BOOLEAN_TYPE_INDEX = ENSURE_INT.length - 4;
CHAR_TYPE_INDEX = ENSURE_INT.length - 3;
LONG_TYPE_INDEX = ENSURE_INT.length - 2;
FLOAT_TYPE_INDEX = ENSURE_INT.length - 1;
final MethodHandle LONG_DOUBLE = findOwnMH("ensureLong", long.class, double.class, int.class);
ENSURE_LONG = new MethodHandle[] {
null,
null,
LONG_DOUBLE,
findOwnMH("ensureLong", long.class, Object.class, int.class),
ENSURE_INT[VOID_TYPE_INDEX].asType(ENSURE_INT[VOID_TYPE_INDEX].type().changeReturnType(long.class)),
ENSURE_INT[BOOLEAN_TYPE_INDEX].asType(ENSURE_INT[BOOLEAN_TYPE_INDEX].type().changeReturnType(long.class)),
ENSURE_INT[CHAR_TYPE_INDEX].asType(ENSURE_INT[CHAR_TYPE_INDEX].type().changeReturnType(long.class)),
LONG_DOUBLE.asType(LONG_DOUBLE.type().changeParameterType(0, float.class)),
};
ENSURE_NUMBER = new MethodHandle[] {
null,
null,
null,
findOwnMH("ensureNumber", double.class, Object.class, int.class),
ENSURE_INT[VOID_TYPE_INDEX].asType(ENSURE_INT[VOID_TYPE_INDEX].type().changeReturnType(double.class)),
ENSURE_INT[BOOLEAN_TYPE_INDEX].asType(ENSURE_INT[BOOLEAN_TYPE_INDEX].type().changeReturnType(double.class)),
ENSURE_INT[CHAR_TYPE_INDEX].asType(ENSURE_INT[CHAR_TYPE_INDEX].type().changeReturnType(double.class)),
findOwnMH("ensureNumber", double.class, long.class, int.class),
null
};
}
@ -136,8 +126,6 @@ public final class OptimisticReturnFilters {
final int provableTypeIndex = getProvableTypeIndex(provable);
if (actual == int.class) {
guard = ENSURE_INT[provableTypeIndex];
} else if (actual == long.class) {
guard = ENSURE_LONG[provableTypeIndex];
} else if (actual == double.class) {
guard = ENSURE_NUMBER[provableTypeIndex];
} else {
@ -167,6 +155,8 @@ public final class OptimisticReturnFilters {
return 0; // never needs a guard, as it's assignable to int
} else if(provable == char.class) {
return CHAR_TYPE_INDEX;
} else if(provable == long.class) {
return LONG_TYPE_INDEX;
} else if(provable == float.class) {
return FLOAT_TYPE_INDEX;
}
@ -179,7 +169,7 @@ public final class OptimisticReturnFilters {
if (JSType.isRepresentableAsInt(arg)) {
return (int)arg;
}
throw new UnwarrantedOptimismException(arg, programPoint);
throw UnwarrantedOptimismException.createNarrowest(arg, programPoint);
}
@SuppressWarnings("unused")
@ -187,7 +177,7 @@ public final class OptimisticReturnFilters {
if (JSType.isStrictlyRepresentableAsInt(arg)) {
return (int)arg;
}
throw new UnwarrantedOptimismException(arg, programPoint);
throw new UnwarrantedOptimismException(arg, programPoint, Type.NUMBER);
}
/**
@ -210,7 +200,7 @@ public final class OptimisticReturnFilters {
return (int)d;
}
}
throw new UnwarrantedOptimismException(arg, programPoint);
throw UnwarrantedOptimismException.createNarrowest(arg, programPoint);
}
private static boolean isPrimitiveNumberWrapper(final Object obj) {
@ -238,51 +228,30 @@ public final class OptimisticReturnFilters {
throw new UnwarrantedOptimismException(ScriptRuntime.UNDEFINED, programPoint, Type.OBJECT);
}
private static long ensureLong(final double arg, final int programPoint) {
if (JSType.isStrictlyRepresentableAsLong(arg)) {
return (long)arg;
@SuppressWarnings("unused")
private static double ensureNumber(final long arg, final int programPoint) {
if (JSType.isRepresentableAsDouble(arg)) {
return (double) arg;
}
throw new UnwarrantedOptimismException(arg, programPoint);
throw new UnwarrantedOptimismException(arg, programPoint, Type.OBJECT);
}
/**
* Returns the argument value as a long. If the argument is not a wrapper for a primitive numeric type
* with a value that can be exactly represented as a long, throw an {@link UnwarrantedOptimismException}.
* This method is only public so that generated script code can use it. See {code CodeGenerator.ENSURE_LONG}.
* @param arg the original argument.
* @param programPoint the program point used in the exception
* @return the value of the argument as a long.
* @throws UnwarrantedOptimismException if the argument is not a wrapper for a primitive numeric type with
* a value that can be exactly represented as a long
*/
public static long ensureLong(final Object arg, final int programPoint) {
if (arg != null) {
final Class<?> c = arg.getClass();
if (c == Long.class) {
// Must check for Long separately, as Long.doubleValue() isn't precise.
return ((Long)arg);
} else if (c == Integer.class || c == Double.class || c == Float.class || c == Short.class ||
c == Byte.class) {
return ensureLong(((Number)arg).doubleValue(), programPoint);
}
}
throw new UnwarrantedOptimismException(arg, programPoint);
}
/**
* Returns the argument value as a double. If the argument is not a a wrapper for a primitive numeric type
* throw an {@link UnwarrantedOptimismException}.This method is only public so that generated script code
* can use it. See {code CodeGenerator.ENSURE_NUMBER}.
* Returns the argument value as a double. If the argument is not a wrapper for a primitive numeric type
* that can be represented as double throw an {@link UnwarrantedOptimismException}.
* This method is only public so that generated script code can use it. See {code CodeGenerator.ENSURE_NUMBER}.
* @param arg the original argument.
* @param programPoint the program point used in the exception
* @return the value of the argument as a double.
* @throws UnwarrantedOptimismException if the argument is not a wrapper for a primitive numeric type.
*/
public static double ensureNumber(final Object arg, final int programPoint) {
if (isPrimitiveNumberWrapper(arg)) {
return ((Number)arg).doubleValue();
if (isPrimitiveNumberWrapper(arg)
&& (arg.getClass() != Long.class || JSType.isRepresentableAsDouble((Long) arg))) {
return ((Number) arg).doubleValue();
}
throw new UnwarrantedOptimismException(arg, programPoint);
throw new UnwarrantedOptimismException(arg, programPoint, Type.OBJECT);
}
private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {

View File

@ -442,16 +442,6 @@ public abstract class Property implements Serializable {
*/
public abstract int getIntValue(final ScriptObject self, final ScriptObject owner);
/**
* get the Object value of this property from {@code owner}. This allows to bypass creation of the
* getter MethodHandle for spill and user accessor properties.
*
* @param self the this object
* @param owner the owner of the property
* @return the property value
*/
public abstract long getLongValue(final ScriptObject self, final ScriptObject owner);
/**
* get the Object value of this property from {@code owner}. This allows to bypass creation of the
* getter MethodHandle for spill and user accessor properties.
@ -483,17 +473,6 @@ public abstract class Property implements Serializable {
*/
public abstract void setValue(final ScriptObject self, final ScriptObject owner, final int value, final boolean strict);
/**
* Set the value of this property in {@code owner}. This allows to bypass creation of the
* setter MethodHandle for spill and user accessor properties.
*
* @param self the this object
* @param owner the owner object
* @param value the new property value
* @param strict is this a strict setter?
*/
public abstract void setValue(final ScriptObject self, final ScriptObject owner, final long value, final boolean strict);
/**
* Set the value of this property in {@code owner}. This allows to bypass creation of the
* setter MethodHandle for spill and user accessor properties.
@ -593,8 +572,6 @@ public abstract class Property implements Serializable {
return "undef";
} else if (type == int.class) {
return "i";
} else if (type == long.class) {
return "j";
} else if (type == double.class) {
return "d";
} else {

View File

@ -51,14 +51,6 @@ public interface PropertyAccess {
*/
public int getInt(double key, int programPoint);
/**
* Get the value for a given key and return it as an int
* @param key the key
* @param programPoint or INVALID_PROGRAM_POINT if pessimistic
* @return the value
*/
public int getInt(long key, int programPoint);
/**
* Get the value for a given key and return it as an int
* @param key the key
@ -67,38 +59,6 @@ public interface PropertyAccess {
*/
public int getInt(int key, int programPoint);
/**
* Get the value for a given key and return it as a long
* @param key the key
* @param programPoint or INVALID_PROGRAM_POINT if pessimistic
* @return the value
*/
public long getLong(Object key, int programPoint);
/**
* Get the value for a given key and return it as a long
* @param key the key
* @param programPoint or INVALID_PROGRAM_POINT if pessimistic
* @return the value
*/
public long getLong(double key, int programPoint);
/**
* Get the value for a given key and return it as a long
* @param key the key
* @param programPoint or INVALID_PROGRAM_POINT if pessimistic
* @return the value
*/
public long getLong(long key, int programPoint);
/**
* Get the value for a given key and return it as a long
* @param key the key
* @param programPoint or INVALID_PROGRAM_POINT if pessimistic
* @return the value
*/
public long getLong(int key, int programPoint);
/**
* Get the value for a given key and return it as a double
* @param key the key
@ -115,14 +75,6 @@ public interface PropertyAccess {
*/
public double getDouble(double key, int programPoint);
/**
* Get the value for a given key and return it as a double
* @param key the key
* @param programPoint or INVALID_PROGRAM_POINT if pessimistic
* @return the value
*/
public double getDouble(long key, int programPoint);
/**
* Get the value for a given key and return it as a double
* @param key the key
@ -145,13 +97,6 @@ public interface PropertyAccess {
*/
public Object get(double key);
/**
* Get the value for a given key and return it as an Object
* @param key the key
* @return the value
*/
public Object get(long key);
/**
* Get the value for a given key and return it as an Object
* @param key the key
@ -167,14 +112,6 @@ public interface PropertyAccess {
*/
public void set(Object key, int value, int flags);
/**
* Set the value of a given key
* @param key the key
* @param value the value
* @param flags call site flags
*/
public void set(Object key, long value, int flags);
/**
* Set the value of a given key
* @param key the key
@ -199,14 +136,6 @@ public interface PropertyAccess {
*/
public void set(double key, int value, int flags);
/**
* Set the value of a given key
* @param key the key
* @param value the value
* @param flags call site flags
*/
public void set(double key, long value, int flags);
/**
* Set the value of a given key
* @param key the key
@ -223,38 +152,6 @@ public interface PropertyAccess {
*/
public void set(double key, Object value, int flags);
/**
* Set the value of a given key
* @param key the key
* @param value the value
* @param flags call site flags
*/
public void set(long key, int value, int flags);
/**
* Set the value of a given key
* @param key the key
* @param value the value
* @param flags call site flags
*/
public void set(long key, long value, int flags);
/**
* Set the value of a given key
* @param key the key
* @param value the value
* @param flags call site flags
*/
public void set(long key, double value, int flags);
/**
* Set the value of a given key
* @param key the key
* @param value the value
* @param flags call site flags
*/
public void set(long key, Object value, int flags);
/**
* Set the value of a given key
* @param key the key
@ -263,14 +160,6 @@ public interface PropertyAccess {
*/
public void set(int key, int value, int flags);
/**
* Set the value of a given key
* @param key the key
* @param value the value
* @param flags call site flags
*/
public void set(int key, long value, int flags);
/**
* Set the value of a given key
* @param key the key
@ -301,13 +190,6 @@ public interface PropertyAccess {
*/
public boolean has(int key);
/**
* Check if the given key exists anywhere in the proto chain
* @param key the key
* @return true if key exists
*/
public boolean has(long key);
/**
* Check if the given key exists anywhere in the proto chain
* @param key the key
@ -329,13 +211,6 @@ public interface PropertyAccess {
*/
public boolean hasOwnProperty(int key);
/**
* Check if the given key exists directly in the implementor
* @param key the key
* @return true if key exists
*/
public boolean hasOwnProperty(long key);
/**
* Check if the given key exists directly in the implementor
* @param key the key
@ -351,14 +226,6 @@ public interface PropertyAccess {
*/
public boolean delete(int key, boolean strict);
/**
* Delete a property with the given key from the implementor
* @param key the key
* @param strict are we in strict mode
* @return true if deletion succeeded, false otherwise
*/
public boolean delete(long key, boolean strict);
/**
* Delete a property with the given key from the implementor
* @param key the key

View File

@ -33,7 +33,6 @@ import static jdk.nashorn.internal.runtime.ECMAErrors.referenceError;
import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
import static jdk.nashorn.internal.runtime.JSType.UNDEFINED_DOUBLE;
import static jdk.nashorn.internal.runtime.JSType.UNDEFINED_INT;
import static jdk.nashorn.internal.runtime.JSType.UNDEFINED_LONG;
import static jdk.nashorn.internal.runtime.PropertyDescriptor.CONFIGURABLE;
import static jdk.nashorn.internal.runtime.PropertyDescriptor.ENUMERABLE;
import static jdk.nashorn.internal.runtime.PropertyDescriptor.GET;
@ -188,7 +187,6 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
static final MethodHandle[] SET_SLOW = new MethodHandle[] {
findOwnMH_V("set", void.class, Object.class, int.class, int.class),
findOwnMH_V("set", void.class, Object.class, long.class, int.class),
findOwnMH_V("set", void.class, Object.class, double.class, int.class),
findOwnMH_V("set", void.class, Object.class, Object.class, int.class)
};
@ -1087,21 +1085,6 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
return UNDEFINED_INT;
}
private static long getLongValue(final FindProperty find, final int programPoint) {
final MethodHandle getter = find.getGetter(long.class, programPoint, null);
if (getter != null) {
try {
return (long)getter.invokeExact((Object)find.getGetterReceiver());
} catch (final Error|RuntimeException e) {
throw e;
} catch (final Throwable e) {
throw new RuntimeException(e);
}
}
return UNDEFINED_LONG;
}
private static double getDoubleValue(final FindProperty find, final int programPoint) {
final MethodHandle getter = find.getGetter(double.class, programPoint, null);
if (getter != null) {
@ -2803,18 +2786,6 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
return getInt(index, JSType.toString(key), programPoint);
}
@Override
public int getInt(final long key, final int programPoint) {
final int index = getArrayIndex(key);
final ArrayData array = getArray();
if (array.has(index)) {
return isValid(programPoint) ? array.getIntOptimistic(index, programPoint) : array.getInt(index);
}
return getInt(index, JSType.toString(key), programPoint);
}
@Override
public int getInt(final int key, final int programPoint) {
final int index = getArrayIndex(key);
@ -2827,88 +2798,6 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
return getInt(index, JSType.toString(key), programPoint);
}
private long getLong(final int index, final Object key, final int programPoint) {
if (isValidArrayIndex(index)) {
for (ScriptObject object = this; ; ) {
if (object.getMap().containsArrayKeys()) {
final FindProperty find = object.findProperty(key, false, this);
if (find != null) {
return getLongValue(find, programPoint);
}
}
if ((object = object.getProto()) == null) {
break;
}
final ArrayData array = object.getArray();
if (array.has(index)) {
return isValid(programPoint) ?
array.getLongOptimistic(index, programPoint) :
array.getLong(index);
}
}
} else {
final FindProperty find = findProperty(key, true);
if (find != null) {
return getLongValue(find, programPoint);
}
}
return JSType.toLong(invokeNoSuchProperty(key, false, programPoint));
}
@Override
public long getLong(final Object key, final int programPoint) {
final Object primitiveKey = JSType.toPrimitive(key, String.class);
final int index = getArrayIndex(primitiveKey);
final ArrayData array = getArray();
if (array.has(index)) {
return isValid(programPoint) ? array.getLongOptimistic(index, programPoint) : array.getLong(index);
}
return getLong(index, JSType.toPropertyKey(primitiveKey), programPoint);
}
@Override
public long getLong(final double key, final int programPoint) {
final int index = getArrayIndex(key);
final ArrayData array = getArray();
if (array.has(index)) {
return isValid(programPoint) ? array.getLongOptimistic(index, programPoint) : array.getLong(index);
}
return getLong(index, JSType.toString(key), programPoint);
}
@Override
public long getLong(final long key, final int programPoint) {
final int index = getArrayIndex(key);
final ArrayData array = getArray();
if (array.has(index)) {
return isValid(programPoint) ? array.getLongOptimistic(index, programPoint) : array.getLong(index);
}
return getLong(index, JSType.toString(key), programPoint);
}
@Override
public long getLong(final int key, final int programPoint) {
final int index = getArrayIndex(key);
final ArrayData array = getArray();
if (array.has(index)) {
return isValid(programPoint) ? array.getLongOptimistic(key, programPoint) : array.getLong(key);
}
return getLong(index, JSType.toString(key), programPoint);
}
private double getDouble(final int index, final Object key, final int programPoint) {
if (isValidArrayIndex(index)) {
for (ScriptObject object = this; ; ) {
@ -2967,18 +2856,6 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
return getDouble(index, JSType.toString(key), programPoint);
}
@Override
public double getDouble(final long key, final int programPoint) {
final int index = getArrayIndex(key);
final ArrayData array = getArray();
if (array.has(index)) {
return isValid(programPoint) ? array.getDoubleOptimistic(index, programPoint) : array.getDouble(index);
}
return getDouble(index, JSType.toString(key), programPoint);
}
@Override
public double getDouble(final int key, final int programPoint) {
final int index = getArrayIndex(key);
@ -3048,18 +2925,6 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
return get(index, JSType.toString(key));
}
@Override
public Object get(final long key) {
final int index = getArrayIndex(key);
final ArrayData array = getArray();
if (array.has(index)) {
return array.getObject(index);
}
return get(index, JSType.toString(key));
}
@Override
public Object get(final int key) {
final int index = getArrayIndex(key);
@ -3143,15 +3008,6 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
}
}
private void doesNotHave(final int index, final long value, final int callSiteFlags) {
final long oldLength = getArray().length();
final long longIndex = ArrayIndex.toLongIndex(index);
if (!doesNotHaveCheckArrayKeys(longIndex, value, callSiteFlags) && !doesNotHaveEnsureLength(longIndex, oldLength, callSiteFlags)) {
final boolean strict = isStrictFlag(callSiteFlags);
setArray(getArray().set(index, value, strict).safeDelete(oldLength, longIndex - 1, strict));
}
}
private void doesNotHave(final int index, final double value, final int callSiteFlags) {
final long oldLength = getArray().length();
final long longIndex = ArrayIndex.toLongIndex(index);
@ -3257,26 +3113,6 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value));
}
@Override
public void set(final Object key, final long value, final int callSiteFlags) {
final Object primitiveKey = JSType.toPrimitive(key, String.class);
final int index = getArrayIndex(primitiveKey);
if (isValidArrayIndex(index)) {
final ArrayData data = getArray();
if (data.has(index)) {
setArray(data.set(index, value, isStrictFlag(callSiteFlags)));
} else {
doesNotHave(index, value, callSiteFlags);
}
return;
}
final Object propName = JSType.toPropertyKey(primitiveKey);
setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value));
}
@Override
public void set(final Object key, final double value, final int callSiteFlags) {
final Object primitiveKey = JSType.toPrimitive(key, String.class);
@ -3336,25 +3172,6 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value));
}
@Override
public void set(final double key, final long value, final int callSiteFlags) {
final int index = getArrayIndex(key);
if (isValidArrayIndex(index)) {
final ArrayData data = getArray();
if (data.has(index)) {
setArray(data.set(index, value, isStrictFlag(callSiteFlags)));
} else {
doesNotHave(index, value, callSiteFlags);
}
return;
}
final String propName = JSType.toString(key);
setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value));
}
@Override
public void set(final double key, final double value, final int callSiteFlags) {
final int index = getArrayIndex(key);
@ -3393,82 +3210,6 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
setObject(findProperty(propName, true), callSiteFlags, propName, value);
}
@Override
public void set(final long key, final int value, final int callSiteFlags) {
final int index = getArrayIndex(key);
if (isValidArrayIndex(index)) {
final ArrayData data = getArray();
if (data.has(index)) {
setArray(data.set(index, value, isStrictFlag(callSiteFlags)));
} else {
doesNotHave(index, value, callSiteFlags);
}
return;
}
final String propName = JSType.toString(key);
setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value));
}
@Override
public void set(final long key, final long value, final int callSiteFlags) {
final int index = getArrayIndex(key);
if (isValidArrayIndex(index)) {
final ArrayData data = getArray();
if (data.has(index)) {
setArray(data.set(index, value, isStrictFlag(callSiteFlags)));
} else {
doesNotHave(index, value, callSiteFlags);
}
return;
}
final String propName = JSType.toString(key);
setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value));
}
@Override
public void set(final long key, final double value, final int callSiteFlags) {
final int index = getArrayIndex(key);
if (isValidArrayIndex(index)) {
final ArrayData data = getArray();
if (data.has(index)) {
setArray(data.set(index, value, isStrictFlag(callSiteFlags)));
} else {
doesNotHave(index, value, callSiteFlags);
}
return;
}
final String propName = JSType.toString(key);
setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value));
}
@Override
public void set(final long key, final Object value, final int callSiteFlags) {
final int index = getArrayIndex(key);
if (isValidArrayIndex(index)) {
final ArrayData data = getArray();
if (data.has(index)) {
setArray(data.set(index, value, isStrictFlag(callSiteFlags)));
} else {
doesNotHave(index, value, callSiteFlags);
}
return;
}
final String propName = JSType.toString(key);
setObject(findProperty(propName, true), callSiteFlags, propName, value);
}
@Override
public void set(final int key, final int value, final int callSiteFlags) {
final int index = getArrayIndex(key);
@ -3486,25 +3227,6 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value));
}
@Override
public void set(final int key, final long value, final int callSiteFlags) {
final int index = getArrayIndex(key);
if (isValidArrayIndex(index)) {
final ArrayData data = getArray();
if (data.has(index)) {
setArray(data.set(index, value, isStrictFlag(callSiteFlags)));
} else {
doesNotHave(index, value, callSiteFlags);
}
return;
}
final String propName = JSType.toString(key);
setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value));
}
@Override
public void set(final int key, final double value, final int callSiteFlags) {
final int index = getArrayIndex(key);
@ -3556,12 +3278,6 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
return isValidArrayIndex(index) ? hasArrayProperty(index) : hasProperty(JSType.toString(key), true);
}
@Override
public boolean has(final long key) {
final int index = getArrayIndex(key);
return isValidArrayIndex(index) ? hasArrayProperty(index) : hasProperty(JSType.toString(key), true);
}
@Override
public boolean has(final int key) {
final int index = getArrayIndex(key);
@ -3594,12 +3310,6 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
return isValidArrayIndex(index) ? hasOwnArrayProperty(index) : hasProperty(JSType.toString(key), false);
}
@Override
public boolean hasOwnProperty(final long key) {
final int index = getArrayIndex(key);
return isValidArrayIndex(index) ? hasOwnArrayProperty(index) : hasProperty(JSType.toString(key), false);
}
@Override
public boolean hasOwnProperty(final double key) {
final int index = getArrayIndex(key);
@ -3625,22 +3335,6 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
return deleteObject(JSType.toObject(key), strict);
}
@Override
public boolean delete(final long key, final boolean strict) {
final int index = getArrayIndex(key);
final ArrayData array = getArray();
if (array.has(index)) {
if (array.canDelete(index, strict)) {
setArray(array.delete(index));
return true;
}
return false;
}
return deleteObject(JSType.toObject(key), strict);
}
@Override
public boolean delete(final double key, final boolean strict) {
final int index = getArrayIndex(key);

View File

@ -49,7 +49,10 @@ public final class UnwarrantedOptimismException extends RuntimeException {
private final Type returnType;
/**
* Constructor
* Constructor without explicit return type. The return type is determined statically from the class of
* the return value, and only canonical internal number representations are recognized. Use
* {@link #createNarrowest} if you want to handle float and long values as numbers instead of objects.
*
* @param returnValue actual return value from the too narrow operation
* @param programPoint program point where unwarranted optimism was detected
*/
@ -58,7 +61,7 @@ public final class UnwarrantedOptimismException extends RuntimeException {
}
/**
* Check if a program point is valid
* Check if a program point is valid.
* @param programPoint the program point
* @return true if valid
*/
@ -70,8 +73,6 @@ public final class UnwarrantedOptimismException extends RuntimeException {
private static Type getReturnType(final Object v) {
if (v instanceof Double) {
return Type.NUMBER;
} else if (v instanceof Long) {
return Type.LONG;
}
assert !(v instanceof Integer) : v + " is an int"; // Can't have an unwarranted optimism exception with int
return Type.OBJECT;
@ -96,6 +97,22 @@ public final class UnwarrantedOptimismException extends RuntimeException {
this.returnType = returnType;
}
/**
* Create an {@code UnwarrantedOptimismException} with the given return value and program point, narrowing
* the type to {@code number} if the value is a float or a long that can be represented as double.
*
* @param returnValue the return value
* @param programPoint the program point
* @return the exception
*/
public static UnwarrantedOptimismException createNarrowest(final Object returnValue, final int programPoint) {
if (returnValue instanceof Float
|| (returnValue instanceof Long && JSType.isRepresentableAsDouble((Long) returnValue))) {
return new UnwarrantedOptimismException(((Number) returnValue).doubleValue(), programPoint, Type.NUMBER);
}
return new UnwarrantedOptimismException(returnValue, programPoint);
}
/**
* Get the return value. This is a destructive readout, after the method is invoked the return value is null'd out.
* @return return value

View File

@ -71,13 +71,11 @@ public final class UserAccessorProperty extends SpillProperty {
/** Getter method handle */
private final static MethodHandle INVOKE_OBJECT_GETTER = findOwnMH_S("invokeObjectGetter", Object.class, Accessors.class, MethodHandle.class, Object.class);
private final static MethodHandle INVOKE_INT_GETTER = findOwnMH_S("invokeIntGetter", int.class, Accessors.class, MethodHandle.class, int.class, Object.class);
private final static MethodHandle INVOKE_LONG_GETTER = findOwnMH_S("invokeLongGetter", long.class, Accessors.class, MethodHandle.class, int.class, Object.class);
private final static MethodHandle INVOKE_NUMBER_GETTER = findOwnMH_S("invokeNumberGetter", double.class, Accessors.class, MethodHandle.class, int.class, Object.class);
/** Setter method handle */
private final static MethodHandle INVOKE_OBJECT_SETTER = findOwnMH_S("invokeObjectSetter", void.class, Accessors.class, MethodHandle.class, String.class, Object.class, Object.class);
private final static MethodHandle INVOKE_INT_SETTER = findOwnMH_S("invokeIntSetter", void.class, Accessors.class, MethodHandle.class, String.class, Object.class, int.class);
private final static MethodHandle INVOKE_LONG_SETTER = findOwnMH_S("invokeLongSetter", void.class, Accessors.class, MethodHandle.class, String.class, Object.class, long.class);
private final static MethodHandle INVOKE_NUMBER_SETTER = findOwnMH_S("invokeNumberSetter", void.class, Accessors.class, MethodHandle.class, String.class, Object.class, double.class);
private static final Object OBJECT_GETTER_INVOKER_KEY = new Object();
@ -187,11 +185,6 @@ public final class UserAccessorProperty extends SpillProperty {
return (int)getObjectValue(self, owner);
}
@Override
public long getLongValue(final ScriptObject self, final ScriptObject owner) {
return (long)getObjectValue(self, owner);
}
@Override
public double getDoubleValue(final ScriptObject self, final ScriptObject owner) {
return (double)getObjectValue(self, owner);
@ -213,11 +206,6 @@ public final class UserAccessorProperty extends SpillProperty {
setValue(self, owner, (Object) value, strict);
}
@Override
public void setValue(final ScriptObject self, final ScriptObject owner, final long value, final boolean strict) {
setValue(self, owner, (Object) value, strict);
}
@Override
public void setValue(final ScriptObject self, final ScriptObject owner, final double value, final boolean strict) {
setValue(self, owner, (Object) value, strict);
@ -244,8 +232,6 @@ public final class UserAccessorProperty extends SpillProperty {
public MethodHandle getOptimisticGetter(final Class<?> type, final int programPoint) {
if (type == int.class) {
return INVOKE_INT_GETTER;
} else if (type == long.class) {
return INVOKE_LONG_GETTER;
} else if (type == double.class) {
return INVOKE_NUMBER_GETTER;
} else {
@ -269,8 +255,6 @@ public final class UserAccessorProperty extends SpillProperty {
public MethodHandle getSetter(final Class<?> type, final PropertyMap currentMap) {
if (type == int.class) {
return INVOKE_INT_SETTER;
} else if (type == long.class) {
return INVOKE_LONG_SETTER;
} else if (type == double.class) {
return INVOKE_NUMBER_SETTER;
} else {
@ -319,16 +303,6 @@ public final class UserAccessorProperty extends SpillProperty {
throw new UnwarrantedOptimismException(UNDEFINED, programPoint);
}
@SuppressWarnings("unused")
private static long invokeLongGetter(final Accessors gs, final MethodHandle invoker, final int programPoint, final Object self) throws Throwable {
final Object func = gs.getter;
if (func instanceof ScriptFunction) {
return (long) invoker.invokeExact(func, self);
}
throw new UnwarrantedOptimismException(UNDEFINED, programPoint);
}
@SuppressWarnings("unused")
private static double invokeNumberGetter(final Accessors gs, final MethodHandle invoker, final int programPoint, final Object self) throws Throwable {
final Object func = gs.getter;
@ -359,16 +333,6 @@ public final class UserAccessorProperty extends SpillProperty {
}
}
@SuppressWarnings("unused")
private static void invokeLongSetter(final Accessors gs, final MethodHandle invoker, final String name, final Object self, final long value) throws Throwable {
final Object func = gs.setter;
if (func instanceof ScriptFunction) {
invoker.invokeExact(func, self, value);
} else if (name != null) {
throw typeError("property.has.no.setter", name, ScriptRuntime.safeToString(self));
}
}
@SuppressWarnings("unused")
private static void invokeNumberSetter(final Accessors gs, final MethodHandle invoker, final String name, final Object self, final double value) throws Throwable {
final Object func = gs.setter;

View File

@ -52,9 +52,6 @@ public abstract class ArrayData {
/** Minimum chunk size for underlying arrays */
protected static final int CHUNK_SIZE = 32;
/** Mask for getting a chunk */
protected static final int CHUNK_MASK = CHUNK_SIZE - 1;
/** Untouched data - still link callsites as IntArrayData, but expands to
* a proper ArrayData when we try to write to it */
public static final ArrayData EMPTY_ARRAY = new UntouchedArrayData();
@ -163,11 +160,6 @@ public abstract class ArrayData {
return toRealArrayData(index).set(index, value, strict);
}
@Override
public ArrayData set(final int index, final long value, final boolean strict) {
return toRealArrayData(index).set(index, value, strict);
}
@Override
public ArrayData set(final int index, final double value, final boolean strict) {
return toRealArrayData(index).set(index, value, strict);
@ -178,11 +170,6 @@ public abstract class ArrayData {
throw new ArrayIndexOutOfBoundsException(index); //empty
}
@Override
public long getLong(final int index) {
throw new ArrayIndexOutOfBoundsException(index); //empty
}
@Override
public double getDouble(final int index) {
throw new ArrayIndexOutOfBoundsException(index); //empty
@ -288,13 +275,13 @@ public abstract class ArrayData {
* @param length the initial length
* @return ArrayData
*/
public static ArrayData allocate(final int length) {
if (length == 0) {
public static ArrayData allocate(final long length) {
if (length == 0L) {
return new IntArrayData();
} else if (length >= SparseArrayData.MAX_DENSE_LENGTH) {
return new SparseArrayData(EMPTY_ARRAY, length);
} else {
return new DeletedRangeArrayFilter(new IntArrayData(length), 0, length - 1);
return new DeletedRangeArrayFilter(new IntArrayData((int) length), 0, length - 1);
}
}
@ -309,8 +296,6 @@ public abstract class ArrayData {
if (clazz == int[].class) {
return new IntArrayData((int[])array, ((int[])array).length);
} else if (clazz == long[].class) {
return new LongArrayData((long[])array, ((long[])array).length);
} else if (clazz == double[].class) {
return new NumberArrayData((double[])array, ((double[])array).length);
} else {
@ -328,16 +313,6 @@ public abstract class ArrayData {
return new IntArrayData(array, array.length);
}
/**
* Allocate an ArrayData wrapping a given array
*
* @param array the array to use for initial elements
* @return the ArrayData
*/
public static ArrayData allocate(final long[] array) {
return new LongArrayData(array, array.length);
}
/**
* Allocate an ArrayData wrapping a given array
*
@ -536,16 +511,6 @@ public abstract class ArrayData {
*/
public abstract ArrayData set(final int index, final int value, final boolean strict);
/**
* Set a long value at a given index
*
* @param index the index
* @param value the value
* @param strict are we in strict mode
* @return new array data (or same)
*/
public abstract ArrayData set(final int index, final long value, final boolean strict);
/**
* Set an double value at a given index
*
@ -608,26 +573,6 @@ public abstract class ArrayData {
throw new UnwarrantedOptimismException(getObject(index), programPoint, getOptimisticType());
}
/**
* Get a long value from a given index
*
* @param index the index
* @return the value
*/
public abstract long getLong(final int index);
/**
* Get optimistic long - default is that it's impossible. Overridden
* by arrays that actually represents longs or narrower
*
* @param index the index
* @param programPoint program point
* @return the value
*/
public long getLongOptimistic(final int index, final int programPoint) {
throw new UnwarrantedOptimismException(getObject(index), programPoint, getOptimisticType());
}
/**
* Get a double value from a given index
*
@ -821,12 +766,8 @@ public abstract class ArrayData {
return Object.class;
}
final Class<?> itemClass = item.getClass();
if (itemClass == Long.class) {
if (itemClass == Double.class || itemClass == Float.class || itemClass == Long.class) {
if (widest == Integer.class) {
widest = Long.class;
}
} else if (itemClass == Double.class || itemClass == Float.class) {
if (widest == Integer.class || widest == Long.class) {
widest = Double.class;
}
} else if (itemClass != Integer.class && itemClass != Short.class && itemClass != Byte.class) {

View File

@ -108,13 +108,6 @@ abstract class ArrayFilter extends ArrayData {
return this;
}
@Override
public ArrayData set(final int index, final long value, final boolean strict) {
underlying = underlying.set(index, value, strict);
setLength(underlying.length());
return this;
}
@Override
public ArrayData set(final int index, final double value, final boolean strict) {
underlying = underlying.set(index, value, strict);
@ -149,16 +142,6 @@ abstract class ArrayFilter extends ArrayData {
return underlying.getIntOptimistic(index, programPoint);
}
@Override
public long getLong(final int index) {
return underlying.getLong(index);
}
@Override
public long getLongOptimistic(final int index, final int programPoint) {
return underlying.getLongOptimistic(index, programPoint);
}
@Override
public double getDouble(final int index) {
return underlying.getDouble(index);

View File

@ -121,12 +121,6 @@ final class ByteBufferArrayData extends ArrayData {
return this;
}
@Override
public ArrayData set(final int index, final long value, final boolean strict) {
buf.put(index, (byte)value);
return this;
}
@Override
public ArrayData set(final int index, final double value, final boolean strict) {
buf.put(index, (byte)value);
@ -138,11 +132,6 @@ final class ByteBufferArrayData extends ArrayData {
return 0x0ff & buf.get(index);
}
@Override
public long getLong(final int index) {
return 0x0ff & buf.get(index);
}
@Override
public double getDouble(final int index) {
return 0x0ff & buf.get(index);

View File

@ -119,12 +119,6 @@ final class DeletedArrayFilter extends ArrayFilter {
return super.set(index, value, strict);
}
@Override
public ArrayData set(final int index, final long value, final boolean strict) {
deleted.clear(ArrayIndex.toLongIndex(index));
return super.set(index, value, strict);
}
@Override
public ArrayData set(final int index, final double value, final boolean strict) {
deleted.clear(ArrayIndex.toLongIndex(index));

View File

@ -162,24 +162,6 @@ final class DeletedRangeArrayFilter extends ArrayFilter {
return isEmpty() ? getUnderlying().set(index, value, strict) : super.set(index, value, strict);
}
@Override
public ArrayData set(final int index, final long value, final boolean strict) {
final long longIndex = ArrayIndex.toLongIndex(index);
if (longIndex < lo || longIndex > hi) {
return super.set(index, value, strict);
} else if (longIndex > lo && longIndex < hi) {
return getDeletedArrayFilter().set(index, value, strict);
}
if (longIndex == lo) {
lo++;
} else {
assert longIndex == hi;
hi--;
}
return isEmpty() ? getUnderlying().set(index, value, strict) : super.set(index, value, strict);
}
@Override
public ArrayData set(final int index, final double value, final boolean strict) {
final long longIndex = ArrayIndex.toLongIndex(index);

View File

@ -56,14 +56,6 @@ final class FrozenArrayFilter extends SealedArrayFilter {
return this;
}
@Override
public ArrayData set(final int index, final long value, final boolean strict) {
if (strict) {
throw typeError("cant.set.property", Integer.toString(index), "frozen array");
}
return this;
}
@Override
public ArrayData set(final int index, final double value, final boolean strict) {
if (strict) {

View File

@ -156,22 +156,6 @@ final class IntArrayData extends ContinuousArrayData implements IntElements {
return darray;
}
private long[] toLongArray() {
assert length() <= array.length : "length exceeds internal array size";
final int len = (int)length();
final long[] larray = new long[array.length];
for (int index = 0; index < len; index++) {
larray[index] = array[index];
}
return larray;
}
private LongArrayData convertToLong() {
return new LongArrayData(toLongArray(), (int)length());
}
private NumberArrayData convertToDouble() {
return new NumberArrayData(toDoubleArray(), (int)length());
}
@ -184,8 +168,6 @@ final class IntArrayData extends ContinuousArrayData implements IntElements {
public ArrayData convert(final Class<?> type) {
if (type == Integer.class || type == Byte.class || type == Short.class) {
return this;
} else if (type == Long.class) {
return convertToLong();
} else if (type == Double.class || type == Float.class) {
return convertToDouble();
} else {
@ -252,17 +234,6 @@ final class IntArrayData extends ContinuousArrayData implements IntElements {
return this;
}
@Override
public ArrayData set(final int index, final long value, final boolean strict) {
if (JSType.isRepresentableAsInt(value)) {
array[index] = JSType.toInt32(value);
setLength(Math.max(index + 1, length()));
return this;
}
return convert(Long.class).set(index, value, strict);
}
@Override
public ArrayData set(final int index, final double value, final boolean strict) {
if (JSType.isRepresentableAsInt(value)) {
@ -284,16 +255,6 @@ final class IntArrayData extends ContinuousArrayData implements IntElements {
return array[index];
}
@Override
public long getLong(final int index) {
return array[index];
}
@Override
public long getLongOptimistic(final int index, final int programPoint) {
return array[index];
}
@Override
public double getDouble(final int index) {
return array[index];

View File

@ -130,6 +130,6 @@ public abstract class IteratorAction<T> {
*
* @throws Throwable if invocation throws an exception/error
*/
protected abstract boolean forEach(final Object val, final long i) throws Throwable;
protected abstract boolean forEach(final Object val, final double i) throws Throwable;
}

View File

@ -90,22 +90,6 @@ final class LengthNotWritableFilter extends ArrayFilter {
return underlying.getIntOptimistic(index, programPoint);
}
@Override
public long getLong(final int index) {
if (index >= length()) {
return JSType.toLong(get(index));
}
return underlying.getLong(index);
}
@Override
public long getLongOptimistic(final int index, final int programPoint) {
if (index >= length()) {
return JSType.toLongOptimistic(get(index), programPoint);
}
return underlying.getLongOptimistic(index, programPoint);
}
@Override
public double getDouble(final int index) {
if (index >= length()) {
@ -148,15 +132,6 @@ final class LengthNotWritableFilter extends ArrayFilter {
return this;
}
@Override
public ArrayData set(final int index, final long value, final boolean strict) {
if (checkAdd(index, value)) {
return this;
}
underlying = underlying.set(index, value, strict);
return this;
}
@Override
public ArrayData set(final int index, final double value, final boolean strict) {
if (checkAdd(index, value)) {

View File

@ -1,406 +0,0 @@
/*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.nashorn.internal.runtime.arrays;
import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
import static jdk.nashorn.internal.lookup.Lookup.MH;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.util.Arrays;
import jdk.nashorn.internal.runtime.JSType;
import jdk.nashorn.internal.runtime.ScriptRuntime;
/**
* Implementation of {@link ArrayData} as soon as a long has been
* written to the array
*/
final class LongArrayData extends ContinuousArrayData implements IntOrLongElements {
/**
* The wrapped array
*/
private long[] array;
/**
* Constructor
* @param array an int array
* @param length a length, not necessarily array.length
*/
LongArrayData(final long array[], final int length) {
super(length);
assert array.length >= length;
this.array = array;
}
@Override
public final Class<?> getElementType() {
return long.class;
}
@Override
public final Class<?> getBoxedElementType() {
return Long.class;
}
@Override
public final ContinuousArrayData widest(final ContinuousArrayData otherData) {
return otherData instanceof IntElements ? this : otherData;
}
@Override
public final int getElementWeight() {
return 2;
}
@Override
public LongArrayData copy() {
return new LongArrayData(array.clone(), (int)length());
}
@Override
public Object[] asObjectArray() {
return toObjectArray(true);
}
private Object[] toObjectArray(final boolean trim) {
assert length() <= array.length : "length exceeds internal array size";
final int len = (int)length();
final Object[] oarray = new Object[trim ? len : array.length];
for (int index = 0; index < len; index++) {
oarray[index] = array[index];
}
return oarray;
}
@Override
public Object asArrayOfType(final Class<?> componentType) {
if (componentType == long.class) {
final int len = (int)length();
return array.length == len ? array.clone() : Arrays.copyOf(array, len);
}
return super.asArrayOfType(componentType);
}
private double[] toDoubleArray() {
assert length() <= array.length : "length exceeds internal array size";
final int len = (int)length();
final double[] darray = new double[array.length];
for (int index = 0; index < len; index++) {
darray[index] = array[index];
}
return darray;
}
@Override
public ContinuousArrayData convert(final Class<?> type) {
if (type == Integer.class || type == Long.class || type == Byte.class || type == Short.class) {
return this;
}
final int len = (int)length();
if (type == Double.class || type == Float.class) {
return new NumberArrayData(toDoubleArray(), len);
}
return new ObjectArrayData(toObjectArray(false), len);
}
@Override
public void shiftLeft(final int by) {
System.arraycopy(array, by, array, 0, array.length - by);
}
@Override
public ArrayData shiftRight(final int by) {
final ArrayData newData = ensure(by + length() - 1);
if (newData != this) {
newData.shiftRight(by);
return newData;
}
System.arraycopy(array, 0, array, by, array.length - by);
return this;
}
@Override
public ArrayData ensure(final long safeIndex) {
if (safeIndex >= SparseArrayData.MAX_DENSE_LENGTH) {
return new SparseArrayData(this, safeIndex + 1);
}
final int alen = array.length;
if (safeIndex >= alen) {
final int newLength = ArrayData.nextSize((int)safeIndex);
array = Arrays.copyOf(array, newLength);
}
if (safeIndex >= length()) {
setLength(safeIndex + 1);
}
return this;
}
@Override
public ArrayData shrink(final long newLength) {
Arrays.fill(array, (int)newLength, array.length, 0L);
return this;
}
@Override
public ArrayData set(final int index, final Object value, final boolean strict) {
if (value instanceof Long || value instanceof Integer ||
value instanceof Byte || value instanceof Short) {
return set(index, ((Number)value).longValue(), strict);
} else if (value == ScriptRuntime.UNDEFINED) {
return new UndefinedArrayFilter(this).set(index, value, strict);
}
final ArrayData newData = convert(value == null ? Object.class : value.getClass());
return newData.set(index, value, strict);
}
@Override
public ArrayData set(final int index, final int value, final boolean strict) {
array[index] = value;
setLength(Math.max(index + 1, length()));
return this;
}
@Override
public ArrayData set(final int index, final long value, final boolean strict) {
array[index] = value;
setLength(Math.max(index + 1, length()));
return this;
}
@Override
public ArrayData set(final int index, final double value, final boolean strict) {
if (JSType.isRepresentableAsLong(value)) {
array[index] = (long)value;
setLength(Math.max(index + 1, length()));
return this;
}
return convert(Double.class).set(index, value, strict);
}
private static final MethodHandle HAS_GET_ELEM = specialCall(MethodHandles.lookup(), LongArrayData.class, "getElem", long.class, int.class).methodHandle();
private static final MethodHandle SET_ELEM = specialCall(MethodHandles.lookup(), LongArrayData.class, "setElem", void.class, int.class, long.class).methodHandle();
@SuppressWarnings("unused")
private long getElem(final int index) {
if (has(index)) {
return array[index];
}
throw new ClassCastException();
}
@SuppressWarnings("unused")
private void setElem(final int index, final long elem) {
if (hasRoomFor(index)) {
array[index] = elem;
return;
}
throw new ClassCastException();
}
@Override
public MethodHandle getElementGetter(final Class<?> returnType, final int programPoint) {
if (returnType == int.class) {
return null;
}
return getContinuousElementGetter(HAS_GET_ELEM, returnType, programPoint);
}
@Override
public MethodHandle getElementSetter(final Class<?> elementType) {
return elementType == int.class || elementType == long.class ? getContinuousElementSetter(MH.asType(SET_ELEM, SET_ELEM.type().changeParameterType(2, elementType)), elementType) : null;
}
@Override
public int getInt(final int index) {
return JSType.toInt32(array[index]);
}
@Override
public long getLong(final int index) {
return array[index];
}
@Override
public long getLongOptimistic(final int index, final int programPoint) {
return array[index];
}
@Override
public double getDouble(final int index) {
return array[index];
}
@Override
public double getDoubleOptimistic(final int index, final int programPoint) {
return array[index];
}
@Override
public Object getObject(final int index) {
return array[index];
}
@Override
public boolean has(final int index) {
return 0 <= index && index < length();
}
@Override
public ArrayData delete(final int index) {
return new DeletedRangeArrayFilter(this, index, index);
}
@Override
public ArrayData delete(final long fromIndex, final long toIndex) {
return new DeletedRangeArrayFilter(this, fromIndex, toIndex);
}
@Override
public Object pop() {
final int len = (int)length();
if (len == 0) {
return ScriptRuntime.UNDEFINED;
}
final int newLength = len - 1;
final long elem = array[newLength];
array[newLength] = 0;
setLength(newLength);
return elem;
}
@Override
public ArrayData slice(final long from, final long to) {
final long start = from < 0 ? from + length() : from;
final long newLength = to - start;
return new LongArrayData(Arrays.copyOfRange(array, (int)from, (int)to), (int)newLength);
}
@Override
public ArrayData fastSplice(final int start, final int removed, final int added) throws UnsupportedOperationException {
final long oldLength = length();
final long newLength = oldLength - removed + added;
if (newLength > SparseArrayData.MAX_DENSE_LENGTH && newLength > array.length) {
throw new UnsupportedOperationException();
}
final ArrayData returnValue = removed == 0 ?
EMPTY_ARRAY : new LongArrayData(Arrays.copyOfRange(array, start, start + removed), removed);
if (newLength != oldLength) {
final long[] newArray;
if (newLength > array.length) {
newArray = new long[ArrayData.nextSize((int)newLength)];
System.arraycopy(array, 0, newArray, 0, start);
} else {
newArray = array;
}
System.arraycopy(array, start + removed, newArray, start + added, (int)(oldLength - start - removed));
array = newArray;
setLength(newLength);
}
return returnValue;
}
@Override
public long fastPush(final int arg) {
return fastPush((long)arg);
}
@Override
public long fastPush(final long arg) {
final int len = (int)length();
if (len == array.length) {
array = Arrays.copyOf(array, nextSize(len));
}
array[len] = arg;
return increaseLength();
}
@Override
public long fastPopLong() {
if (length() == 0) {
throw new ClassCastException(); //undefined result
}
final int newLength = (int)decreaseLength();
final long elem = array[newLength];
array[newLength] = 0;
return elem;
}
@Override
public double fastPopDouble() {
return fastPopLong();
}
@Override
public Object fastPopObject() {
return fastPopLong();
}
@Override
public ContinuousArrayData fastConcat(final ContinuousArrayData otherData) {
final int otherLength = (int)otherData.length();
final int thisLength = (int)length();
assert otherLength > 0 && thisLength > 0;
final long[] otherArray = ((LongArrayData)otherData).array;
final int newLength = otherLength + thisLength;
final long[] newArray = new long[ArrayData.alignUp(newLength)];
System.arraycopy(array, 0, newArray, 0, thisLength);
System.arraycopy(otherArray, 0, newArray, thisLength, otherLength);
return new LongArrayData(newArray, newLength);
}
@Override
public String toString() {
assert length() <= array.length : length() + " > " + array.length;
final StringBuilder sb = new StringBuilder(getClass().getSimpleName()).
append(": [");
final int len = (int)length();
for (int i = 0; i < len; i++) {
sb.append(array[i]).append('L'); //make sure L suffix is on elements, to discriminate this from IntArrayData.toString()
if (i + 1 < len) {
sb.append(", ");
}
}
sb.append(']');
return sb.toString();
}
}

View File

@ -50,14 +50,6 @@ final class NonExtensibleArrayFilter extends ArrayFilter {
return extensionCheck(strict, index);
}
@Override
public ArrayData set(final int index, final long value, final boolean strict) {
if (has(index)) {
return underlying.set(index, value, strict);
}
return extensionCheck(strict, index);
}
@Override
public ArrayData set(final int index, final double value, final boolean strict) {
if (has(index)) {

View File

@ -178,13 +178,6 @@ final class NumberArrayData extends ContinuousArrayData implements NumericElemen
return this;
}
@Override
public ArrayData set(final int index, final long value, final boolean strict) {
array[index] = value;
setLength(Math.max(index + 1, length()));
return this;
}
@Override
public ArrayData set(final int index, final double value, final boolean strict) {
array[index] = value;
@ -214,7 +207,7 @@ final class NumberArrayData extends ContinuousArrayData implements NumericElemen
@Override
public MethodHandle getElementGetter(final Class<?> returnType, final int programPoint) {
if (returnType == int.class || returnType == long.class) {
if (returnType == int.class) {
return null;
}
return getContinuousElementGetter(HAS_GET_ELEM, returnType, programPoint);
@ -230,11 +223,6 @@ final class NumberArrayData extends ContinuousArrayData implements NumericElemen
return JSType.toInt32(array[index]);
}
@Override
public long getLong(final int index) {
return (long)array[index];
}
@Override
public double getDouble(final int index) {
return array[index];

View File

@ -149,13 +149,6 @@ final class ObjectArrayData extends ContinuousArrayData implements AnyElements {
return this;
}
@Override
public ArrayData set(final int index, final long value, final boolean strict) {
array[index] = value;
setLength(Math.max(index + 1, length()));
return this;
}
@Override
public ArrayData set(final int index, final double value, final boolean strict) {
array[index] = value;
@ -215,11 +208,6 @@ final class ObjectArrayData extends ContinuousArrayData implements AnyElements {
return JSType.toInt32(array[index]);
}
@Override
public long getLong(final int index) {
return JSType.toLong(array[index]);
}
@Override
public double getDouble(final int index) {
return JSType.toNumber(array[index]);

View File

@ -194,21 +194,6 @@ class SparseArrayData extends ArrayData {
return this;
}
@Override
public ArrayData set(final int index, final long value, final boolean strict) {
if (index >= 0 && index < maxDenseLength) {
final long oldLength = underlying.length();
ensure(index);
underlying = underlying.set(index, value, strict).safeDelete(oldLength, index - 1, strict);
setLength(Math.max(underlying.length(), length()));
} else {
final Long longIndex = indexToKey(index);
sparseMap.put(longIndex, value);
setLength(Math.max(longIndex + 1, length()));
}
return this;
}
@Override
public ArrayData set(final int index, final double value, final boolean strict) {
if (index >= 0 && index < maxDenseLength) {
@ -257,22 +242,6 @@ class SparseArrayData extends ArrayData {
return JSType.toInt32Optimistic(sparseMap.get(indexToKey(index)), programPoint);
}
@Override
public long getLong(final int index) {
if (index >= 0 && index < maxDenseLength) {
return underlying.getLong(index);
}
return JSType.toLong(sparseMap.get(indexToKey(index)));
}
@Override
public long getLongOptimistic(final int index, final int programPoint) {
if (index >= 0 && index < maxDenseLength) {
return underlying.getLongOptimistic(index, programPoint);
}
return JSType.toLongOptimistic(sparseMap.get(indexToKey(index)), programPoint);
}
@Override
public double getDouble(final int index) {
if (index >= 0 && index < maxDenseLength) {

View File

@ -127,13 +127,6 @@ final class UndefinedArrayFilter extends ArrayFilter {
return super.set(index, value, strict);
}
@Override
public ArrayData set(final int index, final long value, final boolean strict) {
undefined.clear(index);
return super.set(index, value, strict);
}
@Override
public ArrayData set(final int index, final double value, final boolean strict) {
undefined.clear(index);
@ -159,24 +152,6 @@ final class UndefinedArrayFilter extends ArrayFilter {
return super.getIntOptimistic(index, programPoint);
}
@Override
public long getLong(final int index) {
if (undefined.isSet(index)) {
return 0L;
}
return super.getLong(index);
}
@Override
public long getLongOptimistic(final int index, final int programPoint) {
if (undefined.isSet(index)) {
throw new UnwarrantedOptimismException(UNDEFINED, programPoint);
}
return super.getLongOptimistic(index, programPoint);
}
@Override
public double getDouble(final int index) {
if (undefined.isSet(index)) {

View File

@ -201,7 +201,7 @@ public final class Bootstrap {
*
* @return callsite for a math intrinsic node
*/
public static CallSite mathBootstrap(final MethodHandles.Lookup lookup, final String name, final MethodType type, final int programPoint) {
public static CallSite mathBootstrap(final Lookup lookup, final String name, final MethodType type, final int programPoint) {
final MethodHandle mh;
switch (name) {
case "iadd":
@ -222,24 +222,6 @@ public final class Bootstrap {
case "ineg":
mh = JSType.NEGATE_EXACT.methodHandle();
break;
case "ladd":
mh = JSType.ADD_EXACT_LONG.methodHandle();
break;
case "lsub":
mh = JSType.SUB_EXACT_LONG.methodHandle();
break;
case "lmul":
mh = JSType.MUL_EXACT_LONG.methodHandle();
break;
case "ldiv":
mh = JSType.DIV_EXACT_LONG.methodHandle();
break;
case "lrem":
mh = JSType.REM_EXACT_LONG.methodHandle();
break;
case "lneg":
mh = JSType.NEGATE_EXACT_LONG.methodHandle();
break;
default:
throw new AssertionError("unsupported math intrinsic");
}

View File

@ -141,8 +141,9 @@ final class NashornBottomLinker implements GuardingDynamicLinker, GuardingTypeCo
}
/**
* Main part of the implementation of {@link GuardingTypeConverterFactory#convertToType(Class, Class)} that doesn't
* care about adapting the method signature; that's done by the invoking method. Returns conversion from Object to String/number/boolean (JS primitive types).
* Main part of the implementation of {@link GuardingTypeConverterFactory#convertToType} that doesn't
* care about adapting the method signature; that's done by the invoking method. Returns conversion
* from Object to String/number/boolean (JS primitive types).
* @param sourceType the source type
* @param targetType the target type
* @return a guarded invocation that converts from the source type to the target type.

View File

@ -174,28 +174,31 @@ public final class NashornCallSiteDescriptor extends CallSiteDescriptor {
* Function used by {@link NashornTextifier} to represent call site flags in
* human readable form
* @param flags call site flags
* @return human readable form of this callsite descriptor
* @param sb the string builder
*/
public static String toString(final int flags) {
final StringBuilder sb = new StringBuilder();
public static void appendFlags(final int flags, final StringBuilder sb) {
final int pp = flags >> CALLSITE_PROGRAM_POINT_SHIFT;
if (pp != 0) {
sb.append(" pp=").append(pp);
}
if ((flags & CALLSITE_SCOPE) != 0) {
if ((flags & CALLSITE_FAST_SCOPE) != 0) {
sb.append("fastscope ");
sb.append(" fastscope");
} else {
assert (flags & CALLSITE_FAST_SCOPE) == 0 : "can't be fastscope without scope";
sb.append("scope ");
sb.append(" scope");
}
if ((flags & CALLSITE_DECLARE) != 0) {
sb.append("declare ");
sb.append(" declare");
}
} else {
assert (flags & CALLSITE_FAST_SCOPE) == 0 : "can't be fastscope without scope";
}
if ((flags & CALLSITE_APPLY_TO_CALL) != 0) {
sb.append("apply2call ");
sb.append(" apply2call");
}
if ((flags & CALLSITE_STRICT) != 0) {
sb.append("strict ");
sb.append(" strict");
}
return sb.length() == 0 ? "" : " " + sb.toString().trim();
}
/**

View File

@ -33,67 +33,46 @@
var b = true;
var i = 1;
var l = 4294967296;
var d = 2.1;
var o = "foo";
print(inspect(b || b, "b || b"));
print(inspect(b || i, "b || i"));
print(inspect(b || l, "b || l"));
print(inspect(b || d, "b || d"));
print(inspect(b || o, "b || o"));
print(inspect(i || b, "i || b"));
print(inspect(i || i, "i || i"));
print(inspect(i || l, "i || l"));
print(inspect(i || d, "i || d"));
print(inspect(i || o, "i || o"));
print(inspect(l || b, "l || b"));
print(inspect(l || i, "l || i"));
print(inspect(l || l, "l || l"));
print(inspect(l || d, "l || d"));
print(inspect(l || o, "l || o"));
print(inspect(d || b, "d || b"));
print(inspect(d || i, "d || i"));
print(inspect(d || l, "d || l"));
print(inspect(d || d, "d || d"));
print(inspect(d || o, "d || o"));
print(inspect(o || b, "o || b"));
print(inspect(o || i, "o || i"));
print(inspect(o || l, "o || l"));
print(inspect(o || d, "o || d"));
print(inspect(o || o, "o || o"));
print(inspect(b && b, "b && b"));
print(inspect(b && i, "b && i"));
print(inspect(b && l, "b && l"));
print(inspect(b && d, "b && d"));
print(inspect(b && o, "b && o"));
print(inspect(i && b, "i && b"));
print(inspect(i && i, "i && i"));
print(inspect(i && l, "i && l"));
print(inspect(i && d, "i && d"));
print(inspect(i && o, "i && o"));
print(inspect(l && b, "l && b"));
print(inspect(l && i, "l && i"));
print(inspect(l && l, "l && l"));
print(inspect(l && d, "l && d"));
print(inspect(l && o, "l && o"));
print(inspect(d && b, "d && b"));
print(inspect(d && i, "d && i"));
print(inspect(d && l, "d && l"));
print(inspect(d && d, "d && d"));
print(inspect(d && o, "d && o"));
print(inspect(o && b, "o && b"));
print(inspect(o && i, "o && i"));
print(inspect(o && l, "o && l"));
print(inspect(o && d, "o && d"));
print(inspect(o && o, "o && o"));
})();

View File

@ -1,50 +1,32 @@
b || b: boolean
b || i: boolean
b || l: boolean
b || d: boolean
b || o: boolean
i || b: int
i || i: int
i || l: long
i || d: double
i || o: int
l || b: long
l || i: long
l || l: long
l || d: double
l || o: long
d || b: double
d || i: double
d || l: double
d || d: double
d || o: double
o || b: object
o || i: object
o || l: object
o || d: object
o || o: object
b && b: boolean
b && i: int
b && l: long
b && d: double
b && o: object
i && b: boolean
i && i: int
i && l: long
i && d: double
i && o: object
l && b: boolean
l && i: long
l && l: long
l && d: double
l && o: object
d && b: boolean
d && i: double
d && l: double
d && d: double
d && o: object
o && b: boolean
o && i: int
o && l: long
o && d: double
o && o: object

View File

@ -0,0 +1,126 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* JDK-8144020: Remove long as an internal numeric type
*
* @test
* @run
*/
var LongProvider = Java.type("jdk.nashorn.test.models.LongProvider");
var Long = Java.type("java.lang.Long");
var LongClass = Long.class;
var Integer = Java.type("java.lang.Integer");
var Double = Java.type("java.lang.Double");
var INT = "3";
var DOUBLE = "5.5";
var MAX_LONG = "9223372036854775807";
var MIN_LONG = "-9223372036854775808";
var BIG_LONG = "281474976710655"; // can be represented as double
var NEG_LONG = "-281474976710656"; // can be represented as double
var SMALL_LONG = "13";
// Make sure we can pass longs from and to Java without losing precision
LongProvider.checkLong(LongProvider.getLong(MAX_LONG), MAX_LONG);
LongProvider.checkLong(LongProvider.getLong(MIN_LONG), MIN_LONG);
LongProvider.checkLong(LongProvider.getLong(BIG_LONG), BIG_LONG);
LongProvider.checkLong(LongProvider.getLong(NEG_LONG), NEG_LONG);
LongProvider.checkLong(LongProvider.getLong(SMALL_LONG), SMALL_LONG);
// a polymorphic function that can return various number types
function getNumber(str) {
switch (str) {
case INT: return +INT;
case DOUBLE: return +DOUBLE;
default: return Long.parseLong(str);
}
}
function compareValue(n, str) {
switch (str) {
case INT: return Integer.compare(n, Integer.parseInt(str) == 0);
case DOUBLE: return Double.compare(n, Double.parseDouble(str) == 0);
default: return Long.compare(n, Long.parseLong(str) == 0);
}
}
// Call a a function with a sequence of values. The purpose of this is that we can handle
// longs without losing precision in the presence of optimistic deoptimization, cached callsites, etc.
function testSequence(fn, values) {
for (var i in values) {
fn(values[i]);
}
}
// We need to use "fresh" (unlinked and un-deoptimized) functions for each of the test runs.
testSequence(function(str) {
var n = getNumber(str);
Assert.assertTrue(compareValue(n, str));
}, [INT, BIG_LONG, MIN_LONG]);
testSequence(function(str) {
var n = getNumber(str);
Assert.assertTrue(compareValue(n, str));
}, [INT, MAX_LONG]);
testSequence(function(str) {
var n = getNumber(str);
Assert.assertTrue(compareValue(n, str));
}, [INT, DOUBLE, NEG_LONG]);
testSequence(function(str) {
var n = getNumber(str);
Assert.assertTrue(compareValue(n, str));
}, [DOUBLE, MAX_LONG]);
testSequence(function(str) {
var n = getNumber(str);
Assert.assertTrue(compareValue(n, str));
}, [DOUBLE, SMALL_LONG, MAX_LONG]);
testSequence(function(str) {
var n = getNumber(str);
Assert.assertTrue(compareValue(n, str));
}, [INT, DOUBLE, NEG_LONG, MAX_LONG]);
testSequence(function(str) {
var n = getNumber(str);
Assert.assertTrue(compareValue(n, str));
}, [DOUBLE, MAX_LONG, DOUBLE, INT]);
// Make sure long arrays make it through Java.from and Java.to without losing precision
var longArrayType = Java.type("long[]");
for (var i = 0; i < 3; i++) {
LongProvider.checkLongArray(Java.to(Java.from(LongProvider.getLongArray(i)), longArrayType), i);
}
l = Long.parseLong(BIG_LONG);
Assert.assertTrue(l >>> 8 === 0xffffff);
Assert.assertTrue(l << 8 === -0x100);
Assert.assertTrue(l + 1 === 0x1000000000000);
Assert.assertTrue(l - 1 === 0xfffffffffffe);
Assert.assertEquals(LongProvider.getLong(MAX_LONG).getClass(), LongClass);
Assert.assertEquals(LongProvider.getLong(MIN_LONG).getClass(), LongClass);

View File

@ -30,12 +30,9 @@
var doubleArray = [97912312397.234, -182374983434.56];
var doubleArrayResults = [-871935411, -1986357002];
var longArray = [0x7fffffff8c102ebc, -0x7fffffffe9dfec18];
var longArrayResults = [-1945096192, 371201024];
// Make sure arrays use double and long array data
// Make sure array uses double array data
Assert.assertEquals(doubleArray[0].getClass(), java.lang.Double.class);
Assert.assertEquals(longArray[0].getClass(), java.lang.Long.class);
function testBinaryOp(array, index, expected) {
Assert.assertEquals(array[index] & 0xffffffff, expected);
@ -44,7 +41,4 @@ function testBinaryOp(array, index, expected) {
for (var i = 0; i < doubleArray.length; i++) {
testBinaryOp(doubleArray, i, doubleArrayResults[i]);
}
for (var i = 0; i < longArray.length; i++) {
testBinaryOp(longArray, i, longArrayResults[i]);
}

View File

@ -32,7 +32,6 @@
var intType = Java.type("int");
var doubleType = Java.type("double");
var longType = Java.type("long");
var objectType = Java.type("java.lang.Object");
var Context = Java.type("jdk.nashorn.internal.runtime.Context");
@ -58,7 +57,6 @@ function testMap(obj) {
}
if (prop.getType() != getExpectedType(obj[key])) {
throw new Error("Wrong property type: " + prop.getType() + " // " + getExpectedType(obj[key]));
}
}
}
@ -67,14 +65,8 @@ function getExpectedType(value) {
if (!dualFields) {
return objectType.class;
}
if (JSType.isRepresentableAsInt(value)) {
return intType.class;
}
if (JSType.isRepresentableAsLong(value)) {
return longType.class;
}
if (JSType.isNumber(value)) {
return doubleType.class;
if (typeof value === "number") {
return JSType.isRepresentableAsInt(value) ? intType.class : doubleType.class;
}
return objectType.class;
}

View File

@ -143,7 +143,7 @@ public class NumberAccessTest {
@Test
public void accessStaticFinalFieldLong() throws ScriptException {
e.eval("var psf_long = SharedObject.publicStaticFinalLong;");
assertEquals(SharedObject.publicStaticFinalLong, e.get("psf_long"));
assertEquals(SharedObject.publicStaticFinalLong, ((Number) e.get("psf_long")).longValue());
e.eval("SharedObject.publicStaticFinalLong = 120;");
assertEquals(8333333333333L, SharedObject.publicStaticFinalLong);
}

View File

@ -70,7 +70,7 @@ public class NumberBoxingTest {
@Test
public void accessFieldLongBoxing() throws ScriptException {
e.eval("var p_long = o.publicLongBox;");
assertEquals(o.publicLongBox, e.get("p_long"));
assertEquals(o.publicLongBox.longValue(), ((Number) e.get("p_long")).longValue());
e.eval("o.publicLongBox = 12;");
assertEquals(Long.valueOf(12), o.publicLongBox);
}
@ -78,7 +78,7 @@ public class NumberBoxingTest {
@Test
public void accessStaticFieldLongBoxing() throws ScriptException {
e.eval("var ps_long = SharedObject.publicStaticLongBox;");
assertEquals(SharedObject.publicStaticLongBox, e.get("ps_long"));
assertEquals(SharedObject.publicStaticLongBox.longValue(), ((Number) e.get("ps_long")).longValue());
e.eval("SharedObject.publicStaticLongBox = 120;");
assertEquals(120L, SharedObject.publicStaticLongBox.longValue());
}
@ -86,7 +86,7 @@ public class NumberBoxingTest {
@Test
public void accessFinalFieldLongBoxing() throws ScriptException {
e.eval("var pf_long = o.publicFinalLongBox;");
assertEquals(o.publicFinalLongBox, e.get("pf_long"));
assertEquals(o.publicFinalLongBox.longValue(), ((Number) e.get("pf_long")).longValue());
e.eval("o.publicFinalLongBox = 120;");
assertEquals(Long.valueOf(9377333334L), o.publicFinalLongBox);
}
@ -94,7 +94,7 @@ public class NumberBoxingTest {
@Test
public void accessStaticFinalFieldLongBoxing() throws ScriptException {
e.eval("var psf_long = SharedObject.publicStaticFinalLong;");
assertEquals(SharedObject.publicStaticFinalLong, e.get("psf_long"));
assertEquals(SharedObject.publicStaticFinalLong, ((Number) e.get("psf_long")).longValue());
e.eval("SharedObject.publicStaticFinalLong = 120;");
assertEquals(8333333333333L, SharedObject.publicStaticFinalLong);
}

View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.nashorn.test.models;
import java.util.Arrays;
/**
* A class that returns and receives longs.
*/
@SuppressWarnings("javadoc")
public class LongProvider {
final static long[][] arrays = {
{1L, 2L, 3L},
{1L, 1L << 30, 1L << 50, 4L},
{1L, Long.MAX_VALUE, Long.MIN_VALUE, 4L}
};
public static long getLong(final String str) {
final long l = Long.parseLong(str);
checkLong(l, str);
return l;
}
public static long[] getLongArray(final int n) {
return arrays[n];
}
public static void checkLong(final long value, final String str) {
if (!Long.toString(value).equals(str)) {
throw new RuntimeException("Wrong value. Expected " + str + ", got " + value);
}
}
public static void checkLongArray(final long[] array, final int n) {
if (!Arrays.equals(array, arrays[n])) {
throw new RuntimeException("Arrays don't match: " + Arrays.toString(array) + ", " + Arrays.toString(arrays[n]));
}
}
}