mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-04 07:28:22 +00:00
Merge
This commit is contained in:
commit
73ef2bf360
@ -81,13 +81,13 @@ TestNG library and placing its jar file into the lib subdirectory:
|
||||
|
||||
After that, you can run the tests using:
|
||||
cd make
|
||||
ant test
|
||||
ant clean test
|
||||
|
||||
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
|
||||
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
|
||||
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:
|
||||
|
||||
cd nashorn~jdk8/nashorn/make
|
||||
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
|
||||
takes advantage of all processor cores on the computer:
|
||||
|
||||
@ -22,40 +22,62 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
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_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.Type;
|
||||
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
|
||||
* annotations from the jdk.nashorn.internal.objects.annotations package.
|
||||
*/
|
||||
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
|
||||
*/
|
||||
public static enum Kind {
|
||||
/** This is a script class */
|
||||
|
||||
/**
|
||||
* This is a script class
|
||||
*/
|
||||
SCRIPT_CLASS,
|
||||
/** This is a constructor */
|
||||
/**
|
||||
* This is a constructor
|
||||
*/
|
||||
CONSTRUCTOR,
|
||||
/** This is a function */
|
||||
/**
|
||||
* This is a function
|
||||
*/
|
||||
FUNCTION,
|
||||
/** This is a getter */
|
||||
/**
|
||||
* This is a getter
|
||||
*/
|
||||
GETTER,
|
||||
/** This is a setter */
|
||||
/**
|
||||
* This is a setter
|
||||
*/
|
||||
SETTER,
|
||||
/** This is a property */
|
||||
/**
|
||||
* This is a property
|
||||
*/
|
||||
PROPERTY,
|
||||
/** This is a specialized version of a function */
|
||||
/**
|
||||
* This is a specialized version of a function
|
||||
*/
|
||||
SPECIALIZED_FUNCTION,
|
||||
/** This is a specialized version of a constructor */
|
||||
/**
|
||||
* This is a specialized version of a constructor
|
||||
*/
|
||||
SPECIALIZED_CONSTRUCTOR
|
||||
}
|
||||
|
||||
@ -194,6 +216,7 @@ public final class MemberInfo implements Cloneable {
|
||||
|
||||
/**
|
||||
* Check whether this MemberInfo is a getter that resides in the instance
|
||||
*
|
||||
* @return true if instance setter
|
||||
*/
|
||||
boolean isInstanceSetter() {
|
||||
@ -245,92 +268,201 @@ public final class MemberInfo implements Cloneable {
|
||||
}
|
||||
|
||||
void verify() {
|
||||
if (kind == Kind.CONSTRUCTOR) {
|
||||
final Type returnType = Type.getReturnType(javaDesc);
|
||||
if (! returnType.toString().equals(OBJECT_DESC)) {
|
||||
error("return value should be of Object type, found" + returnType);
|
||||
}
|
||||
final Type[] argTypes = Type.getArgumentTypes(javaDesc);
|
||||
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[1].toString().equals(OBJECT_DESC)) {
|
||||
error("second argument should be of Object type, found" + argTypes[0]);
|
||||
}
|
||||
switch (kind) {
|
||||
case CONSTRUCTOR: {
|
||||
final Type returnType = Type.getReturnType(javaDesc);
|
||||
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) {
|
||||
error("@Constructor methods should have at least 2 args");
|
||||
}
|
||||
if (!argTypes[0].equals(Type.BOOLEAN_TYPE)) {
|
||||
error("first argument of a @Constructor method should be of boolean 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) {
|
||||
for (int i = 2; i < argTypes.length - 1; i++) {
|
||||
if (! argTypes[i].toString().equals(OBJECT_DESC)) {
|
||||
error(i + "'th argument should be of Object type, found " + argTypes[i]);
|
||||
if (argTypes.length > 2) {
|
||||
for (int i = 2; i < argTypes.length - 1; i++) {
|
||||
if (!isJavaLangObject(argTypes[i])) {
|
||||
error(i + "'th argument of a @Constructor method should be of Object type, found " + argTypes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
final String lastArgTypeDesc = argTypes[argTypes.length - 1].getDescriptor();
|
||||
final boolean isVarArg = lastArgTypeDesc.equals(OBJECT_ARRAY_DESC);
|
||||
if (!lastArgTypeDesc.equals(OBJECT_DESC) && !isVarArg) {
|
||||
error("last argument of a @Constructor method is neither Object nor Object[] type: " + lastArgTypeDesc);
|
||||
}
|
||||
|
||||
if (isVarArg && argTypes.length > 3) {
|
||||
error("vararg of a @Constructor method has more than 3 arguments");
|
||||
}
|
||||
}
|
||||
|
||||
final String lastArgType = argTypes[argTypes.length - 1].toString();
|
||||
final boolean isVarArg = lastArgType.equals(OBJECT_ARRAY_DESC);
|
||||
if (!lastArgType.equals(OBJECT_DESC) && !isVarArg) {
|
||||
error("last argument is neither Object nor Object[] type: " + lastArgType);
|
||||
}
|
||||
break;
|
||||
case SPECIALIZED_CONSTRUCTOR: {
|
||||
final Type returnType = Type.getReturnType(javaDesc);
|
||||
if (!isJSObjectType(returnType)) {
|
||||
error("return value of a @SpecializedConstructor method should be a valid JS type, found " + returnType);
|
||||
}
|
||||
|
||||
if (isVarArg && argTypes.length > 3) {
|
||||
error("vararg constructor has more than 3 arguments");
|
||||
}
|
||||
}
|
||||
} else if (kind == Kind.FUNCTION) {
|
||||
final Type[] argTypes = Type.getArgumentTypes(javaDesc);
|
||||
if (argTypes.length < 1) {
|
||||
error("function methods should have at least 1 arg");
|
||||
}
|
||||
if (! argTypes[0].toString().equals(OBJECT_DESC)) {
|
||||
error("first argument should be of Object type, found" + argTypes[0]);
|
||||
}
|
||||
|
||||
if (argTypes.length > 1) {
|
||||
for (int i = 1; i < argTypes.length - 1; i++) {
|
||||
if (! argTypes[i].toString().equals(OBJECT_DESC)) {
|
||||
error(i + "'th argument should be of Object type, found " + argTypes[i]);
|
||||
final Type[] argTypes = Type.getArgumentTypes(javaDesc);
|
||||
for (int i = 0; i < argTypes.length; i++) {
|
||||
if (!isValidJSType(argTypes[i])) {
|
||||
error(i + "'th argument of a @SpecializedConstructor method is not valid JS type, found " + argTypes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
final String lastArgType = argTypes[argTypes.length - 1].toString();
|
||||
final boolean isVarArg = lastArgType.equals(OBJECT_ARRAY_DESC);
|
||||
if (!lastArgType.equals(OBJECT_DESC) && !isVarArg) {
|
||||
error("last argument is neither Object nor Object[] type: " + lastArgType);
|
||||
}
|
||||
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 (isVarArg && argTypes.length > 2) {
|
||||
error("vararg function has more than 2 arguments");
|
||||
if (argTypes.length > 1) {
|
||||
for (int i = 1; i < argTypes.length - 1; i++) {
|
||||
if (!isJavaLangObject(argTypes[i])) {
|
||||
error(i + "'th argument of a @Function method should be of Object type, found " + argTypes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
final String lastArgTypeDesc = argTypes[argTypes.length - 1].getDescriptor();
|
||||
final boolean isVarArg = lastArgTypeDesc.equals(OBJECT_ARRAY_DESC);
|
||||
if (!lastArgTypeDesc.equals(OBJECT_DESC) && !isVarArg) {
|
||||
error("last argument of a @Function method is neither Object nor Object[] type: " + lastArgTypeDesc);
|
||||
}
|
||||
|
||||
if (isVarArg && argTypes.length > 2) {
|
||||
error("vararg @Function method has more than 2 arguments");
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (kind == Kind.GETTER) {
|
||||
final Type[] argTypes = Type.getArgumentTypes(javaDesc);
|
||||
if (argTypes.length != 1) {
|
||||
error("getter methods should have one argument");
|
||||
break;
|
||||
case SPECIALIZED_FUNCTION: {
|
||||
final Type returnType = Type.getReturnType(javaDesc);
|
||||
if (!isValidJSType(returnType)) {
|
||||
error("return value of a @SpecializedFunction method should be a valid JS type, found " + returnType);
|
||||
}
|
||||
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 (! argTypes[0].toString().equals(OBJECT_DESC)) {
|
||||
error("first argument of getter should be of Object type, found: " + argTypes[0]);
|
||||
break;
|
||||
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);
|
||||
}
|
||||
}
|
||||
if (Type.getReturnType(javaDesc).equals(Type.VOID_TYPE)) {
|
||||
error("return type of getter should not be void");
|
||||
break;
|
||||
case SETTER: {
|
||||
final Type[] argTypes = Type.getArgumentTypes(javaDesc);
|
||||
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));
|
||||
}
|
||||
}
|
||||
} else if (kind == Kind.SETTER) {
|
||||
final Type[] argTypes = Type.getArgumentTypes(javaDesc);
|
||||
if (argTypes.length != 2) {
|
||||
error("setter methods should have two arguments");
|
||||
}
|
||||
if (! argTypes[0].toString().equals(OBJECT_DESC)) {
|
||||
error("first argument of setter should be of Object type, found: " + argTypes[0]);
|
||||
}
|
||||
if (!Type.getReturnType(javaDesc).toString().equals("V")) {
|
||||
error("return type of setter should be void, found: " + Type.getReturnType(javaDesc));
|
||||
break;
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
throw new RuntimeException(javaName + javaDesc + " : " + msg);
|
||||
throw new RuntimeException(javaName + " of type " + javaDesc + " : " + msg);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -61,6 +61,8 @@ public interface StringConstants {
|
||||
static final String METHODHANDLE_TYPE = TYPE_METHODHANDLE.getInternalName();
|
||||
static final String OBJECT_TYPE = TYPE_OBJECT.getInternalName();
|
||||
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 ARRAYLIST_TYPE = TYPE_ARRAYLIST.getInternalName();
|
||||
static final String COLLECTION_TYPE = TYPE_COLLECTION.getInternalName();
|
||||
@ -129,6 +131,7 @@ public interface StringConstants {
|
||||
|
||||
// ScriptObject
|
||||
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 GETTER_PREFIX = "G$";
|
||||
|
||||
@ -42,6 +42,9 @@
|
||||
<condition property="hg.executable" value="/usr/local/bin/hg" else="hg">
|
||||
<available file="/usr/local/bin/hg"/>
|
||||
</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 -->
|
||||
<available property="asm.available" classname="jdk.internal.org.objectweb.asm.Type"/>
|
||||
<!-- check if testng.jar is avaiable -->
|
||||
@ -503,18 +506,17 @@ grant codeBase "file:/${basedir}/test/script/markdown.js" {
|
||||
|
||||
<!-- test262 test suite -->
|
||||
<target name="get-test262" depends="init" unless="${test-sys-prop.external.test262}">
|
||||
<!-- clone test262 mercurial repo -->
|
||||
<exec executable="${hg.executable}">
|
||||
<!-- clone test262 git repo -->
|
||||
<exec executable="${git.executable}">
|
||||
<arg value="clone"/>
|
||||
<arg value="http://hg.ecmascript.org/tests/test262"/>
|
||||
<arg value="https://github.com/tc39/test262"/>
|
||||
<arg value="${test.external.dir}/test262"/>
|
||||
</exec>
|
||||
</target>
|
||||
<target name="update-test262" depends="init" if="${test-sys-prop.external.test262}">
|
||||
<!-- update test262 mercurial repo -->
|
||||
<exec executable="${hg.executable}" dir="${test.external.dir}/test262">
|
||||
<!-- update test262 git repo -->
|
||||
<exec executable="${git.executable}" dir="${test.external.dir}/test262">
|
||||
<arg value="pull"/>
|
||||
<arg value="-u"/>
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
|
||||
@ -3228,7 +3228,7 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
|
||||
final String className = SCRIPTFUNCTION_IMPL_OBJECT;
|
||||
final int fieldCount = ObjectClassGenerator.getPaddedFieldCount(functionNode.countThisProperties());
|
||||
final String allocatorClassName = Compiler.binaryName(ObjectClassGenerator.getClassName(fieldCount));
|
||||
final PropertyMap allocatorMap = PropertyMap.newMap(null, 0, fieldCount, 0);
|
||||
final PropertyMap allocatorMap = PropertyMap.newMap(null, allocatorClassName, 0, fieldCount, 0);
|
||||
|
||||
method._new(className).dup();
|
||||
loadConstant(new RecompilableScriptFunctionData(functionNode, compiler.getCodeInstaller(), allocatorClassName, allocatorMap));
|
||||
|
||||
@ -405,32 +405,8 @@ public final class Compiler {
|
||||
return newFunctionNode;
|
||||
}
|
||||
|
||||
private Class<?> install(final String className, final byte[] code) {
|
||||
LOG.fine("Installing class ", className);
|
||||
|
||||
final Class<?> clazz = installer.install(Compiler.binaryName(className), code);
|
||||
|
||||
try {
|
||||
final Object[] constants = getConstantData().toArray();
|
||||
// Need doPrivileged because these fields are private
|
||||
AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
|
||||
@Override
|
||||
public Void run() throws Exception {
|
||||
//use reflection to write source and constants table to installed classes
|
||||
final Field sourceField = clazz.getDeclaredField(SOURCE.symbolName());
|
||||
final Field constantsField = clazz.getDeclaredField(CONSTANTS.symbolName());
|
||||
sourceField.setAccessible(true);
|
||||
constantsField.setAccessible(true);
|
||||
sourceField.set(null, source);
|
||||
constantsField.set(null, constants);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
} catch (final PrivilegedActionException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
return clazz;
|
||||
private Class<?> install(final String className, final byte[] code, final Object[] constants) {
|
||||
return installer.install(className, code, source, constants);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -444,10 +420,15 @@ public final class Compiler {
|
||||
assert functionNode.hasState(CompilationState.EMITTED) : functionNode.getName() + " has no bytecode and cannot be installed";
|
||||
|
||||
final Map<String, Class<?>> installedClasses = new HashMap<>();
|
||||
final Object[] constants = getConstantData().toArray();
|
||||
|
||||
final String rootClassName = firstCompileUnitName();
|
||||
final byte[] rootByteCode = bytecode.get(rootClassName);
|
||||
final Class<?> rootClass = install(rootClassName, rootByteCode);
|
||||
final Class<?> rootClass = install(rootClassName, rootByteCode, constants);
|
||||
|
||||
if (!isLazy()) {
|
||||
installer.storeCompiledScript(source, rootClassName, bytecode, constants);
|
||||
}
|
||||
|
||||
int length = rootByteCode.length;
|
||||
|
||||
@ -461,7 +442,7 @@ public final class Compiler {
|
||||
final byte[] code = entry.getValue();
|
||||
length += code.length;
|
||||
|
||||
installedClasses.put(className, install(className, code));
|
||||
installedClasses.put(className, install(className, code, constants));
|
||||
}
|
||||
|
||||
for (final CompileUnit unit : compileUnits) {
|
||||
|
||||
@ -83,7 +83,7 @@ public class MapCreator {
|
||||
}
|
||||
}
|
||||
|
||||
return PropertyMap.newMap(properties, fieldCount, fieldMaximum, 0);
|
||||
return PropertyMap.newMap(properties, structure.getName(), fieldCount, fieldMaximum, 0);
|
||||
}
|
||||
|
||||
PropertyMap makeSpillMap(final boolean hasArguments) {
|
||||
@ -100,7 +100,7 @@ public class MapCreator {
|
||||
}
|
||||
}
|
||||
|
||||
return PropertyMap.newMap(properties, 0, 0, spillIndex);
|
||||
return PropertyMap.newMap(properties, structure.getName(), 0, 0, spillIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -382,7 +382,7 @@ abstract class ArrayBufferView extends ScriptObject {
|
||||
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 int elementLength = arrayView.elementLength();
|
||||
final int begin = NativeArrayBuffer.adjustIndex(JSType.toInt32(begin0), elementLength);
|
||||
|
||||
@ -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.arrays.ArrayLikeIterator.arrayLikeIterator;
|
||||
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.util.ArrayList;
|
||||
@ -349,6 +350,27 @@ public final class NativeArray extends ScriptObject {
|
||||
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
|
||||
* representation
|
||||
@ -367,7 +389,7 @@ public final class NativeArray extends ScriptObject {
|
||||
* @return true if argument is an array
|
||||
*/
|
||||
@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());
|
||||
}
|
||||
|
||||
@ -466,7 +488,7 @@ public final class NativeArray extends ScriptObject {
|
||||
* @return locale specific string representation for array
|
||||
*/
|
||||
@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 Iterator<Object> iter = arrayLikeIterator(self, true);
|
||||
|
||||
@ -512,7 +534,7 @@ public final class NativeArray extends ScriptObject {
|
||||
* @return the new NativeArray
|
||||
*/
|
||||
@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) {
|
||||
case 0:
|
||||
return new NativeArray(0);
|
||||
@ -565,7 +587,7 @@ public final class NativeArray extends ScriptObject {
|
||||
* @return the new NativeArray
|
||||
*/
|
||||
@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);
|
||||
}
|
||||
|
||||
@ -580,7 +602,7 @@ public final class NativeArray extends ScriptObject {
|
||||
* @return the new NativeArray
|
||||
*/
|
||||
@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) {
|
||||
return new NativeArray(length);
|
||||
}
|
||||
@ -599,7 +621,7 @@ public final class NativeArray extends ScriptObject {
|
||||
* @return the new NativeArray
|
||||
*/
|
||||
@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) {
|
||||
return new NativeArray(length);
|
||||
}
|
||||
@ -618,7 +640,7 @@ public final class NativeArray extends ScriptObject {
|
||||
* @return the new NativeArray
|
||||
*/
|
||||
@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);
|
||||
|
||||
if (uint32length == length) {
|
||||
@ -636,7 +658,7 @@ public final class NativeArray extends ScriptObject {
|
||||
* @return resulting NativeArray
|
||||
*/
|
||||
@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<>();
|
||||
concatToList(list, Global.toObject(self));
|
||||
|
||||
@ -683,7 +705,7 @@ public final class NativeArray extends ScriptObject {
|
||||
* @return string representation after join
|
||||
*/
|
||||
@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 Iterator<Object> iter = arrayLikeIterator(self, true);
|
||||
final String sep = separator == ScriptRuntime.UNDEFINED ? "," : JSType.toString(separator);
|
||||
@ -951,7 +973,7 @@ public final class NativeArray extends ScriptObject {
|
||||
* @return sorted array
|
||||
*/
|
||||
@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 {
|
||||
final ScriptObject sobj = (ScriptObject) self;
|
||||
final long len = JSType.toUint32(sobj.getLength());
|
||||
@ -1155,7 +1177,7 @@ public final class NativeArray extends ScriptObject {
|
||||
* @return index of element, or -1 if not found
|
||||
*/
|
||||
@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 {
|
||||
final ScriptObject sobj = (ScriptObject)Global.toObject(self);
|
||||
final long len = JSType.toUint32(sobj.getLength());
|
||||
@ -1191,7 +1213,7 @@ public final class NativeArray extends ScriptObject {
|
||||
* @return index of element, or -1 if not found
|
||||
*/
|
||||
@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 {
|
||||
final ScriptObject sobj = (ScriptObject)Global.toObject(self);
|
||||
final long len = JSType.toUint32(sobj.getLength());
|
||||
@ -1226,7 +1248,7 @@ public final class NativeArray extends ScriptObject {
|
||||
* @return true if callback function return true for every element in the array, false otherwise
|
||||
*/
|
||||
@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);
|
||||
}
|
||||
|
||||
@ -1250,7 +1272,7 @@ public final class NativeArray extends ScriptObject {
|
||||
* @return true if callback function returned true for any element in the array, false otherwise
|
||||
*/
|
||||
@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) {
|
||||
private final MethodHandle someInvoker = getSOME_CALLBACK_INVOKER();
|
||||
|
||||
@ -1291,7 +1313,7 @@ public final class NativeArray extends ScriptObject {
|
||||
* @return array with elements transformed by map function
|
||||
*/
|
||||
@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) {
|
||||
private final MethodHandle mapInvoker = getMAP_CALLBACK_INVOKER();
|
||||
|
||||
@ -1320,7 +1342,7 @@ public final class NativeArray extends ScriptObject {
|
||||
* @return filtered array
|
||||
*/
|
||||
@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()) {
|
||||
private long to = 0;
|
||||
private final MethodHandle filterInvoker = getFILTER_CALLBACK_INVOKER();
|
||||
|
||||
@ -45,7 +45,7 @@ final class NativeArrayBuffer extends ScriptObject {
|
||||
private static PropertyMap $nasgenmap$;
|
||||
|
||||
@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) {
|
||||
throw new RuntimeException("missing length argument");
|
||||
}
|
||||
@ -81,7 +81,7 @@ final class NativeArrayBuffer extends ScriptObject {
|
||||
}
|
||||
|
||||
@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;
|
||||
int begin = JSType.toInt32(begin0);
|
||||
int end = end0 != ScriptRuntime.UNDEFINED ? JSType.toInt32(end0) : arrayBuffer.getByteLength();
|
||||
|
||||
@ -110,7 +110,7 @@ public final class NativeBoolean extends ScriptObject {
|
||||
* @return string representation of this boolean
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object toString(final Object self) {
|
||||
public static String toString(final Object self) {
|
||||
return getBoolean(self).toString();
|
||||
}
|
||||
|
||||
@ -121,7 +121,7 @@ public final class NativeBoolean extends ScriptObject {
|
||||
* @return value of this boolean
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object valueOf(final Object self) {
|
||||
public static boolean valueOf(final Object self) {
|
||||
return getBoolean(self);
|
||||
}
|
||||
|
||||
|
||||
@ -131,7 +131,7 @@ public class NativeDataView extends ScriptObject {
|
||||
* @return newly constructed DataView object
|
||||
*/
|
||||
@Constructor(arity = 1)
|
||||
public static Object constructor(final boolean newObj, final Object self, final Object... args) {
|
||||
public static NativeDataView constructor(final boolean newObj, final Object self, final Object... args) {
|
||||
if (args.length == 0 || !(args[0] instanceof NativeArrayBuffer)) {
|
||||
throw typeError("not.an.arraybuffer.in.dataview");
|
||||
}
|
||||
@ -157,7 +157,7 @@ public class NativeDataView extends ScriptObject {
|
||||
* @return newly constructed DataView object
|
||||
*/
|
||||
@SpecializedConstructor
|
||||
public static Object constructor(final boolean newObj, final Object self, final Object arrBuf, final int offset) {
|
||||
public static NativeDataView constructor(final boolean newObj, final Object self, final Object arrBuf, final int offset) {
|
||||
if (!(arrBuf instanceof NativeArrayBuffer)) {
|
||||
throw typeError("not.an.arraybuffer.in.dataview");
|
||||
}
|
||||
@ -175,7 +175,7 @@ public class NativeDataView extends ScriptObject {
|
||||
* @return newly constructed DataView object
|
||||
*/
|
||||
@SpecializedConstructor
|
||||
public static Object constructor(final boolean newObj, final Object self, final Object arrBuf, final int offset, final int length) {
|
||||
public static NativeDataView constructor(final boolean newObj, final Object self, final Object arrBuf, final int offset, final int length) {
|
||||
if (!(arrBuf instanceof NativeArrayBuffer)) {
|
||||
throw typeError("not.an.arraybuffer.in.dataview");
|
||||
}
|
||||
|
||||
@ -226,7 +226,7 @@ public final class NativeDate extends ScriptObject {
|
||||
* @return Date interpreted from the string, or NaN for illegal values
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
|
||||
public static Object parse(final Object self, final Object string) {
|
||||
public static double parse(final Object self, final Object string) {
|
||||
return parseDateString(JSType.toString(string));
|
||||
}
|
||||
|
||||
@ -238,7 +238,7 @@ public final class NativeDate extends ScriptObject {
|
||||
* @return a time clip according to the ECMA specification
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 7, where = Where.CONSTRUCTOR)
|
||||
public static Object UTC(final Object self, final Object... args) {
|
||||
public static double UTC(final Object self, final Object... args) {
|
||||
final NativeDate nd = new NativeDate(0);
|
||||
final double[] d = convertCtorArgs(args);
|
||||
final double time = d == null ? Double.NaN : timeClip(makeDate(d));
|
||||
@ -253,8 +253,8 @@ public final class NativeDate extends ScriptObject {
|
||||
* @return a Date that points to the current moment in time
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
|
||||
public static Object now(final Object self) {
|
||||
return (double)System.currentTimeMillis();
|
||||
public static long now(final Object self) {
|
||||
return System.currentTimeMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -264,7 +264,7 @@ public final class NativeDate extends ScriptObject {
|
||||
* @return string value that represents the Date in the current time zone
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object toString(final Object self) {
|
||||
public static String toString(final Object self) {
|
||||
return toStringImpl(self, FORMAT_DATE_TIME);
|
||||
}
|
||||
|
||||
@ -275,7 +275,7 @@ public final class NativeDate extends ScriptObject {
|
||||
* @return string value with the "date" part of the Date in the current time zone
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object toDateString(final Object self) {
|
||||
public static String toDateString(final Object self) {
|
||||
return toStringImpl(self, FORMAT_DATE);
|
||||
}
|
||||
|
||||
@ -286,7 +286,7 @@ public final class NativeDate extends ScriptObject {
|
||||
* @return string value with "time" part of Date in the current time zone
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object toTimeString(final Object self) {
|
||||
public static String toTimeString(final Object self) {
|
||||
return toStringImpl(self, FORMAT_TIME);
|
||||
}
|
||||
|
||||
@ -297,7 +297,7 @@ public final class NativeDate extends ScriptObject {
|
||||
* @return string value that represents the Data in the current time zone and locale
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object toLocaleString(final Object self) {
|
||||
public static String toLocaleString(final Object self) {
|
||||
return toStringImpl(self, FORMAT_LOCAL_DATE_TIME);
|
||||
}
|
||||
|
||||
@ -308,7 +308,7 @@ public final class NativeDate extends ScriptObject {
|
||||
* @return string value with the "date" part of the Date in the current time zone and locale
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object toLocaleDateString(final Object self) {
|
||||
public static String toLocaleDateString(final Object self) {
|
||||
return toStringImpl(self, FORMAT_LOCAL_DATE);
|
||||
}
|
||||
|
||||
@ -319,7 +319,7 @@ public final class NativeDate extends ScriptObject {
|
||||
* @return string value with the "time" part of Date in the current time zone and locale
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object toLocaleTimeString(final Object self) {
|
||||
public static String toLocaleTimeString(final Object self) {
|
||||
return toStringImpl(self, FORMAT_LOCAL_TIME);
|
||||
}
|
||||
|
||||
@ -330,7 +330,7 @@ public final class NativeDate extends ScriptObject {
|
||||
* @return valueOf - a number which is this time value
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object valueOf(final Object self) {
|
||||
public static double valueOf(final Object self) {
|
||||
final NativeDate nd = getNativeDate(self);
|
||||
return (nd != null) ? nd.getTime() : Double.NaN;
|
||||
}
|
||||
@ -342,7 +342,7 @@ public final class NativeDate extends ScriptObject {
|
||||
* @return time
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object getTime(final Object self) {
|
||||
public static double getTime(final Object self) {
|
||||
final NativeDate nd = getNativeDate(self);
|
||||
return (nd != null) ? nd.getTime() : Double.NaN;
|
||||
}
|
||||
@ -365,7 +365,7 @@ public final class NativeDate extends ScriptObject {
|
||||
* @return UTC full year
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object getUTCFullYear(final Object self) {
|
||||
public static double getUTCFullYear(final Object self) {
|
||||
return getUTCField(self, YEAR);
|
||||
}
|
||||
|
||||
@ -376,7 +376,7 @@ public final class NativeDate extends ScriptObject {
|
||||
* @return year
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object getYear(final Object self) {
|
||||
public static double getYear(final Object self) {
|
||||
final NativeDate nd = getNativeDate(self);
|
||||
return (nd != null && nd.isValidDate()) ? (yearFromTime(nd.getLocalTime()) - 1900) : Double.NaN;
|
||||
}
|
||||
@ -388,7 +388,7 @@ public final class NativeDate extends ScriptObject {
|
||||
* @return month
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object getMonth(final Object self) {
|
||||
public static double getMonth(final Object self) {
|
||||
return getField(self, MONTH);
|
||||
}
|
||||
|
||||
@ -399,7 +399,7 @@ public final class NativeDate extends ScriptObject {
|
||||
* @return UTC month
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object getUTCMonth(final Object self) {
|
||||
public static double getUTCMonth(final Object self) {
|
||||
return getUTCField(self, MONTH);
|
||||
}
|
||||
|
||||
@ -410,7 +410,7 @@ public final class NativeDate extends ScriptObject {
|
||||
* @return date
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object getDate(final Object self) {
|
||||
public static double getDate(final Object self) {
|
||||
return getField(self, DAY);
|
||||
}
|
||||
|
||||
@ -421,7 +421,7 @@ public final class NativeDate extends ScriptObject {
|
||||
* @return UTC Date
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object getUTCDate(final Object self) {
|
||||
public static double getUTCDate(final Object self) {
|
||||
return getUTCField(self, DAY);
|
||||
}
|
||||
|
||||
@ -432,7 +432,7 @@ public final class NativeDate extends ScriptObject {
|
||||
* @return day
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object getDay(final Object self) {
|
||||
public static double getDay(final Object self) {
|
||||
final NativeDate nd = getNativeDate(self);
|
||||
return (nd != null && nd.isValidDate()) ? weekDay(nd.getLocalTime()) : Double.NaN;
|
||||
}
|
||||
@ -444,7 +444,7 @@ public final class NativeDate extends ScriptObject {
|
||||
* @return UTC day
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object getUTCDay(final Object self) {
|
||||
public static double getUTCDay(final Object self) {
|
||||
final NativeDate nd = getNativeDate(self);
|
||||
return (nd != null && nd.isValidDate()) ? weekDay(nd.getTime()) : Double.NaN;
|
||||
}
|
||||
@ -456,7 +456,7 @@ public final class NativeDate extends ScriptObject {
|
||||
* @return hours
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object getHours(final Object self) {
|
||||
public static double getHours(final Object self) {
|
||||
return getField(self, HOUR);
|
||||
}
|
||||
|
||||
@ -467,7 +467,7 @@ public final class NativeDate extends ScriptObject {
|
||||
* @return UTC hours
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object getUTCHours(final Object self) {
|
||||
public static double getUTCHours(final Object self) {
|
||||
return getUTCField(self, HOUR);
|
||||
}
|
||||
|
||||
@ -478,7 +478,7 @@ public final class NativeDate extends ScriptObject {
|
||||
* @return minutes
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object getMinutes(final Object self) {
|
||||
public static double getMinutes(final Object self) {
|
||||
return getField(self, MINUTE);
|
||||
}
|
||||
|
||||
@ -489,7 +489,7 @@ public final class NativeDate extends ScriptObject {
|
||||
* @return UTC minutes
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object getUTCMinutes(final Object self) {
|
||||
public static double getUTCMinutes(final Object self) {
|
||||
return getUTCField(self, MINUTE);
|
||||
}
|
||||
|
||||
@ -500,7 +500,7 @@ public final class NativeDate extends ScriptObject {
|
||||
* @return seconds
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object getSeconds(final Object self) {
|
||||
public static double getSeconds(final Object self) {
|
||||
return getField(self, SECOND);
|
||||
}
|
||||
|
||||
@ -511,7 +511,7 @@ public final class NativeDate extends ScriptObject {
|
||||
* @return UTC seconds
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object getUTCSeconds(final Object self) {
|
||||
public static double getUTCSeconds(final Object self) {
|
||||
return getUTCField(self, SECOND);
|
||||
}
|
||||
|
||||
@ -522,7 +522,7 @@ public final class NativeDate extends ScriptObject {
|
||||
* @return milliseconds
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object getMilliseconds(final Object self) {
|
||||
public static double getMilliseconds(final Object self) {
|
||||
return getField(self, MILLISECOND);
|
||||
}
|
||||
|
||||
@ -533,7 +533,7 @@ public final class NativeDate extends ScriptObject {
|
||||
* @return UTC milliseconds
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object getUTCMilliseconds(final Object self) {
|
||||
public static double getUTCMilliseconds(final Object self) {
|
||||
return getUTCField(self, MILLISECOND);
|
||||
}
|
||||
|
||||
@ -544,7 +544,7 @@ public final class NativeDate extends ScriptObject {
|
||||
* @return time zone offset or NaN if N/A
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object getTimezoneOffset(final Object self) {
|
||||
public static double getTimezoneOffset(final Object self) {
|
||||
final NativeDate nd = getNativeDate(self);
|
||||
if (nd != null && nd.isValidDate()) {
|
||||
final long msec = (long) nd.getTime();
|
||||
@ -561,7 +561,7 @@ public final class NativeDate extends ScriptObject {
|
||||
* @return time
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object setTime(final Object self, final Object time) {
|
||||
public static double setTime(final Object self, final Object time) {
|
||||
final NativeDate nd = getNativeDate(self);
|
||||
final double num = timeClip(JSType.toNumber(time));
|
||||
nd.setTime(num);
|
||||
@ -576,7 +576,7 @@ public final class NativeDate extends ScriptObject {
|
||||
* @return time
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
|
||||
public static Object setMilliseconds(final Object self, final Object... args) {
|
||||
public static double setMilliseconds(final Object self, final Object... args) {
|
||||
final NativeDate nd = getNativeDate(self);
|
||||
setFields(nd, MILLISECOND, args, true);
|
||||
return nd.getTime();
|
||||
@ -590,7 +590,7 @@ public final class NativeDate extends ScriptObject {
|
||||
* @return time
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
|
||||
public static Object setUTCMilliseconds(final Object self, final Object... args) {
|
||||
public static double setUTCMilliseconds(final Object self, final Object... args) {
|
||||
final NativeDate nd = getNativeDate(self);
|
||||
setFields(nd, MILLISECOND, args, false);
|
||||
return nd.getTime();
|
||||
@ -604,7 +604,7 @@ public final class NativeDate extends ScriptObject {
|
||||
* @return time
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 2)
|
||||
public static Object setSeconds(final Object self, final Object... args) {
|
||||
public static double setSeconds(final Object self, final Object... args) {
|
||||
final NativeDate nd = getNativeDate(self);
|
||||
setFields(nd, SECOND, args, true);
|
||||
return nd.getTime();
|
||||
@ -618,7 +618,7 @@ public final class NativeDate extends ScriptObject {
|
||||
* @return time
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 2)
|
||||
public static Object setUTCSeconds(final Object self, final Object... args) {
|
||||
public static double setUTCSeconds(final Object self, final Object... args) {
|
||||
final NativeDate nd = getNativeDate(self);
|
||||
setFields(nd, SECOND, args, false);
|
||||
return nd.getTime();
|
||||
@ -632,7 +632,7 @@ public final class NativeDate extends ScriptObject {
|
||||
* @return time
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 3)
|
||||
public static Object setMinutes(final Object self, final Object... args) {
|
||||
public static double setMinutes(final Object self, final Object... args) {
|
||||
final NativeDate nd = getNativeDate(self);
|
||||
setFields(nd, MINUTE, args, true);
|
||||
return nd.getTime();
|
||||
@ -646,7 +646,7 @@ public final class NativeDate extends ScriptObject {
|
||||
* @return time
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 3)
|
||||
public static Object setUTCMinutes(final Object self, final Object... args) {
|
||||
public static double setUTCMinutes(final Object self, final Object... args) {
|
||||
final NativeDate nd = getNativeDate(self);
|
||||
setFields(nd, MINUTE, args, false);
|
||||
return nd.getTime();
|
||||
@ -660,7 +660,7 @@ public final class NativeDate extends ScriptObject {
|
||||
* @return time
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 4)
|
||||
public static Object setHours(final Object self, final Object... args) {
|
||||
public static double setHours(final Object self, final Object... args) {
|
||||
final NativeDate nd = getNativeDate(self);
|
||||
setFields(nd, HOUR, args, true);
|
||||
return nd.getTime();
|
||||
@ -674,7 +674,7 @@ public final class NativeDate extends ScriptObject {
|
||||
* @return time
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 4)
|
||||
public static Object setUTCHours(final Object self, final Object... args) {
|
||||
public static double setUTCHours(final Object self, final Object... args) {
|
||||
final NativeDate nd = getNativeDate(self);
|
||||
setFields(nd, HOUR, args, false);
|
||||
return nd.getTime();
|
||||
@ -688,7 +688,7 @@ public final class NativeDate extends ScriptObject {
|
||||
* @return time
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
|
||||
public static Object setDate(final Object self, final Object... args) {
|
||||
public static double setDate(final Object self, final Object... args) {
|
||||
final NativeDate nd = getNativeDate(self);
|
||||
setFields(nd, DAY, args, true);
|
||||
return nd.getTime();
|
||||
@ -702,7 +702,7 @@ public final class NativeDate extends ScriptObject {
|
||||
* @return time
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
|
||||
public static Object setUTCDate(final Object self, final Object... args) {
|
||||
public static double setUTCDate(final Object self, final Object... args) {
|
||||
final NativeDate nd = getNativeDate(self);
|
||||
setFields(nd, DAY, args, false);
|
||||
return nd.getTime();
|
||||
@ -716,7 +716,7 @@ public final class NativeDate extends ScriptObject {
|
||||
* @return time
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 2)
|
||||
public static Object setMonth(final Object self, final Object... args) {
|
||||
public static double setMonth(final Object self, final Object... args) {
|
||||
final NativeDate nd = getNativeDate(self);
|
||||
setFields(nd, MONTH, args, true);
|
||||
return nd.getTime();
|
||||
@ -730,7 +730,7 @@ public final class NativeDate extends ScriptObject {
|
||||
* @return time
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 2)
|
||||
public static Object setUTCMonth(final Object self, final Object... args) {
|
||||
public static double setUTCMonth(final Object self, final Object... args) {
|
||||
final NativeDate nd = ensureNativeDate(self);
|
||||
setFields(nd, MONTH, args, false);
|
||||
return nd.getTime();
|
||||
@ -744,7 +744,7 @@ public final class NativeDate extends ScriptObject {
|
||||
* @return time
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 3)
|
||||
public static Object setFullYear(final Object self, final Object... args) {
|
||||
public static double setFullYear(final Object self, final Object... args) {
|
||||
final NativeDate nd = ensureNativeDate(self);
|
||||
if (nd.isValidDate()) {
|
||||
setFields(nd, YEAR, args, true);
|
||||
@ -767,7 +767,7 @@ public final class NativeDate extends ScriptObject {
|
||||
* @return time
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 3)
|
||||
public static Object setUTCFullYear(final Object self, final Object... args) {
|
||||
public static double setUTCFullYear(final Object self, final Object... args) {
|
||||
final NativeDate nd = ensureNativeDate(self);
|
||||
if (nd.isValidDate()) {
|
||||
setFields(nd, YEAR, args, false);
|
||||
@ -786,7 +786,7 @@ public final class NativeDate extends ScriptObject {
|
||||
* @return NativeDate
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object setYear(final Object self, final Object year) {
|
||||
public static double setYear(final Object self, final Object year) {
|
||||
final NativeDate nd = getNativeDate(self);
|
||||
if (isNaN(nd.getTime())) {
|
||||
nd.setTime(utc(0, nd.getTimeZone()));
|
||||
@ -813,7 +813,7 @@ public final class NativeDate extends ScriptObject {
|
||||
* @return string representation of date
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object toUTCString(final Object self) {
|
||||
public static String toUTCString(final Object self) {
|
||||
return toGMTStringImpl(self);
|
||||
}
|
||||
|
||||
@ -826,7 +826,7 @@ public final class NativeDate extends ScriptObject {
|
||||
* @return string representation of date
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object toGMTString(final Object self) {
|
||||
public static String toGMTString(final Object self) {
|
||||
return toGMTStringImpl(self);
|
||||
}
|
||||
|
||||
@ -837,7 +837,7 @@ public final class NativeDate extends ScriptObject {
|
||||
* @return string representation of date
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object toISOString(final Object self) {
|
||||
public static String toISOString(final Object self) {
|
||||
return toISOStringImpl(self);
|
||||
}
|
||||
|
||||
@ -1282,14 +1282,14 @@ public final class NativeDate extends ScriptObject {
|
||||
}
|
||||
}
|
||||
|
||||
private static Object getField(final Object self, final int field) {
|
||||
private static double getField(final Object self, final int field) {
|
||||
final NativeDate nd = getNativeDate(self);
|
||||
return (nd != null && nd.isValidDate()) ? valueFromTime(field, nd.getLocalTime()) : Double.NaN;
|
||||
return (nd != null && nd.isValidDate()) ? (double)valueFromTime(field, nd.getLocalTime()) : Double.NaN;
|
||||
}
|
||||
|
||||
private static Object getUTCField(final Object self, final int field) {
|
||||
private static double getUTCField(final Object self, final int field) {
|
||||
final NativeDate nd = getNativeDate(self);
|
||||
return (nd != null && nd.isValidDate()) ? valueFromTime(field, nd.getTime()) : Double.NaN;
|
||||
return (nd != null && nd.isValidDate()) ? (double)valueFromTime(field, nd.getTime()) : Double.NaN;
|
||||
}
|
||||
|
||||
private static void setFields(final NativeDate nd, final int fieldId, final Object[] args, final boolean local) {
|
||||
@ -1344,5 +1344,4 @@ public final class NativeDate extends ScriptObject {
|
||||
private TimeZone getTimeZone() {
|
||||
return timezone;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -116,7 +116,7 @@ public final class NativeDebug extends ScriptObject {
|
||||
* @return true if reference identity
|
||||
*/
|
||||
@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;
|
||||
}
|
||||
|
||||
@ -144,7 +144,7 @@ public final class NativeDebug extends ScriptObject {
|
||||
* @return return {@link Object#equals(Object)} for objects.
|
||||
*/
|
||||
@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);
|
||||
}
|
||||
|
||||
@ -156,7 +156,7 @@ public final class NativeDebug extends ScriptObject {
|
||||
* @return Java string representation of {@code obj}
|
||||
*/
|
||||
@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);
|
||||
}
|
||||
|
||||
@ -168,7 +168,7 @@ public final class NativeDebug extends ScriptObject {
|
||||
* @return string representation
|
||||
*/
|
||||
@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) {
|
||||
return "null";
|
||||
}
|
||||
@ -185,7 +185,7 @@ public final class NativeDebug extends ScriptObject {
|
||||
* @return listener count
|
||||
*/
|
||||
@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) ? PropertyListeners.getListenerCount((ScriptObject) obj) : 0;
|
||||
}
|
||||
|
||||
|
||||
@ -126,7 +126,7 @@ public final class NativeError extends ScriptObject {
|
||||
* @return NativeError instance
|
||||
*/
|
||||
@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);
|
||||
}
|
||||
|
||||
|
||||
@ -98,7 +98,7 @@ public final class NativeEvalError extends ScriptObject {
|
||||
* @return new 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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -136,8 +136,8 @@ public final class NativeFloat32Array extends ArrayBufferView {
|
||||
* @return new typed array
|
||||
*/
|
||||
@Constructor(arity = 1)
|
||||
public static Object constructor(final boolean newObj, final Object self, final Object... args) {
|
||||
return constructorImpl(args, FACTORY);
|
||||
public static NativeFloat32Array constructor(final boolean newObj, final Object self, final Object... args) {
|
||||
return (NativeFloat32Array)constructorImpl(args, FACTORY);
|
||||
}
|
||||
|
||||
NativeFloat32Array(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
|
||||
@ -192,8 +192,8 @@ public final class NativeFloat32Array extends ArrayBufferView {
|
||||
* @return sub array
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
protected static Object subarray(final Object self, final Object begin, final Object end) {
|
||||
return ArrayBufferView.subarrayImpl(self, begin, end);
|
||||
protected static NativeFloat32Array subarray(final Object self, final Object begin, final Object end) {
|
||||
return (NativeFloat32Array)ArrayBufferView.subarrayImpl(self, begin, end);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -146,8 +146,8 @@ public final class NativeFloat64Array extends ArrayBufferView {
|
||||
* @return new typed array
|
||||
*/
|
||||
@Constructor(arity = 1)
|
||||
public static Object constructor(final boolean newObj, final Object self, final Object... args) {
|
||||
return constructorImpl(args, FACTORY);
|
||||
public static NativeFloat64Array constructor(final boolean newObj, final Object self, final Object... args) {
|
||||
return (NativeFloat64Array)constructorImpl(args, FACTORY);
|
||||
}
|
||||
|
||||
NativeFloat64Array(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
|
||||
@ -202,8 +202,8 @@ public final class NativeFloat64Array extends ArrayBufferView {
|
||||
* @return sub array
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
protected static Object subarray(final Object self, final Object begin, final Object end) {
|
||||
return ArrayBufferView.subarrayImpl(self, begin, end);
|
||||
protected static NativeFloat64Array subarray(final Object self, final Object begin, final Object end) {
|
||||
return (NativeFloat64Array)ArrayBufferView.subarrayImpl(self, begin, end);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -71,7 +71,7 @@ public final class NativeFunction {
|
||||
* @return string representation of Function
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object toString(final Object self) {
|
||||
public static String toString(final Object self) {
|
||||
if (!(self instanceof ScriptFunction)) {
|
||||
throw typeError("not.a.function", ScriptRuntime.safeToString(self));
|
||||
}
|
||||
@ -174,7 +174,7 @@ public final class NativeFunction {
|
||||
* @return function with bound arguments
|
||||
*/
|
||||
@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)) {
|
||||
throw typeError("not.a.function", ScriptRuntime.safeToString(self));
|
||||
}
|
||||
@ -199,7 +199,7 @@ public final class NativeFunction {
|
||||
* @return source for function
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object toSource(final Object self) {
|
||||
public static String toSource(final Object self) {
|
||||
if (!(self instanceof ScriptFunction)) {
|
||||
throw typeError("not.a.function", ScriptRuntime.safeToString(self));
|
||||
}
|
||||
@ -217,7 +217,7 @@ public final class NativeFunction {
|
||||
* @return new NativeFunction
|
||||
*/
|
||||
@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();
|
||||
|
||||
sb.append("(function (");
|
||||
@ -253,7 +253,7 @@ public final class NativeFunction {
|
||||
|
||||
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) {
|
||||
|
||||
@ -100,8 +100,8 @@ public final class NativeInt16Array extends ArrayBufferView {
|
||||
* @return new typed array
|
||||
*/
|
||||
@Constructor(arity = 1)
|
||||
public static Object constructor(final boolean newObj, final Object self, final Object... args) {
|
||||
return constructorImpl(args, FACTORY);
|
||||
public static NativeInt16Array constructor(final boolean newObj, final Object self, final Object... args) {
|
||||
return (NativeInt16Array)constructorImpl(args, FACTORY);
|
||||
}
|
||||
|
||||
NativeInt16Array(final NativeArrayBuffer buffer, final int byteOffset, final int byteLength) {
|
||||
@ -151,8 +151,8 @@ public final class NativeInt16Array extends ArrayBufferView {
|
||||
* @return sub array
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
protected static Object subarray(final Object self, final Object begin, final Object end) {
|
||||
return ArrayBufferView.subarrayImpl(self, begin, end);
|
||||
protected static NativeInt16Array subarray(final Object self, final Object begin, final Object end) {
|
||||
return (NativeInt16Array)ArrayBufferView.subarrayImpl(self, begin, end);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -103,8 +103,8 @@ public final class NativeInt32Array extends ArrayBufferView {
|
||||
* @return new typed array
|
||||
*/
|
||||
@Constructor(arity = 1)
|
||||
public static Object constructor(final boolean newObj, final Object self, final Object... args) {
|
||||
return constructorImpl(args, FACTORY);
|
||||
public static NativeInt32Array constructor(final boolean newObj, final Object self, final Object... args) {
|
||||
return (NativeInt32Array)constructorImpl(args, FACTORY);
|
||||
}
|
||||
|
||||
NativeInt32Array(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
|
||||
@ -154,8 +154,8 @@ public final class NativeInt32Array extends ArrayBufferView {
|
||||
* @return sub array
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
protected static Object subarray(final Object self, final Object begin, final Object end) {
|
||||
return ArrayBufferView.subarrayImpl(self, begin, end);
|
||||
protected static NativeInt32Array subarray(final Object self, final Object begin, final Object end) {
|
||||
return (NativeInt32Array)ArrayBufferView.subarrayImpl(self, begin, end);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -93,8 +93,8 @@ public final class NativeInt8Array extends ArrayBufferView {
|
||||
* @return new typed array
|
||||
*/
|
||||
@Constructor(arity = 1)
|
||||
public static Object constructor(final boolean newObj, final Object self, final Object... args) {
|
||||
return constructorImpl(args, FACTORY);
|
||||
public static NativeInt8Array constructor(final boolean newObj, final Object self, final Object... args) {
|
||||
return (NativeInt8Array)constructorImpl(args, FACTORY);
|
||||
}
|
||||
|
||||
NativeInt8Array(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
|
||||
@ -144,8 +144,8 @@ public final class NativeInt8Array extends ArrayBufferView {
|
||||
* @return sub array
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
protected static Object subarray(final Object self, final Object begin, final Object end) {
|
||||
return ArrayBufferView.subarrayImpl(self, begin, end);
|
||||
protected static NativeInt8Array subarray(final Object self, final Object begin, final Object end) {
|
||||
return (NativeInt8Array)ArrayBufferView.subarrayImpl(self, begin, end);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -536,7 +536,7 @@ public final class NativeJSAdapter extends ScriptObject {
|
||||
* @return new NativeJSAdapter
|
||||
*/
|
||||
@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 overrides = UNDEFINED;
|
||||
Object adaptee;
|
||||
|
||||
@ -75,7 +75,7 @@ public final class NativeJava {
|
||||
* @see #type(Object, Object)
|
||||
*/
|
||||
@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;
|
||||
}
|
||||
|
||||
@ -338,7 +338,7 @@ public final class NativeJava {
|
||||
* null.
|
||||
*/
|
||||
@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) {
|
||||
return null;
|
||||
} else if (objArray instanceof Collection) {
|
||||
|
||||
@ -86,7 +86,7 @@ public final class NativeJavaImporter extends ScriptObject {
|
||||
* @return NativeJavaImporter instance
|
||||
*/
|
||||
@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);
|
||||
}
|
||||
|
||||
|
||||
@ -185,7 +185,7 @@ public final class NativeNumber extends ScriptObject {
|
||||
* @return number in decimal fixed point notation
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object toFixed(final Object self, final Object fractionDigits) {
|
||||
public static String toFixed(final Object self, final Object fractionDigits) {
|
||||
final int f = JSType.toInteger(fractionDigits);
|
||||
if (f < 0 || f > 20) {
|
||||
throw rangeError("invalid.fraction.digits", "toFixed");
|
||||
@ -217,7 +217,7 @@ public final class NativeNumber extends ScriptObject {
|
||||
* @return number in decimal exponential notation
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object toExponential(final Object self, final Object fractionDigits) {
|
||||
public static String toExponential(final Object self, final Object fractionDigits) {
|
||||
final double x = getNumberValue(self);
|
||||
final boolean trimZeros = fractionDigits == UNDEFINED;
|
||||
final int f = trimZeros ? 16 : JSType.toInteger(fractionDigits);
|
||||
@ -245,7 +245,7 @@ public final class NativeNumber extends ScriptObject {
|
||||
* @return number in decimal exponentiation notation or decimal fixed notation depending on {@code precision}
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object toPrecision(final Object self, final Object precision) {
|
||||
public static String toPrecision(final Object self, final Object precision) {
|
||||
final double x = getNumberValue(self);
|
||||
if (precision == UNDEFINED) {
|
||||
return JSType.toString(x);
|
||||
@ -278,7 +278,7 @@ public final class NativeNumber extends ScriptObject {
|
||||
* @return string representation of this Number in the given radix
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object toString(final Object self, final Object radix) {
|
||||
public static String toString(final Object self, final Object radix) {
|
||||
if (radix != UNDEFINED) {
|
||||
final int intRadix = JSType.toInteger(radix);
|
||||
if (intRadix != 10) {
|
||||
@ -299,7 +299,7 @@ public final class NativeNumber extends ScriptObject {
|
||||
* @return localized string for this Number
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object toLocaleString(final Object self) {
|
||||
public static String toLocaleString(final Object self) {
|
||||
return JSType.toString(getNumberValue(self));
|
||||
}
|
||||
|
||||
@ -308,10 +308,10 @@ public final class NativeNumber extends ScriptObject {
|
||||
* ECMA 15.7.4.4 Number.prototype.valueOf ( )
|
||||
*
|
||||
* @param self self reference
|
||||
* @return boxed number value for this Number
|
||||
* @return number value for this Number
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object valueOf(final Object self) {
|
||||
public static double valueOf(final Object self) {
|
||||
return getNumberValue(self);
|
||||
}
|
||||
|
||||
|
||||
@ -111,7 +111,7 @@ public final class NativeObject {
|
||||
* @return the 'obj' object
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
|
||||
public static Object setIndexedPropertiesToExternalArrayData(final Object self, final Object obj, final Object buf) {
|
||||
public static ScriptObject setIndexedPropertiesToExternalArrayData(final Object self, final Object obj, final Object buf) {
|
||||
Global.checkObject(obj);
|
||||
final ScriptObject sobj = (ScriptObject)obj;
|
||||
if (buf instanceof ByteBuffer) {
|
||||
@ -203,7 +203,7 @@ public final class NativeObject {
|
||||
* @return array of property names
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
|
||||
public static Object getOwnPropertyNames(final Object self, final Object obj) {
|
||||
public static ScriptObject getOwnPropertyNames(final Object self, final Object obj) {
|
||||
if (obj instanceof ScriptObject) {
|
||||
return new NativeArray(((ScriptObject)obj).getOwnKeys(true));
|
||||
} else if (obj instanceof ScriptObjectMirror) {
|
||||
@ -222,7 +222,7 @@ public final class NativeObject {
|
||||
* @return object created
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
|
||||
public static Object create(final Object self, final Object proto, final Object props) {
|
||||
public static ScriptObject create(final Object self, final Object proto, final Object props) {
|
||||
if (proto != null) {
|
||||
Global.checkObject(proto);
|
||||
}
|
||||
@ -248,10 +248,11 @@ public final class NativeObject {
|
||||
* @return object
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
|
||||
public static Object defineProperty(final Object self, final Object obj, final Object prop, final Object attr) {
|
||||
public static ScriptObject defineProperty(final Object self, final Object obj, final Object prop, final Object attr) {
|
||||
Global.checkObject(obj);
|
||||
((ScriptObject)obj).defineOwnProperty(JSType.toString(prop), attr, true);
|
||||
return obj;
|
||||
final ScriptObject sobj = (ScriptObject)obj;
|
||||
sobj.defineOwnProperty(JSType.toString(prop), attr, true);
|
||||
return sobj;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -263,7 +264,7 @@ public final class NativeObject {
|
||||
* @return object
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
|
||||
public static Object defineProperties(final Object self, final Object obj, final Object props) {
|
||||
public static ScriptObject defineProperties(final Object self, final Object obj, final Object props) {
|
||||
Global.checkObject(obj);
|
||||
|
||||
final ScriptObject sobj = (ScriptObject)obj;
|
||||
@ -342,7 +343,7 @@ public final class NativeObject {
|
||||
* @return true if sealed, false otherwise
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
|
||||
public static Object isSealed(final Object self, final Object obj) {
|
||||
public static boolean isSealed(final Object self, final Object obj) {
|
||||
if (obj instanceof ScriptObject) {
|
||||
return ((ScriptObject)obj).isSealed();
|
||||
} else if (obj instanceof ScriptObjectMirror) {
|
||||
@ -360,7 +361,7 @@ public final class NativeObject {
|
||||
* @return true if object is frozen, false otherwise
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
|
||||
public static Object isFrozen(final Object self, final Object obj) {
|
||||
public static boolean isFrozen(final Object self, final Object obj) {
|
||||
if (obj instanceof ScriptObject) {
|
||||
return ((ScriptObject)obj).isFrozen();
|
||||
} else if (obj instanceof ScriptObjectMirror) {
|
||||
@ -378,7 +379,7 @@ public final class NativeObject {
|
||||
* @return true if object is extensible, false otherwise
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
|
||||
public static Object isExtensible(final Object self, final Object obj) {
|
||||
public static boolean isExtensible(final Object self, final Object obj) {
|
||||
if (obj instanceof ScriptObject) {
|
||||
return ((ScriptObject)obj).isExtensible();
|
||||
} else if (obj instanceof ScriptObjectMirror) {
|
||||
@ -396,7 +397,7 @@ public final class NativeObject {
|
||||
* @return array of keys in object
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
|
||||
public static Object keys(final Object self, final Object obj) {
|
||||
public static ScriptObject keys(final Object self, final Object obj) {
|
||||
if (obj instanceof ScriptObject) {
|
||||
final ScriptObject sobj = (ScriptObject)obj;
|
||||
return new NativeArray(sobj.getOwnKeys(false));
|
||||
@ -453,7 +454,7 @@ public final class NativeObject {
|
||||
* @return ToString of object
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object toString(final Object self) {
|
||||
public static String toString(final Object self) {
|
||||
return ScriptRuntime.builtinObjectToString(self);
|
||||
}
|
||||
|
||||
@ -506,7 +507,7 @@ public final class NativeObject {
|
||||
* @return true if property exists in object
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object hasOwnProperty(final Object self, final Object v) {
|
||||
public static boolean hasOwnProperty(final Object self, final Object v) {
|
||||
// Convert ScriptObjects to primitive with String.class hint
|
||||
// but no need to convert other primitives to string.
|
||||
final Object key = JSType.toPrimitive(v, String.class);
|
||||
@ -523,7 +524,7 @@ public final class NativeObject {
|
||||
* @return true if object is prototype of v
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object isPrototypeOf(final Object self, final Object v) {
|
||||
public static boolean isPrototypeOf(final Object self, final Object v) {
|
||||
if (!(v instanceof ScriptObject)) {
|
||||
return false;
|
||||
}
|
||||
@ -549,7 +550,7 @@ public final class NativeObject {
|
||||
* @return true if property is enumerable
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object propertyIsEnumerable(final Object self, final Object v) {
|
||||
public static boolean propertyIsEnumerable(final Object self, final Object v) {
|
||||
final String str = JSType.toString(v);
|
||||
final Object obj = Global.toObject(self);
|
||||
|
||||
|
||||
@ -98,7 +98,7 @@ public final class NativeRangeError extends ScriptObject {
|
||||
* @return new 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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -98,7 +98,7 @@ public final class NativeReferenceError extends ScriptObject {
|
||||
* @return new 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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -122,7 +122,7 @@ public final class NativeRegExp extends ScriptObject {
|
||||
* @return new NativeRegExp
|
||||
*/
|
||||
@Constructor(arity = 2)
|
||||
public static Object constructor(final boolean isNew, final Object self, final Object... args) {
|
||||
public static NativeRegExp constructor(final boolean isNew, final Object self, final Object... args) {
|
||||
if (args.length > 1) {
|
||||
return newRegExp(args[0], args[1]);
|
||||
} else if (args.length > 0) {
|
||||
@ -142,7 +142,7 @@ public final class NativeRegExp extends ScriptObject {
|
||||
* @return new NativeRegExp
|
||||
*/
|
||||
@SpecializedConstructor
|
||||
public static Object constructor(final boolean isNew, final Object self) {
|
||||
public static NativeRegExp constructor(final boolean isNew, final Object self) {
|
||||
return new NativeRegExp("", "");
|
||||
}
|
||||
|
||||
@ -157,7 +157,7 @@ public final class NativeRegExp extends ScriptObject {
|
||||
* @return new NativeRegExp
|
||||
*/
|
||||
@SpecializedConstructor
|
||||
public static Object constructor(final boolean isNew, final Object self, final Object pattern) {
|
||||
public static NativeRegExp constructor(final boolean isNew, final Object self, final Object pattern) {
|
||||
return newRegExp(pattern, UNDEFINED);
|
||||
}
|
||||
|
||||
@ -173,7 +173,7 @@ public final class NativeRegExp extends ScriptObject {
|
||||
* @return new NativeRegExp
|
||||
*/
|
||||
@SpecializedConstructor
|
||||
public static Object constructor(final boolean isNew, final Object self, final Object pattern, final Object flags) {
|
||||
public static NativeRegExp constructor(final boolean isNew, final Object self, final Object pattern, final Object flags) {
|
||||
return newRegExp(pattern, flags);
|
||||
}
|
||||
|
||||
@ -283,7 +283,7 @@ public final class NativeRegExp extends ScriptObject {
|
||||
* @return new NativeRegExp
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object compile(final Object self, final Object pattern, final Object flags) {
|
||||
public static ScriptObject compile(final Object self, final Object pattern, final Object flags) {
|
||||
final NativeRegExp regExp = checkRegExp(self);
|
||||
final NativeRegExp compiled = newRegExp(pattern, flags);
|
||||
// copy over regexp to 'self'
|
||||
@ -302,7 +302,7 @@ public final class NativeRegExp extends ScriptObject {
|
||||
* @return array containing the matches or {@code null} if no match
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object exec(final Object self, final Object string) {
|
||||
public static ScriptObject exec(final Object self, final Object string) {
|
||||
return checkRegExp(self).exec(JSType.toString(string));
|
||||
}
|
||||
|
||||
@ -314,7 +314,7 @@ public final class NativeRegExp extends ScriptObject {
|
||||
* @return true if matches found, false otherwise
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object test(final Object self, final Object string) {
|
||||
public static boolean test(final Object self, final Object string) {
|
||||
return checkRegExp(self).test(JSType.toString(string));
|
||||
}
|
||||
|
||||
@ -325,7 +325,7 @@ public final class NativeRegExp extends ScriptObject {
|
||||
* @return string version of regexp
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object toString(final Object self) {
|
||||
public static String toString(final Object self) {
|
||||
return checkRegExp(self).toString();
|
||||
}
|
||||
|
||||
@ -618,7 +618,7 @@ public final class NativeRegExp extends ScriptObject {
|
||||
* @param string String to match.
|
||||
* @return NativeArray of matches, string or null.
|
||||
*/
|
||||
public Object exec(final String string) {
|
||||
public NativeRegExpExecResult exec(final String string) {
|
||||
final RegExpResult match = execInner(string);
|
||||
|
||||
if (match == null) {
|
||||
@ -635,7 +635,7 @@ public final class NativeRegExp extends ScriptObject {
|
||||
* @param string String to match.
|
||||
* @return True if a match is found.
|
||||
*/
|
||||
public Object test(final String string) {
|
||||
public boolean test(final String string) {
|
||||
return execInner(string) != null;
|
||||
}
|
||||
|
||||
@ -649,7 +649,7 @@ public final class NativeRegExp extends ScriptObject {
|
||||
* @param replacement Replacement string.
|
||||
* @return String with substitutions.
|
||||
*/
|
||||
Object replace(final String string, final String replacement, final ScriptFunction function) {
|
||||
String replace(final String string, final String replacement, final ScriptFunction function) {
|
||||
final RegExpMatcher matcher = regexp.match(string);
|
||||
|
||||
if (matcher == null) {
|
||||
@ -804,7 +804,7 @@ public final class NativeRegExp extends ScriptObject {
|
||||
* @param limit Split limit.
|
||||
* @return Array of substrings.
|
||||
*/
|
||||
Object split(final String string, final long limit) {
|
||||
NativeArray split(final String string, final long limit) {
|
||||
if (limit == 0L) {
|
||||
return new NativeArray();
|
||||
}
|
||||
@ -867,7 +867,7 @@ public final class NativeRegExp extends ScriptObject {
|
||||
* @param string String to match.
|
||||
* @return Index of match.
|
||||
*/
|
||||
Object search(final String string) {
|
||||
int search(final String string) {
|
||||
final RegExpResult match = execInner(string);
|
||||
|
||||
if (match == null) {
|
||||
|
||||
@ -425,7 +425,7 @@ public final class NativeString extends ScriptObject {
|
||||
* @return string with arguments translated to charcodes
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1, where = Where.CONSTRUCTOR)
|
||||
public static Object fromCharCode(final Object self, final Object... args) {
|
||||
public static String fromCharCode(final Object self, final Object... args) {
|
||||
final char[] buf = new char[args.length];
|
||||
int index = 0;
|
||||
for (final Object arg : args) {
|
||||
@ -441,7 +441,7 @@ public final class NativeString extends ScriptObject {
|
||||
* @return string with one charcode
|
||||
*/
|
||||
@SpecializedFunction
|
||||
public static Object fromCharCode(final Object self, final Object value) {
|
||||
public static String fromCharCode(final Object self, final Object value) {
|
||||
try {
|
||||
return "" + (char)JSType.toUint16(((Number)value).doubleValue());
|
||||
} catch (final ClassCastException e) {
|
||||
@ -456,7 +456,7 @@ public final class NativeString extends ScriptObject {
|
||||
* @return string with one charcode
|
||||
*/
|
||||
@SpecializedFunction
|
||||
public static Object fromCharCode(final Object self, final int value) {
|
||||
public static String fromCharCode(final Object self, final int value) {
|
||||
return "" + (char)(value & 0xffff);
|
||||
}
|
||||
|
||||
@ -467,7 +467,7 @@ public final class NativeString extends ScriptObject {
|
||||
* @return string with one charcode
|
||||
*/
|
||||
@SpecializedFunction
|
||||
public static Object fromCharCode(final Object self, final long value) {
|
||||
public static String fromCharCode(final Object self, final long value) {
|
||||
return "" + (char)((int)value & 0xffff);
|
||||
}
|
||||
|
||||
@ -478,7 +478,7 @@ public final class NativeString extends ScriptObject {
|
||||
* @return string with one charcode
|
||||
*/
|
||||
@SpecializedFunction
|
||||
public static Object fromCharCode(final Object self, final double value) {
|
||||
public static String fromCharCode(final Object self, final double value) {
|
||||
return "" + (char)JSType.toUint16(value);
|
||||
}
|
||||
|
||||
@ -488,7 +488,7 @@ public final class NativeString extends ScriptObject {
|
||||
* @return self as string
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object toString(final Object self) {
|
||||
public static String toString(final Object self) {
|
||||
return getString(self);
|
||||
}
|
||||
|
||||
@ -498,7 +498,7 @@ public final class NativeString extends ScriptObject {
|
||||
* @return self as string
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object valueOf(final Object self) {
|
||||
public static String valueOf(final Object self) {
|
||||
return getString(self);
|
||||
}
|
||||
|
||||
@ -509,7 +509,7 @@ public final class NativeString extends ScriptObject {
|
||||
* @return string representing the char at the given position
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object charAt(final Object self, final Object pos) {
|
||||
public static String charAt(final Object self, final Object pos) {
|
||||
return charAtImpl(checkObjectToString(self), JSType.toInteger(pos));
|
||||
}
|
||||
|
||||
@ -546,7 +546,7 @@ public final class NativeString extends ScriptObject {
|
||||
* @return number representing charcode at position
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object charCodeAt(final Object self, final Object pos) {
|
||||
public static double charCodeAt(final Object self, final Object pos) {
|
||||
return charCodeAtImpl(checkObjectToString(self), JSType.toInteger(pos));
|
||||
}
|
||||
|
||||
@ -601,7 +601,7 @@ public final class NativeString extends ScriptObject {
|
||||
* @return position of first match or -1
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
|
||||
public static Object indexOf(final Object self, final Object search, final Object pos) {
|
||||
public static int indexOf(final Object self, final Object search, final Object pos) {
|
||||
final String str = checkObjectToString(self);
|
||||
return str.indexOf(JSType.toString(search), JSType.toInteger(pos));
|
||||
}
|
||||
@ -649,7 +649,7 @@ public final class NativeString extends ScriptObject {
|
||||
* @return last position of match or -1
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
|
||||
public static Object lastIndexOf(final Object self, final Object search, final Object pos) {
|
||||
public static int lastIndexOf(final Object self, final Object search, final Object pos) {
|
||||
|
||||
final String str = checkObjectToString(self);
|
||||
final String searchStr = JSType.toString(search);
|
||||
@ -680,7 +680,7 @@ public final class NativeString extends ScriptObject {
|
||||
* @return result of locale sensitive comparison operation between {@code self} and {@code that}
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object localeCompare(final Object self, final Object that) {
|
||||
public static double localeCompare(final Object self, final Object that) {
|
||||
|
||||
final String str = checkObjectToString(self);
|
||||
final Collator collator = Collator.getInstance(Global.getEnv()._locale);
|
||||
@ -698,7 +698,7 @@ public final class NativeString extends ScriptObject {
|
||||
* @return array of regexp matches
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object match(final Object self, final Object regexp) {
|
||||
public static ScriptObject match(final Object self, final Object regexp) {
|
||||
|
||||
final String str = checkObjectToString(self);
|
||||
|
||||
@ -745,7 +745,7 @@ public final class NativeString extends ScriptObject {
|
||||
* @return string after replacement
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object replace(final Object self, final Object string, final Object replacement) {
|
||||
public static String replace(final Object self, final Object string, final Object replacement) {
|
||||
|
||||
final String str = checkObjectToString(self);
|
||||
|
||||
@ -771,7 +771,7 @@ public final class NativeString extends ScriptObject {
|
||||
* @return offset where match occurred
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object search(final Object self, final Object string) {
|
||||
public static int search(final Object self, final Object string) {
|
||||
|
||||
final String str = checkObjectToString(self);
|
||||
final NativeRegExp nativeRegExp = Global.toRegExp(string == UNDEFINED ? "" : string);
|
||||
@ -788,7 +788,7 @@ public final class NativeString extends ScriptObject {
|
||||
* @return sliced out substring
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object slice(final Object self, final Object start, final Object end) {
|
||||
public static String slice(final Object self, final Object start, final Object end) {
|
||||
|
||||
final String str = checkObjectToString(self);
|
||||
if (end == UNDEFINED) {
|
||||
@ -805,7 +805,7 @@ public final class NativeString extends ScriptObject {
|
||||
* @return sliced out substring
|
||||
*/
|
||||
@SpecializedFunction
|
||||
public static Object slice(final Object self, final int start) {
|
||||
public static String slice(final Object self, final int start) {
|
||||
final String str = checkObjectToString(self);
|
||||
final int from = (start < 0) ? Math.max(str.length() + start, 0) : Math.min(start, str.length());
|
||||
|
||||
@ -820,7 +820,7 @@ public final class NativeString extends ScriptObject {
|
||||
* @return sliced out substring
|
||||
*/
|
||||
@SpecializedFunction
|
||||
public static Object slice(final Object self, final double start) {
|
||||
public static String slice(final Object self, final double start) {
|
||||
return slice(self, (int)start);
|
||||
}
|
||||
|
||||
@ -833,7 +833,7 @@ public final class NativeString extends ScriptObject {
|
||||
* @return sliced out substring
|
||||
*/
|
||||
@SpecializedFunction
|
||||
public static Object slice(final Object self, final int start, final int end) {
|
||||
public static String slice(final Object self, final int start, final int end) {
|
||||
|
||||
final String str = checkObjectToString(self);
|
||||
final int len = str.length();
|
||||
@ -853,7 +853,7 @@ public final class NativeString extends ScriptObject {
|
||||
* @return sliced out substring
|
||||
*/
|
||||
@SpecializedFunction
|
||||
public static Object slice(final Object self, final double start, final double end) {
|
||||
public static String slice(final Object self, final double start, final double end) {
|
||||
return slice(self, (int)start, (int)end);
|
||||
}
|
||||
|
||||
@ -866,7 +866,7 @@ public final class NativeString extends ScriptObject {
|
||||
* @return array object in which splits have been placed
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object split(final Object self, final Object separator, final Object limit) {
|
||||
public static ScriptObject split(final Object self, final Object separator, final Object limit) {
|
||||
final String str = checkObjectToString(self);
|
||||
final long lim = (limit == UNDEFINED) ? JSType.MAX_UINT : JSType.toUint32(limit);
|
||||
|
||||
@ -882,7 +882,7 @@ public final class NativeString extends ScriptObject {
|
||||
return splitString(str, JSType.toString(separator), lim);
|
||||
}
|
||||
|
||||
private static Object splitString(String str, String separator, long limit) {
|
||||
private static ScriptObject splitString(String str, String separator, long limit) {
|
||||
if (separator.isEmpty()) {
|
||||
final int length = (int) Math.min(str.length(), limit);
|
||||
final Object[] array = new Object[length];
|
||||
@ -923,7 +923,7 @@ public final class NativeString extends ScriptObject {
|
||||
* @return substring given start and length of section
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object substr(final Object self, final Object start, final Object length) {
|
||||
public static String substr(final Object self, final Object start, final Object length) {
|
||||
final String str = JSType.toString(self);
|
||||
final int strLength = str.length();
|
||||
|
||||
@ -946,7 +946,7 @@ public final class NativeString extends ScriptObject {
|
||||
* @return substring given start and end indexes
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object substring(final Object self, final Object start, final Object end) {
|
||||
public static String substring(final Object self, final Object start, final Object end) {
|
||||
|
||||
final String str = checkObjectToString(self);
|
||||
if (end == UNDEFINED) {
|
||||
@ -1026,7 +1026,7 @@ public final class NativeString extends ScriptObject {
|
||||
* @return string to lower case
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object toLowerCase(final Object self) {
|
||||
public static String toLowerCase(final Object self) {
|
||||
return checkObjectToString(self).toLowerCase(Locale.ROOT);
|
||||
}
|
||||
|
||||
@ -1036,7 +1036,7 @@ public final class NativeString extends ScriptObject {
|
||||
* @return string to locale sensitive lower case
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object toLocaleLowerCase(final Object self) {
|
||||
public static String toLocaleLowerCase(final Object self) {
|
||||
return checkObjectToString(self).toLowerCase(Global.getEnv()._locale);
|
||||
}
|
||||
|
||||
@ -1046,7 +1046,7 @@ public final class NativeString extends ScriptObject {
|
||||
* @return string to upper case
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object toUpperCase(final Object self) {
|
||||
public static String toUpperCase(final Object self) {
|
||||
return checkObjectToString(self).toUpperCase(Locale.ROOT);
|
||||
}
|
||||
|
||||
@ -1056,7 +1056,7 @@ public final class NativeString extends ScriptObject {
|
||||
* @return string to locale sensitive upper case
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object toLocaleUpperCase(final Object self) {
|
||||
public static String toLocaleUpperCase(final Object self) {
|
||||
return checkObjectToString(self).toUpperCase(Global.getEnv()._locale);
|
||||
}
|
||||
|
||||
@ -1066,7 +1066,7 @@ public final class NativeString extends ScriptObject {
|
||||
* @return string trimmed from whitespace
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object trim(final Object self) {
|
||||
public static String trim(final Object self) {
|
||||
|
||||
final String str = checkObjectToString(self);
|
||||
int start = 0;
|
||||
@ -1088,7 +1088,7 @@ public final class NativeString extends ScriptObject {
|
||||
* @return string trimmed left from whitespace
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object trimLeft(final Object self) {
|
||||
public static String trimLeft(final Object self) {
|
||||
|
||||
final String str = checkObjectToString(self);
|
||||
int start = 0;
|
||||
@ -1107,7 +1107,7 @@ public final class NativeString extends ScriptObject {
|
||||
* @return string trimmed right from whitespace
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
public static Object trimRight(final Object self) {
|
||||
public static String trimRight(final Object self) {
|
||||
|
||||
final String str = checkObjectToString(self);
|
||||
int start = 0;
|
||||
@ -1120,7 +1120,7 @@ public final class NativeString extends ScriptObject {
|
||||
return str.substring(start, end + 1);
|
||||
}
|
||||
|
||||
private static Object newObj(final Object self, final CharSequence str) {
|
||||
private static ScriptObject newObj(final Object self, final CharSequence str) {
|
||||
return new NativeString(str);
|
||||
}
|
||||
|
||||
|
||||
@ -94,7 +94,7 @@ public final class NativeSyntaxError extends ScriptObject {
|
||||
* @return new SyntaxError
|
||||
*/
|
||||
@Constructor(name = "SyntaxError")
|
||||
public static Object constructor(final boolean newObj, final Object self, final Object msg) {
|
||||
public static NativeSyntaxError constructor(final boolean newObj, final Object self, final Object msg) {
|
||||
return new NativeSyntaxError(msg);
|
||||
}
|
||||
}
|
||||
|
||||
@ -94,7 +94,7 @@ public final class NativeTypeError extends ScriptObject {
|
||||
* @return new TypeError
|
||||
*/
|
||||
@Constructor(name = "TypeError")
|
||||
public static Object constructor(final boolean newObj, final Object self, final Object msg) {
|
||||
public static NativeTypeError constructor(final boolean newObj, final Object self, final Object msg) {
|
||||
return new NativeTypeError(msg);
|
||||
}
|
||||
}
|
||||
|
||||
@ -93,7 +93,7 @@ public final class NativeURIError extends ScriptObject {
|
||||
* @return new URIError
|
||||
*/
|
||||
@Constructor(name = "URIError")
|
||||
public static Object constructor(final boolean newObj, final Object self, final Object msg) {
|
||||
public static NativeURIError constructor(final boolean newObj, final Object self, final Object msg) {
|
||||
return new NativeURIError(msg);
|
||||
}
|
||||
}
|
||||
|
||||
@ -99,8 +99,8 @@ public final class NativeUint16Array extends ArrayBufferView {
|
||||
* @return new typed array
|
||||
*/
|
||||
@Constructor(arity = 1)
|
||||
public static Object constructor(final boolean newObj, final Object self, final Object... args) {
|
||||
return constructorImpl(args, FACTORY);
|
||||
public static NativeUint16Array constructor(final boolean newObj, final Object self, final Object... args) {
|
||||
return (NativeUint16Array)constructorImpl(args, FACTORY);
|
||||
}
|
||||
|
||||
NativeUint16Array(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
|
||||
@ -150,8 +150,8 @@ public final class NativeUint16Array extends ArrayBufferView {
|
||||
* @return sub array
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
protected static Object subarray(final Object self, final Object begin, final Object end) {
|
||||
return ArrayBufferView.subarrayImpl(self, begin, end);
|
||||
protected static NativeUint16Array subarray(final Object self, final Object begin, final Object end) {
|
||||
return (NativeUint16Array)ArrayBufferView.subarrayImpl(self, begin, end);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -118,8 +118,8 @@ public final class NativeUint32Array extends ArrayBufferView {
|
||||
* @return new typed array
|
||||
*/
|
||||
@Constructor(arity = 1)
|
||||
public static Object constructor(final boolean newObj, final Object self, final Object... args) {
|
||||
return constructorImpl(args, FACTORY);
|
||||
public static NativeUint32Array constructor(final boolean newObj, final Object self, final Object... args) {
|
||||
return (NativeUint32Array)constructorImpl(args, FACTORY);
|
||||
}
|
||||
|
||||
NativeUint32Array(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
|
||||
@ -169,8 +169,8 @@ public final class NativeUint32Array extends ArrayBufferView {
|
||||
* @return sub array
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
protected static Object subarray(final Object self, final Object begin, final Object end) {
|
||||
return ArrayBufferView.subarrayImpl(self, begin, end);
|
||||
protected static NativeUint32Array subarray(final Object self, final Object begin, final Object end) {
|
||||
return (NativeUint32Array)ArrayBufferView.subarrayImpl(self, begin, end);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -92,8 +92,8 @@ public final class NativeUint8Array extends ArrayBufferView {
|
||||
* @return new typed array
|
||||
*/
|
||||
@Constructor(arity = 1)
|
||||
public static Object constructor(final boolean newObj, final Object self, final Object... args) {
|
||||
return constructorImpl(args, FACTORY);
|
||||
public static NativeUint8Array constructor(final boolean newObj, final Object self, final Object... args) {
|
||||
return (NativeUint8Array)constructorImpl(args, FACTORY);
|
||||
}
|
||||
|
||||
NativeUint8Array(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
|
||||
@ -143,8 +143,8 @@ public final class NativeUint8Array extends ArrayBufferView {
|
||||
* @return sub array
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
protected static Object subarray(final Object self, final Object begin, final Object end) {
|
||||
return ArrayBufferView.subarrayImpl(self, begin, end);
|
||||
protected static NativeUint8Array subarray(final Object self, final Object begin, final Object end) {
|
||||
return (NativeUint8Array)ArrayBufferView.subarrayImpl(self, begin, end);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -109,8 +109,8 @@ public final class NativeUint8ClampedArray extends ArrayBufferView {
|
||||
* @return new typed array
|
||||
*/
|
||||
@Constructor(arity = 1)
|
||||
public static Object constructor(final boolean newObj, final Object self, final Object... args) {
|
||||
return constructorImpl(args, FACTORY);
|
||||
public static NativeUint8ClampedArray constructor(final boolean newObj, final Object self, final Object... args) {
|
||||
return (NativeUint8ClampedArray)constructorImpl(args, FACTORY);
|
||||
}
|
||||
|
||||
NativeUint8ClampedArray(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
|
||||
@ -160,8 +160,8 @@ public final class NativeUint8ClampedArray extends ArrayBufferView {
|
||||
* @return sub array
|
||||
*/
|
||||
@Function(attributes = Attribute.NOT_ENUMERABLE)
|
||||
protected static Object subarray(final Object self, final Object begin, final Object end) {
|
||||
return ArrayBufferView.subarrayImpl(self, begin, end);
|
||||
protected static NativeUint8ClampedArray subarray(final Object self, final Object begin, final Object end) {
|
||||
return (NativeUint8ClampedArray)ArrayBufferView.subarrayImpl(self, begin, end);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -1700,9 +1700,11 @@ loop:
|
||||
// ECMA 12.4.1 strict mode restrictions
|
||||
verifyStrictIdent(exception, "catch argument");
|
||||
|
||||
// Check for conditional catch.
|
||||
// Nashorn extension: catch clause can have optional
|
||||
// condition. So, a single try can have more than one
|
||||
// catch clause each with it's own condition.
|
||||
final Expression ifExpression;
|
||||
if (type == IF) {
|
||||
if (!env._no_syntax_extensions && type == IF) {
|
||||
next();
|
||||
// Get the exception condition.
|
||||
ifExpression = expression();
|
||||
|
||||
@ -39,6 +39,9 @@ import static jdk.nashorn.internal.codegen.ObjectClassGenerator.getNumberOfAcces
|
||||
import static jdk.nashorn.internal.lookup.Lookup.MH;
|
||||
import static jdk.nashorn.internal.lookup.MethodHandleFactory.stripName;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.Serializable;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
@ -51,11 +54,12 @@ import jdk.nashorn.internal.lookup.MethodHandleFactory;
|
||||
* An AccessorProperty is the most generic property type. An AccessorProperty is
|
||||
* represented as fields in a ScriptObject class.
|
||||
*/
|
||||
public final class AccessorProperty extends Property {
|
||||
public final class AccessorProperty extends Property implements Serializable {
|
||||
private static final MethodHandles.Lookup lookup = MethodHandles.lookup();
|
||||
private static final MethodHandle REPLACE_MAP = findOwnMH("replaceMap", Object.class, Object.class, PropertyMap.class, String.class, Class.class, Class.class);
|
||||
|
||||
private static final int NOOF_TYPES = getNumberOfAccessorTypes();
|
||||
private static final long serialVersionUID = 3371720170182154920L;
|
||||
|
||||
/**
|
||||
* Properties in different maps for the same structure class will share their field getters and setters. This could
|
||||
@ -71,7 +75,7 @@ public final class AccessorProperty extends Property {
|
||||
};
|
||||
|
||||
/** Property getter cache */
|
||||
private MethodHandle[] getters = new MethodHandle[NOOF_TYPES];
|
||||
private transient MethodHandle[] getters = new MethodHandle[NOOF_TYPES];
|
||||
|
||||
private static final MethodType[] ACCESSOR_GETTER_TYPES = new MethodType[NOOF_TYPES];
|
||||
private static final MethodType[] ACCESSOR_SETTER_TYPES = new MethodType[NOOF_TYPES];
|
||||
@ -122,16 +126,16 @@ public final class AccessorProperty extends Property {
|
||||
}
|
||||
|
||||
/** Seed getter for the primitive version of this field (in -Dnashorn.fields.dual=true mode) */
|
||||
private MethodHandle primitiveGetter;
|
||||
private transient MethodHandle primitiveGetter;
|
||||
|
||||
/** Seed setter for the primitive version of this field (in -Dnashorn.fields.dual=true mode) */
|
||||
private MethodHandle primitiveSetter;
|
||||
private transient MethodHandle primitiveSetter;
|
||||
|
||||
/** Seed getter for the Object version of this field */
|
||||
private MethodHandle objectGetter;
|
||||
private transient MethodHandle objectGetter;
|
||||
|
||||
/** Seed setter for the Object version of this field */
|
||||
private MethodHandle objectSetter;
|
||||
private transient MethodHandle objectSetter;
|
||||
|
||||
/**
|
||||
* Current type of this object, in object only mode, this is an Object.class. In dual-fields mode
|
||||
@ -243,6 +247,12 @@ public final class AccessorProperty extends Property {
|
||||
public AccessorProperty(final String key, final int flags, final Class<?> structure, final int slot) {
|
||||
super(key, flags, slot);
|
||||
|
||||
initGetterSetter(structure);
|
||||
}
|
||||
|
||||
private void initGetterSetter(final Class<?> structure) {
|
||||
final int slot = getSlot();
|
||||
final String key = getKey();
|
||||
/*
|
||||
* primitiveGetter and primitiveSetter are only used in dual fields mode. Setting them to null also
|
||||
* works in dual field mode, it only means that the property never has a primitive
|
||||
@ -305,6 +315,12 @@ public final class AccessorProperty extends Property {
|
||||
setCurrentType(property.getCurrentType());
|
||||
}
|
||||
|
||||
private void readObject(final ObjectInputStream s) throws IOException, ClassNotFoundException {
|
||||
s.defaultReadObject();
|
||||
// Restore getters array
|
||||
getters = new MethodHandle[NOOF_TYPES];
|
||||
}
|
||||
|
||||
private static MethodHandle bindTo(final MethodHandle mh, final Object receiver) {
|
||||
if (mh == null) {
|
||||
return null;
|
||||
@ -363,6 +379,16 @@ public final class AccessorProperty extends Property {
|
||||
return objectSetter;
|
||||
}
|
||||
|
||||
@Override
|
||||
void initMethodHandles(final Class<?> structure) {
|
||||
if (!ScriptObject.class.isAssignableFrom(structure) || !StructureLoader.isStructureClass(structure.getName())) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
if (!isSpill()) {
|
||||
initGetterSetter(structure);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodHandle getGetter(final Class<?> type) {
|
||||
final int i = getAccessorTypeIndex(type);
|
||||
|
||||
@ -25,6 +25,7 @@
|
||||
|
||||
package jdk.nashorn.internal.runtime;
|
||||
|
||||
import java.util.Map;
|
||||
import jdk.nashorn.internal.codegen.ClassEmitter;
|
||||
|
||||
/**
|
||||
@ -52,7 +53,7 @@ public interface CodeInstaller<T> {
|
||||
* @param bytecode bytecode
|
||||
* @return the installed class
|
||||
*/
|
||||
public Class<?> install(final String className, final byte[] bytecode);
|
||||
public Class<?> install(final String className, final byte[] bytecode, final Source source, final Object[] constants);
|
||||
|
||||
/**
|
||||
* Verify generated bytecode before emission. This is called back from the
|
||||
@ -74,4 +75,13 @@ public interface CodeInstaller<T> {
|
||||
* @return unique eval id
|
||||
*/
|
||||
public long getUniqueEvalId();
|
||||
|
||||
/**
|
||||
* Store a compiled script for later reuse
|
||||
* @param source the script source
|
||||
* @param mainClassName the main class name
|
||||
* @param classBytes map of class names to class bytes
|
||||
* @param constants constants array
|
||||
*/
|
||||
public void storeCompiledScript(Source source, String mainClassName, Map<String, byte[]> classBytes, Object[] constants);
|
||||
}
|
||||
|
||||
179
nashorn/src/jdk/nashorn/internal/runtime/CodeStore.java
Normal file
179
nashorn/src/jdk/nashorn/internal/runtime/CodeStore.java
Normal file
@ -0,0 +1,179 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package jdk.nashorn.internal.runtime;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.util.Base64;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A code cache for persistent caching of compiled scripts.
|
||||
*/
|
||||
final class CodeStore {
|
||||
|
||||
private final File dir;
|
||||
private final int minSize;
|
||||
|
||||
// Message digest to file name encoder
|
||||
private final static Base64.Encoder BASE64 = Base64.getUrlEncoder().withoutPadding();
|
||||
|
||||
// Default minimum size for storing a compiled script class
|
||||
private final static int DEFAULT_MIN_SIZE = 1000;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param path directory to store code in
|
||||
* @throws IOException
|
||||
*/
|
||||
public CodeStore(final String path) throws IOException {
|
||||
this(path, DEFAULT_MIN_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param path directory to store code in
|
||||
* @param minSize minimum file size for caching scripts
|
||||
* @throws IOException
|
||||
*/
|
||||
public CodeStore(final String path, final int minSize) throws IOException {
|
||||
this.dir = new File(path);
|
||||
this.minSize = minSize;
|
||||
checkDirectory(this.dir);
|
||||
}
|
||||
|
||||
private static void checkDirectory(final File dir) throws IOException {
|
||||
try {
|
||||
AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
|
||||
@Override
|
||||
public Void run() throws IOException {
|
||||
if (!dir.exists() && !dir.mkdirs()) {
|
||||
throw new IOException("Could not create directory: " + dir);
|
||||
} else if (!dir.isDirectory()) {
|
||||
throw new IOException("Not a directory: " + dir);
|
||||
} else if (!dir.canRead() || !dir.canWrite()) {
|
||||
throw new IOException("Directory not readable or writable: " + dir);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
} catch (PrivilegedActionException e) {
|
||||
throw (IOException) e.getException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a compiled script from the cache, or null if it isn't found.
|
||||
*
|
||||
* @param source the source
|
||||
* @return the compiled script or null
|
||||
* @throws IOException
|
||||
* @throws ClassNotFoundException
|
||||
*/
|
||||
public CompiledScript getScript(final Source source) throws IOException, ClassNotFoundException {
|
||||
if (source.getLength() < minSize) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final String digest = BASE64.encodeToString(source.getDigest());
|
||||
final File file = new File(dir, digest);
|
||||
|
||||
try {
|
||||
return AccessController.doPrivileged(new PrivilegedExceptionAction<CompiledScript>() {
|
||||
@Override
|
||||
public CompiledScript run() throws IOException, ClassNotFoundException {
|
||||
if (!file.exists()) {
|
||||
return null;
|
||||
}
|
||||
try (ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(new FileInputStream(file)))) {
|
||||
CompiledScript compiledScript = (CompiledScript) in.readObject();
|
||||
compiledScript.setSource(source);
|
||||
return compiledScript;
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (PrivilegedActionException e) {
|
||||
final Exception ex = e.getException();
|
||||
if (ex instanceof IOException) {
|
||||
throw (IOException) ex;
|
||||
} else if (ex instanceof ClassNotFoundException) {
|
||||
throw (ClassNotFoundException) ex;
|
||||
}
|
||||
throw (new RuntimeException(ex));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a compiled script in the cache.
|
||||
*
|
||||
* @param source the source
|
||||
* @param mainClassName the main class name
|
||||
* @param classBytes a map of class bytes
|
||||
* @param constants the constants array
|
||||
* @throws IOException
|
||||
*/
|
||||
public void putScript(final Source source, final String mainClassName, final Map<String, byte[]> classBytes, final Object[] constants)
|
||||
throws IOException {
|
||||
if (source.getLength() < minSize) {
|
||||
return;
|
||||
}
|
||||
for (final Object constant : constants) {
|
||||
// Make sure all constant data is serializable
|
||||
if (! (constant instanceof Serializable)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
final String digest = BASE64.encodeToString(source.getDigest());
|
||||
final File file = new File(dir, digest);
|
||||
final CompiledScript script = new CompiledScript(source, mainClassName, classBytes, constants);
|
||||
|
||||
try {
|
||||
AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
|
||||
@Override
|
||||
public Void run() throws IOException {
|
||||
try (ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(file)))) {
|
||||
out.writeObject(script);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
} catch (PrivilegedActionException e) {
|
||||
throw (IOException) e.getException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
127
nashorn/src/jdk/nashorn/internal/runtime/CompiledScript.java
Normal file
127
nashorn/src/jdk/nashorn/internal/runtime/CompiledScript.java
Normal file
@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package jdk.nashorn.internal.runtime;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Class representing a compiled script.
|
||||
*/
|
||||
final class CompiledScript implements Serializable {
|
||||
|
||||
/** Main class name. */
|
||||
private final String mainClassName;
|
||||
|
||||
/** Map of class names to class bytes. */
|
||||
private final Map<String, byte[]> classBytes;
|
||||
|
||||
/** Constants array. */
|
||||
private final Object[] constants;
|
||||
|
||||
/** The source */
|
||||
private transient Source source;
|
||||
|
||||
private static final long serialVersionUID = 2958227232195298340L;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param mainClassName main class name
|
||||
* @param classBytes map of class names to class bytes
|
||||
* @param constants constants array
|
||||
*/
|
||||
CompiledScript(final Source source, final String mainClassName, final Map<String, byte[]> classBytes, final Object[] constants) {
|
||||
this.source = source;
|
||||
this.mainClassName = mainClassName;
|
||||
this.classBytes = classBytes;
|
||||
this.constants = constants;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the main class name.
|
||||
* @return the main class name
|
||||
*/
|
||||
public String getMainClassName() {
|
||||
return mainClassName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a map of class names to class bytes.
|
||||
* @return map of class bytes
|
||||
*/
|
||||
public Map<String, byte[]> getClassBytes() {
|
||||
return classBytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the constants array.
|
||||
* @return constants array
|
||||
*/
|
||||
public Object[] getConstants() {
|
||||
return constants;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the source of this cached script.
|
||||
* @return the source
|
||||
*/
|
||||
public Source getSource() {
|
||||
return source;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the source of this cached script.
|
||||
* @param source the source
|
||||
*/
|
||||
void setSource(final Source source) {
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = mainClassName.hashCode();
|
||||
hash = 31 * hash + classBytes.hashCode();
|
||||
hash = 31 * hash + Arrays.hashCode(constants);
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof CompiledScript)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final CompiledScript cs = (CompiledScript) obj;
|
||||
return mainClassName.equals(cs.mainClassName)
|
||||
&& classBytes.equals(cs.classBytes)
|
||||
&& Arrays.equals(constants, cs.constants);
|
||||
}
|
||||
}
|
||||
@ -25,7 +25,9 @@
|
||||
|
||||
package jdk.nashorn.internal.runtime;
|
||||
|
||||
import static jdk.nashorn.internal.codegen.CompilerConstants.CONSTANTS;
|
||||
import static jdk.nashorn.internal.codegen.CompilerConstants.RUN_SCRIPT;
|
||||
import static jdk.nashorn.internal.codegen.CompilerConstants.SOURCE;
|
||||
import static jdk.nashorn.internal.codegen.CompilerConstants.STRICT_MODE;
|
||||
import static jdk.nashorn.internal.lookup.Lookup.MH;
|
||||
import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
|
||||
@ -38,6 +40,7 @@ import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.ref.ReferenceQueue;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
@ -47,7 +50,10 @@ import java.security.CodeSigner;
|
||||
import java.security.CodeSource;
|
||||
import java.security.Permissions;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.security.ProtectionDomain;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
@ -133,8 +139,32 @@ public final class Context {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> install(final String className, final byte[] bytecode) {
|
||||
return loader.installClass(className, bytecode, codeSource);
|
||||
public Class<?> install(final String className, final byte[] bytecode, final Source source, final Object[] constants) {
|
||||
Compiler.LOG.fine("Installing class ", className);
|
||||
|
||||
final String binaryName = Compiler.binaryName(className);
|
||||
final Class<?> clazz = loader.installClass(binaryName, bytecode, codeSource);
|
||||
|
||||
try {
|
||||
// Need doPrivileged because these fields are private
|
||||
AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
|
||||
@Override
|
||||
public Void run() throws Exception {
|
||||
//use reflection to write source and constants table to installed classes
|
||||
final Field sourceField = clazz.getDeclaredField(SOURCE.symbolName());
|
||||
final Field constantsField = clazz.getDeclaredField(CONSTANTS.symbolName());
|
||||
sourceField.setAccessible(true);
|
||||
constantsField.setAccessible(true);
|
||||
sourceField.set(null, source);
|
||||
constantsField.set(null, constants);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
} catch (final PrivilegedActionException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
return clazz;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -151,6 +181,18 @@ public final class Context {
|
||||
public long getUniqueEvalId() {
|
||||
return context.getUniqueEvalId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void storeCompiledScript(final Source source, final String mainClassName,
|
||||
final Map<String, byte[]> classBytes, final Object[] constants) {
|
||||
if (context.codeStore != null) {
|
||||
try {
|
||||
context.codeStore.putScript(source, mainClassName, classBytes, constants);
|
||||
} catch (final IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Is Context global debug mode enabled ? */
|
||||
@ -158,9 +200,12 @@ public final class Context {
|
||||
|
||||
private static final ThreadLocal<Global> currentGlobal = new ThreadLocal<>();
|
||||
|
||||
// class cache
|
||||
// in-memory cache for loaded classes
|
||||
private ClassCache classCache;
|
||||
|
||||
// persistent code store
|
||||
private CodeStore codeStore;
|
||||
|
||||
/**
|
||||
* Get the current global scope
|
||||
* @return the current global scope
|
||||
@ -368,6 +413,19 @@ public final class Context {
|
||||
classCache = new ClassCache(cacheSize);
|
||||
}
|
||||
|
||||
if (env._persistent_cache) {
|
||||
if (env._lazy_compilation || env._specialize_calls != null) {
|
||||
getErr().println("Can not use persistent class caching with lazy compilation or call specialization.");
|
||||
} else {
|
||||
try {
|
||||
final String cacheDir = Options.getStringProperty("nashorn.persistent.code.cache", "nashorn_code_cache");
|
||||
codeStore = new CodeStore(cacheDir);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Error initializing code cache", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// print version info if asked.
|
||||
if (env._version) {
|
||||
getErr().println("nashorn " + Version.version());
|
||||
@ -932,17 +990,32 @@ public final class Context {
|
||||
return script;
|
||||
}
|
||||
|
||||
final FunctionNode functionNode = new Parser(env, source, errMan, strict).parse();
|
||||
if (errors.hasErrors()) {
|
||||
return null;
|
||||
CompiledScript compiledScript = null;
|
||||
FunctionNode functionNode = null;
|
||||
|
||||
if (!env._parse_only && codeStore != null) {
|
||||
try {
|
||||
compiledScript = codeStore.getScript(source);
|
||||
} catch (IOException | ClassNotFoundException e) {
|
||||
Compiler.LOG.warning("Error loading ", source, " from cache: ", e);
|
||||
// Fall back to normal compilation
|
||||
}
|
||||
}
|
||||
|
||||
if (env._print_ast) {
|
||||
getErr().println(new ASTWriter(functionNode));
|
||||
}
|
||||
if (compiledScript == null) {
|
||||
functionNode = new Parser(env, source, errMan, strict).parse();
|
||||
|
||||
if (env._print_parse) {
|
||||
getErr().println(new PrintVisitor(functionNode));
|
||||
if (errors.hasErrors()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (env._print_ast) {
|
||||
getErr().println(new ASTWriter(functionNode));
|
||||
}
|
||||
|
||||
if (env._print_parse) {
|
||||
getErr().println(new PrintVisitor(functionNode));
|
||||
}
|
||||
}
|
||||
|
||||
if (env._parse_only) {
|
||||
@ -954,12 +1027,15 @@ public final class Context {
|
||||
final CodeSource cs = new CodeSource(url, (CodeSigner[])null);
|
||||
final CodeInstaller<ScriptEnvironment> installer = new ContextCodeInstaller(this, loader, cs);
|
||||
|
||||
final Compiler compiler = new Compiler(installer, strict);
|
||||
if (functionNode != null) {
|
||||
final Compiler compiler = new Compiler(installer, strict);
|
||||
final FunctionNode newFunctionNode = compiler.compile(functionNode);
|
||||
script = compiler.install(newFunctionNode);
|
||||
} else {
|
||||
script = install(compiledScript, installer);
|
||||
}
|
||||
|
||||
final FunctionNode newFunctionNode = compiler.compile(functionNode);
|
||||
script = compiler.install(newFunctionNode);
|
||||
cacheClass(source, script);
|
||||
|
||||
return script;
|
||||
}
|
||||
|
||||
@ -981,6 +1057,42 @@ public final class Context {
|
||||
return uniqueScriptId.getAndIncrement();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Install a previously compiled class from the code cache.
|
||||
*
|
||||
* @param compiledScript cached script containing class bytes and constants
|
||||
* @return main script class
|
||||
*/
|
||||
private Class<?> install(final CompiledScript compiledScript, final CodeInstaller<ScriptEnvironment> installer) {
|
||||
|
||||
final Map<String, Class<?>> installedClasses = new HashMap<>();
|
||||
final Source source = compiledScript.getSource();
|
||||
final Object[] constants = compiledScript.getConstants();
|
||||
final String rootClassName = compiledScript.getMainClassName();
|
||||
final byte[] rootByteCode = compiledScript.getClassBytes().get(rootClassName);
|
||||
final Class<?> rootClass = installer.install(rootClassName, rootByteCode, source, constants);
|
||||
|
||||
installedClasses.put(rootClassName, rootClass);
|
||||
|
||||
for (final Map.Entry<String, byte[]> entry : compiledScript.getClassBytes().entrySet()) {
|
||||
final String className = entry.getKey();
|
||||
if (className.equals(rootClassName)) {
|
||||
continue;
|
||||
}
|
||||
final byte[] code = entry.getValue();
|
||||
|
||||
installedClasses.put(className, installer.install(className, code, source, constants));
|
||||
}
|
||||
for (Object constant : constants) {
|
||||
if (constant instanceof RecompilableScriptFunctionData) {
|
||||
((RecompilableScriptFunctionData) constant).setCodeAndSource(installedClasses, source);
|
||||
}
|
||||
}
|
||||
|
||||
return rootClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cache for compiled script classes.
|
||||
*/
|
||||
|
||||
@ -101,7 +101,6 @@ public final class JSONFunctions {
|
||||
// apply 'reviver' function if available
|
||||
private static Object applyReviver(final Global global, final Object unfiltered, final Object reviver) {
|
||||
if (reviver instanceof ScriptFunction) {
|
||||
assert global instanceof Global;
|
||||
final ScriptObject root = global.newObject();
|
||||
root.addOwnProperty("", Property.WRITABLE_ENUMERABLE_CONFIGURABLE, unfiltered);
|
||||
return walk(root, "", (ScriptFunction)reviver);
|
||||
|
||||
@ -29,6 +29,7 @@ import static jdk.nashorn.internal.runtime.PropertyDescriptor.CONFIGURABLE;
|
||||
import static jdk.nashorn.internal.runtime.PropertyDescriptor.ENUMERABLE;
|
||||
import static jdk.nashorn.internal.runtime.PropertyDescriptor.WRITABLE;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.util.Objects;
|
||||
import jdk.nashorn.internal.codegen.ObjectClassGenerator;
|
||||
@ -43,7 +44,7 @@ import jdk.nashorn.internal.codegen.types.Type;
|
||||
* @see AccessorProperty
|
||||
* @see UserAccessorProperty
|
||||
*/
|
||||
public abstract class Property {
|
||||
public abstract class Property implements Serializable {
|
||||
/*
|
||||
* ECMA 8.6.1 Property Attributes
|
||||
*
|
||||
@ -100,6 +101,8 @@ public abstract class Property {
|
||||
/** Property field number or spill slot. */
|
||||
private final int slot;
|
||||
|
||||
private static final long serialVersionUID = 2099814273074501176L;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
@ -357,6 +360,13 @@ public abstract class Property {
|
||||
*/
|
||||
public abstract MethodHandle getGetter(final Class<?> type);
|
||||
|
||||
/**
|
||||
* Hook to initialize method handles after deserialization.
|
||||
*
|
||||
* @param structure the structure class
|
||||
*/
|
||||
abstract void initMethodHandles(final Class<?> structure);
|
||||
|
||||
/**
|
||||
* Get the key for this property. This key is an ordinary string. The "name".
|
||||
* @return key for property
|
||||
|
||||
@ -29,6 +29,10 @@ import static jdk.nashorn.internal.runtime.PropertyHashMap.EMPTY_HASHMAP;
|
||||
import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.getArrayIndex;
|
||||
import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.isValidArrayIndex;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.lang.invoke.SwitchPoint;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.util.Arrays;
|
||||
@ -37,6 +41,7 @@ import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.WeakHashMap;
|
||||
import jdk.nashorn.internal.scripts.JO;
|
||||
|
||||
/**
|
||||
* Map of object properties. The PropertyMap is the "template" for JavaScript object
|
||||
@ -47,7 +52,7 @@ import java.util.WeakHashMap;
|
||||
* All property maps are immutable. If a property is added, modified or removed, the mutator
|
||||
* will return a new map.
|
||||
*/
|
||||
public final class PropertyMap implements Iterable<Object> {
|
||||
public final class PropertyMap implements Iterable<Object>, Serializable {
|
||||
/** Used for non extensible PropertyMaps, negative logic as the normal case is extensible. See {@link ScriptObject#preventExtensions()} */
|
||||
public static final int NOT_EXTENSIBLE = 0b0000_0001;
|
||||
/** Does this map contain valid array keys? */
|
||||
@ -57,7 +62,7 @@ public final class PropertyMap implements Iterable<Object> {
|
||||
private int flags;
|
||||
|
||||
/** Map of properties. */
|
||||
private final PropertyHashMap properties;
|
||||
private transient PropertyHashMap properties;
|
||||
|
||||
/** Number of fields in use. */
|
||||
private int fieldCount;
|
||||
@ -68,17 +73,22 @@ public final class PropertyMap implements Iterable<Object> {
|
||||
/** Length of spill in use. */
|
||||
private int spillLength;
|
||||
|
||||
/** Structure class name */
|
||||
private String className;
|
||||
|
||||
/** {@link SwitchPoint}s for gets on inherited properties. */
|
||||
private HashMap<String, SwitchPoint> protoGetSwitches;
|
||||
private transient HashMap<String, SwitchPoint> protoGetSwitches;
|
||||
|
||||
/** History of maps, used to limit map duplication. */
|
||||
private WeakHashMap<Property, SoftReference<PropertyMap>> history;
|
||||
private transient WeakHashMap<Property, SoftReference<PropertyMap>> history;
|
||||
|
||||
/** History of prototypes, used to limit map duplication. */
|
||||
private WeakHashMap<PropertyMap, SoftReference<PropertyMap>> protoHistory;
|
||||
private transient WeakHashMap<PropertyMap, SoftReference<PropertyMap>> protoHistory;
|
||||
|
||||
/** property listeners */
|
||||
private PropertyListeners listeners;
|
||||
private transient PropertyListeners listeners;
|
||||
|
||||
private static final long serialVersionUID = -7041836752008732533L;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
@ -89,8 +99,10 @@ public final class PropertyMap implements Iterable<Object> {
|
||||
* @param spillLength Number of spill slots used.
|
||||
* @param containsArrayKeys True if properties contain numeric keys
|
||||
*/
|
||||
private PropertyMap(final PropertyHashMap properties, final int fieldCount, final int fieldMaximum, final int spillLength, final boolean containsArrayKeys) {
|
||||
private PropertyMap(final PropertyHashMap properties, final String className, final int fieldCount,
|
||||
final int fieldMaximum, final int spillLength, final boolean containsArrayKeys) {
|
||||
this.properties = properties;
|
||||
this.className = className;
|
||||
this.fieldCount = fieldCount;
|
||||
this.fieldMaximum = fieldMaximum;
|
||||
this.spillLength = spillLength;
|
||||
@ -145,7 +157,25 @@ public final class PropertyMap implements Iterable<Object> {
|
||||
if (Context.DEBUG) {
|
||||
duplicatedCount++;
|
||||
}
|
||||
return new PropertyMap(this.properties, 0, 0, 0, containsArrayKeys());
|
||||
return new PropertyMap(this.properties, this.className, 0, 0, 0, containsArrayKeys());
|
||||
}
|
||||
|
||||
private void writeObject(final ObjectOutputStream out) throws IOException {
|
||||
out.defaultWriteObject();
|
||||
out.writeObject(properties.getProperties());
|
||||
}
|
||||
|
||||
private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
|
||||
in.defaultReadObject();
|
||||
|
||||
final Property[] props = (Property[]) in.readObject();
|
||||
this.properties = EMPTY_HASHMAP.immutableAdd(props);
|
||||
|
||||
assert className != null;
|
||||
final Class<?> structure = Context.forStructureClass(className);
|
||||
for (Property prop : props) {
|
||||
prop.initMethodHandles(structure);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -160,9 +190,9 @@ public final class PropertyMap implements Iterable<Object> {
|
||||
* @param spillLength Number of used spill slots.
|
||||
* @return New {@link PropertyMap}.
|
||||
*/
|
||||
public static PropertyMap newMap(final Collection<Property> properties, final int fieldCount, final int fieldMaximum, final int spillLength) {
|
||||
public static PropertyMap newMap(final Collection<Property> properties, final String className, final int fieldCount, final int fieldMaximum, final int spillLength) {
|
||||
PropertyHashMap newProperties = EMPTY_HASHMAP.immutableAdd(properties);
|
||||
return new PropertyMap(newProperties, fieldCount, fieldMaximum, spillLength, false);
|
||||
return new PropertyMap(newProperties, className, fieldCount, fieldMaximum, spillLength, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -175,7 +205,7 @@ public final class PropertyMap implements Iterable<Object> {
|
||||
* @return New {@link PropertyMap}.
|
||||
*/
|
||||
public static PropertyMap newMap(final Collection<Property> properties) {
|
||||
return (properties == null || properties.isEmpty())? newMap() : newMap(properties, 0, 0, 0);
|
||||
return (properties == null || properties.isEmpty())? newMap() : newMap(properties, JO.class.getName(), 0, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -184,7 +214,7 @@ public final class PropertyMap implements Iterable<Object> {
|
||||
* @return New empty {@link PropertyMap}.
|
||||
*/
|
||||
public static PropertyMap newMap() {
|
||||
return new PropertyMap(EMPTY_HASHMAP, 0, 0, 0, false);
|
||||
return new PropertyMap(EMPTY_HASHMAP, JO.class.getName(), 0, 0, 0, false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -27,14 +27,15 @@ package jdk.nashorn.internal.runtime;
|
||||
|
||||
import static jdk.nashorn.internal.lookup.Lookup.MH;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
import jdk.internal.dynalink.support.NameCodec;
|
||||
|
||||
import jdk.nashorn.internal.codegen.Compiler;
|
||||
import jdk.nashorn.internal.codegen.CompilerConstants;
|
||||
import jdk.nashorn.internal.codegen.FunctionSignature;
|
||||
@ -43,6 +44,7 @@ import jdk.nashorn.internal.ir.FunctionNode;
|
||||
import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
|
||||
import jdk.nashorn.internal.parser.Token;
|
||||
import jdk.nashorn.internal.parser.TokenType;
|
||||
import jdk.nashorn.internal.scripts.JS;
|
||||
|
||||
/**
|
||||
* This is a subclass that represents a script function that may be regenerated,
|
||||
@ -50,13 +52,19 @@ import jdk.nashorn.internal.parser.TokenType;
|
||||
* The common denominator is that it can get new invokers during its lifespan,
|
||||
* unlike {@code FinalScriptFunctionData}
|
||||
*/
|
||||
public final class RecompilableScriptFunctionData extends ScriptFunctionData {
|
||||
public final class RecompilableScriptFunctionData extends ScriptFunctionData implements Serializable {
|
||||
|
||||
/** FunctionNode with the code for this ScriptFunction */
|
||||
private FunctionNode functionNode;
|
||||
private transient FunctionNode functionNode;
|
||||
|
||||
/** Source from which FunctionNode was parsed. */
|
||||
private final Source source;
|
||||
private transient Source source;
|
||||
|
||||
/** The line number where this function begins. */
|
||||
private final int lineNumber;
|
||||
|
||||
/** Allows us to retrieve the method handle for this function once the code is compiled */
|
||||
private MethodLocator methodLocator;
|
||||
|
||||
/** Token of this function within the source. */
|
||||
private final long token;
|
||||
@ -65,13 +73,13 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData {
|
||||
private final PropertyMap allocatorMap;
|
||||
|
||||
/** Code installer used for all further recompilation/specialization of this ScriptFunction */
|
||||
private CodeInstaller<ScriptEnvironment> installer;
|
||||
private transient CodeInstaller<ScriptEnvironment> installer;
|
||||
|
||||
/** Name of class where allocator function resides */
|
||||
private final String allocatorClassName;
|
||||
|
||||
/** lazily generated allocator */
|
||||
private MethodHandle allocator;
|
||||
private transient MethodHandle allocator;
|
||||
|
||||
private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
|
||||
|
||||
@ -79,7 +87,7 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData {
|
||||
* Used for specialization based on runtime arguments. Whenever we specialize on
|
||||
* callsite parameter types at runtime, we need to use a parameter type guard to
|
||||
* ensure that the specialized version of the script function continues to be
|
||||
* applicable for a particular callsite *
|
||||
* applicable for a particular callsite.
|
||||
*/
|
||||
private static final MethodHandle PARAM_TYPE_GUARD = findOwnMH("paramTypeGuard", boolean.class, Type[].class, Object[].class);
|
||||
|
||||
@ -88,10 +96,12 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData {
|
||||
* (or java.lang.Number instance) to specialize the parameter to an integer, if the
|
||||
* parameter in question can be represented as one. The double typically only exists
|
||||
* because the compiler doesn't know any better than "a number type" and conservatively
|
||||
* picks doubles when it can't prove that an integer addition wouldn't overflow
|
||||
* picks doubles when it can't prove that an integer addition wouldn't overflow.
|
||||
*/
|
||||
private static final MethodHandle ENSURE_INT = findOwnMH("ensureInt", int.class, Object.class);
|
||||
|
||||
private static final long serialVersionUID = 4914839316174633726L;
|
||||
|
||||
/**
|
||||
* Constructor - public as scripts use it
|
||||
*
|
||||
@ -104,13 +114,16 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData {
|
||||
super(functionName(functionNode),
|
||||
functionNode.getParameters().size(),
|
||||
getFlags(functionNode));
|
||||
|
||||
this.functionNode = functionNode;
|
||||
this.source = functionNode.getSource();
|
||||
this.lineNumber = functionNode.getLineNumber();
|
||||
this.token = tokenFor(functionNode);
|
||||
this.installer = installer;
|
||||
this.allocatorClassName = allocatorClassName;
|
||||
this.allocatorMap = allocatorMap;
|
||||
if (!functionNode.isLazy()) {
|
||||
methodLocator = new MethodLocator(functionNode);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -122,16 +135,19 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData {
|
||||
return "function " + (name == null ? "" : name) + "() { [native code] }";
|
||||
}
|
||||
|
||||
public void setCodeAndSource(final Map<String, Class<?>> code, final Source source) {
|
||||
this.source = source;
|
||||
if (methodLocator != null) {
|
||||
methodLocator.setClass(code.get(methodLocator.getClassName()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
|
||||
if (source != null) {
|
||||
sb.append(source.getName());
|
||||
if (functionNode != null) {
|
||||
sb.append(':').append(functionNode.getLineNumber());
|
||||
}
|
||||
sb.append(' ');
|
||||
sb.append(source.getName()).append(':').append(lineNumber).append(' ');
|
||||
}
|
||||
|
||||
return sb.toString() + super.toString();
|
||||
@ -204,8 +220,13 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData {
|
||||
functionNode = compiler.compile(functionNode);
|
||||
assert !functionNode.isLazy();
|
||||
compiler.install(functionNode);
|
||||
methodLocator = new MethodLocator(functionNode);
|
||||
flags = getFlags(functionNode);
|
||||
}
|
||||
|
||||
if (functionNode != null) {
|
||||
methodLocator.setClass(functionNode.getCompileUnit().getCode());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -221,12 +242,13 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData {
|
||||
* eager compilation or from running a lazy compile on the lines above
|
||||
*/
|
||||
|
||||
assert functionNode.hasState(CompilationState.EMITTED) : functionNode.getName() + " " + functionNode.getState() + " " + Debug.id(functionNode);
|
||||
assert functionNode == null || functionNode.hasState(CompilationState.EMITTED) :
|
||||
functionNode.getName() + " " + functionNode.getState() + " " + Debug.id(functionNode);
|
||||
|
||||
// code exists - look it up and add it into the automatically sorted invoker list
|
||||
addCode(functionNode);
|
||||
|
||||
if (! functionNode.canSpecialize()) {
|
||||
if (functionNode != null && !functionNode.canSpecialize()) {
|
||||
// allow GC to claim IR stuff that is not needed anymore
|
||||
functionNode = null;
|
||||
installer = null;
|
||||
@ -238,13 +260,9 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData {
|
||||
}
|
||||
|
||||
private MethodHandle addCode(final FunctionNode fn, final MethodType runtimeType, final MethodHandle guard, final MethodHandle fallback) {
|
||||
final MethodType targetType = new FunctionSignature(fn).getMethodType();
|
||||
MethodHandle target =
|
||||
MH.findStatic(
|
||||
LOOKUP,
|
||||
fn.getCompileUnit().getCode(),
|
||||
fn.getName(),
|
||||
targetType);
|
||||
assert methodLocator != null;
|
||||
MethodHandle target = methodLocator.getMethodHandle();
|
||||
final MethodType targetType = methodLocator.getMethodType();
|
||||
|
||||
/*
|
||||
* For any integer argument. a double that is representable as an integer is OK.
|
||||
@ -424,7 +442,6 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData {
|
||||
|
||||
Compiler.LOG.info("Callsite specialized ", name, " runtimeType=", runtimeType, " parameters=", snapshot.getParameters(), " args=", Arrays.asList(args));
|
||||
|
||||
assert snapshot != null;
|
||||
assert snapshot != functionNode;
|
||||
|
||||
final Compiler compiler = new Compiler(installer);
|
||||
@ -450,5 +467,45 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData {
|
||||
return MH.findStatic(MethodHandles.lookup(), RecompilableScriptFunctionData.class, name, MH.type(rtype, types));
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper class that allows us to retrieve the method handle for this function once it has been generated.
|
||||
*/
|
||||
private static class MethodLocator implements Serializable {
|
||||
private transient Class<?> clazz;
|
||||
private final String className;
|
||||
private final String methodName;
|
||||
private final MethodType methodType;
|
||||
|
||||
private static final long serialVersionUID = -5420835725902966692L;
|
||||
|
||||
MethodLocator(final FunctionNode functionNode) {
|
||||
this.className = functionNode.getCompileUnit().getUnitClassName();
|
||||
this.methodName = functionNode.getName();
|
||||
this.methodType = new FunctionSignature(functionNode).getMethodType();
|
||||
|
||||
assert className != null;
|
||||
assert methodName != null;
|
||||
}
|
||||
|
||||
void setClass(final Class<?> clazz) {
|
||||
if (!JS.class.isAssignableFrom(clazz)) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
this.clazz = clazz;
|
||||
}
|
||||
|
||||
String getClassName() {
|
||||
return className;
|
||||
}
|
||||
|
||||
MethodType getMethodType() {
|
||||
return methodType;
|
||||
}
|
||||
|
||||
MethodHandle getMethodHandle() {
|
||||
return MH.findStatic(LOOKUP, clazz, methodName, methodType);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -134,6 +134,9 @@ public final class ScriptEnvironment {
|
||||
/** Only parse the source code, do not compile */
|
||||
public final boolean _parse_only;
|
||||
|
||||
/** Enable disk cache for compiled scripts */
|
||||
public final boolean _persistent_cache;
|
||||
|
||||
/** Print the AST before lowering */
|
||||
public final boolean _print_ast;
|
||||
|
||||
@ -218,6 +221,7 @@ public final class ScriptEnvironment {
|
||||
_no_syntax_extensions = options.getBoolean("no.syntax.extensions");
|
||||
_no_typed_arrays = options.getBoolean("no.typed.arrays");
|
||||
_parse_only = options.getBoolean("parse.only");
|
||||
_persistent_cache = options.getBoolean("persistent.code.cache");
|
||||
_print_ast = options.getBoolean("print.ast");
|
||||
_print_lower_ast = options.getBoolean("print.lower.ast");
|
||||
_print_code = options.getBoolean("print.code");
|
||||
|
||||
@ -29,10 +29,10 @@ import static jdk.nashorn.internal.lookup.Lookup.MH;
|
||||
import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
|
||||
import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
import jdk.nashorn.internal.objects.Global;
|
||||
import jdk.nashorn.internal.runtime.linker.JavaAdapterFactory;
|
||||
|
||||
/**
|
||||
@ -40,7 +40,7 @@ import jdk.nashorn.internal.runtime.linker.JavaAdapterFactory;
|
||||
* Instances of this class are created during codegen and stored in script classes'
|
||||
* constants array to reduce function instantiation overhead during runtime.
|
||||
*/
|
||||
public abstract class ScriptFunctionData {
|
||||
public abstract class ScriptFunctionData implements Serializable {
|
||||
|
||||
/** Name of the function or "" for anonynous functions */
|
||||
protected final String name;
|
||||
@ -74,6 +74,8 @@ public abstract class ScriptFunctionData {
|
||||
/** Flag for strict constructors */
|
||||
public static final int IS_STRICT_CONSTRUCTOR = IS_STRICT | IS_CONSTRUCTOR;
|
||||
|
||||
private static final long serialVersionUID = 4252901245508769114L;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
|
||||
@ -593,23 +593,16 @@ public abstract class ScriptObject implements PropertyAccess {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* Almost like defineOwnProperty(int,Object) for arrays this one does
|
||||
* not add 'gap' elements (like the array one does).
|
||||
*
|
||||
* @param index key for property
|
||||
* @param value value to define
|
||||
*/
|
||||
public final void defineOwnProperty(final int index, final Object value) {
|
||||
public 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));
|
||||
setValueAtArrayIndex(longIndex, index, value, false);
|
||||
}
|
||||
|
||||
private void checkIntegerKey(final String key) {
|
||||
@ -2747,9 +2740,7 @@ public abstract class ScriptObject implements PropertyAccess {
|
||||
* @param strict are we in strict mode
|
||||
*/
|
||||
private void doesNotHave(final int index, final Object value, final boolean strict) {
|
||||
final long oldLength = getArray().length();
|
||||
final long longIndex = ArrayIndex.toLongIndex(index);
|
||||
|
||||
if (getMap().containsArrayKeys()) {
|
||||
final String key = JSType.toString(longIndex);
|
||||
final FindProperty find = findProperty(key, true);
|
||||
@ -2760,6 +2751,18 @@ public abstract class ScriptObject implements PropertyAccess {
|
||||
}
|
||||
}
|
||||
|
||||
setValueAtArrayIndex(longIndex, index, value, strict);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle when an array doesn't have a slot - possibly grow and/or convert array.
|
||||
*
|
||||
* @param index key as index
|
||||
* @param value element value
|
||||
* @param strict are we in strict mode
|
||||
*/
|
||||
private void setValueAtArrayIndex(final long longIndex, final int index, final Object value, final boolean strict) {
|
||||
final long oldLength = getArray().length();
|
||||
if (longIndex >= oldLength) {
|
||||
if (!isExtensible()) {
|
||||
if (strict) {
|
||||
|
||||
@ -39,6 +39,8 @@ import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
import jdk.nashorn.internal.parser.Token;
|
||||
@ -71,6 +73,9 @@ public final class Source {
|
||||
/** Cached hash code */
|
||||
private int hash;
|
||||
|
||||
/** Message digest */
|
||||
private byte[] digest;
|
||||
|
||||
/** Source URL if available */
|
||||
private final URL url;
|
||||
|
||||
@ -416,6 +421,40 @@ public final class Source {
|
||||
return readFully(url.openStream(), cs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a message digest for this source.
|
||||
*
|
||||
* @return a message digest for this source
|
||||
*/
|
||||
public synchronized byte[] getDigest() {
|
||||
if (digest == null) {
|
||||
|
||||
final byte[] bytes = new byte[content.length * 2];
|
||||
|
||||
for (int i = 0; i < content.length; i++) {
|
||||
bytes[i * 2] = (byte) (content[i] & 0x00ff);
|
||||
bytes[i * 2 + 1] = (byte) ((content[i] & 0xff00) >> 8);
|
||||
}
|
||||
|
||||
try {
|
||||
final MessageDigest md = MessageDigest.getInstance("SHA-1");
|
||||
if (name != null) {
|
||||
md.update(name.getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
if (base != null) {
|
||||
md.update(base.getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
if (url != null) {
|
||||
md.update(url.toString().getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
digest = md.digest(bytes);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return digest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the base url. This is currently used for testing only
|
||||
* @param url a URL
|
||||
|
||||
@ -186,6 +186,11 @@ public final class UserAccessorProperty extends Property {
|
||||
return Lookup.filterReturnType(USER_ACCESSOR_GETTER.methodHandle(), type);
|
||||
}
|
||||
|
||||
@Override
|
||||
void initMethodHandles(final Class<?> structure) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScriptFunction getGetterFunction(final ScriptObject obj) {
|
||||
final Object value = obj.getSpill(getterSlot);
|
||||
|
||||
@ -230,6 +230,14 @@ nashorn.option.parse.only = { \
|
||||
desc="Parse without compiling." \
|
||||
}
|
||||
|
||||
nashorn.option.persistent.code.cache = { \
|
||||
name="--persistent-code-cache", \
|
||||
short_name="-pcc", \
|
||||
desc="Enable disk cache for compiled scripts.", \
|
||||
is_undocumented=true, \
|
||||
default=false \
|
||||
}
|
||||
|
||||
nashorn.option.profile.callsites = { \
|
||||
name="--profile-callsites", \
|
||||
short_name="-pcs", \
|
||||
|
||||
41
nashorn/test/script/basic/JDK-8037562.js
Normal file
41
nashorn/test/script/basic/JDK-8037562.js
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* JDK-8037562: Nashorn: JSON.parse comes up with nonexistent entries if there are gaps between the keys
|
||||
*
|
||||
* @test
|
||||
* @run
|
||||
*/
|
||||
|
||||
var strs = [
|
||||
'{ "0":0, "2":2 }',
|
||||
'{ "0":"", "2":"" }',
|
||||
'{ "0":0, "5":"hello" }',
|
||||
'{ "0":"", "15":3234 }',
|
||||
]
|
||||
|
||||
for (var i in strs) {
|
||||
print(JSON.stringify(JSON.parse(strs[i])));
|
||||
}
|
||||
4
nashorn/test/script/basic/JDK-8037562.js.EXPECTED
Normal file
4
nashorn/test/script/basic/JDK-8037562.js.EXPECTED
Normal file
@ -0,0 +1,4 @@
|
||||
{"0":0,"2":2}
|
||||
{"0":"","2":""}
|
||||
{"0":0,"5":"hello"}
|
||||
{"0":"","15":3234}
|
||||
35
nashorn/test/script/error/JDK-8039047.js
Normal file
35
nashorn/test/script/error/JDK-8039047.js
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* JDK-8039047: Parser accepts conditional catch clauses even when --no-syntax-extensions / -nse option is passed
|
||||
*
|
||||
* @option --no-syntax-extensions
|
||||
* @test/compile-error
|
||||
*/
|
||||
|
||||
try {
|
||||
func()
|
||||
} catch (e if e instanceof ReferenceError) {
|
||||
print("Got ReferenceError " + e);
|
||||
}
|
||||
6
nashorn/test/script/error/JDK-8039047.js.EXPECTED
Normal file
6
nashorn/test/script/error/JDK-8039047.js.EXPECTED
Normal file
@ -0,0 +1,6 @@
|
||||
test/script/error/JDK-8039047.js:33:11 Expected ) but found if
|
||||
} catch (e if e instanceof ReferenceError) {
|
||||
^
|
||||
test/script/error/JDK-8039047.js:35:0 Expected eof but found }
|
||||
}
|
||||
^
|
||||
@ -37,6 +37,8 @@ import javax.script.ScriptEngineFactory;
|
||||
import javax.script.ScriptEngineManager;
|
||||
import javax.script.SimpleScriptContext;
|
||||
import jdk.nashorn.api.scripting.NashornScriptEngineFactory;
|
||||
import org.testng.annotations.AfterTest;
|
||||
import org.testng.annotations.BeforeTest;
|
||||
|
||||
/**
|
||||
* @test
|
||||
@ -50,8 +52,8 @@ public class NoPersistenceCachingTest {
|
||||
private ScriptContext context1, context2, context3;
|
||||
private ByteArrayOutputStream stderr;
|
||||
private PrintStream prevStderr;
|
||||
private final String script = "print('Hello')";
|
||||
|
||||
@BeforeTest
|
||||
public void setupTest() {
|
||||
stderr = new ByteArrayOutputStream();
|
||||
prevStderr = System.err;
|
||||
@ -69,33 +71,33 @@ public class NoPersistenceCachingTest {
|
||||
}
|
||||
String[] options = new String[]{"--log=compiler:finest"};
|
||||
engine = nashornFactory.getScriptEngine(options);
|
||||
context1 = engine.getContext();
|
||||
context2 = new SimpleScriptContext();
|
||||
context2.setBindings(engine.createBindings(), ScriptContext.ENGINE_SCOPE);
|
||||
context3 = new SimpleScriptContext();
|
||||
context3.setBindings(engine.createBindings(), ScriptContext.ENGINE_SCOPE);
|
||||
}
|
||||
|
||||
@AfterTest
|
||||
public void setErrTest() {
|
||||
System.setErr(prevStderr);
|
||||
}
|
||||
|
||||
public void runTest(int numberOfContext, String expectedOutputPattern,
|
||||
int expectedPatternOccurrence) {
|
||||
setupTest();
|
||||
|
||||
try {
|
||||
switch (numberOfContext) {
|
||||
case 2:
|
||||
context1 = engine.getContext();
|
||||
context2 = new SimpleScriptContext();
|
||||
context2.setBindings(engine.createBindings(), ScriptContext.ENGINE_SCOPE);
|
||||
engine.eval(script, context1);
|
||||
engine.eval(script, context2);
|
||||
String scriptTwoContexts = "print('HelloTwoContexts')";
|
||||
engine.eval(scriptTwoContexts, context1);
|
||||
engine.eval(scriptTwoContexts, context2);
|
||||
break;
|
||||
case 3:
|
||||
context1 = engine.getContext();
|
||||
context2 = new SimpleScriptContext();
|
||||
context2.setBindings(engine.createBindings(), ScriptContext.ENGINE_SCOPE);
|
||||
context3 = new SimpleScriptContext();
|
||||
context3.setBindings(engine.createBindings(), ScriptContext.ENGINE_SCOPE);
|
||||
engine.eval(script, context1);
|
||||
engine.eval(script, context2);
|
||||
engine.eval(script, context3);
|
||||
String scriptThreeContexts = "print('HelloThreeContexts')";
|
||||
engine.eval(scriptThreeContexts, context1);
|
||||
engine.eval(scriptThreeContexts, context2);
|
||||
engine.eval(scriptThreeContexts, context3);
|
||||
break;
|
||||
}
|
||||
} catch (final Exception se) {
|
||||
@ -113,7 +115,7 @@ public class NoPersistenceCachingTest {
|
||||
+ expectedPatternOccurrence + " and found: " + matches + "\n"
|
||||
+ stderr);
|
||||
}
|
||||
setErrTest();
|
||||
stderr.reset();
|
||||
}
|
||||
|
||||
private static String getCodeCachePattern() {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user