提交 d198c834 编写于 作者: A amurillo

Merge

...@@ -81,13 +81,13 @@ TestNG library and placing its jar file into the lib subdirectory: ...@@ -81,13 +81,13 @@ TestNG library and placing its jar file into the lib subdirectory:
After that, you can run the tests using: After that, you can run the tests using:
cd make cd make
ant test ant clean test
You can also run the ECMA-262 test suite with Nashorn. In order to do You can also run the ECMA-262 test suite with Nashorn. In order to do
that, you will need to get a copy of it and put it in that, you will need to get a copy of it and put it in
test/script/external/test262 directory. A convenient way to do it is: test/script/external/test262 directory. A convenient way to do it is:
hg clone http://hg.ecmascript.org/tests/test262/ test/script/external/test262 git clone https://github.com/tc39/test262 test/script/external/test262
Alternatively, you can check it out elsewhere and make Alternatively, you can check it out elsewhere and make
test/script/external/test262 a symbolic link to that directory. After test/script/external/test262 a symbolic link to that directory. After
...@@ -95,6 +95,11 @@ you've done this, you can run the ECMA-262 tests using: ...@@ -95,6 +95,11 @@ you've done this, you can run the ECMA-262 tests using:
cd nashorn~jdk8/nashorn/make cd nashorn~jdk8/nashorn/make
ant test262 ant test262
Ant target to get/update external test suites:
ant externals
ant update-externals
These tests take time, so we have a parallelized runner for them that These tests take time, so we have a parallelized runner for them that
takes advantage of all processor cores on the computer: takes advantage of all processor cores on the computer:
......
...@@ -50,8 +50,6 @@ import static jdk.nashorn.internal.tools.nasgen.StringConstants.COLLECTIONS_TYPE ...@@ -50,8 +50,6 @@ import static jdk.nashorn.internal.tools.nasgen.StringConstants.COLLECTIONS_TYPE
import static jdk.nashorn.internal.tools.nasgen.StringConstants.COLLECTIONS_EMPTY_LIST; import static jdk.nashorn.internal.tools.nasgen.StringConstants.COLLECTIONS_EMPTY_LIST;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_DESC; import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_DESC;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_FIELD_NAME; import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_FIELD_NAME;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_SETISSHARED;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_SETISSHARED_DESC;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_NEWMAP; import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_NEWMAP;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_NEWMAP_DESC; import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_NEWMAP_DESC;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_TYPE; import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_TYPE;
...@@ -191,8 +189,6 @@ public class ClassGenerator { ...@@ -191,8 +189,6 @@ public class ClassGenerator {
// stack: Collection // stack: Collection
// pmap = PropertyMap.newMap(Collection<Property>); // pmap = PropertyMap.newMap(Collection<Property>);
mi.invokeStatic(PROPERTYMAP_TYPE, PROPERTYMAP_NEWMAP, PROPERTYMAP_NEWMAP_DESC); mi.invokeStatic(PROPERTYMAP_TYPE, PROPERTYMAP_NEWMAP, PROPERTYMAP_NEWMAP_DESC);
// pmap.setIsShared();
mi.invokeVirtual(PROPERTYMAP_TYPE, PROPERTYMAP_SETISSHARED, PROPERTYMAP_SETISSHARED_DESC);
// $nasgenmap$ = pmap; // $nasgenmap$ = pmap;
mi.putStatic(className, PROPERTYMAP_FIELD_NAME, PROPERTYMAP_DESC); mi.putStatic(className, PROPERTYMAP_FIELD_NAME, PROPERTYMAP_DESC);
mi.returnVoid(); mi.returnVoid();
......
...@@ -33,10 +33,7 @@ import static jdk.nashorn.internal.tools.nasgen.StringConstants.CONSTRUCTOR_SUFF ...@@ -33,10 +33,7 @@ import static jdk.nashorn.internal.tools.nasgen.StringConstants.CONSTRUCTOR_SUFF
import static jdk.nashorn.internal.tools.nasgen.StringConstants.DEFAULT_INIT_DESC; import static jdk.nashorn.internal.tools.nasgen.StringConstants.DEFAULT_INIT_DESC;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.INIT; import static jdk.nashorn.internal.tools.nasgen.StringConstants.INIT;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_DESC; import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_DESC;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_DUPLICATE;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_DUPLICATE_DESC;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_FIELD_NAME; import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_FIELD_NAME;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_TYPE;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC; import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_SETCONSTRUCTOR; import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_SETCONSTRUCTOR;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_SETCONSTRUCTOR_DESC; import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_SETCONSTRUCTOR_DESC;
...@@ -171,9 +168,6 @@ public class ConstructorGenerator extends ClassGenerator { ...@@ -171,9 +168,6 @@ public class ConstructorGenerator extends ClassGenerator {
private void loadMap(final MethodGenerator mi) { private void loadMap(final MethodGenerator mi) {
if (memberCount > 0) { if (memberCount > 0) {
mi.getStatic(className, PROPERTYMAP_FIELD_NAME, PROPERTYMAP_DESC); mi.getStatic(className, PROPERTYMAP_FIELD_NAME, PROPERTYMAP_DESC);
// make sure we use duplicated PropertyMap so that original map
// stays intact and so can be used for many globals.
mi.invokeVirtual(PROPERTYMAP_TYPE, PROPERTYMAP_DUPLICATE, PROPERTYMAP_DUPLICATE_DESC);
} }
} }
......
...@@ -22,40 +22,62 @@ ...@@ -22,40 +22,62 @@
* or visit www.oracle.com if you need additional information or have any * or visit www.oracle.com if you need additional information or have any
* questions. * questions.
*/ */
package jdk.nashorn.internal.tools.nasgen; package jdk.nashorn.internal.tools.nasgen;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_ARRAY_DESC; import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_ARRAY_DESC;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC; import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTOBJECT_DESC;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.STRING_DESC;
import jdk.internal.org.objectweb.asm.Opcodes; import jdk.internal.org.objectweb.asm.Opcodes;
import jdk.internal.org.objectweb.asm.Type; import jdk.internal.org.objectweb.asm.Type;
import jdk.nashorn.internal.objects.annotations.Where; import jdk.nashorn.internal.objects.annotations.Where;
import jdk.nashorn.internal.runtime.ScriptObject;
/** /**
* Details about a Java method or field annotated with any of the field/method * Details about a Java method or field annotated with any of the field/method
* annotations from the jdk.nashorn.internal.objects.annotations package. * annotations from the jdk.nashorn.internal.objects.annotations package.
*/ */
public final class MemberInfo implements Cloneable { public final class MemberInfo implements Cloneable {
// class loader of this class
private static ClassLoader myLoader = MemberInfo.class.getClassLoader();
/** /**
* The different kinds of available class annotations * The different kinds of available class annotations
*/ */
public static enum Kind { public static enum Kind {
/** This is a script class */
/**
* This is a script class
*/
SCRIPT_CLASS, SCRIPT_CLASS,
/** This is a constructor */ /**
* This is a constructor
*/
CONSTRUCTOR, CONSTRUCTOR,
/** This is a function */ /**
* This is a function
*/
FUNCTION, FUNCTION,
/** This is a getter */ /**
* This is a getter
*/
GETTER, GETTER,
/** This is a setter */ /**
* This is a setter
*/
SETTER, SETTER,
/** This is a property */ /**
* This is a property
*/
PROPERTY, PROPERTY,
/** This is a specialized version of a function */ /**
* This is a specialized version of a function
*/
SPECIALIZED_FUNCTION, SPECIALIZED_FUNCTION,
/** This is a specialized version of a constructor */ /**
* This is a specialized version of a constructor
*/
SPECIALIZED_CONSTRUCTOR SPECIALIZED_CONSTRUCTOR
} }
...@@ -194,6 +216,7 @@ public final class MemberInfo implements Cloneable { ...@@ -194,6 +216,7 @@ public final class MemberInfo implements Cloneable {
/** /**
* Check whether this MemberInfo is a getter that resides in the instance * Check whether this MemberInfo is a getter that resides in the instance
*
* @return true if instance setter * @return true if instance setter
*/ */
boolean isInstanceSetter() { boolean isInstanceSetter() {
...@@ -245,96 +268,201 @@ public final class MemberInfo implements Cloneable { ...@@ -245,96 +268,201 @@ public final class MemberInfo implements Cloneable {
} }
void verify() { void verify() {
if (kind == Kind.CONSTRUCTOR) { switch (kind) {
final Type returnType = Type.getReturnType(javaDesc); case CONSTRUCTOR: {
if (! returnType.toString().equals(OBJECT_DESC)) { final Type returnType = Type.getReturnType(javaDesc);
error("return value should be of Object type, found" + returnType); if (!isJSObjectType(returnType)) {
} error("return value of a @Constructor method should be of Object type, found " + returnType);
final Type[] argTypes = Type.getArgumentTypes(javaDesc); }
if (argTypes.length < 2) { final Type[] argTypes = Type.getArgumentTypes(javaDesc);
error("constructor methods should have at least 2 args"); if (argTypes.length < 2) {
} error("@Constructor methods should have at least 2 args");
if (! argTypes[0].equals(Type.BOOLEAN_TYPE)) { }
error("first argument should be of boolean type, found" + argTypes[0]); if (!argTypes[0].equals(Type.BOOLEAN_TYPE)) {
} error("first argument of a @Constructor method should be of boolean type, found " + argTypes[0]);
if (! argTypes[1].toString().equals(OBJECT_DESC)) { }
error("second argument should be of Object type, found" + argTypes[0]); if (!isJavaLangObject(argTypes[1])) {
} error("second argument of a @Constructor method should be of Object type, found " + argTypes[0]);
}
if (argTypes.length > 2) { if (argTypes.length > 2) {
for (int i = 2; i < argTypes.length - 1; i++) { for (int i = 2; i < argTypes.length - 1; i++) {
if (! argTypes[i].toString().equals(OBJECT_DESC)) { if (!isJavaLangObject(argTypes[i])) {
error(i + "'th argument should be of Object type, found " + argTypes[i]); error(i + "'th argument of a @Constructor method should be of Object type, found " + argTypes[i]);
}
} }
}
final String lastArgType = argTypes[argTypes.length - 1].toString(); final String lastArgTypeDesc = argTypes[argTypes.length - 1].getDescriptor();
final boolean isVarArg = lastArgType.equals(OBJECT_ARRAY_DESC); final boolean isVarArg = lastArgTypeDesc.equals(OBJECT_ARRAY_DESC);
if (!lastArgType.equals(OBJECT_DESC) && !isVarArg) { if (!lastArgTypeDesc.equals(OBJECT_DESC) && !isVarArg) {
error("last argument is neither Object nor Object[] type: " + lastArgType); error("last argument of a @Constructor method is neither Object nor Object[] type: " + lastArgTypeDesc);
} }
if (isVarArg && argTypes.length > 3) { if (isVarArg && argTypes.length > 3) {
error("vararg constructor has more than 3 arguments"); error("vararg of a @Constructor method has more than 3 arguments");
}
} }
} }
} else if (kind == Kind.FUNCTION) { break;
final Type returnType = Type.getReturnType(javaDesc); case SPECIALIZED_CONSTRUCTOR: {
if (! returnType.toString().equals(OBJECT_DESC)) { final Type returnType = Type.getReturnType(javaDesc);
error("return value should be of Object type, found" + returnType); if (!isJSObjectType(returnType)) {
} error("return value of a @SpecializedConstructor method should be a valid JS type, found " + returnType);
final Type[] argTypes = Type.getArgumentTypes(javaDesc); }
if (argTypes.length < 1) { final Type[] argTypes = Type.getArgumentTypes(javaDesc);
error("function methods should have at least 1 arg"); for (int i = 0; i < argTypes.length; i++) {
} if (!isValidJSType(argTypes[i])) {
if (! argTypes[0].toString().equals(OBJECT_DESC)) { error(i + "'th argument of a @SpecializedConstructor method is not valid JS type, found " + argTypes[i]);
error("first argument should be of Object type, found" + argTypes[0]); }
}
} }
break;
case FUNCTION: {
final Type returnType = Type.getReturnType(javaDesc);
if (!isValidJSType(returnType)) {
error("return value of a @Function method should be a valid JS type, found " + returnType);
}
final Type[] argTypes = Type.getArgumentTypes(javaDesc);
if (argTypes.length < 1) {
error("@Function methods should have at least 1 arg");
}
if (!isJavaLangObject(argTypes[0])) {
error("first argument of a @Function method should be of Object type, found " + argTypes[0]);
}
if (argTypes.length > 1) { if (argTypes.length > 1) {
for (int i = 1; i < argTypes.length - 1; i++) { for (int i = 1; i < argTypes.length - 1; i++) {
if (! argTypes[i].toString().equals(OBJECT_DESC)) { if (!isJavaLangObject(argTypes[i])) {
error(i + "'th argument should be of Object type, found " + argTypes[i]); error(i + "'th argument of a @Function method should be of Object type, found " + argTypes[i]);
}
} }
}
final String lastArgType = argTypes[argTypes.length - 1].toString(); final String lastArgTypeDesc = argTypes[argTypes.length - 1].getDescriptor();
final boolean isVarArg = lastArgType.equals(OBJECT_ARRAY_DESC); final boolean isVarArg = lastArgTypeDesc.equals(OBJECT_ARRAY_DESC);
if (!lastArgType.equals(OBJECT_DESC) && !isVarArg) { if (!lastArgTypeDesc.equals(OBJECT_DESC) && !isVarArg) {
error("last argument is neither Object nor Object[] type: " + lastArgType); error("last argument of a @Function method is neither Object nor Object[] type: " + lastArgTypeDesc);
} }
if (isVarArg && argTypes.length > 2) { if (isVarArg && argTypes.length > 2) {
error("vararg function has more than 2 arguments"); error("vararg @Function method has more than 2 arguments");
}
} }
} }
} else if (kind == Kind.GETTER) { break;
final Type[] argTypes = Type.getArgumentTypes(javaDesc); case SPECIALIZED_FUNCTION: {
if (argTypes.length != 1) { final Type returnType = Type.getReturnType(javaDesc);
error("getter methods should have one argument"); if (!isValidJSType(returnType)) {
} error("return value of a @SpecializedFunction method should be a valid JS type, found " + returnType);
if (! argTypes[0].toString().equals(OBJECT_DESC)) { }
error("first argument of getter should be of Object type, found: " + argTypes[0]); final Type[] argTypes = Type.getArgumentTypes(javaDesc);
for (int i = 0; i < argTypes.length; i++) {
if (!isValidJSType(argTypes[i])) {
error(i + "'th argument of a @SpecializedFunction method is not valid JS type, found " + argTypes[i]);
}
}
} }
if (Type.getReturnType(javaDesc).equals(Type.VOID_TYPE)) { break;
error("return type of getter should not be void"); case GETTER: {
final Type[] argTypes = Type.getArgumentTypes(javaDesc);
if (argTypes.length != 1) {
error("@Getter methods should have one argument");
}
if (!isJavaLangObject(argTypes[0])) {
error("first argument of a @Getter method should be of Object type, found: " + argTypes[0]);
}
final Type returnType = Type.getReturnType(javaDesc);
if (!isJavaLangObject(returnType)) {
error("return type of a @Getter method should be Object, found: " + javaDesc);
}
} }
} else if (kind == Kind.SETTER) { break;
final Type[] argTypes = Type.getArgumentTypes(javaDesc); case SETTER: {
if (argTypes.length != 2) { final Type[] argTypes = Type.getArgumentTypes(javaDesc);
error("setter methods should have two arguments"); if (argTypes.length != 2) {
error("@Setter methods should have two arguments");
}
if (!isJavaLangObject(argTypes[0])) {
error("first argument of a @Setter method should be of Object type, found: " + argTypes[0]);
}
if (!Type.getReturnType(javaDesc).toString().equals("V")) {
error("return type of of a @Setter method should be void, found: " + Type.getReturnType(javaDesc));
}
} }
if (! argTypes[0].toString().equals(OBJECT_DESC)) { break;
error("first argument of setter should be of Object type, found: " + argTypes[0]); case PROPERTY: {
if (where == Where.CONSTRUCTOR) {
if (isStatic()) {
if (!isFinal()) {
error("static Where.CONSTRUCTOR @Property should be final");
}
if (!isJSPrimitiveType(Type.getType(javaDesc))) {
error("static Where.CONSTRUCTOR @Property should be a JS primitive");
}
}
} else if (where == Where.PROTOTYPE) {
if (isStatic()) {
if (!isFinal()) {
error("static Where.PROTOTYPE @Property should be final");
}
if (!isJSPrimitiveType(Type.getType(javaDesc))) {
error("static Where.PROTOTYPE @Property should be a JS primitive");
}
}
}
} }
if (!Type.getReturnType(javaDesc).toString().equals("V")) { }
error("return type of setter should be void, found: " + Type.getReturnType(javaDesc)); }
private static boolean isValidJSType(final Type type) {
return isJSPrimitiveType(type) || isJSObjectType(type);
}
private static boolean isJSPrimitiveType(final Type type) {
switch (type.getSort()) {
case Type.BOOLEAN:
case Type.INT:
case Type.LONG:
case Type.DOUBLE:
return true;
default:
return false;
}
}
private static boolean isJSObjectType(final Type type) {
return isJavaLangObject(type) || isJavaLangString(type) || isScriptObject(type);
}
private static boolean isJavaLangObject(final Type type) {
return type.getDescriptor().equals(OBJECT_DESC);
}
private static boolean isJavaLangString(final Type type) {
return type.getDescriptor().equals(STRING_DESC);
}
private static boolean isScriptObject(final Type type) {
if (type.getDescriptor().equals(SCRIPTOBJECT_DESC)) {
return true;
}
if (type.getSort() == Type.OBJECT) {
try {
final Class clazz = Class.forName(type.getClassName(), false, myLoader);
return ScriptObject.class.isAssignableFrom(clazz);
} catch (final ClassNotFoundException cnfe) {
return false;
} }
} }
return false;
} }
private void error(final String msg) { private void error(final String msg) {
throw new RuntimeException(javaName + javaDesc + " : " + msg); throw new RuntimeException(javaName + " of type " + javaDesc + " : " + msg);
} }
/** /**
......
...@@ -349,19 +349,19 @@ public class MethodGenerator extends MethodVisitor { ...@@ -349,19 +349,19 @@ public class MethodGenerator extends MethodVisitor {
// invokes, field get/sets // invokes, field get/sets
void invokeInterface(final String owner, final String method, final String desc) { void invokeInterface(final String owner, final String method, final String desc) {
super.visitMethodInsn(INVOKEINTERFACE, owner, method, desc); super.visitMethodInsn(INVOKEINTERFACE, owner, method, desc, true);
} }
void invokeVirtual(final String owner, final String method, final String desc) { void invokeVirtual(final String owner, final String method, final String desc) {
super.visitMethodInsn(INVOKEVIRTUAL, owner, method, desc); super.visitMethodInsn(INVOKEVIRTUAL, owner, method, desc, false);
} }
void invokeSpecial(final String owner, final String method, final String desc) { void invokeSpecial(final String owner, final String method, final String desc) {
super.visitMethodInsn(INVOKESPECIAL, owner, method, desc); super.visitMethodInsn(INVOKESPECIAL, owner, method, desc, false);
} }
void invokeStatic(final String owner, final String method, final String desc) { void invokeStatic(final String owner, final String method, final String desc) {
super.visitMethodInsn(INVOKESTATIC, owner, method, desc); super.visitMethodInsn(INVOKESTATIC, owner, method, desc, false);
} }
void putStatic(final String owner, final String field, final String desc) { void putStatic(final String owner, final String field, final String desc) {
...@@ -413,7 +413,7 @@ public class MethodGenerator extends MethodVisitor { ...@@ -413,7 +413,7 @@ public class MethodGenerator extends MethodVisitor {
super.visitMethodInsn(INVOKEVIRTUAL, super.visitMethodInsn(INVOKEVIRTUAL,
"java/io/PrintStream", "java/io/PrintStream",
"println", "println",
"(Ljava/lang/String;)V"); "(Ljava/lang/String;)V", false);
} }
// print the object on the top of the stack // print the object on the top of the stack
...@@ -426,6 +426,6 @@ public class MethodGenerator extends MethodVisitor { ...@@ -426,6 +426,6 @@ public class MethodGenerator extends MethodVisitor {
super.visitMethodInsn(INVOKEVIRTUAL, super.visitMethodInsn(INVOKEVIRTUAL,
"java/io/PrintStream", "java/io/PrintStream",
"println", "println",
"(Ljava/lang/Object;)V"); "(Ljava/lang/Object;)V", false);
} }
} }
...@@ -32,10 +32,7 @@ import static jdk.internal.org.objectweb.asm.Opcodes.V1_7; ...@@ -32,10 +32,7 @@ import static jdk.internal.org.objectweb.asm.Opcodes.V1_7;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.DEFAULT_INIT_DESC; import static jdk.nashorn.internal.tools.nasgen.StringConstants.DEFAULT_INIT_DESC;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.INIT; import static jdk.nashorn.internal.tools.nasgen.StringConstants.INIT;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_DESC; import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_DESC;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_DUPLICATE;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_DUPLICATE_DESC;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_FIELD_NAME; import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_FIELD_NAME;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_TYPE;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC; import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_TYPE; import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_TYPE;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPE_SUFFIX; import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPE_SUFFIX;
...@@ -129,7 +126,6 @@ public class PrototypeGenerator extends ClassGenerator { ...@@ -129,7 +126,6 @@ public class PrototypeGenerator extends ClassGenerator {
mi.getStatic(className, PROPERTYMAP_FIELD_NAME, PROPERTYMAP_DESC); mi.getStatic(className, PROPERTYMAP_FIELD_NAME, PROPERTYMAP_DESC);
// make sure we use duplicated PropertyMap so that original map // make sure we use duplicated PropertyMap so that original map
// stays intact and so can be used for many global. // stays intact and so can be used for many global.
mi.invokeVirtual(PROPERTYMAP_TYPE, PROPERTYMAP_DUPLICATE, PROPERTYMAP_DUPLICATE_DESC);
mi.invokeSpecial(PROTOTYPEOBJECT_TYPE, INIT, SCRIPTOBJECT_INIT_DESC); mi.invokeSpecial(PROTOTYPEOBJECT_TYPE, INIT, SCRIPTOBJECT_INIT_DESC);
// initialize Function type fields // initialize Function type fields
initFunctionFields(mi); initFunctionFields(mi);
......
...@@ -146,16 +146,16 @@ public class ScriptClassInstrumentor extends ClassVisitor { ...@@ -146,16 +146,16 @@ public class ScriptClassInstrumentor extends ClassVisitor {
// call $clinit$ just before return from <clinit> // call $clinit$ just before return from <clinit>
if (isStaticInit && opcode == RETURN) { if (isStaticInit && opcode == RETURN) {
super.visitMethodInsn(INVOKESTATIC, scriptClassInfo.getJavaName(), super.visitMethodInsn(INVOKESTATIC, scriptClassInfo.getJavaName(),
$CLINIT$, DEFAULT_INIT_DESC); $CLINIT$, DEFAULT_INIT_DESC, false);
} }
super.visitInsn(opcode); super.visitInsn(opcode);
} }
@Override @Override
public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc) { public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc, final boolean itf) {
if (isConstructor && opcode == INVOKESPECIAL && if (isConstructor && opcode == INVOKESPECIAL &&
INIT.equals(name) && SCRIPTOBJECT_TYPE.equals(owner)) { INIT.equals(name) && SCRIPTOBJECT_TYPE.equals(owner)) {
super.visitMethodInsn(opcode, owner, name, desc); super.visitMethodInsn(opcode, owner, name, desc, false);
if (memberCount > 0) { if (memberCount > 0) {
// initialize @Property fields if needed // initialize @Property fields if needed
...@@ -166,7 +166,7 @@ public class ScriptClassInstrumentor extends ClassVisitor { ...@@ -166,7 +166,7 @@ public class ScriptClassInstrumentor extends ClassVisitor {
super.visitTypeInsn(NEW, clazz); super.visitTypeInsn(NEW, clazz);
super.visitInsn(DUP); super.visitInsn(DUP);
super.visitMethodInsn(INVOKESPECIAL, clazz, super.visitMethodInsn(INVOKESPECIAL, clazz,
INIT, DEFAULT_INIT_DESC); INIT, DEFAULT_INIT_DESC, false);
super.visitFieldInsn(PUTFIELD, scriptClassInfo.getJavaName(), super.visitFieldInsn(PUTFIELD, scriptClassInfo.getJavaName(),
memInfo.getJavaName(), memInfo.getJavaDesc()); memInfo.getJavaName(), memInfo.getJavaDesc());
} }
...@@ -180,7 +180,7 @@ public class ScriptClassInstrumentor extends ClassVisitor { ...@@ -180,7 +180,7 @@ public class ScriptClassInstrumentor extends ClassVisitor {
} }
} }
} else { } else {
super.visitMethodInsn(opcode, owner, name, desc); super.visitMethodInsn(opcode, owner, name, desc, itf);
} }
} }
......
...@@ -45,11 +45,9 @@ import jdk.nashorn.internal.runtime.ScriptObject; ...@@ -45,11 +45,9 @@ import jdk.nashorn.internal.runtime.ScriptObject;
@SuppressWarnings("javadoc") @SuppressWarnings("javadoc")
public interface StringConstants { public interface StringConstants {
// standard jdk types, methods // standard jdk types, methods
static final Type TYPE_METHOD = Type.getType(Method.class);
static final Type TYPE_METHODHANDLE = Type.getType(MethodHandle.class); static final Type TYPE_METHODHANDLE = Type.getType(MethodHandle.class);
static final Type TYPE_METHODHANDLE_ARRAY = Type.getType(MethodHandle[].class); static final Type TYPE_METHODHANDLE_ARRAY = Type.getType(MethodHandle[].class);
static final Type TYPE_OBJECT = Type.getType(Object.class); static final Type TYPE_OBJECT = Type.getType(Object.class);
static final Type TYPE_CLASS = Type.getType(Class.class);
static final Type TYPE_STRING = Type.getType(String.class); static final Type TYPE_STRING = Type.getType(String.class);
static final Type TYPE_COLLECTION = Type.getType(Collection.class); static final Type TYPE_COLLECTION = Type.getType(Collection.class);
static final Type TYPE_COLLECTIONS = Type.getType(Collections.class); static final Type TYPE_COLLECTIONS = Type.getType(Collections.class);
...@@ -63,6 +61,8 @@ public interface StringConstants { ...@@ -63,6 +61,8 @@ public interface StringConstants {
static final String METHODHANDLE_TYPE = TYPE_METHODHANDLE.getInternalName(); static final String METHODHANDLE_TYPE = TYPE_METHODHANDLE.getInternalName();
static final String OBJECT_TYPE = TYPE_OBJECT.getInternalName(); static final String OBJECT_TYPE = TYPE_OBJECT.getInternalName();
static final String OBJECT_DESC = TYPE_OBJECT.getDescriptor(); static final String OBJECT_DESC = TYPE_OBJECT.getDescriptor();
static final String STRING_TYPE = TYPE_STRING.getInternalName();
static final String STRING_DESC = TYPE_STRING.getDescriptor();
static final String OBJECT_ARRAY_DESC = Type.getDescriptor(Object[].class); static final String OBJECT_ARRAY_DESC = Type.getDescriptor(Object[].class);
static final String ARRAYLIST_TYPE = TYPE_ARRAYLIST.getInternalName(); static final String ARRAYLIST_TYPE = TYPE_ARRAYLIST.getInternalName();
static final String COLLECTION_TYPE = TYPE_COLLECTION.getInternalName(); static final String COLLECTION_TYPE = TYPE_COLLECTION.getInternalName();
...@@ -104,10 +104,6 @@ public interface StringConstants { ...@@ -104,10 +104,6 @@ public interface StringConstants {
static final String PROPERTYMAP_DESC = TYPE_PROPERTYMAP.getDescriptor(); static final String PROPERTYMAP_DESC = TYPE_PROPERTYMAP.getDescriptor();
static final String PROPERTYMAP_NEWMAP = "newMap"; static final String PROPERTYMAP_NEWMAP = "newMap";
static final String PROPERTYMAP_NEWMAP_DESC = Type.getMethodDescriptor(TYPE_PROPERTYMAP, TYPE_COLLECTION); static final String PROPERTYMAP_NEWMAP_DESC = Type.getMethodDescriptor(TYPE_PROPERTYMAP, TYPE_COLLECTION);
static final String PROPERTYMAP_DUPLICATE = "duplicate";
static final String PROPERTYMAP_DUPLICATE_DESC = Type.getMethodDescriptor(TYPE_PROPERTYMAP);
static final String PROPERTYMAP_SETISSHARED = "setIsShared";
static final String PROPERTYMAP_SETISSHARED_DESC = Type.getMethodDescriptor(TYPE_PROPERTYMAP);
// PrototypeObject // PrototypeObject
static final String PROTOTYPEOBJECT_TYPE = TYPE_PROTOTYPEOBJECT.getInternalName(); static final String PROTOTYPEOBJECT_TYPE = TYPE_PROTOTYPEOBJECT.getInternalName();
...@@ -135,6 +131,7 @@ public interface StringConstants { ...@@ -135,6 +131,7 @@ public interface StringConstants {
// ScriptObject // ScriptObject
static final String SCRIPTOBJECT_TYPE = TYPE_SCRIPTOBJECT.getInternalName(); static final String SCRIPTOBJECT_TYPE = TYPE_SCRIPTOBJECT.getInternalName();
static final String SCRIPTOBJECT_DESC = TYPE_SCRIPTOBJECT.getDescriptor();
static final String SCRIPTOBJECT_INIT_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_PROPERTYMAP); static final String SCRIPTOBJECT_INIT_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_PROPERTYMAP);
static final String GETTER_PREFIX = "G$"; static final String GETTER_PREFIX = "G$";
......
...@@ -77,7 +77,7 @@ $(NASHORN_OUTPUTDIR)/classes/_the.nasgen.run: $(BUILD_NASGEN) ...@@ -77,7 +77,7 @@ $(NASHORN_OUTPUTDIR)/classes/_the.nasgen.run: $(BUILD_NASGEN)
$(RM) -rf $(@D)/jdk $(@D)/netscape $(RM) -rf $(@D)/jdk $(@D)/netscape
$(CP) -R -p $(NASHORN_OUTPUTDIR)/nashorn_classes/* $(@D)/ $(CP) -R -p $(NASHORN_OUTPUTDIR)/nashorn_classes/* $(@D)/
$(FIXPATH) $(JAVA) \ $(FIXPATH) $(JAVA) \
-cp "$(NASHORN_OUTPUTDIR)/nasgen_classes$(PATH_SEP)$(NASHORN_OUTPUTDIR)/nashorn_classes" \ -Xbootclasspath/p:"$(NASHORN_OUTPUTDIR)/nasgen_classes$(PATH_SEP)$(NASHORN_OUTPUTDIR)/nashorn_classes" \
jdk.nashorn.internal.tools.nasgen.Main $(@D) jdk.nashorn.internal.objects $(@D) jdk.nashorn.internal.tools.nasgen.Main $(@D) jdk.nashorn.internal.objects $(@D)
$(TOUCH) $@ $(TOUCH) $@
......
...@@ -42,6 +42,9 @@ ...@@ -42,6 +42,9 @@
<condition property="hg.executable" value="/usr/local/bin/hg" else="hg"> <condition property="hg.executable" value="/usr/local/bin/hg" else="hg">
<available file="/usr/local/bin/hg"/> <available file="/usr/local/bin/hg"/>
</condition> </condition>
<condition property="git.executable" value="/usr/local/bin/git" else="git">
<available file="/usr/local/bin/git"/>
</condition>
<!-- check if JDK already has ASM classes --> <!-- check if JDK already has ASM classes -->
<available property="asm.available" classname="jdk.internal.org.objectweb.asm.Type"/> <available property="asm.available" classname="jdk.internal.org.objectweb.asm.Type"/>
<!-- check if testng.jar is avaiable --> <!-- check if testng.jar is avaiable -->
...@@ -122,6 +125,7 @@ ...@@ -122,6 +125,7 @@
<compilerarg value="-Xlint:unchecked"/> <compilerarg value="-Xlint:unchecked"/>
<compilerarg value="-Xlint:deprecation"/> <compilerarg value="-Xlint:deprecation"/>
<compilerarg value="-XDignore.symbol.file"/> <compilerarg value="-XDignore.symbol.file"/>
<compilerarg value="-Xdiags:verbose"/>
</javac> </javac>
<copy todir="${build.classes.dir}/META-INF/services"> <copy todir="${build.classes.dir}/META-INF/services">
<fileset dir="${meta.inf.dir}/services/"/> <fileset dir="${meta.inf.dir}/services/"/>
...@@ -240,6 +244,7 @@ ...@@ -240,6 +244,7 @@
<compilerarg value="-J-Djava.ext.dirs="/> <compilerarg value="-J-Djava.ext.dirs="/>
<compilerarg value="-Xlint:unchecked"/> <compilerarg value="-Xlint:unchecked"/>
<compilerarg value="-Xlint:deprecation"/> <compilerarg value="-Xlint:deprecation"/>
<compilerarg value="-Xdiags:verbose"/>
</javac> </javac>
<copy todir="${build.test.classes.dir}/META-INF/services"> <copy todir="${build.test.classes.dir}/META-INF/services">
...@@ -250,6 +255,10 @@ ...@@ -250,6 +255,10 @@
<fileset dir="${test.src.dir}/jdk/nashorn/internal/runtime/resources"/> <fileset dir="${test.src.dir}/jdk/nashorn/internal/runtime/resources"/>
</copy> </copy>
<copy todir="${build.test.classes.dir}/jdk/nashorn/api/scripting/resources">
<fileset dir="${test.src.dir}/jdk/nashorn/api/scripting/resources"/>
</copy>
<!-- tests that check nashorn internals and internal API --> <!-- tests that check nashorn internals and internal API -->
<jar jarfile="${nashorn.internal.tests.jar}"> <jar jarfile="${nashorn.internal.tests.jar}">
<fileset dir="${build.test.classes.dir}" excludes="**/api/**"/> <fileset dir="${build.test.classes.dir}" excludes="**/api/**"/>
...@@ -279,6 +288,11 @@ grant codeBase "file:/${basedir}/test/script/trusted/*" { ...@@ -279,6 +288,11 @@ grant codeBase "file:/${basedir}/test/script/trusted/*" {
permission java.security.AllPermission; permission java.security.AllPermission;
}; };
grant codeBase "file:/${basedir}/test/script/maptests/*" {
permission java.io.FilePermission "${basedir}/test/script/maptests/*","read";
permission java.lang.RuntimePermission "nashorn.debugMode";
};
grant codeBase "file:/${basedir}/test/script/basic/*" { grant codeBase "file:/${basedir}/test/script/basic/*" {
permission java.io.FilePermission "${basedir}/test/script/-", "read"; permission java.io.FilePermission "${basedir}/test/script/-", "read";
permission java.io.FilePermission "$${user.dir}", "read"; permission java.io.FilePermission "$${user.dir}", "read";
...@@ -459,18 +473,17 @@ grant codeBase "file:/${basedir}/test/script/basic/classloader.js" { ...@@ -459,18 +473,17 @@ grant codeBase "file:/${basedir}/test/script/basic/classloader.js" {
<!-- test262 test suite --> <!-- test262 test suite -->
<target name="get-test262" depends="init" unless="${test-sys-prop.external.test262}"> <target name="get-test262" depends="init" unless="${test-sys-prop.external.test262}">
<!-- clone test262 mercurial repo --> <!-- clone test262 git repo -->
<exec executable="${hg.executable}"> <exec executable="${git.executable}">
<arg value="clone"/> <arg value="clone"/>
<arg value="http://hg.ecmascript.org/tests/test262"/> <arg value="https://github.com/tc39/test262"/>
<arg value="${test.external.dir}/test262"/> <arg value="${test.external.dir}/test262"/>
</exec> </exec>
</target> </target>
<target name="update-test262" depends="init" if="${test-sys-prop.external.test262}"> <target name="update-test262" depends="init" if="${test-sys-prop.external.test262}">
<!-- update test262 mercurial repo --> <!-- update test262 git repo -->
<exec executable="${hg.executable}" dir="${test.external.dir}/test262"> <exec executable="${git.executable}" dir="${test.external.dir}/test262">
<arg value="pull"/> <arg value="pull"/>
<arg value="-u"/>
</exec> </exec>
</target> </target>
......
...@@ -112,6 +112,7 @@ run.classpath=\ ...@@ -112,6 +112,7 @@ run.classpath=\
test.dir=test test.dir=test
test.script.dir=test/script test.script.dir=test/script
test.basic.dir=test/script/basic test.basic.dir=test/script/basic
test.maptests.dir=test/script/maptests
test.error.dir=test/script/error test.error.dir=test/script/error
test.sandbox.dir=test/script/sandbox test.sandbox.dir=test/script/sandbox
test.trusted.dir=test/script/trusted test.trusted.dir=test/script/trusted
...@@ -121,7 +122,7 @@ test262.suite.dir=${test262.dir}/test/suite ...@@ -121,7 +122,7 @@ test262.suite.dir=${test262.dir}/test/suite
testjfx.dir=${test.script.dir}/jfx testjfx.dir=${test.script.dir}/jfx
test-sys-prop.test.dir=${test.dir} test-sys-prop.test.dir=${test.dir}
test-sys-prop.test.js.roots=${test.basic.dir} ${test.error.dir} ${test.sandbox.dir} ${test.trusted.dir} test-sys-prop.test.js.roots=${test.basic.dir} ${test.maptests.dir} ${test.error.dir} ${test.sandbox.dir} ${test.trusted.dir}
test-sys-prop.test262.suite.dir=${test262.suite.dir} test-sys-prop.test262.suite.dir=${test262.suite.dir}
test-sys-prop.es5conform.testcases.dir=${test.external.dir}/ES5Conform/TestCases test-sys-prop.es5conform.testcases.dir=${test.external.dir}/ES5Conform/TestCases
test-sys-prop.test.basic.dir=${test.basic.dir} test-sys-prop.test.basic.dir=${test.basic.dir}
...@@ -201,7 +202,7 @@ test262-test-sys-prop.test.failed.list.file=${build.dir}/test/failedTests ...@@ -201,7 +202,7 @@ test262-test-sys-prop.test.failed.list.file=${build.dir}/test/failedTests
# test262 test frameworks # test262 test frameworks
test262-test-sys-prop.test.js.framework=\ test262-test-sys-prop.test.js.framework=\
--class-cache-size=0 \ --class-cache-size=10 \
--no-java \ --no-java \
--no-typed-arrays \ --no-typed-arrays \
-timezone=PST \ -timezone=PST \
...@@ -264,7 +265,7 @@ run.test.jvmargs.octane.main=${run.test.jvmargs.common} ...@@ -264,7 +265,7 @@ run.test.jvmargs.octane.main=${run.test.jvmargs.common}
run.test.jvmsecurityargs=-Xverify:all -Djava.security.manager -Djava.security.policy=${basedir}/build/nashorn.policy run.test.jvmsecurityargs=-Xverify:all -Djava.security.manager -Djava.security.policy=${basedir}/build/nashorn.policy
# VM options for script tests with @fork option # VM options for script tests with @fork option
test-sys-prop.test.fork.jvm.options=${run.test.jvmargs.main} -Xmx${run.test.xmx} ${run.test.jvmsecurityargs} test-sys-prop.test.fork.jvm.options=${run.test.jvmargs.main} -Xmx${run.test.xmx} ${run.test.jvmsecurityargs} -cp ${run.test.classpath}
# path of rhino.jar for benchmarks # path of rhino.jar for benchmarks
rhino.jar= rhino.jar=
......
...@@ -29,6 +29,7 @@ import java.util.ArrayList; ...@@ -29,6 +29,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import jdk.nashorn.internal.codegen.CompilerConstants; import jdk.nashorn.internal.codegen.CompilerConstants;
import jdk.nashorn.internal.runtime.ECMAErrors; import jdk.nashorn.internal.runtime.ECMAErrors;
import jdk.nashorn.internal.runtime.ScriptObject;
/** /**
* This is base exception for all Nashorn exceptions. These originate from * This is base exception for all Nashorn exceptions. These originate from
...@@ -44,11 +45,13 @@ import jdk.nashorn.internal.runtime.ECMAErrors; ...@@ -44,11 +45,13 @@ import jdk.nashorn.internal.runtime.ECMAErrors;
@SuppressWarnings("serial") @SuppressWarnings("serial")
public abstract class NashornException extends RuntimeException { public abstract class NashornException extends RuntimeException {
// script file name // script file name
private final String fileName; private String fileName;
// script line number // script line number
private final int line; private int line;
// script column number // script column number
private final int column; private int column;
// underlying ECMA error object - lazily initialized
private Object ecmaError;
/** script source name used for "engine.js" */ /** script source name used for "engine.js" */
public static final String ENGINE_SCRIPT_SOURCE_NAME = "nashorn:engine/resources/engine.js"; public static final String ENGINE_SCRIPT_SOURCE_NAME = "nashorn:engine/resources/engine.js";
...@@ -121,6 +124,15 @@ public abstract class NashornException extends RuntimeException { ...@@ -121,6 +124,15 @@ public abstract class NashornException extends RuntimeException {
return fileName; return fileName;
} }
/**
* Set the source file name for this {@code NashornException}
*
* @param fileName the file name
*/
public final void setFileName(final String fileName) {
this.fileName = fileName;
}
/** /**
* Get the line number for this {@code NashornException} * Get the line number for this {@code NashornException}
* *
...@@ -130,15 +142,33 @@ public abstract class NashornException extends RuntimeException { ...@@ -130,15 +142,33 @@ public abstract class NashornException extends RuntimeException {
return line; return line;
} }
/**
* Set the line number for this {@code NashornException}
*
* @param line the line number
*/
public final void setLineNumber(final int line) {
this.line = line;
}
/** /**
* Get the column for this {@code NashornException} * Get the column for this {@code NashornException}
* *
* @return the column * @return the column number
*/ */
public final int getColumnNumber() { public final int getColumnNumber() {
return column; return column;
} }
/**
* Set the column for this {@code NashornException}
*
* @param column the column number
*/
public final void setColumnNumber(final int column) {
this.column = column;
}
/** /**
* Returns array javascript stack frames from the given exception object. * Returns array javascript stack frames from the given exception object.
* *
...@@ -155,6 +185,11 @@ public abstract class NashornException extends RuntimeException { ...@@ -155,6 +185,11 @@ public abstract class NashornException extends RuntimeException {
if (methodName.equals(CompilerConstants.RUN_SCRIPT.symbolName())) { if (methodName.equals(CompilerConstants.RUN_SCRIPT.symbolName())) {
methodName = "<program>"; methodName = "<program>";
} }
if (methodName.contains(CompilerConstants.ANON_FUNCTION_PREFIX.symbolName())) {
methodName = "<anonymous>";
}
filtered.add(new StackTraceElement(className, methodName, filtered.add(new StackTraceElement(className, methodName,
st.getFileName(), st.getLineNumber())); st.getFileName(), st.getLineNumber()));
} }
...@@ -188,4 +223,43 @@ public abstract class NashornException extends RuntimeException { ...@@ -188,4 +223,43 @@ public abstract class NashornException extends RuntimeException {
} }
return buf.toString(); return buf.toString();
} }
protected Object getThrown() {
return null;
}
protected NashornException initEcmaError(final ScriptObject global) {
if (ecmaError != null) {
return this; // initialized already!
}
final Object thrown = getThrown();
if (thrown instanceof ScriptObject) {
setEcmaError(ScriptObjectMirror.wrap(thrown, global));
} else {
setEcmaError(thrown);
}
return this;
}
/**
* Return the underlying ECMA error object, if available.
*
* @return underlying ECMA Error object's mirror or whatever was thrown
* from script such as a String, Number or a Boolean.
*/
public Object getEcmaError() {
return ecmaError;
}
/**
* Return the underlying ECMA error object, if available.
*
* @param ecmaError underlying ECMA Error object's mirror or whatever was thrown
* from script such as a String, Number or a Boolean.
*/
public void setEcmaError(final Object ecmaError) {
this.ecmaError = ecmaError;
}
} }
...@@ -57,9 +57,9 @@ import javax.script.ScriptEngine; ...@@ -57,9 +57,9 @@ import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory; import javax.script.ScriptEngineFactory;
import javax.script.ScriptException; import javax.script.ScriptException;
import javax.script.SimpleBindings; import javax.script.SimpleBindings;
import jdk.nashorn.internal.objects.Global;
import jdk.nashorn.internal.runtime.Context; import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.ErrorManager; import jdk.nashorn.internal.runtime.ErrorManager;
import jdk.nashorn.internal.runtime.GlobalObject;
import jdk.nashorn.internal.runtime.Property; import jdk.nashorn.internal.runtime.Property;
import jdk.nashorn.internal.runtime.ScriptFunction; import jdk.nashorn.internal.runtime.ScriptFunction;
import jdk.nashorn.internal.runtime.ScriptObject; import jdk.nashorn.internal.runtime.ScriptObject;
...@@ -99,7 +99,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C ...@@ -99,7 +99,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
private final boolean _global_per_engine; private final boolean _global_per_engine;
// This is the initial default Nashorn global object. // This is the initial default Nashorn global object.
// This is used as "shared" global if above option is true. // This is used as "shared" global if above option is true.
private final ScriptObject global; private final Global global;
// initialized bit late to be made 'final'. // initialized bit late to be made 'final'.
// Property object for "context" property of global object. // Property object for "context" property of global object.
private volatile Property contextProperty; private volatile Property contextProperty;
...@@ -264,7 +264,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C ...@@ -264,7 +264,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
public Object __noSuchProperty__(final Object self, final ScriptContext ctxt, final String name) { public Object __noSuchProperty__(final Object self, final ScriptContext ctxt, final String name) {
if (ctxt != null) { if (ctxt != null) {
final int scope = ctxt.getAttributesScope(name); final int scope = ctxt.getAttributesScope(name);
final ScriptObject ctxtGlobal = getNashornGlobalFrom(ctxt); final Global ctxtGlobal = getNashornGlobalFrom(ctxt);
if (scope != -1) { if (scope != -1) {
return ScriptObjectMirror.unwrap(ctxt.getAttribute(name, scope), ctxtGlobal); return ScriptObjectMirror.unwrap(ctxt.getAttribute(name, scope), ctxtGlobal);
} }
...@@ -317,7 +317,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C ...@@ -317,7 +317,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
} }
ScriptObject realSelf = null; ScriptObject realSelf = null;
ScriptObject realGlobal = null; Global realGlobal = null;
if(thiz == null) { if(thiz == null) {
// making interface out of global functions // making interface out of global functions
realSelf = realGlobal = getNashornGlobalFrom(context); realSelf = realGlobal = getNashornGlobalFrom(context);
...@@ -346,7 +346,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C ...@@ -346,7 +346,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
} }
try { try {
final ScriptObject oldGlobal = Context.getGlobal(); final Global oldGlobal = Context.getGlobal();
final boolean globalChanged = (oldGlobal != realGlobal); final boolean globalChanged = (oldGlobal != realGlobal);
try { try {
if (globalChanged) { if (globalChanged) {
...@@ -371,7 +371,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C ...@@ -371,7 +371,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
} }
// Retrieve nashorn Global object for a given ScriptContext object // Retrieve nashorn Global object for a given ScriptContext object
private ScriptObject getNashornGlobalFrom(final ScriptContext ctxt) { private Global getNashornGlobalFrom(final ScriptContext ctxt) {
if (_global_per_engine) { if (_global_per_engine) {
// shared single global object for all ENGINE_SCOPE Bindings // shared single global object for all ENGINE_SCOPE Bindings
return global; return global;
...@@ -380,18 +380,18 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C ...@@ -380,18 +380,18 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
final Bindings bindings = ctxt.getBindings(ScriptContext.ENGINE_SCOPE); final Bindings bindings = ctxt.getBindings(ScriptContext.ENGINE_SCOPE);
// is this Nashorn's own Bindings implementation? // is this Nashorn's own Bindings implementation?
if (bindings instanceof ScriptObjectMirror) { if (bindings instanceof ScriptObjectMirror) {
final ScriptObject sobj = globalFromMirror((ScriptObjectMirror)bindings); final Global glob = globalFromMirror((ScriptObjectMirror)bindings);
if (sobj != null) { if (glob != null) {
return sobj; return glob;
} }
} }
// Arbitrary user Bindings implementation. Look for NASHORN_GLOBAL in it! // Arbitrary user Bindings implementation. Look for NASHORN_GLOBAL in it!
Object scope = bindings.get(NASHORN_GLOBAL); Object scope = bindings.get(NASHORN_GLOBAL);
if (scope instanceof ScriptObjectMirror) { if (scope instanceof ScriptObjectMirror) {
final ScriptObject sobj = globalFromMirror((ScriptObjectMirror)scope); final Global glob = globalFromMirror((ScriptObjectMirror)scope);
if (sobj != null) { if (glob != null) {
return sobj; return glob;
} }
} }
...@@ -399,14 +399,14 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C ...@@ -399,14 +399,14 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
// Create new global instance mirror and associate with the Bindings. // Create new global instance mirror and associate with the Bindings.
final ScriptObjectMirror mirror = createGlobalMirror(ctxt); final ScriptObjectMirror mirror = createGlobalMirror(ctxt);
bindings.put(NASHORN_GLOBAL, mirror); bindings.put(NASHORN_GLOBAL, mirror);
return mirror.getScriptObject(); return mirror.getHomeGlobal();
} }
// Retrieve nashorn Global object from a given ScriptObjectMirror // Retrieve nashorn Global object from a given ScriptObjectMirror
private ScriptObject globalFromMirror(final ScriptObjectMirror mirror) { private Global globalFromMirror(final ScriptObjectMirror mirror) {
ScriptObject sobj = mirror.getScriptObject(); ScriptObject sobj = mirror.getScriptObject();
if (sobj instanceof GlobalObject && isOfContext(sobj, nashornContext)) { if (sobj instanceof Global && isOfContext((Global)sobj, nashornContext)) {
return sobj; return (Global)sobj;
} }
return null; return null;
...@@ -414,15 +414,15 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C ...@@ -414,15 +414,15 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
// Create a new ScriptObjectMirror wrapping a newly created Nashorn Global object // Create a new ScriptObjectMirror wrapping a newly created Nashorn Global object
private ScriptObjectMirror createGlobalMirror(final ScriptContext ctxt) { private ScriptObjectMirror createGlobalMirror(final ScriptContext ctxt) {
final ScriptObject newGlobal = createNashornGlobal(ctxt); final Global newGlobal = createNashornGlobal(ctxt);
return new ScriptObjectMirror(newGlobal, newGlobal); return new ScriptObjectMirror(newGlobal, newGlobal);
} }
// Create a new Nashorn Global object // Create a new Nashorn Global object
private ScriptObject createNashornGlobal(final ScriptContext ctxt) { private Global createNashornGlobal(final ScriptContext ctxt) {
final ScriptObject newGlobal = AccessController.doPrivileged(new PrivilegedAction<ScriptObject>() { final Global newGlobal = AccessController.doPrivileged(new PrivilegedAction<Global>() {
@Override @Override
public ScriptObject run() { public Global run() {
try { try {
return nashornContext.newGlobal(); return nashornContext.newGlobal();
} catch (final RuntimeException e) { } catch (final RuntimeException e) {
...@@ -460,7 +460,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C ...@@ -460,7 +460,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
} }
// scripts should see "context" and "engine" as variables in the given global object // scripts should see "context" and "engine" as variables in the given global object
private void setContextVariables(final ScriptObject ctxtGlobal, final ScriptContext ctxt) { private void setContextVariables(final Global ctxtGlobal, final ScriptContext ctxt) {
// set "context" global variable via contextProperty - because this // set "context" global variable via contextProperty - because this
// property is non-writable // property is non-writable
contextProperty.setObjectValue(ctxtGlobal, ctxtGlobal, ctxt, false); contextProperty.setObjectValue(ctxtGlobal, ctxtGlobal, ctxt, false);
...@@ -470,7 +470,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C ...@@ -470,7 +470,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
} }
// if no arguments passed, expose it // if no arguments passed, expose it
if (! (args instanceof ScriptObject)) { if (! (args instanceof ScriptObject)) {
args = ((GlobalObject)ctxtGlobal).wrapAsObject(args); args = ctxtGlobal.wrapAsObject(args);
ctxtGlobal.set("arguments", args, false); ctxtGlobal.set("arguments", args, false);
} }
} }
...@@ -478,16 +478,19 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C ...@@ -478,16 +478,19 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
private Object invokeImpl(final Object selfObject, final String name, final Object... args) throws ScriptException, NoSuchMethodException { private Object invokeImpl(final Object selfObject, final String name, final Object... args) throws ScriptException, NoSuchMethodException {
name.getClass(); // null check name.getClass(); // null check
Global invokeGlobal = null;
ScriptObjectMirror selfMirror = null; ScriptObjectMirror selfMirror = null;
if (selfObject instanceof ScriptObjectMirror) { if (selfObject instanceof ScriptObjectMirror) {
selfMirror = (ScriptObjectMirror)selfObject; selfMirror = (ScriptObjectMirror)selfObject;
if (! isOfContext(selfMirror.getHomeGlobal(), nashornContext)) { if (! isOfContext(selfMirror.getHomeGlobal(), nashornContext)) {
throw new IllegalArgumentException(getMessage("script.object.from.another.engine")); throw new IllegalArgumentException(getMessage("script.object.from.another.engine"));
} }
invokeGlobal = selfMirror.getHomeGlobal();
} else if (selfObject instanceof ScriptObject) { } else if (selfObject instanceof ScriptObject) {
// invokeMethod called from script code - in which case we may get 'naked' ScriptObject // invokeMethod called from script code - in which case we may get 'naked' ScriptObject
// Wrap it with oldGlobal to make a ScriptObjectMirror for the same. // Wrap it with oldGlobal to make a ScriptObjectMirror for the same.
final ScriptObject oldGlobal = Context.getGlobal(); final Global oldGlobal = Context.getGlobal();
invokeGlobal = oldGlobal;
if (oldGlobal == null) { if (oldGlobal == null) {
throw new IllegalArgumentException(getMessage("no.current.nashorn.global")); throw new IllegalArgumentException(getMessage("no.current.nashorn.global"));
} }
...@@ -499,7 +502,8 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C ...@@ -499,7 +502,8 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
selfMirror = (ScriptObjectMirror)ScriptObjectMirror.wrap(selfObject, oldGlobal); selfMirror = (ScriptObjectMirror)ScriptObjectMirror.wrap(selfObject, oldGlobal);
} else if (selfObject == null) { } else if (selfObject == null) {
// selfObject is null => global function call // selfObject is null => global function call
final ScriptObject ctxtGlobal = getNashornGlobalFrom(context); final Global ctxtGlobal = getNashornGlobalFrom(context);
invokeGlobal = ctxtGlobal;
selfMirror = (ScriptObjectMirror)ScriptObjectMirror.wrap(ctxtGlobal, ctxtGlobal); selfMirror = (ScriptObjectMirror)ScriptObjectMirror.wrap(ctxtGlobal, ctxtGlobal);
} }
...@@ -511,7 +515,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C ...@@ -511,7 +515,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
if (cause instanceof NoSuchMethodException) { if (cause instanceof NoSuchMethodException) {
throw (NoSuchMethodException)cause; throw (NoSuchMethodException)cause;
} }
throwAsScriptException(e); throwAsScriptException(e, invokeGlobal);
throw new AssertionError("should not reach here"); throw new AssertionError("should not reach here");
} }
} }
...@@ -528,11 +532,11 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C ...@@ -528,11 +532,11 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
return evalImpl(script, ctxt, getNashornGlobalFrom(ctxt)); return evalImpl(script, ctxt, getNashornGlobalFrom(ctxt));
} }
private Object evalImpl(final ScriptFunction script, final ScriptContext ctxt, final ScriptObject ctxtGlobal) throws ScriptException { private Object evalImpl(final ScriptFunction script, final ScriptContext ctxt, final Global ctxtGlobal) throws ScriptException {
if (script == null) { if (script == null) {
return null; return null;
} }
final ScriptObject oldGlobal = Context.getGlobal(); final Global oldGlobal = Context.getGlobal();
final boolean globalChanged = (oldGlobal != ctxtGlobal); final boolean globalChanged = (oldGlobal != ctxtGlobal);
try { try {
if (globalChanged) { if (globalChanged) {
...@@ -545,7 +549,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C ...@@ -545,7 +549,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
} }
return ScriptObjectMirror.translateUndefined(ScriptObjectMirror.wrap(ScriptRuntime.apply(script, ctxtGlobal), ctxtGlobal)); return ScriptObjectMirror.translateUndefined(ScriptObjectMirror.wrap(ScriptRuntime.apply(script, ctxtGlobal), ctxtGlobal));
} catch (final Exception e) { } catch (final Exception e) {
throwAsScriptException(e); throwAsScriptException(e, ctxtGlobal);
throw new AssertionError("should not reach here"); throw new AssertionError("should not reach here");
} finally { } finally {
if (globalChanged) { if (globalChanged) {
...@@ -554,7 +558,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C ...@@ -554,7 +558,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
} }
} }
private static void throwAsScriptException(final Exception e) throws ScriptException { private static void throwAsScriptException(final Exception e, final Global global) throws ScriptException {
if (e instanceof ScriptException) { if (e instanceof ScriptException) {
throw (ScriptException)e; throw (ScriptException)e;
} else if (e instanceof NashornException) { } else if (e instanceof NashornException) {
...@@ -562,6 +566,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C ...@@ -562,6 +566,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
final ScriptException se = new ScriptException( final ScriptException se = new ScriptException(
ne.getMessage(), ne.getFileName(), ne.getMessage(), ne.getFileName(),
ne.getLineNumber(), ne.getColumnNumber()); ne.getLineNumber(), ne.getColumnNumber());
ne.initEcmaError(global);
se.initCause(e); se.initCause(e);
throw se; throw se;
} else if (e instanceof RuntimeException) { } else if (e instanceof RuntimeException) {
...@@ -577,7 +582,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C ...@@ -577,7 +582,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
return new CompiledScript() { return new CompiledScript() {
@Override @Override
public Object eval(final ScriptContext ctxt) throws ScriptException { public Object eval(final ScriptContext ctxt) throws ScriptException {
final ScriptObject globalObject = getNashornGlobalFrom(ctxt); final Global globalObject = getNashornGlobalFrom(ctxt);
// Are we running the script in the correct global? // Are we running the script in the correct global?
if (func.getScope() == globalObject) { if (func.getScope() == globalObject) {
return evalImpl(func, ctxt, globalObject); return evalImpl(func, ctxt, globalObject);
...@@ -597,8 +602,8 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C ...@@ -597,8 +602,8 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
return compileImpl(source, getNashornGlobalFrom(ctxt)); return compileImpl(source, getNashornGlobalFrom(ctxt));
} }
private ScriptFunction compileImpl(final Source source, final ScriptObject newGlobal) throws ScriptException { private ScriptFunction compileImpl(final Source source, final Global newGlobal) throws ScriptException {
final ScriptObject oldGlobal = Context.getGlobal(); final Global oldGlobal = Context.getGlobal();
final boolean globalChanged = (oldGlobal != newGlobal); final boolean globalChanged = (oldGlobal != newGlobal);
try { try {
if (globalChanged) { if (globalChanged) {
...@@ -607,7 +612,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C ...@@ -607,7 +612,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
return nashornContext.compileScript(source, newGlobal); return nashornContext.compileScript(source, newGlobal);
} catch (final Exception e) { } catch (final Exception e) {
throwAsScriptException(e); throwAsScriptException(e, newGlobal);
throw new AssertionError("should not reach here"); throw new AssertionError("should not reach here");
} finally { } finally {
if (globalChanged) { if (globalChanged) {
...@@ -623,6 +628,11 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C ...@@ -623,6 +628,11 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
continue; continue;
} }
// skip check for default methods - non-abstract, interface methods
if (! Modifier.isAbstract(method.getModifiers())) {
continue;
}
Object obj = sobj.get(method.getName()); Object obj = sobj.get(method.getName());
if (! (obj instanceof ScriptFunction)) { if (! (obj instanceof ScriptFunction)) {
return false; return false;
...@@ -631,8 +641,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C ...@@ -631,8 +641,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
return true; return true;
} }
private static boolean isOfContext(final ScriptObject global, final Context context) { private static boolean isOfContext(final Global global, final Context context) {
assert global instanceof GlobalObject: "Not a Global object"; return global.isOfContext(context);
return ((GlobalObject)global).isOfContext(context);
} }
} }
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
package jdk.nashorn.api.scripting; package jdk.nashorn.api.scripting;
import java.nio.ByteBuffer;
import java.security.AccessControlContext; import java.security.AccessControlContext;
import java.security.AccessController; import java.security.AccessController;
import java.security.Permissions; import java.security.Permissions;
...@@ -41,9 +42,10 @@ import java.util.Map; ...@@ -41,9 +42,10 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import javax.script.Bindings; import javax.script.Bindings;
import jdk.nashorn.internal.objects.Global;
import jdk.nashorn.internal.runtime.arrays.ArrayData;
import jdk.nashorn.internal.runtime.ConsString; import jdk.nashorn.internal.runtime.ConsString;
import jdk.nashorn.internal.runtime.Context; import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.GlobalObject;
import jdk.nashorn.internal.runtime.JSType; import jdk.nashorn.internal.runtime.JSType;
import jdk.nashorn.internal.runtime.ScriptFunction; import jdk.nashorn.internal.runtime.ScriptFunction;
import jdk.nashorn.internal.runtime.ScriptObject; import jdk.nashorn.internal.runtime.ScriptObject;
...@@ -62,7 +64,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin ...@@ -62,7 +64,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
private static final AccessControlContext GET_CONTEXT_ACC_CTXT = getContextAccCtxt(); private static final AccessControlContext GET_CONTEXT_ACC_CTXT = getContextAccCtxt();
private final ScriptObject sobj; private final ScriptObject sobj;
private final ScriptObject global; private final Global global;
private final boolean strict; private final boolean strict;
@Override @Override
...@@ -93,7 +95,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin ...@@ -93,7 +95,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
@Override @Override
public Object call(final Object thiz, final Object... args) { public Object call(final Object thiz, final Object... args) {
final ScriptObject oldGlobal = Context.getGlobal(); final Global oldGlobal = Context.getGlobal();
final boolean globalChanged = (oldGlobal != global); final boolean globalChanged = (oldGlobal != global);
try { try {
...@@ -108,6 +110,8 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin ...@@ -108,6 +110,8 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
} }
throw new RuntimeException("not a function: " + toString()); throw new RuntimeException("not a function: " + toString());
} catch (final NashornException ne) {
throw ne.initEcmaError(global);
} catch (final RuntimeException | Error e) { } catch (final RuntimeException | Error e) {
throw e; throw e;
} catch (final Throwable t) { } catch (final Throwable t) {
...@@ -121,7 +125,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin ...@@ -121,7 +125,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
@Override @Override
public Object newObject(final Object... args) { public Object newObject(final Object... args) {
final ScriptObject oldGlobal = Context.getGlobal(); final Global oldGlobal = Context.getGlobal();
final boolean globalChanged = (oldGlobal != global); final boolean globalChanged = (oldGlobal != global);
try { try {
...@@ -135,6 +139,8 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin ...@@ -135,6 +139,8 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
} }
throw new RuntimeException("not a constructor: " + toString()); throw new RuntimeException("not a constructor: " + toString());
} catch (final NashornException ne) {
throw ne.initEcmaError(global);
} catch (final RuntimeException | Error e) { } catch (final RuntimeException | Error e) {
throw e; throw e;
} catch (final Throwable t) { } catch (final Throwable t) {
...@@ -165,7 +171,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin ...@@ -165,7 +171,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
public Object callMember(final String functionName, final Object... args) { public Object callMember(final String functionName, final Object... args) {
functionName.getClass(); // null check functionName.getClass(); // null check
final ScriptObject oldGlobal = Context.getGlobal(); final Global oldGlobal = Context.getGlobal();
final boolean globalChanged = (oldGlobal != global); final boolean globalChanged = (oldGlobal != global);
try { try {
...@@ -182,6 +188,8 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin ...@@ -182,6 +188,8 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
} }
throw new NoSuchMethodException("No such function " + functionName); throw new NoSuchMethodException("No such function " + functionName);
} catch (final NashornException ne) {
throw ne.initEcmaError(global);
} catch (final RuntimeException | Error e) { } catch (final RuntimeException | Error e) {
throw e; throw e;
} catch (final Throwable t) { } catch (final Throwable t) {
...@@ -253,6 +261,22 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin ...@@ -253,6 +261,22 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
}); });
} }
/**
* Nashorn extension: setIndexedPropertiesToExternalArrayData.
* set indexed properties be exposed from a given nio ByteBuffer.
*
* @param buf external buffer - should be a nio ByteBuffer
*/
public void setIndexedPropertiesToExternalArrayData(final ByteBuffer buf) {
inGlobal(new Callable<Void>() {
@Override public Void call() {
sobj.setArray(ArrayData.allocate(buf));
return null;
}
});
}
@Override @Override
public boolean isInstance(final Object obj) { public boolean isInstance(final Object obj) {
if (! (obj instanceof ScriptObjectMirror)) { if (! (obj instanceof ScriptObjectMirror)) {
...@@ -618,7 +642,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin ...@@ -618,7 +642,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
*/ */
public static Object wrap(final Object obj, final Object homeGlobal) { public static Object wrap(final Object obj, final Object homeGlobal) {
if(obj instanceof ScriptObject) { if(obj instanceof ScriptObject) {
return homeGlobal instanceof ScriptObject ? new ScriptObjectMirror((ScriptObject)obj, (ScriptObject)homeGlobal) : obj; return homeGlobal instanceof Global ? new ScriptObjectMirror((ScriptObject)obj, (Global)homeGlobal) : obj;
} }
if(obj instanceof ConsString) { if(obj instanceof ConsString) {
return obj.toString(); return obj.toString();
...@@ -686,13 +710,13 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin ...@@ -686,13 +710,13 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
// package-privates below this. // package-privates below this.
ScriptObjectMirror(final ScriptObject sobj, final ScriptObject global) { ScriptObjectMirror(final ScriptObject sobj, final Global global) {
assert sobj != null : "ScriptObjectMirror on null!"; assert sobj != null : "ScriptObjectMirror on null!";
assert global instanceof GlobalObject : "global is not a GlobalObject"; assert global != null : "home Global is null";
this.sobj = sobj; this.sobj = sobj;
this.global = global; this.global = global;
this.strict = ((GlobalObject)global).isStrictContext(); this.strict = global.isStrictContext();
} }
// accessors for script engine // accessors for script engine
...@@ -700,7 +724,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin ...@@ -700,7 +724,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
return sobj; return sobj;
} }
ScriptObject getHomeGlobal() { Global getHomeGlobal() {
return global; return global;
} }
...@@ -710,13 +734,15 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin ...@@ -710,13 +734,15 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
// internals only below this. // internals only below this.
private <V> V inGlobal(final Callable<V> callable) { private <V> V inGlobal(final Callable<V> callable) {
final ScriptObject oldGlobal = Context.getGlobal(); final Global oldGlobal = Context.getGlobal();
final boolean globalChanged = (oldGlobal != global); final boolean globalChanged = (oldGlobal != global);
if (globalChanged) { if (globalChanged) {
Context.setGlobal(global); Context.setGlobal(global);
} }
try { try {
return callable.call(); return callable.call();
} catch (final NashornException ne) {
throw ne.initEcmaError(global);
} catch (final RuntimeException e) { } catch (final RuntimeException e) {
throw e; throw e;
} catch (final Exception e) { } catch (final Exception e) {
......
...@@ -375,10 +375,11 @@ final class Attr extends NodeOperatorVisitor<LexicalContext> { ...@@ -375,10 +375,11 @@ final class Attr extends NodeOperatorVisitor<LexicalContext> {
* @return Symbol for given name or null for redefinition. * @return Symbol for given name or null for redefinition.
*/ */
private Symbol defineSymbol(final Block block, final String name, final int symbolFlags) { private Symbol defineSymbol(final Block block, final String name, final int symbolFlags) {
int flags = symbolFlags; int flags = symbolFlags;
Symbol symbol = findSymbol(block, name); // Locate symbol. Symbol symbol = findSymbol(block, name); // Locate symbol.
boolean isGlobal = (flags & KINDMASK) == IS_GLOBAL;
if ((flags & KINDMASK) == IS_GLOBAL) { if (isGlobal) {
flags |= IS_SCOPE; flags |= IS_SCOPE;
} }
...@@ -414,6 +415,8 @@ final class Attr extends NodeOperatorVisitor<LexicalContext> { ...@@ -414,6 +415,8 @@ final class Attr extends NodeOperatorVisitor<LexicalContext> {
// Determine where to create it. // Determine where to create it.
if ((flags & Symbol.KINDMASK) == IS_VAR && ((flags & IS_INTERNAL) == IS_INTERNAL || (flags & IS_LET) == IS_LET)) { if ((flags & Symbol.KINDMASK) == IS_VAR && ((flags & IS_INTERNAL) == IS_INTERNAL || (flags & IS_LET) == IS_LET)) {
symbolBlock = block; //internal vars are always defined in the block closest to them symbolBlock = block; //internal vars are always defined in the block closest to them
} else if (isGlobal) {
symbolBlock = lc.getOutermostFunction().getBody();
} else { } else {
symbolBlock = lc.getFunctionBody(function); symbolBlock = lc.getFunctionBody(function);
} }
......
...@@ -685,7 +685,7 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex ...@@ -685,7 +685,7 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
private void scopeCall(final IdentNode node, final int flags) { private void scopeCall(final IdentNode node, final int flags) {
load(node, Type.OBJECT); // Type.OBJECT as foo() makes no sense if foo == 3 load(node, Type.OBJECT); // Type.OBJECT as foo() makes no sense if foo == 3
// ScriptFunction will see CALLSITE_SCOPE and will bind scope accordingly. // ScriptFunction will see CALLSITE_SCOPE and will bind scope accordingly.
method.loadNull(); //the 'this' method.loadUndefined(Type.OBJECT); //the 'this' object
method.dynamicCall(callNodeType, 2 + loadArgs(args), flags); method.dynamicCall(callNodeType, 2 + loadArgs(args), flags);
} }
...@@ -818,7 +818,7 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex ...@@ -818,7 +818,7 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
protected boolean enterDefault(final Node node) { protected boolean enterDefault(final Node node) {
// Load up function. // Load up function.
load(function, Type.OBJECT); //TODO, e.g. booleans can be used as functions load(function, Type.OBJECT); //TODO, e.g. booleans can be used as functions
method.loadNull(); // ScriptFunction will figure out the correct this when it sees CALLSITE_SCOPE method.loadUndefined(Type.OBJECT); // ScriptFunction will figure out the correct this when it sees CALLSITE_SCOPE
method.dynamicCall(callNodeType, 2 + loadArgs(args), getCallSiteFlags() | CALLSITE_SCOPE); method.dynamicCall(callNodeType, 2 + loadArgs(args), getCallSiteFlags() | CALLSITE_SCOPE);
return false; return false;
...@@ -2023,8 +2023,6 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex ...@@ -2023,8 +2023,6 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
return false; return false;
} }
method._new(ECMAException.class).dup();
final Source source = lc.getCurrentFunction().getSource(); final Source source = lc.getCurrentFunction().getSource();
final Expression expression = throwNode.getExpression(); final Expression expression = throwNode.getExpression();
...@@ -2037,7 +2035,7 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex ...@@ -2037,7 +2035,7 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
method.load(source.getName()); method.load(source.getName());
method.load(line); method.load(line);
method.load(column); method.load(column);
method.invoke(ECMAException.THROW_INIT); method.invoke(ECMAException.CREATE);
method.athrow(); method.athrow();
......
...@@ -158,7 +158,7 @@ final class CodeGeneratorLexicalContext extends LexicalContext { ...@@ -158,7 +158,7 @@ final class CodeGeneratorLexicalContext extends LexicalContext {
if (scopeCalls.containsKey(scopeCall)) { if (scopeCalls.containsKey(scopeCall)) {
return scopeCalls.get(scopeCall); return scopeCalls.get(scopeCall);
} }
scopeCall.setClassAndName(unit, getCurrentFunction().uniqueName("scopeCall")); scopeCall.setClassAndName(unit, getCurrentFunction().uniqueName(":scopeCall"));
scopeCalls.put(scopeCall, scopeCall); scopeCalls.put(scopeCall, scopeCall);
return scopeCall; return scopeCall;
} }
...@@ -177,7 +177,7 @@ final class CodeGeneratorLexicalContext extends LexicalContext { ...@@ -177,7 +177,7 @@ final class CodeGeneratorLexicalContext extends LexicalContext {
if (scopeCalls.containsKey(scopeCall)) { if (scopeCalls.containsKey(scopeCall)) {
return scopeCalls.get(scopeCall); return scopeCalls.get(scopeCall);
} }
scopeCall.setClassAndName(unit, getCurrentFunction().uniqueName("scopeCall")); scopeCall.setClassAndName(unit, getCurrentFunction().uniqueName(":scopeCall"));
scopeCalls.put(scopeCall, scopeCall); scopeCalls.put(scopeCall, scopeCall);
return scopeCall; return scopeCall;
} }
......
...@@ -85,6 +85,8 @@ public final class Compiler { ...@@ -85,6 +85,8 @@ public final class Compiler {
private Source source; private Source source;
private String sourceName;
private final Map<String, byte[]> bytecode; private final Map<String, byte[]> bytecode;
private final Set<CompileUnit> compileUnits; private final Set<CompileUnit> compileUnits;
...@@ -267,6 +269,7 @@ public final class Compiler { ...@@ -267,6 +269,7 @@ public final class Compiler {
append('$'). append('$').
append(safeSourceName(functionNode.getSource())); append(safeSourceName(functionNode.getSource()));
this.source = functionNode.getSource(); this.source = functionNode.getSource();
this.sourceName = functionNode.getSourceName();
this.scriptName = sb.toString(); this.scriptName = sb.toString();
} }
...@@ -573,7 +576,7 @@ public final class Compiler { ...@@ -573,7 +576,7 @@ public final class Compiler {
} }
private CompileUnit initCompileUnit(final String unitClassName, final long initialWeight) { private CompileUnit initCompileUnit(final String unitClassName, final long initialWeight) {
final ClassEmitter classEmitter = new ClassEmitter(env, source.getName(), unitClassName, strict); final ClassEmitter classEmitter = new ClassEmitter(env, sourceName, unitClassName, strict);
final CompileUnit compileUnit = new CompileUnit(unitClassName, classEmitter, initialWeight); final CompileUnit compileUnit = new CompileUnit(unitClassName, classEmitter, initialWeight);
classEmitter.begin(); classEmitter.begin();
......
...@@ -41,6 +41,7 @@ import jdk.nashorn.internal.runtime.Source; ...@@ -41,6 +41,7 @@ import jdk.nashorn.internal.runtime.Source;
*/ */
public enum CompilerConstants { public enum CompilerConstants {
/** the __FILE__ variable */ /** the __FILE__ variable */
__FILE__, __FILE__,
...@@ -75,7 +76,7 @@ public enum CompilerConstants { ...@@ -75,7 +76,7 @@ public enum CompilerConstants {
DEFAULT_SCRIPT_NAME("Script"), DEFAULT_SCRIPT_NAME("Script"),
/** function prefix for anonymous functions */ /** function prefix for anonymous functions */
FUNCTION_PREFIX("function$"), ANON_FUNCTION_PREFIX("L:"),
/** method name for Java method that is script entry point */ /** method name for Java method that is script entry point */
RUN_SCRIPT("runScript"), RUN_SCRIPT("runScript"),
...@@ -149,26 +150,31 @@ public enum CompilerConstants { ...@@ -149,26 +150,31 @@ public enum CompilerConstants {
ALLOCATE("allocate"), ALLOCATE("allocate"),
/** prefix for split methods, @see Splitter */ /** prefix for split methods, @see Splitter */
SPLIT_PREFIX("$split"), SPLIT_PREFIX(":split"),
/** prefix for split array method and slot */ /** prefix for split array method and slot */
SPLIT_ARRAY_ARG("split_array", 3), SPLIT_ARRAY_ARG(":split_array", 3),
/** get string from constant pool */ /** get string from constant pool */
GET_STRING("$getString"), GET_STRING(":getString"),
/** get map */ /** get map */
GET_MAP("$getMap"), GET_MAP(":getMap"),
/** get map */ /** get map */
SET_MAP("$setMap"), SET_MAP(":setMap"),
/** get array prefix */ /** get array prefix */
GET_ARRAY_PREFIX("$get"), GET_ARRAY_PREFIX(":get"),
/** get array suffix */ /** get array suffix */
GET_ARRAY_SUFFIX("$array"); GET_ARRAY_SUFFIX("$array");
/**
* Prefix used for internal methods generated in script clases.
*/
public static final String INTERNAL_METHOD_PREFIX = ":";
private final String symbolName; private final String symbolName;
private final Class<?> type; private final Class<?> type;
private final int slot; private final int slot;
......
...@@ -25,6 +25,9 @@ ...@@ -25,6 +25,9 @@
package jdk.nashorn.internal.codegen; package jdk.nashorn.internal.codegen;
import jdk.nashorn.internal.runtime.Property;
import jdk.nashorn.internal.runtime.PropertyMap;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
...@@ -109,6 +112,43 @@ class ConstantData { ...@@ -109,6 +112,43 @@ class ConstantData {
} }
} }
/**
* {@link PropertyMap} wrapper class that provides implementations for the {@code hashCode} and {@code equals}
* methods that are based on the map layout. {@code PropertyMap} itself inherits the identity based implementations
* from {@code java.lang.Object}.
*/
private static class PropertyMapWrapper {
private final PropertyMap propertyMap;
private final int hashCode;
public PropertyMapWrapper(final PropertyMap map) {
int hash = 0;
for (final Property property : map.getProperties()) {
hash = hash << 7 ^ hash >> 7;
hash ^= property.hashCode();
}
this.hashCode = hash;
this.propertyMap = map;
}
@Override
public int hashCode() {
return hashCode;
}
@Override
public boolean equals(final Object other) {
if (!(other instanceof PropertyMapWrapper)) {
return false;
}
final Property[] ownProperties = propertyMap.getProperties();
final Property[] otherProperties = ((PropertyMapWrapper) other).propertyMap.getProperties();
return Arrays.equals(ownProperties, otherProperties);
}
}
/** /**
* Constructor * Constructor
*/ */
...@@ -145,7 +185,14 @@ class ConstantData { ...@@ -145,7 +185,14 @@ class ConstantData {
* @return the index in the constant pool that the object was given * @return the index in the constant pool that the object was given
*/ */
public int add(final Object object) { public int add(final Object object) {
final Object entry = object.getClass().isArray() ? new ArrayWrapper(object) : object; final Object entry;
if (object.getClass().isArray()) {
entry = new ArrayWrapper(object);
} else if (object instanceof PropertyMap) {
entry = new PropertyMapWrapper((PropertyMap) object);
} else {
entry = object;
}
final Integer value = objectMap.get(entry); final Integer value = objectMap.get(entry);
if (value != null) { if (value != null) {
......
...@@ -1130,7 +1130,11 @@ public class MethodEmitter implements Emitter { ...@@ -1130,7 +1130,11 @@ public class MethodEmitter implements Emitter {
popType(Type.OBJECT); popType(Type.OBJECT);
} }
method.visitMethodInsn(opcode, className, methodName, methodDescriptor); if (opcode == INVOKEINTERFACE) {
method.visitMethodInsn(opcode, className, methodName, methodDescriptor, true);
} else {
method.visitMethodInsn(opcode, className, methodName, methodDescriptor, false);
}
if (returnType != null) { if (returnType != null) {
pushType(returnType); pushType(returnType);
......
...@@ -156,7 +156,7 @@ class SharedScopeCall { ...@@ -156,7 +156,7 @@ class SharedScopeCall {
if (isCall) { if (isCall) {
method.convert(Type.OBJECT); method.convert(Type.OBJECT);
// ScriptFunction will see CALLSITE_SCOPE and will bind scope accordingly. // ScriptFunction will see CALLSITE_SCOPE and will bind scope accordingly.
method.loadNull(); method.loadUndefined(Type.OBJECT);
int slot = 2; int slot = 2;
for (final Type type : paramTypes) { for (final Type type : paramTypes) {
method.load(type, slot++); method.load(type, slot++);
......
...@@ -261,7 +261,7 @@ public abstract class Type implements Comparable<Type>, BytecodeOps { ...@@ -261,7 +261,7 @@ public abstract class Type implements Comparable<Type>, BytecodeOps {
} }
static void invokeStatic(final MethodVisitor method, final Call call) { static void invokeStatic(final MethodVisitor method, final Call call) {
method.visitMethodInsn(INVOKESTATIC, call.className(), call.name(), call.descriptor()); method.visitMethodInsn(INVOKESTATIC, call.className(), call.name(), call.descriptor(), false);
} }
/** /**
......
...@@ -29,6 +29,7 @@ import java.util.Collections; ...@@ -29,6 +29,7 @@ import java.util.Collections;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.Set; import java.util.Set;
import jdk.nashorn.internal.codegen.CompileUnit; import jdk.nashorn.internal.codegen.CompileUnit;
import jdk.nashorn.internal.codegen.Compiler; import jdk.nashorn.internal.codegen.Compiler;
...@@ -138,6 +139,9 @@ public final class FunctionNode extends LexicalContextExpression implements Flag ...@@ -138,6 +139,9 @@ public final class FunctionNode extends LexicalContextExpression implements Flag
/** Function flags. */ /** Function flags. */
private final int flags; private final int flags;
/** //@ sourceURL or //# sourceURL for program function nodes */
private final String sourceURL;
private final int lineNumber; private final int lineNumber;
/** Is anonymous function flag. */ /** Is anonymous function flag. */
...@@ -160,11 +164,11 @@ public final class FunctionNode extends LexicalContextExpression implements Flag ...@@ -160,11 +164,11 @@ public final class FunctionNode extends LexicalContextExpression implements Flag
public static final int HAS_EVAL = 1 << 5; public static final int HAS_EVAL = 1 << 5;
/** Does a nested function contain eval? If it does, then all variables in this function might be get/set by it. */ /** Does a nested function contain eval? If it does, then all variables in this function might be get/set by it. */
public static final int HAS_NESTED_EVAL = 1 << 6; public static final int HAS_NESTED_EVAL = 1 << 6;
/** Does this function have any blocks that create a scope? This is used to determine if the function needs to /** Does this function have any blocks that create a scope? This is used to determine if the function needs to
* have a local variable slot for the scope symbol. */ * have a local variable slot for the scope symbol. */
public static final int HAS_SCOPE_BLOCK = 1 << 7; public static final int HAS_SCOPE_BLOCK = 1 << 7;
/** /**
* Flag this function as one that defines the identifier "arguments" as a function parameter or nested function * Flag this function as one that defines the identifier "arguments" as a function parameter or nested function
...@@ -193,6 +197,9 @@ public final class FunctionNode extends LexicalContextExpression implements Flag ...@@ -193,6 +197,9 @@ public final class FunctionNode extends LexicalContextExpression implements Flag
/** Can this function be specialized? */ /** Can this function be specialized? */
public static final int CAN_SPECIALIZE = 1 << 14; public static final int CAN_SPECIALIZE = 1 << 14;
/** Does this function use the "this" keyword? */
public static final int USES_THIS = 1 << 15;
/** Does this function or any nested functions contain an eval? */ /** Does this function or any nested functions contain an eval? */
private static final int HAS_DEEP_EVAL = HAS_EVAL | HAS_NESTED_EVAL; private static final int HAS_DEEP_EVAL = HAS_EVAL | HAS_NESTED_EVAL;
...@@ -223,6 +230,7 @@ public final class FunctionNode extends LexicalContextExpression implements Flag ...@@ -223,6 +230,7 @@ public final class FunctionNode extends LexicalContextExpression implements Flag
* @param parameters parameter list * @param parameters parameter list
* @param kind kind of function as in {@link FunctionNode.Kind} * @param kind kind of function as in {@link FunctionNode.Kind}
* @param flags initial flags * @param flags initial flags
* @param sourceURL sourceURL specified in script (optional)
*/ */
public FunctionNode( public FunctionNode(
final Source source, final Source source,
...@@ -235,7 +243,8 @@ public final class FunctionNode extends LexicalContextExpression implements Flag ...@@ -235,7 +243,8 @@ public final class FunctionNode extends LexicalContextExpression implements Flag
final String name, final String name,
final List<IdentNode> parameters, final List<IdentNode> parameters,
final FunctionNode.Kind kind, final FunctionNode.Kind kind,
final int flags) { final int flags,
final String sourceURL) {
super(token, finish); super(token, finish);
this.source = source; this.source = source;
...@@ -250,6 +259,7 @@ public final class FunctionNode extends LexicalContextExpression implements Flag ...@@ -250,6 +259,7 @@ public final class FunctionNode extends LexicalContextExpression implements Flag
this.compilationState = EnumSet.of(CompilationState.INITIALIZED); this.compilationState = EnumSet.of(CompilationState.INITIALIZED);
this.declaredSymbols = new HashSet<>(); this.declaredSymbols = new HashSet<>();
this.flags = flags; this.flags = flags;
this.sourceURL = sourceURL;
this.compileUnit = null; this.compileUnit = null;
this.body = null; this.body = null;
this.snapshot = null; this.snapshot = null;
...@@ -260,6 +270,7 @@ public final class FunctionNode extends LexicalContextExpression implements Flag ...@@ -260,6 +270,7 @@ public final class FunctionNode extends LexicalContextExpression implements Flag
final FunctionNode functionNode, final FunctionNode functionNode,
final long lastToken, final long lastToken,
final int flags, final int flags,
final String sourceURL,
final String name, final String name,
final Type returnType, final Type returnType,
final CompileUnit compileUnit, final CompileUnit compileUnit,
...@@ -271,6 +282,7 @@ public final class FunctionNode extends LexicalContextExpression implements Flag ...@@ -271,6 +282,7 @@ public final class FunctionNode extends LexicalContextExpression implements Flag
super(functionNode); super(functionNode);
this.lineNumber = functionNode.lineNumber; this.lineNumber = functionNode.lineNumber;
this.flags = flags; this.flags = flags;
this.sourceURL = sourceURL;
this.name = name; this.name = name;
this.returnType = returnType; this.returnType = returnType;
this.compileUnit = compileUnit; this.compileUnit = compileUnit;
...@@ -307,6 +319,38 @@ public final class FunctionNode extends LexicalContextExpression implements Flag ...@@ -307,6 +319,38 @@ public final class FunctionNode extends LexicalContextExpression implements Flag
return source; return source;
} }
/**
* get source name - sourceURL or name derived from Source.
*
* @return name for the script source
*/
public String getSourceName() {
return (sourceURL != null)? sourceURL : source.getName();
}
/**
* get the sourceURL
* @return the sourceURL
*/
public String getSourceURL() {
return sourceURL;
}
/**
* Set the sourceURL
*
* @param lc lexical context
* @param newSourceURL source url string to set
* @return function node or a new one if state was changed
*/
public FunctionNode setSourceURL(final LexicalContext lc, final String newSourceURL) {
if (Objects.equals(sourceURL, newSourceURL)) {
return this;
}
return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, newSourceURL, name, returnType, compileUnit, compilationState, body, parameters, null, hints));
}
/** /**
* Returns the line number. * Returns the line number.
* @return the line number. * @return the line number.
...@@ -335,7 +379,7 @@ public final class FunctionNode extends LexicalContextExpression implements Flag ...@@ -335,7 +379,7 @@ public final class FunctionNode extends LexicalContextExpression implements Flag
if (this.snapshot == null) { if (this.snapshot == null) {
return this; return this;
} }
return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, name, returnType, compileUnit, compilationState, body, parameters, null, hints)); return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, sourceURL, name, returnType, compileUnit, compilationState, body, parameters, null, hints));
} }
/** /**
...@@ -351,7 +395,7 @@ public final class FunctionNode extends LexicalContextExpression implements Flag ...@@ -351,7 +395,7 @@ public final class FunctionNode extends LexicalContextExpression implements Flag
if (isProgram() || parameters.isEmpty()) { if (isProgram() || parameters.isEmpty()) {
return this; //never specialize anything that won't be recompiled return this; //never specialize anything that won't be recompiled
} }
return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, name, returnType, compileUnit, compilationState, body, parameters, this, hints)); return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, sourceURL, name, returnType, compileUnit, compilationState, body, parameters, this, hints));
} }
/** /**
...@@ -409,7 +453,7 @@ public final class FunctionNode extends LexicalContextExpression implements Flag ...@@ -409,7 +453,7 @@ public final class FunctionNode extends LexicalContextExpression implements Flag
} }
final EnumSet<CompilationState> newState = EnumSet.copyOf(this.compilationState); final EnumSet<CompilationState> newState = EnumSet.copyOf(this.compilationState);
newState.add(state); newState.add(state);
return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, name, returnType, compileUnit, newState, body, parameters, snapshot, hints)); return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, sourceURL, name, returnType, compileUnit, newState, body, parameters, snapshot, hints));
} }
/** /**
...@@ -430,7 +474,7 @@ public final class FunctionNode extends LexicalContextExpression implements Flag ...@@ -430,7 +474,7 @@ public final class FunctionNode extends LexicalContextExpression implements Flag
if (this.hints == hints) { if (this.hints == hints) {
return this; return this;
} }
return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, name, returnType, compileUnit, compilationState, body, parameters, snapshot, hints)); return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, sourceURL, name, returnType, compileUnit, compilationState, body, parameters, snapshot, hints));
} }
/** /**
...@@ -483,7 +527,7 @@ public final class FunctionNode extends LexicalContextExpression implements Flag ...@@ -483,7 +527,7 @@ public final class FunctionNode extends LexicalContextExpression implements Flag
if (this.flags == flags) { if (this.flags == flags) {
return this; return this;
} }
return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, name, returnType, compileUnit, compilationState, body, parameters, snapshot, hints)); return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, sourceURL, name, returnType, compileUnit, compilationState, body, parameters, snapshot, hints));
} }
@Override @Override
...@@ -549,6 +593,15 @@ public final class FunctionNode extends LexicalContextExpression implements Flag ...@@ -549,6 +593,15 @@ public final class FunctionNode extends LexicalContextExpression implements Flag
return needsParentScope() || needsSelfSymbol() || isSplit() || (needsArguments() && !isStrict()); return needsParentScope() || needsSelfSymbol() || isSplit() || (needsArguments() && !isStrict());
} }
/**
* Return {@code true} if this function makes use of the {@code this} object.
*
* @return true if function uses {@code this} object
*/
public boolean usesThis() {
return getFlag(USES_THIS);
}
/** /**
* Get the identifier for this function, this is its symbol. * Get the identifier for this function, this is its symbol.
* @return the identifier as an IdentityNode * @return the identifier as an IdentityNode
...@@ -593,7 +646,7 @@ public final class FunctionNode extends LexicalContextExpression implements Flag ...@@ -593,7 +646,7 @@ public final class FunctionNode extends LexicalContextExpression implements Flag
if(this.body == body) { if(this.body == body) {
return this; return this;
} }
return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags | (body.needsScope() ? FunctionNode.HAS_SCOPE_BLOCK : 0), name, returnType, compileUnit, compilationState, body, parameters, snapshot, hints)); return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags | (body.needsScope() ? FunctionNode.HAS_SCOPE_BLOCK : 0), sourceURL, name, returnType, compileUnit, compilationState, body, parameters, snapshot, hints));
} }
/** /**
...@@ -688,7 +741,7 @@ public final class FunctionNode extends LexicalContextExpression implements Flag ...@@ -688,7 +741,7 @@ public final class FunctionNode extends LexicalContextExpression implements Flag
if (this.lastToken == lastToken) { if (this.lastToken == lastToken) {
return this; return this;
} }
return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, name, returnType, compileUnit, compilationState, body, parameters, snapshot, hints)); return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, sourceURL, name, returnType, compileUnit, compilationState, body, parameters, snapshot, hints));
} }
/** /**
...@@ -710,7 +763,7 @@ public final class FunctionNode extends LexicalContextExpression implements Flag ...@@ -710,7 +763,7 @@ public final class FunctionNode extends LexicalContextExpression implements Flag
if (this.name.equals(name)) { if (this.name.equals(name)) {
return this; return this;
} }
return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, name, returnType, compileUnit, compilationState, body, parameters, snapshot, hints)); return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, sourceURL, name, returnType, compileUnit, compilationState, body, parameters, snapshot, hints));
} }
/** /**
...@@ -760,7 +813,7 @@ public final class FunctionNode extends LexicalContextExpression implements Flag ...@@ -760,7 +813,7 @@ public final class FunctionNode extends LexicalContextExpression implements Flag
if (this.parameters == parameters) { if (this.parameters == parameters) {
return this; return this;
} }
return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, name, returnType, compileUnit, compilationState, body, parameters, snapshot, hints)); return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, sourceURL, name, returnType, compileUnit, compilationState, body, parameters, snapshot, hints));
} }
/** /**
...@@ -825,6 +878,7 @@ public final class FunctionNode extends LexicalContextExpression implements Flag ...@@ -825,6 +878,7 @@ public final class FunctionNode extends LexicalContextExpression implements Flag
this, this,
lastToken, lastToken,
flags, flags,
sourceURL,
name, name,
type, type,
compileUnit, compileUnit,
...@@ -863,7 +917,7 @@ public final class FunctionNode extends LexicalContextExpression implements Flag ...@@ -863,7 +917,7 @@ public final class FunctionNode extends LexicalContextExpression implements Flag
if (this.compileUnit == compileUnit) { if (this.compileUnit == compileUnit) {
return this; return this;
} }
return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, name, returnType, compileUnit, compilationState, body, parameters, snapshot, hints)); return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, sourceURL, name, returnType, compileUnit, compilationState, body, parameters, snapshot, hints));
} }
/** /**
......
...@@ -67,12 +67,8 @@ public final class AccessorPropertyDescriptor extends ScriptObject implements Pr ...@@ -67,12 +67,8 @@ public final class AccessorPropertyDescriptor extends ScriptObject implements Pr
// initialized by nasgen // initialized by nasgen
private static PropertyMap $nasgenmap$; private static PropertyMap $nasgenmap$;
static PropertyMap getInitialMap() {
return $nasgenmap$;
}
AccessorPropertyDescriptor(final boolean configurable, final boolean enumerable, final Object get, final Object set, final Global global) { AccessorPropertyDescriptor(final boolean configurable, final boolean enumerable, final Object get, final Object set, final Global global) {
super(global.getObjectPrototype(), global.getAccessorPropertyDescriptorMap()); super(global.getObjectPrototype(), $nasgenmap$);
this.configurable = configurable; this.configurable = configurable;
this.enumerable = enumerable; this.enumerable = enumerable;
this.get = get; this.get = get;
...@@ -184,6 +180,18 @@ public final class AccessorPropertyDescriptor extends ScriptObject implements Pr ...@@ -184,6 +180,18 @@ public final class AccessorPropertyDescriptor extends ScriptObject implements Pr
return ACCESSOR; return ACCESSOR;
} }
@Override
public boolean hasAndEquals(final PropertyDescriptor otherDesc) {
if (! (otherDesc instanceof AccessorPropertyDescriptor)) {
return false;
}
final AccessorPropertyDescriptor other = (AccessorPropertyDescriptor)otherDesc;
return (!has(CONFIGURABLE) || sameValue(configurable, other.configurable)) &&
(!has(ENUMERABLE) || sameValue(enumerable, other.enumerable)) &&
(!has(GET) || sameValue(get, other.get)) &&
(!has(SET) || sameValue(set, other.set));
}
@Override @Override
public boolean equals(final Object obj) { public boolean equals(final Object obj) {
if (this == obj) { if (this == obj) {
......
...@@ -42,12 +42,8 @@ abstract class ArrayBufferView extends ScriptObject { ...@@ -42,12 +42,8 @@ abstract class ArrayBufferView extends ScriptObject {
// initialized by nasgen // initialized by nasgen
private static PropertyMap $nasgenmap$; private static PropertyMap $nasgenmap$;
static PropertyMap getInitialMap() {
return $nasgenmap$;
}
private ArrayBufferView(final NativeArrayBuffer buffer, final int byteOffset, final int elementLength, final Global global) { private ArrayBufferView(final NativeArrayBuffer buffer, final int byteOffset, final int elementLength, final Global global) {
super(global.getArrayBufferViewMap()); super($nasgenmap$);
checkConstructorArgs(buffer, byteOffset, elementLength); checkConstructorArgs(buffer, byteOffset, elementLength);
this.setProto(getPrototype(global)); this.setProto(getPrototype(global));
this.setArray(factory().createArrayData(buffer, byteOffset, elementLength)); this.setArray(factory().createArrayData(buffer, byteOffset, elementLength));
...@@ -386,7 +382,7 @@ abstract class ArrayBufferView extends ScriptObject { ...@@ -386,7 +382,7 @@ abstract class ArrayBufferView extends ScriptObject {
return (int) (length & Integer.MAX_VALUE); return (int) (length & Integer.MAX_VALUE);
} }
protected static Object subarrayImpl(final Object self, final Object begin0, final Object end0) { protected static ScriptObject subarrayImpl(final Object self, final Object begin0, final Object end0) {
final ArrayBufferView arrayView = ((ArrayBufferView)self); final ArrayBufferView arrayView = ((ArrayBufferView)self);
final int elementLength = arrayView.elementLength(); final int elementLength = arrayView.elementLength();
final int begin = NativeArrayBuffer.adjustIndex(JSType.toInt32(begin0), elementLength); final int begin = NativeArrayBuffer.adjustIndex(JSType.toInt32(begin0), elementLength);
......
...@@ -64,12 +64,8 @@ public final class DataPropertyDescriptor extends ScriptObject implements Proper ...@@ -64,12 +64,8 @@ public final class DataPropertyDescriptor extends ScriptObject implements Proper
// initialized by nasgen // initialized by nasgen
private static PropertyMap $nasgenmap$; private static PropertyMap $nasgenmap$;
static PropertyMap getInitialMap() {
return $nasgenmap$;
}
DataPropertyDescriptor(final boolean configurable, final boolean enumerable, final boolean writable, final Object value, final Global global) { DataPropertyDescriptor(final boolean configurable, final boolean enumerable, final boolean writable, final Object value, final Global global) {
super(global.getObjectPrototype(), global.getDataPropertyDescriptorMap()); super(global.getObjectPrototype(), $nasgenmap$);
this.configurable = configurable; this.configurable = configurable;
this.enumerable = enumerable; this.enumerable = enumerable;
this.writable = writable; this.writable = writable;
...@@ -171,6 +167,19 @@ public final class DataPropertyDescriptor extends ScriptObject implements Proper ...@@ -171,6 +167,19 @@ public final class DataPropertyDescriptor extends ScriptObject implements Proper
return DATA; return DATA;
} }
@Override
public boolean hasAndEquals(final PropertyDescriptor otherDesc) {
if (! (otherDesc instanceof DataPropertyDescriptor)) {
return false;
}
final DataPropertyDescriptor other = (DataPropertyDescriptor)otherDesc;
return (!has(CONFIGURABLE) || sameValue(configurable, other.configurable)) &&
(!has(ENUMERABLE) || sameValue(enumerable, other.enumerable)) &&
(!has(WRITABLE) || sameValue(writable, other.writable)) &&
(!has(VALUE) || sameValue(value, other.value));
}
@Override @Override
public boolean equals(final Object obj) { public boolean equals(final Object obj) {
if (this == obj) { if (this == obj) {
......
...@@ -55,12 +55,8 @@ public final class GenericPropertyDescriptor extends ScriptObject implements Pro ...@@ -55,12 +55,8 @@ public final class GenericPropertyDescriptor extends ScriptObject implements Pro
// initialized by nasgen // initialized by nasgen
private static PropertyMap $nasgenmap$; private static PropertyMap $nasgenmap$;
static PropertyMap getInitialMap() {
return $nasgenmap$;
}
GenericPropertyDescriptor(final boolean configurable, final boolean enumerable, final Global global) { GenericPropertyDescriptor(final boolean configurable, final boolean enumerable, final Global global) {
super(global.getObjectPrototype(), global.getGenericPropertyDescriptorMap()); super(global.getObjectPrototype(), $nasgenmap$);
this.configurable = configurable; this.configurable = configurable;
this.enumerable = enumerable; this.enumerable = enumerable;
} }
...@@ -148,6 +144,23 @@ public final class GenericPropertyDescriptor extends ScriptObject implements Pro ...@@ -148,6 +144,23 @@ public final class GenericPropertyDescriptor extends ScriptObject implements Pro
return GENERIC; return GENERIC;
} }
@Override
public boolean hasAndEquals(final PropertyDescriptor other) {
if (has(CONFIGURABLE) && other.has(CONFIGURABLE)) {
if (isConfigurable() != other.isConfigurable()) {
return false;
}
}
if (has(ENUMERABLE) && other.has(ENUMERABLE)) {
if (isEnumerable() != other.isEnumerable()) {
return false;
}
}
return true;
}
@Override @Override
public boolean equals(final Object obj) { public boolean equals(final Object obj) {
if (this == obj) { if (this == obj) {
......
...@@ -68,7 +68,7 @@ public final class NativeArguments extends ScriptObject { ...@@ -68,7 +68,7 @@ public final class NativeArguments extends ScriptObject {
final ArrayList<Property> properties = new ArrayList<>(2); final ArrayList<Property> properties = new ArrayList<>(2);
properties.add(AccessorProperty.create("length", Property.NOT_ENUMERABLE, G$LENGTH, S$LENGTH)); properties.add(AccessorProperty.create("length", Property.NOT_ENUMERABLE, G$LENGTH, S$LENGTH));
properties.add(AccessorProperty.create("callee", Property.NOT_ENUMERABLE, G$CALLEE, S$CALLEE)); properties.add(AccessorProperty.create("callee", Property.NOT_ENUMERABLE, G$CALLEE, S$CALLEE));
map$ = PropertyMap.newMap(properties).setIsShared(); map$ = PropertyMap.newMap(properties);
} }
static PropertyMap getInitialMap() { static PropertyMap getInitialMap() {
...@@ -267,9 +267,9 @@ public final class NativeArguments extends ScriptObject { ...@@ -267,9 +267,9 @@ public final class NativeArguments extends ScriptObject {
final Global global = Global.instance(); final Global global = Global.instance();
final ScriptObject proto = global.getObjectPrototype(); final ScriptObject proto = global.getObjectPrototype();
if (isStrict) { if (isStrict) {
return new NativeStrictArguments(arguments, numParams, proto, global.getStrictArgumentsMap()); return new NativeStrictArguments(arguments, numParams, proto, NativeStrictArguments.getInitialMap());
} }
return new NativeArguments(arguments, callee, numParams, proto, global.getArgumentsMap()); return new NativeArguments(arguments, callee, numParams, proto, NativeArguments.getInitialMap());
} }
/** /**
......
...@@ -31,6 +31,7 @@ import static jdk.nashorn.internal.runtime.PropertyDescriptor.VALUE; ...@@ -31,6 +31,7 @@ import static jdk.nashorn.internal.runtime.PropertyDescriptor.VALUE;
import static jdk.nashorn.internal.runtime.PropertyDescriptor.WRITABLE; import static jdk.nashorn.internal.runtime.PropertyDescriptor.WRITABLE;
import static jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator.arrayLikeIterator; import static jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator.arrayLikeIterator;
import static jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator.reverseArrayLikeIterator; import static jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator.reverseArrayLikeIterator;
import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.isValidArrayIndex;
import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandle;
import java.util.ArrayList; import java.util.ArrayList;
...@@ -156,10 +157,6 @@ public final class NativeArray extends ScriptObject { ...@@ -156,10 +157,6 @@ public final class NativeArray extends ScriptObject {
// initialized by nasgen // initialized by nasgen
private static PropertyMap $nasgenmap$; private static PropertyMap $nasgenmap$;
static PropertyMap getInitialMap() {
return $nasgenmap$;
}
/* /*
* Constructors. * Constructors.
*/ */
...@@ -208,7 +205,7 @@ public final class NativeArray extends ScriptObject { ...@@ -208,7 +205,7 @@ public final class NativeArray extends ScriptObject {
} }
NativeArray(final ArrayData arrayData, final Global global) { NativeArray(final ArrayData arrayData, final Global global) {
super(global.getArrayPrototype(), global.getArrayMap()); super(global.getArrayPrototype(), $nasgenmap$);
this.setArray(arrayData); this.setArray(arrayData);
this.setIsArray(); this.setIsArray();
} }
...@@ -353,6 +350,27 @@ public final class NativeArray extends ScriptObject { ...@@ -353,6 +350,27 @@ public final class NativeArray extends ScriptObject {
return super.defineOwnProperty(key, desc, reject); return super.defineOwnProperty(key, desc, reject);
} }
/**
* Spec. mentions use of [[DefineOwnProperty]] for indexed properties in
* certain places (eg. Array.prototype.map, filter). We can not use ScriptObject.set
* method in such cases. This is because set method uses inherited setters (if any)
* from any object in proto chain such as Array.prototype, Object.prototype.
* This method directly sets a particular element value in the current object.
*
* @param index key for property
* @param value value to define
*/
@Override
public final void defineOwnProperty(final int index, final Object value) {
assert isValidArrayIndex(index) : "invalid array index";
final long longIndex = ArrayIndex.toLongIndex(index);
if (longIndex >= getArray().length()) {
// make array big enough to hold..
setArray(getArray().ensure(longIndex));
}
setArray(getArray().set(index, value, false));
}
/** /**
* Return the array contents upcasted as an ObjectArray, regardless of * Return the array contents upcasted as an ObjectArray, regardless of
* representation * representation
...@@ -371,7 +389,7 @@ public final class NativeArray extends ScriptObject { ...@@ -371,7 +389,7 @@ public final class NativeArray extends ScriptObject {
* @return true if argument is an array * @return true if argument is an array
*/ */
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static Object isArray(final Object self, final Object arg) { public static boolean isArray(final Object self, final Object arg) {
return isArray(arg) || (arg instanceof JSObject && ((JSObject)arg).isArray()); return isArray(arg) || (arg instanceof JSObject && ((JSObject)arg).isArray());
} }
...@@ -470,7 +488,7 @@ public final class NativeArray extends ScriptObject { ...@@ -470,7 +488,7 @@ public final class NativeArray extends ScriptObject {
* @return locale specific string representation for array * @return locale specific string representation for array
*/ */
@Function(attributes = Attribute.NOT_ENUMERABLE) @Function(attributes = Attribute.NOT_ENUMERABLE)
public static Object toLocaleString(final Object self) { public static String toLocaleString(final Object self) {
final StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
final Iterator<Object> iter = arrayLikeIterator(self, true); final Iterator<Object> iter = arrayLikeIterator(self, true);
...@@ -516,7 +534,7 @@ public final class NativeArray extends ScriptObject { ...@@ -516,7 +534,7 @@ public final class NativeArray extends ScriptObject {
* @return the new NativeArray * @return the new NativeArray
*/ */
@Constructor(arity = 1) @Constructor(arity = 1)
public static Object construct(final boolean newObj, final Object self, final Object... args) { public static NativeArray construct(final boolean newObj, final Object self, final Object... args) {
switch (args.length) { switch (args.length) {
case 0: case 0:
return new NativeArray(0); return new NativeArray(0);
...@@ -569,7 +587,7 @@ public final class NativeArray extends ScriptObject { ...@@ -569,7 +587,7 @@ public final class NativeArray extends ScriptObject {
* @return the new NativeArray * @return the new NativeArray
*/ */
@SpecializedConstructor @SpecializedConstructor
public static Object construct(final boolean newObj, final Object self) { public static NativeArray construct(final boolean newObj, final Object self) {
return new NativeArray(0); return new NativeArray(0);
} }
...@@ -584,7 +602,7 @@ public final class NativeArray extends ScriptObject { ...@@ -584,7 +602,7 @@ public final class NativeArray extends ScriptObject {
* @return the new NativeArray * @return the new NativeArray
*/ */
@SpecializedConstructor @SpecializedConstructor
public static Object construct(final boolean newObj, final Object self, final int length) { public static NativeArray construct(final boolean newObj, final Object self, final int length) {
if (length >= 0) { if (length >= 0) {
return new NativeArray(length); return new NativeArray(length);
} }
...@@ -603,7 +621,7 @@ public final class NativeArray extends ScriptObject { ...@@ -603,7 +621,7 @@ public final class NativeArray extends ScriptObject {
* @return the new NativeArray * @return the new NativeArray
*/ */
@SpecializedConstructor @SpecializedConstructor
public static Object construct(final boolean newObj, final Object self, final long length) { public static NativeArray construct(final boolean newObj, final Object self, final long length) {
if (length >= 0L && length <= JSType.MAX_UINT) { if (length >= 0L && length <= JSType.MAX_UINT) {
return new NativeArray(length); return new NativeArray(length);
} }
...@@ -622,7 +640,7 @@ public final class NativeArray extends ScriptObject { ...@@ -622,7 +640,7 @@ public final class NativeArray extends ScriptObject {
* @return the new NativeArray * @return the new NativeArray
*/ */
@SpecializedConstructor @SpecializedConstructor
public static Object construct(final boolean newObj, final Object self, final double length) { public static NativeArray construct(final boolean newObj, final Object self, final double length) {
final long uint32length = JSType.toUint32(length); final long uint32length = JSType.toUint32(length);
if (uint32length == length) { if (uint32length == length) {
...@@ -640,7 +658,7 @@ public final class NativeArray extends ScriptObject { ...@@ -640,7 +658,7 @@ public final class NativeArray extends ScriptObject {
* @return resulting NativeArray * @return resulting NativeArray
*/ */
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1) @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
public static Object concat(final Object self, final Object... args) { public static NativeArray concat(final Object self, final Object... args) {
final ArrayList<Object> list = new ArrayList<>(); final ArrayList<Object> list = new ArrayList<>();
concatToList(list, Global.toObject(self)); concatToList(list, Global.toObject(self));
...@@ -687,7 +705,7 @@ public final class NativeArray extends ScriptObject { ...@@ -687,7 +705,7 @@ public final class NativeArray extends ScriptObject {
* @return string representation after join * @return string representation after join
*/ */
@Function(attributes = Attribute.NOT_ENUMERABLE) @Function(attributes = Attribute.NOT_ENUMERABLE)
public static Object join(final Object self, final Object separator) { public static String join(final Object self, final Object separator) {
final StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
final Iterator<Object> iter = arrayLikeIterator(self, true); final Iterator<Object> iter = arrayLikeIterator(self, true);
final String sep = separator == ScriptRuntime.UNDEFINED ? "," : JSType.toString(separator); final String sep = separator == ScriptRuntime.UNDEFINED ? "," : JSType.toString(separator);
...@@ -955,7 +973,7 @@ public final class NativeArray extends ScriptObject { ...@@ -955,7 +973,7 @@ public final class NativeArray extends ScriptObject {
* @return sorted array * @return sorted array
*/ */
@Function(attributes = Attribute.NOT_ENUMERABLE) @Function(attributes = Attribute.NOT_ENUMERABLE)
public static Object sort(final Object self, final Object comparefn) { public static ScriptObject sort(final Object self, final Object comparefn) {
try { try {
final ScriptObject sobj = (ScriptObject) self; final ScriptObject sobj = (ScriptObject) self;
final long len = JSType.toUint32(sobj.getLength()); final long len = JSType.toUint32(sobj.getLength());
...@@ -1159,7 +1177,7 @@ public final class NativeArray extends ScriptObject { ...@@ -1159,7 +1177,7 @@ public final class NativeArray extends ScriptObject {
* @return index of element, or -1 if not found * @return index of element, or -1 if not found
*/ */
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1) @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
public static Object indexOf(final Object self, final Object searchElement, final Object fromIndex) { public static long indexOf(final Object self, final Object searchElement, final Object fromIndex) {
try { try {
final ScriptObject sobj = (ScriptObject)Global.toObject(self); final ScriptObject sobj = (ScriptObject)Global.toObject(self);
final long len = JSType.toUint32(sobj.getLength()); final long len = JSType.toUint32(sobj.getLength());
...@@ -1195,7 +1213,7 @@ public final class NativeArray extends ScriptObject { ...@@ -1195,7 +1213,7 @@ public final class NativeArray extends ScriptObject {
* @return index of element, or -1 if not found * @return index of element, or -1 if not found
*/ */
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1) @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
public static Object lastIndexOf(final Object self, final Object... args) { public static long lastIndexOf(final Object self, final Object... args) {
try { try {
final ScriptObject sobj = (ScriptObject)Global.toObject(self); final ScriptObject sobj = (ScriptObject)Global.toObject(self);
final long len = JSType.toUint32(sobj.getLength()); final long len = JSType.toUint32(sobj.getLength());
...@@ -1230,7 +1248,7 @@ public final class NativeArray extends ScriptObject { ...@@ -1230,7 +1248,7 @@ public final class NativeArray extends ScriptObject {
* @return true if callback function return true for every element in the array, false otherwise * @return true if callback function return true for every element in the array, false otherwise
*/ */
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1) @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
public static Object every(final Object self, final Object callbackfn, final Object thisArg) { public static boolean every(final Object self, final Object callbackfn, final Object thisArg) {
return applyEvery(Global.toObject(self), callbackfn, thisArg); return applyEvery(Global.toObject(self), callbackfn, thisArg);
} }
...@@ -1254,7 +1272,7 @@ public final class NativeArray extends ScriptObject { ...@@ -1254,7 +1272,7 @@ public final class NativeArray extends ScriptObject {
* @return true if callback function returned true for any element in the array, false otherwise * @return true if callback function returned true for any element in the array, false otherwise
*/ */
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1) @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
public static Object some(final Object self, final Object callbackfn, final Object thisArg) { public static boolean some(final Object self, final Object callbackfn, final Object thisArg) {
return new IteratorAction<Boolean>(Global.toObject(self), callbackfn, thisArg, false) { return new IteratorAction<Boolean>(Global.toObject(self), callbackfn, thisArg, false) {
private final MethodHandle someInvoker = getSOME_CALLBACK_INVOKER(); private final MethodHandle someInvoker = getSOME_CALLBACK_INVOKER();
...@@ -1295,7 +1313,7 @@ public final class NativeArray extends ScriptObject { ...@@ -1295,7 +1313,7 @@ public final class NativeArray extends ScriptObject {
* @return array with elements transformed by map function * @return array with elements transformed by map function
*/ */
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1) @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
public static Object map(final Object self, final Object callbackfn, final Object thisArg) { public static NativeArray map(final Object self, final Object callbackfn, final Object thisArg) {
return new IteratorAction<NativeArray>(Global.toObject(self), callbackfn, thisArg, null) { return new IteratorAction<NativeArray>(Global.toObject(self), callbackfn, thisArg, null) {
private final MethodHandle mapInvoker = getMAP_CALLBACK_INVOKER(); private final MethodHandle mapInvoker = getMAP_CALLBACK_INVOKER();
...@@ -1324,7 +1342,7 @@ public final class NativeArray extends ScriptObject { ...@@ -1324,7 +1342,7 @@ public final class NativeArray extends ScriptObject {
* @return filtered array * @return filtered array
*/ */
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1) @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
public static Object filter(final Object self, final Object callbackfn, final Object thisArg) { public static NativeArray filter(final Object self, final Object callbackfn, final Object thisArg) {
return new IteratorAction<NativeArray>(Global.toObject(self), callbackfn, thisArg, new NativeArray()) { return new IteratorAction<NativeArray>(Global.toObject(self), callbackfn, thisArg, new NativeArray()) {
private long to = 0; private long to = 0;
private final MethodHandle filterInvoker = getFILTER_CALLBACK_INVOKER(); private final MethodHandle filterInvoker = getFILTER_CALLBACK_INVOKER();
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
package jdk.nashorn.internal.objects; package jdk.nashorn.internal.objects;
import java.nio.ByteBuffer;
import java.util.Arrays; import java.util.Arrays;
import jdk.nashorn.internal.objects.annotations.Attribute; import jdk.nashorn.internal.objects.annotations.Attribute;
import jdk.nashorn.internal.objects.annotations.Constructor; import jdk.nashorn.internal.objects.annotations.Constructor;
...@@ -43,12 +44,8 @@ final class NativeArrayBuffer extends ScriptObject { ...@@ -43,12 +44,8 @@ final class NativeArrayBuffer extends ScriptObject {
// initialized by nasgen // initialized by nasgen
private static PropertyMap $nasgenmap$; private static PropertyMap $nasgenmap$;
static PropertyMap getInitialMap() {
return $nasgenmap$;
}
@Constructor(arity = 1) @Constructor(arity = 1)
public static Object constructor(final boolean newObj, final Object self, final Object... args) { public static NativeArrayBuffer constructor(final boolean newObj, final Object self, final Object... args) {
if (args.length == 0) { if (args.length == 0) {
throw new RuntimeException("missing length argument"); throw new RuntimeException("missing length argument");
} }
...@@ -57,7 +54,7 @@ final class NativeArrayBuffer extends ScriptObject { ...@@ -57,7 +54,7 @@ final class NativeArrayBuffer extends ScriptObject {
} }
protected NativeArrayBuffer(final byte[] byteArray, final Global global) { protected NativeArrayBuffer(final byte[] byteArray, final Global global) {
super(global.getArrayBufferPrototype(), global.getArrayBufferMap()); super(global.getArrayBufferPrototype(), $nasgenmap$);
this.buffer = byteArray; this.buffer = byteArray;
} }
...@@ -84,7 +81,7 @@ final class NativeArrayBuffer extends ScriptObject { ...@@ -84,7 +81,7 @@ final class NativeArrayBuffer extends ScriptObject {
} }
@Function(attributes = Attribute.NOT_ENUMERABLE) @Function(attributes = Attribute.NOT_ENUMERABLE)
public static Object slice(final Object self, final Object begin0, final Object end0) { public static NativeArrayBuffer slice(final Object self, final Object begin0, final Object end0) {
final NativeArrayBuffer arrayBuffer = (NativeArrayBuffer)self; final NativeArrayBuffer arrayBuffer = (NativeArrayBuffer)self;
int begin = JSType.toInt32(begin0); int begin = JSType.toInt32(begin0);
int end = end0 != ScriptRuntime.UNDEFINED ? JSType.toInt32(end0) : arrayBuffer.getByteLength(); int end = end0 != ScriptRuntime.UNDEFINED ? JSType.toInt32(end0) : arrayBuffer.getByteLength();
...@@ -128,4 +125,16 @@ final class NativeArrayBuffer extends ScriptObject { ...@@ -128,4 +125,16 @@ final class NativeArrayBuffer extends ScriptObject {
public int getByteLength() { public int getByteLength() {
return buffer.length; return buffer.length;
} }
ByteBuffer getBuffer() {
return ByteBuffer.wrap(buffer);
}
ByteBuffer getBuffer(final int offset) {
return ByteBuffer.wrap(buffer, offset, buffer.length - offset);
}
ByteBuffer getBuffer(final int offset, final int length) {
return ByteBuffer.wrap(buffer, offset, length);
}
} }
...@@ -30,6 +30,7 @@ import static jdk.nashorn.internal.lookup.Lookup.MH; ...@@ -30,6 +30,7 @@ import static jdk.nashorn.internal.lookup.Lookup.MH;
import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import jdk.internal.dynalink.linker.GuardedInvocation; import jdk.internal.dynalink.linker.GuardedInvocation;
import jdk.internal.dynalink.linker.LinkRequest; import jdk.internal.dynalink.linker.LinkRequest;
import jdk.nashorn.internal.objects.annotations.Attribute; import jdk.nashorn.internal.objects.annotations.Attribute;
...@@ -50,22 +51,21 @@ import jdk.nashorn.internal.runtime.linker.PrimitiveLookup; ...@@ -50,22 +51,21 @@ import jdk.nashorn.internal.runtime.linker.PrimitiveLookup;
public final class NativeBoolean extends ScriptObject { public final class NativeBoolean extends ScriptObject {
private final boolean value; private final boolean value;
final static MethodHandle WRAPFILTER = findWrapFilter(); // Method handle to create an object wrapper for a primitive boolean
private static final MethodHandle WRAPFILTER = findOwnMH("wrapFilter", MH.type(NativeBoolean.class, Object.class));
// Method handle to retrieve the Boolean prototype object
private static final MethodHandle PROTOFILTER = findOwnMH("protoFilter", MH.type(Object.class, Object.class));
// initialized by nasgen // initialized by nasgen
private static PropertyMap $nasgenmap$; private static PropertyMap $nasgenmap$;
static PropertyMap getInitialMap() {
return $nasgenmap$;
}
private NativeBoolean(final boolean value, final ScriptObject proto, final PropertyMap map) { private NativeBoolean(final boolean value, final ScriptObject proto, final PropertyMap map) {
super(proto, map); super(proto, map);
this.value = value; this.value = value;
} }
NativeBoolean(final boolean flag, final Global global) { NativeBoolean(final boolean flag, final Global global) {
this(flag, global.getBooleanPrototype(), global.getBooleanMap()); this(flag, global.getBooleanPrototype(), $nasgenmap$);
} }
NativeBoolean(final boolean flag) { NativeBoolean(final boolean flag) {
...@@ -110,7 +110,7 @@ public final class NativeBoolean extends ScriptObject { ...@@ -110,7 +110,7 @@ public final class NativeBoolean extends ScriptObject {
* @return string representation of this boolean * @return string representation of this boolean
*/ */
@Function(attributes = Attribute.NOT_ENUMERABLE) @Function(attributes = Attribute.NOT_ENUMERABLE)
public static Object toString(final Object self) { public static String toString(final Object self) {
return getBoolean(self).toString(); return getBoolean(self).toString();
} }
...@@ -121,7 +121,7 @@ public final class NativeBoolean extends ScriptObject { ...@@ -121,7 +121,7 @@ public final class NativeBoolean extends ScriptObject {
* @return value of this boolean * @return value of this boolean
*/ */
@Function(attributes = Attribute.NOT_ENUMERABLE) @Function(attributes = Attribute.NOT_ENUMERABLE)
public static Object valueOf(final Object self) { public static boolean valueOf(final Object self) {
return getBoolean(self); return getBoolean(self);
} }
...@@ -164,7 +164,7 @@ public final class NativeBoolean extends ScriptObject { ...@@ -164,7 +164,7 @@ public final class NativeBoolean extends ScriptObject {
* @return Link to be invoked at call site. * @return Link to be invoked at call site.
*/ */
public static GuardedInvocation lookupPrimitive(final LinkRequest request, final Object receiver) { public static GuardedInvocation lookupPrimitive(final LinkRequest request, final Object receiver) {
return PrimitiveLookup.lookupPrimitive(request, Boolean.class, new NativeBoolean((Boolean)receiver), WRAPFILTER); return PrimitiveLookup.lookupPrimitive(request, Boolean.class, new NativeBoolean((Boolean)receiver), WRAPFILTER, PROTOFILTER);
} }
/** /**
...@@ -178,7 +178,12 @@ public final class NativeBoolean extends ScriptObject { ...@@ -178,7 +178,12 @@ public final class NativeBoolean extends ScriptObject {
return new NativeBoolean((Boolean)receiver); return new NativeBoolean((Boolean)receiver);
} }
private static MethodHandle findWrapFilter() { @SuppressWarnings("unused")
return MH.findStatic(MethodHandles.lookup(), NativeBoolean.class, "wrapFilter", MH.type(NativeBoolean.class, Object.class)); private static Object protoFilter(final Object object) {
return Global.instance().getBooleanPrototype();
}
private static MethodHandle findOwnMH(final String name, final MethodType type) {
return MH.findStatic(MethodHandles.lookup(), NativeBoolean.class, name, type);
} }
} }
此差异已折叠。
...@@ -34,7 +34,7 @@ import jdk.nashorn.internal.objects.annotations.Function; ...@@ -34,7 +34,7 @@ import jdk.nashorn.internal.objects.annotations.Function;
import jdk.nashorn.internal.objects.annotations.ScriptClass; import jdk.nashorn.internal.objects.annotations.ScriptClass;
import jdk.nashorn.internal.objects.annotations.Where; import jdk.nashorn.internal.objects.annotations.Where;
import jdk.nashorn.internal.runtime.Context; import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.PropertyListenerManager; import jdk.nashorn.internal.runtime.PropertyListeners;
import jdk.nashorn.internal.runtime.PropertyMap; import jdk.nashorn.internal.runtime.PropertyMap;
import jdk.nashorn.internal.runtime.ScriptFunction; import jdk.nashorn.internal.runtime.ScriptFunction;
import jdk.nashorn.internal.runtime.ScriptObject; import jdk.nashorn.internal.runtime.ScriptObject;
...@@ -116,7 +116,7 @@ public final class NativeDebug extends ScriptObject { ...@@ -116,7 +116,7 @@ public final class NativeDebug extends ScriptObject {
* @return true if reference identity * @return true if reference identity
*/ */
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static Object identical(final Object self, final Object obj1, final Object obj2) { public static boolean identical(final Object self, final Object obj1, final Object obj2) {
return obj1 == obj2; return obj1 == obj2;
} }
...@@ -144,7 +144,7 @@ public final class NativeDebug extends ScriptObject { ...@@ -144,7 +144,7 @@ public final class NativeDebug extends ScriptObject {
* @return return {@link Object#equals(Object)} for objects. * @return return {@link Object#equals(Object)} for objects.
*/ */
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static Object equals(final Object self, final Object obj1, final Object obj2) { public static boolean equals(final Object self, final Object obj1, final Object obj2) {
return Objects.equals(obj1, obj2); return Objects.equals(obj1, obj2);
} }
...@@ -156,7 +156,7 @@ public final class NativeDebug extends ScriptObject { ...@@ -156,7 +156,7 @@ public final class NativeDebug extends ScriptObject {
* @return Java string representation of {@code obj} * @return Java string representation of {@code obj}
*/ */
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static Object toJavaString(final Object self, final Object obj) { public static String toJavaString(final Object self, final Object obj) {
return Objects.toString(obj); return Objects.toString(obj);
} }
...@@ -168,7 +168,7 @@ public final class NativeDebug extends ScriptObject { ...@@ -168,7 +168,7 @@ public final class NativeDebug extends ScriptObject {
* @return string representation * @return string representation
*/ */
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static Object toIdentString(final Object self, final Object obj) { public static String toIdentString(final Object self, final Object obj) {
if (obj == null) { if (obj == null) {
return "null"; return "null";
} }
...@@ -185,8 +185,8 @@ public final class NativeDebug extends ScriptObject { ...@@ -185,8 +185,8 @@ public final class NativeDebug extends ScriptObject {
* @return listener count * @return listener count
*/ */
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static Object getListenerCount(final Object self, final Object obj) { public static int getListenerCount(final Object self, final Object obj) {
return (obj instanceof ScriptObject)? ((ScriptObject)obj).getListenerCount() : 0; return (obj instanceof ScriptObject) ? PropertyListeners.getListenerCount((ScriptObject) obj) : 0;
} }
/** /**
...@@ -203,14 +203,13 @@ public final class NativeDebug extends ScriptObject { ...@@ -203,14 +203,13 @@ public final class NativeDebug extends ScriptObject {
out.println("ScriptObject count " + ScriptObject.getCount()); out.println("ScriptObject count " + ScriptObject.getCount());
out.println("Scope count " + ScriptObject.getScopeCount()); out.println("Scope count " + ScriptObject.getScopeCount());
out.println("ScriptObject listeners added " + PropertyListenerManager.getListenersAdded()); out.println("ScriptObject listeners added " + PropertyListeners.getListenersAdded());
out.println("ScriptObject listeners removed " + PropertyListenerManager.getListenersRemoved()); out.println("ScriptObject listeners removed " + PropertyListeners.getListenersRemoved());
out.println("ScriptFunction constructor calls " + ScriptFunction.getConstructorCount()); out.println("ScriptFunction constructor calls " + ScriptFunction.getConstructorCount());
out.println("ScriptFunction invokes " + ScriptFunction.getInvokes()); out.println("ScriptFunction invokes " + ScriptFunction.getInvokes());
out.println("ScriptFunction allocations " + ScriptFunction.getAllocations()); out.println("ScriptFunction allocations " + ScriptFunction.getAllocations());
out.println("PropertyMap count " + PropertyMap.getCount()); out.println("PropertyMap count " + PropertyMap.getCount());
out.println("PropertyMap cloned " + PropertyMap.getClonedCount()); out.println("PropertyMap cloned " + PropertyMap.getClonedCount());
out.println("PropertyMap shared " + PropertyMap.getSharedCount());
out.println("PropertyMap duplicated " + PropertyMap.getDuplicatedCount()); out.println("PropertyMap duplicated " + PropertyMap.getDuplicatedCount());
out.println("PropertyMap history hit " + PropertyMap.getHistoryHit()); out.println("PropertyMap history hit " + PropertyMap.getHistoryHit());
out.println("PropertyMap proto invalidations " + PropertyMap.getProtoInvalidations()); out.println("PropertyMap proto invalidations " + PropertyMap.getProtoInvalidations());
......
...@@ -38,7 +38,6 @@ import jdk.nashorn.internal.objects.annotations.Function; ...@@ -38,7 +38,6 @@ import jdk.nashorn.internal.objects.annotations.Function;
import jdk.nashorn.internal.objects.annotations.Property; import jdk.nashorn.internal.objects.annotations.Property;
import jdk.nashorn.internal.objects.annotations.ScriptClass; import jdk.nashorn.internal.objects.annotations.ScriptClass;
import jdk.nashorn.internal.objects.annotations.Where; import jdk.nashorn.internal.objects.annotations.Where;
import jdk.nashorn.internal.objects.ScriptFunctionImpl;
import jdk.nashorn.internal.runtime.ECMAException; import jdk.nashorn.internal.runtime.ECMAException;
import jdk.nashorn.internal.runtime.JSType; import jdk.nashorn.internal.runtime.JSType;
import jdk.nashorn.internal.runtime.PropertyMap; import jdk.nashorn.internal.runtime.PropertyMap;
...@@ -75,7 +74,7 @@ public final class NativeError extends ScriptObject { ...@@ -75,7 +74,7 @@ public final class NativeError extends ScriptObject {
static final String FILENAME = "__fileName__"; static final String FILENAME = "__fileName__";
/** Message property name */ /** Message property name */
@Property(name = NativeError.MESSAGE) @Property(name = NativeError.MESSAGE, attributes = Attribute.NOT_ENUMERABLE)
public Object instMessage; public Object instMessage;
/** ECMA 15.11.4.2 Error.prototype.name */ /** ECMA 15.11.4.2 Error.prototype.name */
...@@ -86,13 +85,14 @@ public final class NativeError extends ScriptObject { ...@@ -86,13 +85,14 @@ public final class NativeError extends ScriptObject {
@Property(attributes = Attribute.NOT_ENUMERABLE, where = Where.PROTOTYPE) @Property(attributes = Attribute.NOT_ENUMERABLE, where = Where.PROTOTYPE)
public Object message; public Object message;
/** Nashorn extension: underlying exception */
@Property(attributes = Attribute.NOT_ENUMERABLE)
public Object nashornException;
// initialized by nasgen // initialized by nasgen
private static PropertyMap $nasgenmap$; private static PropertyMap $nasgenmap$;
static PropertyMap getInitialMap() { @SuppressWarnings("LeakingThisInConstructor")
return $nasgenmap$;
}
private NativeError(final Object msg, final ScriptObject proto, final PropertyMap map) { private NativeError(final Object msg, final ScriptObject proto, final PropertyMap map) {
super(proto, map); super(proto, map);
if (msg != UNDEFINED) { if (msg != UNDEFINED) {
...@@ -100,10 +100,11 @@ public final class NativeError extends ScriptObject { ...@@ -100,10 +100,11 @@ public final class NativeError extends ScriptObject {
} else { } else {
this.delete(NativeError.MESSAGE, false); this.delete(NativeError.MESSAGE, false);
} }
initException(this);
} }
NativeError(final Object msg, final Global global) { NativeError(final Object msg, final Global global) {
this(msg, global.getErrorPrototype(), global.getErrorMap()); this(msg, global.getErrorPrototype(), $nasgenmap$);
} }
private NativeError(final Object msg) { private NativeError(final Object msg) {
...@@ -125,10 +126,18 @@ public final class NativeError extends ScriptObject { ...@@ -125,10 +126,18 @@ public final class NativeError extends ScriptObject {
* @return NativeError instance * @return NativeError instance
*/ */
@Constructor @Constructor
public static Object constructor(final boolean newObj, final Object self, final Object msg) { public static NativeError constructor(final boolean newObj, final Object self, final Object msg) {
return new NativeError(msg); return new NativeError(msg);
} }
// This is called NativeError, NativeTypeError etc. to
// associate a ECMAException with the ECMA Error object.
@SuppressWarnings("unused")
static void initException(final ScriptObject self) {
// ECMAException constructor has side effects
new ECMAException(self, null);
}
/** /**
* Nashorn extension: Error.captureStackTrace. Capture stack trace at the point of call into the Error object provided. * Nashorn extension: Error.captureStackTrace. Capture stack trace at the point of call into the Error object provided.
* *
...@@ -136,16 +145,17 @@ public final class NativeError extends ScriptObject { ...@@ -136,16 +145,17 @@ public final class NativeError extends ScriptObject {
* @param errorObj the error object * @param errorObj the error object
* @return undefined * @return undefined
*/ */
@SuppressWarnings("unused")
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static Object captureStackTrace(final Object self, final Object errorObj) { public static Object captureStackTrace(final Object self, final Object errorObj) {
Global.checkObject(errorObj); Global.checkObject(errorObj);
final ScriptObject sobj = (ScriptObject)errorObj; final ScriptObject sobj = (ScriptObject)errorObj;
new ECMAException(sobj, null); //constructor has side effects initException(sobj);
sobj.delete("stack", false); sobj.delete(STACK, false);
final ScriptFunction getStack = ScriptFunctionImpl.makeFunction("getStack", GET_STACK); if (! sobj.has("stack")) {
final ScriptFunction setStack = ScriptFunctionImpl.makeFunction("setStack", SET_STACK); final ScriptFunction getStack = ScriptFunctionImpl.makeFunction("getStack", GET_STACK);
sobj.addOwnProperty("stack", Attribute.NOT_ENUMERABLE, getStack, setStack); final ScriptFunction setStack = ScriptFunctionImpl.makeFunction("setStack", SET_STACK);
sobj.addOwnProperty("stack", Attribute.NOT_ENUMERABLE, getStack, setStack);
}
return UNDEFINED; return UNDEFINED;
} }
...@@ -226,7 +236,11 @@ public final class NativeError extends ScriptObject { ...@@ -226,7 +236,11 @@ public final class NativeError extends ScriptObject {
public static Object setLineNumber(final Object self, final Object value) { public static Object setLineNumber(final Object self, final Object value) {
Global.checkObject(self); Global.checkObject(self);
final ScriptObject sobj = (ScriptObject)self; final ScriptObject sobj = (ScriptObject)self;
sobj.set(LINENUMBER, value, false); if (sobj.hasOwnProperty(LINENUMBER)) {
sobj.put(LINENUMBER, value, false);
} else {
sobj.addOwnProperty(LINENUMBER, Attribute.NOT_ENUMERABLE, value);
}
return value; return value;
} }
...@@ -254,7 +268,11 @@ public final class NativeError extends ScriptObject { ...@@ -254,7 +268,11 @@ public final class NativeError extends ScriptObject {
public static Object setColumnNumber(final Object self, final Object value) { public static Object setColumnNumber(final Object self, final Object value) {
Global.checkObject(self); Global.checkObject(self);
final ScriptObject sobj = (ScriptObject)self; final ScriptObject sobj = (ScriptObject)self;
sobj.set(COLUMNNUMBER, value, false); if (sobj.hasOwnProperty(COLUMNNUMBER)) {
sobj.put(COLUMNNUMBER, value, false);
} else {
sobj.addOwnProperty(COLUMNNUMBER, Attribute.NOT_ENUMERABLE, value);
}
return value; return value;
} }
...@@ -282,7 +300,11 @@ public final class NativeError extends ScriptObject { ...@@ -282,7 +300,11 @@ public final class NativeError extends ScriptObject {
public static Object setFileName(final Object self, final Object value) { public static Object setFileName(final Object self, final Object value) {
Global.checkObject(self); Global.checkObject(self);
final ScriptObject sobj = (ScriptObject)self; final ScriptObject sobj = (ScriptObject)self;
sobj.set(FILENAME, value, false); if (sobj.hasOwnProperty(FILENAME)) {
sobj.put(FILENAME, value, false);
} else {
sobj.addOwnProperty(FILENAME, Attribute.NOT_ENUMERABLE, value);
}
return value; return value;
} }
...@@ -304,10 +326,12 @@ public final class NativeError extends ScriptObject { ...@@ -304,10 +326,12 @@ public final class NativeError extends ScriptObject {
final Object exception = ECMAException.getException(sobj); final Object exception = ECMAException.getException(sobj);
if (exception instanceof Throwable) { if (exception instanceof Throwable) {
return getScriptStackString(sobj, (Throwable)exception); Object value = getScriptStackString(sobj, (Throwable)exception);
sobj.put(STACK, value, false);
return value;
} }
return ""; return UNDEFINED;
} }
/** /**
......
...@@ -44,7 +44,7 @@ import jdk.nashorn.internal.runtime.ScriptObject; ...@@ -44,7 +44,7 @@ import jdk.nashorn.internal.runtime.ScriptObject;
public final class NativeEvalError extends ScriptObject { public final class NativeEvalError extends ScriptObject {
/** message property in instance */ /** message property in instance */
@Property(name = NativeError.MESSAGE) @Property(name = NativeError.MESSAGE, attributes = Attribute.NOT_ENUMERABLE)
public Object instMessage; public Object instMessage;
/** error name property */ /** error name property */
...@@ -55,13 +55,14 @@ public final class NativeEvalError extends ScriptObject { ...@@ -55,13 +55,14 @@ public final class NativeEvalError extends ScriptObject {
@Property(attributes = Attribute.NOT_ENUMERABLE, where = Where.PROTOTYPE) @Property(attributes = Attribute.NOT_ENUMERABLE, where = Where.PROTOTYPE)
public Object message; public Object message;
/** Nashorn extension: underlying exception */
@Property(attributes = Attribute.NOT_ENUMERABLE)
public Object nashornException;
// initialized by nasgen // initialized by nasgen
private static PropertyMap $nasgenmap$; private static PropertyMap $nasgenmap$;
static PropertyMap getInitialMap() { @SuppressWarnings("LeakingThisInConstructor")
return $nasgenmap$;
}
private NativeEvalError(final Object msg, final ScriptObject proto, final PropertyMap map) { private NativeEvalError(final Object msg, final ScriptObject proto, final PropertyMap map) {
super(proto, map); super(proto, map);
if (msg != UNDEFINED) { if (msg != UNDEFINED) {
...@@ -69,10 +70,11 @@ public final class NativeEvalError extends ScriptObject { ...@@ -69,10 +70,11 @@ public final class NativeEvalError extends ScriptObject {
} else { } else {
this.delete(NativeError.MESSAGE, false); this.delete(NativeError.MESSAGE, false);
} }
NativeError.initException(this);
} }
NativeEvalError(final Object msg, final Global global) { NativeEvalError(final Object msg, final Global global) {
this(msg, global.getEvalErrorPrototype(), global.getEvalErrorMap()); this(msg, global.getEvalErrorPrototype(), $nasgenmap$);
} }
private NativeEvalError(final Object msg) { private NativeEvalError(final Object msg) {
...@@ -96,7 +98,7 @@ public final class NativeEvalError extends ScriptObject { ...@@ -96,7 +98,7 @@ public final class NativeEvalError extends ScriptObject {
* @return new EvalError * @return new EvalError
*/ */
@Constructor(name = "EvalError") @Constructor(name = "EvalError")
public static Object constructor(final boolean newObj, final Object self, final Object msg) { public static NativeEvalError constructor(final boolean newObj, final Object self, final Object msg) {
return new NativeEvalError(msg); return new NativeEvalError(msg);
} }
} }
...@@ -136,8 +136,8 @@ public final class NativeFloat32Array extends ArrayBufferView { ...@@ -136,8 +136,8 @@ public final class NativeFloat32Array extends ArrayBufferView {
* @return new typed array * @return new typed array
*/ */
@Constructor(arity = 1) @Constructor(arity = 1)
public static Object constructor(final boolean newObj, final Object self, final Object... args) { public static NativeFloat32Array constructor(final boolean newObj, final Object self, final Object... args) {
return constructorImpl(args, FACTORY); return (NativeFloat32Array)constructorImpl(args, FACTORY);
} }
NativeFloat32Array(final NativeArrayBuffer buffer, final int byteOffset, final int length) { NativeFloat32Array(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
...@@ -192,8 +192,8 @@ public final class NativeFloat32Array extends ArrayBufferView { ...@@ -192,8 +192,8 @@ public final class NativeFloat32Array extends ArrayBufferView {
* @return sub array * @return sub array
*/ */
@Function(attributes = Attribute.NOT_ENUMERABLE) @Function(attributes = Attribute.NOT_ENUMERABLE)
protected static Object subarray(final Object self, final Object begin, final Object end) { protected static NativeFloat32Array subarray(final Object self, final Object begin, final Object end) {
return ArrayBufferView.subarrayImpl(self, begin, end); return (NativeFloat32Array)ArrayBufferView.subarrayImpl(self, begin, end);
} }
@Override @Override
......
...@@ -146,8 +146,8 @@ public final class NativeFloat64Array extends ArrayBufferView { ...@@ -146,8 +146,8 @@ public final class NativeFloat64Array extends ArrayBufferView {
* @return new typed array * @return new typed array
*/ */
@Constructor(arity = 1) @Constructor(arity = 1)
public static Object constructor(final boolean newObj, final Object self, final Object... args) { public static NativeFloat64Array constructor(final boolean newObj, final Object self, final Object... args) {
return constructorImpl(args, FACTORY); return (NativeFloat64Array)constructorImpl(args, FACTORY);
} }
NativeFloat64Array(final NativeArrayBuffer buffer, final int byteOffset, final int length) { NativeFloat64Array(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
...@@ -202,8 +202,8 @@ public final class NativeFloat64Array extends ArrayBufferView { ...@@ -202,8 +202,8 @@ public final class NativeFloat64Array extends ArrayBufferView {
* @return sub array * @return sub array
*/ */
@Function(attributes = Attribute.NOT_ENUMERABLE) @Function(attributes = Attribute.NOT_ENUMERABLE)
protected static Object subarray(final Object self, final Object begin, final Object end) { protected static NativeFloat64Array subarray(final Object self, final Object begin, final Object end) {
return ArrayBufferView.subarrayImpl(self, begin, end); return (NativeFloat64Array)ArrayBufferView.subarrayImpl(self, begin, end);
} }
@Override @Override
......
...@@ -71,7 +71,7 @@ public final class NativeFunction { ...@@ -71,7 +71,7 @@ public final class NativeFunction {
* @return string representation of Function * @return string representation of Function
*/ */
@Function(attributes = Attribute.NOT_ENUMERABLE) @Function(attributes = Attribute.NOT_ENUMERABLE)
public static Object toString(final Object self) { public static String toString(final Object self) {
if (!(self instanceof ScriptFunction)) { if (!(self instanceof ScriptFunction)) {
throw typeError("not.a.function", ScriptRuntime.safeToString(self)); throw typeError("not.a.function", ScriptRuntime.safeToString(self));
} }
...@@ -174,7 +174,7 @@ public final class NativeFunction { ...@@ -174,7 +174,7 @@ public final class NativeFunction {
* @return function with bound arguments * @return function with bound arguments
*/ */
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1) @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
public static Object bind(final Object self, final Object... args) { public static ScriptFunction bind(final Object self, final Object... args) {
if (!(self instanceof ScriptFunction)) { if (!(self instanceof ScriptFunction)) {
throw typeError("not.a.function", ScriptRuntime.safeToString(self)); throw typeError("not.a.function", ScriptRuntime.safeToString(self));
} }
...@@ -199,7 +199,7 @@ public final class NativeFunction { ...@@ -199,7 +199,7 @@ public final class NativeFunction {
* @return source for function * @return source for function
*/ */
@Function(attributes = Attribute.NOT_ENUMERABLE) @Function(attributes = Attribute.NOT_ENUMERABLE)
public static Object toSource(final Object self) { public static String toSource(final Object self) {
if (!(self instanceof ScriptFunction)) { if (!(self instanceof ScriptFunction)) {
throw typeError("not.a.function", ScriptRuntime.safeToString(self)); throw typeError("not.a.function", ScriptRuntime.safeToString(self));
} }
...@@ -217,7 +217,7 @@ public final class NativeFunction { ...@@ -217,7 +217,7 @@ public final class NativeFunction {
* @return new NativeFunction * @return new NativeFunction
*/ */
@Constructor(arity = 1) @Constructor(arity = 1)
public static Object function(final boolean newObj, final Object self, final Object... args) { public static ScriptFunction function(final boolean newObj, final Object self, final Object... args) {
final StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
sb.append("(function ("); sb.append("(function (");
...@@ -253,7 +253,7 @@ public final class NativeFunction { ...@@ -253,7 +253,7 @@ public final class NativeFunction {
final Global global = Global.instance(); final Global global = Global.instance();
return Global.directEval(global, sb.toString(), global, "<function>", global.isStrictContext()); return (ScriptFunction)Global.directEval(global, sb.toString(), global, "<function>", global.isStrictContext());
} }
private static void checkFunctionParameters(final String params) { private static void checkFunctionParameters(final String params) {
......
...@@ -100,8 +100,8 @@ public final class NativeInt16Array extends ArrayBufferView { ...@@ -100,8 +100,8 @@ public final class NativeInt16Array extends ArrayBufferView {
* @return new typed array * @return new typed array
*/ */
@Constructor(arity = 1) @Constructor(arity = 1)
public static Object constructor(final boolean newObj, final Object self, final Object... args) { public static NativeInt16Array constructor(final boolean newObj, final Object self, final Object... args) {
return constructorImpl(args, FACTORY); return (NativeInt16Array)constructorImpl(args, FACTORY);
} }
NativeInt16Array(final NativeArrayBuffer buffer, final int byteOffset, final int byteLength) { NativeInt16Array(final NativeArrayBuffer buffer, final int byteOffset, final int byteLength) {
...@@ -151,8 +151,8 @@ public final class NativeInt16Array extends ArrayBufferView { ...@@ -151,8 +151,8 @@ public final class NativeInt16Array extends ArrayBufferView {
* @return sub array * @return sub array
*/ */
@Function(attributes = Attribute.NOT_ENUMERABLE) @Function(attributes = Attribute.NOT_ENUMERABLE)
protected static Object subarray(final Object self, final Object begin, final Object end) { protected static NativeInt16Array subarray(final Object self, final Object begin, final Object end) {
return ArrayBufferView.subarrayImpl(self, begin, end); return (NativeInt16Array)ArrayBufferView.subarrayImpl(self, begin, end);
} }
@Override @Override
......
...@@ -103,8 +103,8 @@ public final class NativeInt32Array extends ArrayBufferView { ...@@ -103,8 +103,8 @@ public final class NativeInt32Array extends ArrayBufferView {
* @return new typed array * @return new typed array
*/ */
@Constructor(arity = 1) @Constructor(arity = 1)
public static Object constructor(final boolean newObj, final Object self, final Object... args) { public static NativeInt32Array constructor(final boolean newObj, final Object self, final Object... args) {
return constructorImpl(args, FACTORY); return (NativeInt32Array)constructorImpl(args, FACTORY);
} }
NativeInt32Array(final NativeArrayBuffer buffer, final int byteOffset, final int length) { NativeInt32Array(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
...@@ -154,8 +154,8 @@ public final class NativeInt32Array extends ArrayBufferView { ...@@ -154,8 +154,8 @@ public final class NativeInt32Array extends ArrayBufferView {
* @return sub array * @return sub array
*/ */
@Function(attributes = Attribute.NOT_ENUMERABLE) @Function(attributes = Attribute.NOT_ENUMERABLE)
protected static Object subarray(final Object self, final Object begin, final Object end) { protected static NativeInt32Array subarray(final Object self, final Object begin, final Object end) {
return ArrayBufferView.subarrayImpl(self, begin, end); return (NativeInt32Array)ArrayBufferView.subarrayImpl(self, begin, end);
} }
@Override @Override
......
...@@ -93,8 +93,8 @@ public final class NativeInt8Array extends ArrayBufferView { ...@@ -93,8 +93,8 @@ public final class NativeInt8Array extends ArrayBufferView {
* @return new typed array * @return new typed array
*/ */
@Constructor(arity = 1) @Constructor(arity = 1)
public static Object constructor(final boolean newObj, final Object self, final Object... args) { public static NativeInt8Array constructor(final boolean newObj, final Object self, final Object... args) {
return constructorImpl(args, FACTORY); return (NativeInt8Array)constructorImpl(args, FACTORY);
} }
NativeInt8Array(final NativeArrayBuffer buffer, final int byteOffset, final int length) { NativeInt8Array(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
...@@ -144,8 +144,8 @@ public final class NativeInt8Array extends ArrayBufferView { ...@@ -144,8 +144,8 @@ public final class NativeInt8Array extends ArrayBufferView {
* @return sub array * @return sub array
*/ */
@Function(attributes = Attribute.NOT_ENUMERABLE) @Function(attributes = Attribute.NOT_ENUMERABLE)
protected static Object subarray(final Object self, final Object begin, final Object end) { protected static NativeInt8Array subarray(final Object self, final Object begin, final Object end) {
return ArrayBufferView.subarrayImpl(self, begin, end); return (NativeInt8Array)ArrayBufferView.subarrayImpl(self, begin, end);
} }
@Override @Override
......
...@@ -146,10 +146,6 @@ public final class NativeJSAdapter extends ScriptObject { ...@@ -146,10 +146,6 @@ public final class NativeJSAdapter extends ScriptObject {
// initialized by nasgen // initialized by nasgen
private static PropertyMap $nasgenmap$; private static PropertyMap $nasgenmap$;
static PropertyMap getInitialMap() {
return $nasgenmap$;
}
NativeJSAdapter(final Object overrides, final ScriptObject adaptee, final ScriptObject proto, final PropertyMap map) { NativeJSAdapter(final Object overrides, final ScriptObject adaptee, final ScriptObject proto, final PropertyMap map) {
super(proto, map); super(proto, map);
this.adaptee = wrapAdaptee(adaptee); this.adaptee = wrapAdaptee(adaptee);
...@@ -163,7 +159,7 @@ public final class NativeJSAdapter extends ScriptObject { ...@@ -163,7 +159,7 @@ public final class NativeJSAdapter extends ScriptObject {
} }
private static ScriptObject wrapAdaptee(final ScriptObject adaptee) { private static ScriptObject wrapAdaptee(final ScriptObject adaptee) {
return new JO(adaptee, Global.instance().getObjectMap()); return new JO(adaptee, JO.getInitialMap());
} }
@Override @Override
...@@ -540,7 +536,7 @@ public final class NativeJSAdapter extends ScriptObject { ...@@ -540,7 +536,7 @@ public final class NativeJSAdapter extends ScriptObject {
* @return new NativeJSAdapter * @return new NativeJSAdapter
*/ */
@Constructor @Constructor
public static Object construct(final boolean isNew, final Object self, final Object... args) { public static NativeJSAdapter construct(final boolean isNew, final Object self, final Object... args) {
Object proto = UNDEFINED; Object proto = UNDEFINED;
Object overrides = UNDEFINED; Object overrides = UNDEFINED;
Object adaptee; Object adaptee;
...@@ -577,7 +573,7 @@ public final class NativeJSAdapter extends ScriptObject { ...@@ -577,7 +573,7 @@ public final class NativeJSAdapter extends ScriptObject {
proto = global.getJSAdapterPrototype(); proto = global.getJSAdapterPrototype();
} }
return new NativeJSAdapter(overrides, (ScriptObject)adaptee, (ScriptObject)proto, global.getJSAdapterMap()); return new NativeJSAdapter(overrides, (ScriptObject)adaptee, (ScriptObject)proto, $nasgenmap$);
} }
@Override @Override
...@@ -622,14 +618,14 @@ public final class NativeJSAdapter extends ScriptObject { ...@@ -622,14 +618,14 @@ public final class NativeJSAdapter extends ScriptObject {
case "getMethod": case "getMethod":
final FindProperty find = adaptee.findProperty(__call__, true); final FindProperty find = adaptee.findProperty(__call__, true);
if (find != null) { if (find != null) {
final Object value = getObjectValue(find); final Object value = find.getObjectValue();
if (value instanceof ScriptFunction) { if (value instanceof ScriptFunction) {
final ScriptFunctionImpl func = (ScriptFunctionImpl)value; final ScriptFunctionImpl func = (ScriptFunctionImpl)value;
// TODO: It's a shame we need to produce a function bound to this and name, when we'd only need it bound // TODO: It's a shame we need to produce a function bound to this and name, when we'd only need it bound
// to name. Probably not a big deal, but if we can ever make it leaner, it'd be nice. // to name. Probably not a big deal, but if we can ever make it leaner, it'd be nice.
return new GuardedInvocation(MH.dropArguments(MH.constant(Object.class, return new GuardedInvocation(MH.dropArguments(MH.constant(Object.class,
func.makeBoundFunction(this, new Object[] { name })), 0, Object.class), func.makeBoundFunction(this, new Object[] { name })), 0, Object.class),
adaptee.getMap().getProtoGetSwitchPoint(adaptee.getProto(), __call__), adaptee.getProtoSwitchPoint(__call__, find.getOwner()),
testJSAdaptor(adaptee, null, null, null)); testJSAdaptor(adaptee, null, null, null));
} }
} }
...@@ -691,7 +687,7 @@ public final class NativeJSAdapter extends ScriptObject { ...@@ -691,7 +687,7 @@ public final class NativeJSAdapter extends ScriptObject {
final MethodType type = desc.getMethodType(); final MethodType type = desc.getMethodType();
if (findData != null) { if (findData != null) {
final String name = desc.getNameTokenCount() > 2 ? desc.getNameToken(2) : null; final String name = desc.getNameTokenCount() > 2 ? desc.getNameToken(2) : null;
final Object value = getObjectValue(findData); final Object value = findData.getObjectValue();
if (value instanceof ScriptFunction) { if (value instanceof ScriptFunction) {
final ScriptFunction func = (ScriptFunction)value; final ScriptFunction func = (ScriptFunction)value;
...@@ -700,7 +696,7 @@ public final class NativeJSAdapter extends ScriptObject { ...@@ -700,7 +696,7 @@ public final class NativeJSAdapter extends ScriptObject {
if (methodHandle != null) { if (methodHandle != null) {
return new GuardedInvocation( return new GuardedInvocation(
methodHandle, methodHandle,
adaptee.getMap().getProtoGetSwitchPoint(adaptee.getProto(), hook), adaptee.getProtoSwitchPoint(hook, findData.getOwner()),
testJSAdaptor(adaptee, findData.getGetter(Object.class), findData.getOwner(), func)); testJSAdaptor(adaptee, findData.getGetter(Object.class), findData.getOwner(), func));
} }
} }
...@@ -713,7 +709,7 @@ public final class NativeJSAdapter extends ScriptObject { ...@@ -713,7 +709,7 @@ public final class NativeJSAdapter extends ScriptObject {
final MethodHandle methodHandle = hook.equals(__put__) ? final MethodHandle methodHandle = hook.equals(__put__) ?
MH.asType(Lookup.EMPTY_SETTER, type) : MH.asType(Lookup.EMPTY_SETTER, type) :
Lookup.emptyGetter(type.returnType()); Lookup.emptyGetter(type.returnType());
return new GuardedInvocation(methodHandle, adaptee.getMap().getProtoGetSwitchPoint(adaptee.getProto(), hook), testJSAdaptor(adaptee, null, null, null)); return new GuardedInvocation(methodHandle, adaptee.getProtoSwitchPoint(hook, null), testJSAdaptor(adaptee, null, null, null));
} }
} }
......
...@@ -75,7 +75,7 @@ public final class NativeJava { ...@@ -75,7 +75,7 @@ public final class NativeJava {
* @see #type(Object, Object) * @see #type(Object, Object)
*/ */
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static Object isType(final Object self, final Object type) { public static boolean isType(final Object self, final Object type) {
return type instanceof StaticClass; return type instanceof StaticClass;
} }
...@@ -338,7 +338,7 @@ public final class NativeJava { ...@@ -338,7 +338,7 @@ public final class NativeJava {
* null. * null.
*/ */
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static Object from(final Object self, final Object objArray) { public static NativeArray from(final Object self, final Object objArray) {
if (objArray == null) { if (objArray == null) {
return null; return null;
} else if (objArray instanceof Collection) { } else if (objArray instanceof Collection) {
......
...@@ -60,17 +60,13 @@ public final class NativeJavaImporter extends ScriptObject { ...@@ -60,17 +60,13 @@ public final class NativeJavaImporter extends ScriptObject {
// initialized by nasgen // initialized by nasgen
private static PropertyMap $nasgenmap$; private static PropertyMap $nasgenmap$;
static PropertyMap getInitialMap() {
return $nasgenmap$;
}
private NativeJavaImporter(final Object[] args, final ScriptObject proto, final PropertyMap map) { private NativeJavaImporter(final Object[] args, final ScriptObject proto, final PropertyMap map) {
super(proto, map); super(proto, map);
this.args = args; this.args = args;
} }
private NativeJavaImporter(final Object[] args, final Global global) { private NativeJavaImporter(final Object[] args, final Global global) {
this(args, global.getJavaImporterPrototype(), global.getJavaImporterMap()); this(args, global.getJavaImporterPrototype(), $nasgenmap$);
} }
private NativeJavaImporter(final Object[] args) { private NativeJavaImporter(final Object[] args) {
...@@ -90,7 +86,7 @@ public final class NativeJavaImporter extends ScriptObject { ...@@ -90,7 +86,7 @@ public final class NativeJavaImporter extends ScriptObject {
* @return NativeJavaImporter instance * @return NativeJavaImporter instance
*/ */
@Constructor(arity = 1) @Constructor(arity = 1)
public static Object constructor(final boolean isNew, final Object self, final Object... args) { public static NativeJavaImporter constructor(final boolean isNew, final Object self, final Object... args) {
return new NativeJavaImporter(args); return new NativeJavaImporter(args);
} }
...@@ -134,6 +130,11 @@ public final class NativeJavaImporter extends ScriptObject { ...@@ -134,6 +130,11 @@ public final class NativeJavaImporter extends ScriptObject {
return createAndSetProperty(desc) ? super.lookup(desc, request) : super.noSuchMethod(desc, request); return createAndSetProperty(desc) ? super.lookup(desc, request) : super.noSuchMethod(desc, request);
} }
@Override
protected Object invokeNoSuchProperty(final String name) {
return createProperty(name);
}
private boolean createAndSetProperty(final CallSiteDescriptor desc) { private boolean createAndSetProperty(final CallSiteDescriptor desc) {
final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND); final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
final Object value = createProperty(name); final Object value = createProperty(name);
......
...@@ -92,7 +92,7 @@ public final class NativeMath extends ScriptObject { ...@@ -92,7 +92,7 @@ public final class NativeMath extends ScriptObject {
* @return abs of value * @return abs of value
*/ */
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static Object abs(final Object self, final Object x) { public static double abs(final Object self, final Object x) {
return Math.abs(JSType.toNumber(x)); return Math.abs(JSType.toNumber(x));
} }
...@@ -144,7 +144,7 @@ public final class NativeMath extends ScriptObject { ...@@ -144,7 +144,7 @@ public final class NativeMath extends ScriptObject {
* @return acos of argument * @return acos of argument
*/ */
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static Object acos(final Object self, final Object x) { public static double acos(final Object self, final Object x) {
return Math.acos(JSType.toNumber(x)); return Math.acos(JSType.toNumber(x));
} }
...@@ -170,7 +170,7 @@ public final class NativeMath extends ScriptObject { ...@@ -170,7 +170,7 @@ public final class NativeMath extends ScriptObject {
* @return asin of argument * @return asin of argument
*/ */
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static Object asin(final Object self, final Object x) { public static double asin(final Object self, final Object x) {
return Math.asin(JSType.toNumber(x)); return Math.asin(JSType.toNumber(x));
} }
...@@ -196,7 +196,7 @@ public final class NativeMath extends ScriptObject { ...@@ -196,7 +196,7 @@ public final class NativeMath extends ScriptObject {
* @return atan of argument * @return atan of argument
*/ */
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static Object atan(final Object self, final Object x) { public static double atan(final Object self, final Object x) {
return Math.atan(JSType.toNumber(x)); return Math.atan(JSType.toNumber(x));
} }
...@@ -223,7 +223,7 @@ public final class NativeMath extends ScriptObject { ...@@ -223,7 +223,7 @@ public final class NativeMath extends ScriptObject {
* @return atan2 of x and y * @return atan2 of x and y
*/ */
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static Object atan2(final Object self, final Object y, final Object x) { public static double atan2(final Object self, final Object y, final Object x) {
return Math.atan2(JSType.toNumber(y), JSType.toNumber(x)); return Math.atan2(JSType.toNumber(y), JSType.toNumber(x));
} }
...@@ -250,7 +250,7 @@ public final class NativeMath extends ScriptObject { ...@@ -250,7 +250,7 @@ public final class NativeMath extends ScriptObject {
* @return ceil of argument * @return ceil of argument
*/ */
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static Object ceil(final Object self, final Object x) { public static double ceil(final Object self, final Object x) {
return Math.ceil(JSType.toNumber(x)); return Math.ceil(JSType.toNumber(x));
} }
...@@ -302,7 +302,7 @@ public final class NativeMath extends ScriptObject { ...@@ -302,7 +302,7 @@ public final class NativeMath extends ScriptObject {
* @return cos of argument * @return cos of argument
*/ */
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static Object cos(final Object self, final Object x) { public static double cos(final Object self, final Object x) {
return Math.cos(JSType.toNumber(x)); return Math.cos(JSType.toNumber(x));
} }
...@@ -328,7 +328,7 @@ public final class NativeMath extends ScriptObject { ...@@ -328,7 +328,7 @@ public final class NativeMath extends ScriptObject {
* @return exp of argument * @return exp of argument
*/ */
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static Object exp(final Object self, final Object x) { public static double exp(final Object self, final Object x) {
return Math.exp(JSType.toNumber(x)); return Math.exp(JSType.toNumber(x));
} }
...@@ -341,7 +341,7 @@ public final class NativeMath extends ScriptObject { ...@@ -341,7 +341,7 @@ public final class NativeMath extends ScriptObject {
* @return floor of argument * @return floor of argument
*/ */
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static Object floor(final Object self, final Object x) { public static double floor(final Object self, final Object x) {
return Math.floor(JSType.toNumber(x)); return Math.floor(JSType.toNumber(x));
} }
...@@ -393,7 +393,7 @@ public final class NativeMath extends ScriptObject { ...@@ -393,7 +393,7 @@ public final class NativeMath extends ScriptObject {
* @return log of argument * @return log of argument
*/ */
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static Object log(final Object self, final Object x) { public static double log(final Object self, final Object x) {
return Math.log(JSType.toNumber(x)); return Math.log(JSType.toNumber(x));
} }
...@@ -419,7 +419,7 @@ public final class NativeMath extends ScriptObject { ...@@ -419,7 +419,7 @@ public final class NativeMath extends ScriptObject {
* @return the largest of the arguments, {@link Double#NEGATIVE_INFINITY} if no args given, or identity if one arg is given * @return the largest of the arguments, {@link Double#NEGATIVE_INFINITY} if no args given, or identity if one arg is given
*/ */
@Function(arity = 2, attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) @Function(arity = 2, attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static Object max(final Object self, final Object... args) { public static double max(final Object self, final Object... args) {
switch (args.length) { switch (args.length) {
case 0: case 0:
return Double.NEGATIVE_INFINITY; return Double.NEGATIVE_INFINITY;
...@@ -497,7 +497,7 @@ public final class NativeMath extends ScriptObject { ...@@ -497,7 +497,7 @@ public final class NativeMath extends ScriptObject {
* @return the smallest of the arguments, {@link Double#NEGATIVE_INFINITY} if no args given, or identity if one arg is given * @return the smallest of the arguments, {@link Double#NEGATIVE_INFINITY} if no args given, or identity if one arg is given
*/ */
@Function(arity = 2, attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) @Function(arity = 2, attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static Object min(final Object self, final Object... args) { public static double min(final Object self, final Object... args) {
switch (args.length) { switch (args.length) {
case 0: case 0:
return Double.POSITIVE_INFINITY; return Double.POSITIVE_INFINITY;
...@@ -576,7 +576,7 @@ public final class NativeMath extends ScriptObject { ...@@ -576,7 +576,7 @@ public final class NativeMath extends ScriptObject {
* @return x raised to the power of y * @return x raised to the power of y
*/ */
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static Object pow(final Object self, final Object x, final Object y) { public static double pow(final Object self, final Object x, final Object y) {
return Math.pow(JSType.toNumber(x), JSType.toNumber(y)); return Math.pow(JSType.toNumber(x), JSType.toNumber(y));
} }
...@@ -602,7 +602,7 @@ public final class NativeMath extends ScriptObject { ...@@ -602,7 +602,7 @@ public final class NativeMath extends ScriptObject {
* @return random number in the range [0..1) * @return random number in the range [0..1)
*/ */
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static Object random(final Object self) { public static double random(final Object self) {
return Math.random(); return Math.random();
} }
...@@ -615,7 +615,7 @@ public final class NativeMath extends ScriptObject { ...@@ -615,7 +615,7 @@ public final class NativeMath extends ScriptObject {
* @return x rounded * @return x rounded
*/ */
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static Object round(final Object self, final Object x) { public static double round(final Object self, final Object x) {
final double d = JSType.toNumber(x); final double d = JSType.toNumber(x);
if (Math.getExponent(d) >= 52) { if (Math.getExponent(d) >= 52) {
return d; return d;
...@@ -632,7 +632,7 @@ public final class NativeMath extends ScriptObject { ...@@ -632,7 +632,7 @@ public final class NativeMath extends ScriptObject {
* @return sin of x * @return sin of x
*/ */
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static Object sin(final Object self, final Object x) { public static double sin(final Object self, final Object x) {
return Math.sin(JSType.toNumber(x)); return Math.sin(JSType.toNumber(x));
} }
...@@ -658,7 +658,7 @@ public final class NativeMath extends ScriptObject { ...@@ -658,7 +658,7 @@ public final class NativeMath extends ScriptObject {
* @return sqrt of x * @return sqrt of x
*/ */
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static Object sqrt(final Object self, final Object x) { public static double sqrt(final Object self, final Object x) {
return Math.sqrt(JSType.toNumber(x)); return Math.sqrt(JSType.toNumber(x));
} }
...@@ -684,7 +684,7 @@ public final class NativeMath extends ScriptObject { ...@@ -684,7 +684,7 @@ public final class NativeMath extends ScriptObject {
* @return tan of x * @return tan of x
*/ */
@Function(attributes = Attribute.NOT_ENUMERABLE, where=Where.CONSTRUCTOR) @Function(attributes = Attribute.NOT_ENUMERABLE, where=Where.CONSTRUCTOR)
public static Object tan(final Object self, final Object x) { public static double tan(final Object self, final Object x) {
return Math.tan(JSType.toNumber(x)); return Math.tan(JSType.toNumber(x));
} }
......
...@@ -44,7 +44,7 @@ import jdk.nashorn.internal.runtime.ScriptObject; ...@@ -44,7 +44,7 @@ import jdk.nashorn.internal.runtime.ScriptObject;
public final class NativeRangeError extends ScriptObject { public final class NativeRangeError extends ScriptObject {
/** message property in instance */ /** message property in instance */
@Property(name = NativeError.MESSAGE) @Property(name = NativeError.MESSAGE, attributes = Attribute.NOT_ENUMERABLE)
public Object instMessage; public Object instMessage;
/** error name property */ /** error name property */
...@@ -55,13 +55,14 @@ public final class NativeRangeError extends ScriptObject { ...@@ -55,13 +55,14 @@ public final class NativeRangeError extends ScriptObject {
@Property(attributes = Attribute.NOT_ENUMERABLE, where = Where.PROTOTYPE) @Property(attributes = Attribute.NOT_ENUMERABLE, where = Where.PROTOTYPE)
public Object message; public Object message;
/** Nashorn extension: underlying exception */
@Property(attributes = Attribute.NOT_ENUMERABLE)
public Object nashornException;
// initialized by nasgen // initialized by nasgen
private static PropertyMap $nasgenmap$; private static PropertyMap $nasgenmap$;
static PropertyMap getInitialMap() { @SuppressWarnings("LeakingThisInConstructor")
return $nasgenmap$;
}
private NativeRangeError(final Object msg, final ScriptObject proto, final PropertyMap map) { private NativeRangeError(final Object msg, final ScriptObject proto, final PropertyMap map) {
super(proto, map); super(proto, map);
if (msg != UNDEFINED) { if (msg != UNDEFINED) {
...@@ -69,10 +70,11 @@ public final class NativeRangeError extends ScriptObject { ...@@ -69,10 +70,11 @@ public final class NativeRangeError extends ScriptObject {
} else { } else {
this.delete(NativeError.MESSAGE, false); this.delete(NativeError.MESSAGE, false);
} }
NativeError.initException(this);
} }
NativeRangeError(final Object msg, final Global global) { NativeRangeError(final Object msg, final Global global) {
this(msg, global.getRangeErrorPrototype(), global.getRangeErrorMap()); this(msg, global.getRangeErrorPrototype(), $nasgenmap$);
} }
private NativeRangeError(final Object msg) { private NativeRangeError(final Object msg) {
...@@ -96,7 +98,7 @@ public final class NativeRangeError extends ScriptObject { ...@@ -96,7 +98,7 @@ public final class NativeRangeError extends ScriptObject {
* @return new RangeError * @return new RangeError
*/ */
@Constructor(name = "RangeError") @Constructor(name = "RangeError")
public static Object constructor(final boolean newObj, final Object self, final Object msg) { public static NativeRangeError constructor(final boolean newObj, final Object self, final Object msg) {
return new NativeRangeError(msg); return new NativeRangeError(msg);
} }
} }
...@@ -44,7 +44,7 @@ import jdk.nashorn.internal.runtime.ScriptObject; ...@@ -44,7 +44,7 @@ import jdk.nashorn.internal.runtime.ScriptObject;
public final class NativeReferenceError extends ScriptObject { public final class NativeReferenceError extends ScriptObject {
/** message property in instance */ /** message property in instance */
@Property(name = NativeError.MESSAGE) @Property(name = NativeError.MESSAGE, attributes = Attribute.NOT_ENUMERABLE)
public Object instMessage; public Object instMessage;
/** error name property */ /** error name property */
...@@ -55,13 +55,14 @@ public final class NativeReferenceError extends ScriptObject { ...@@ -55,13 +55,14 @@ public final class NativeReferenceError extends ScriptObject {
@Property(attributes = Attribute.NOT_ENUMERABLE, where = Where.PROTOTYPE) @Property(attributes = Attribute.NOT_ENUMERABLE, where = Where.PROTOTYPE)
public Object message; public Object message;
/** Nashorn extension: underlying exception */
@Property(attributes = Attribute.NOT_ENUMERABLE)
public Object nashornException;
// initialized by nasgen // initialized by nasgen
private static PropertyMap $nasgenmap$; private static PropertyMap $nasgenmap$;
static PropertyMap getInitialMap() { @SuppressWarnings("LeakingThisInConstructor")
return $nasgenmap$;
}
private NativeReferenceError(final Object msg, final ScriptObject proto, final PropertyMap map) { private NativeReferenceError(final Object msg, final ScriptObject proto, final PropertyMap map) {
super(proto, map); super(proto, map);
if (msg != UNDEFINED) { if (msg != UNDEFINED) {
...@@ -69,10 +70,11 @@ public final class NativeReferenceError extends ScriptObject { ...@@ -69,10 +70,11 @@ public final class NativeReferenceError extends ScriptObject {
} else { } else {
this.delete(NativeError.MESSAGE, false); this.delete(NativeError.MESSAGE, false);
} }
NativeError.initException(this);
} }
NativeReferenceError(final Object msg, final Global global) { NativeReferenceError(final Object msg, final Global global) {
this(msg, global.getReferenceErrorPrototype(), global.getReferenceErrorMap()); this(msg, global.getReferenceErrorPrototype(), $nasgenmap$);
} }
private NativeReferenceError(final Object msg) { private NativeReferenceError(final Object msg) {
...@@ -96,7 +98,7 @@ public final class NativeReferenceError extends ScriptObject { ...@@ -96,7 +98,7 @@ public final class NativeReferenceError extends ScriptObject {
* @return new ReferenceError * @return new ReferenceError
*/ */
@Constructor(name = "ReferenceError") @Constructor(name = "ReferenceError")
public static Object constructor(final boolean newObj, final Object self, final Object msg) { public static NativeReferenceError constructor(final boolean newObj, final Object self, final Object msg) {
return new NativeReferenceError(msg); return new NativeReferenceError(msg);
} }
} }
...@@ -60,9 +60,9 @@ public final class NativeStrictArguments extends ScriptObject { ...@@ -60,9 +60,9 @@ public final class NativeStrictArguments extends ScriptObject {
// In strict mode, the caller and callee properties should throw TypeError // In strict mode, the caller and callee properties should throw TypeError
// Need to add properties directly to map since slots are assigned speculatively by newUserAccessors. // Need to add properties directly to map since slots are assigned speculatively by newUserAccessors.
final int flags = Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE; final int flags = Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE;
map = map.addProperty(map.newUserAccessors("caller", flags)); map = map.addPropertyNoHistory(map.newUserAccessors("caller", flags));
map = map.addProperty(map.newUserAccessors("callee", flags)); map = map.addPropertyNoHistory(map.newUserAccessors("callee", flags));
map$ = map.setIsShared(); map$ = map;
} }
static PropertyMap getInitialMap() { static PropertyMap getInitialMap() {
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册