Merge
This commit is contained in:
commit
803a8d9310
@ -280,12 +280,11 @@ public class ClassGenerator {
|
||||
addField(cv, name, OBJECT_DESC);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
static void newFunction(final MethodGenerator mi, final String objName, final String className, final MemberInfo memInfo, final List<MemberInfo> specs) {
|
||||
final boolean arityFound = (memInfo.getArity() != MemberInfo.DEFAULT_ARITY);
|
||||
|
||||
loadFunctionName(mi, memInfo.getName());
|
||||
mi.visitLdcInsn(new Handle(H_INVOKESTATIC, className, memInfo.getJavaName(), memInfo.getJavaDesc()));
|
||||
mi.visitLdcInsn(new Handle(H_INVOKESTATIC, className, memInfo.getJavaName(), memInfo.getJavaDesc(), false));
|
||||
|
||||
assert specs != null;
|
||||
if (!specs.isEmpty()) {
|
||||
@ -306,7 +305,6 @@ public class ClassGenerator {
|
||||
mi.invokeVirtual(SCRIPTFUNCTION_TYPE, SCRIPTFUNCTION_SETDOCUMENTATIONKEY, SCRIPTFUNCTION_SETDOCUMENTATIONKEY_DESC);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
static void linkerAddGetterSetter(final MethodGenerator mi, final String className, final MemberInfo memInfo) {
|
||||
final String propertyName = memInfo.getName();
|
||||
// stack: Collection
|
||||
@ -319,13 +317,13 @@ public class ClassGenerator {
|
||||
mi.push(memInfo.getAttributes());
|
||||
// setup getter method handle
|
||||
String javaName = GETTER_PREFIX + memInfo.getJavaName();
|
||||
mi.visitLdcInsn(new Handle(H_INVOKEVIRTUAL, className, javaName, getterDesc(memInfo)));
|
||||
mi.visitLdcInsn(new Handle(H_INVOKEVIRTUAL, className, javaName, getterDesc(memInfo), false));
|
||||
// setup setter method handle
|
||||
if (memInfo.isFinal()) {
|
||||
mi.pushNull();
|
||||
} else {
|
||||
javaName = SETTER_PREFIX + memInfo.getJavaName();
|
||||
mi.visitLdcInsn(new Handle(H_INVOKEVIRTUAL, className, javaName, setterDesc(memInfo)));
|
||||
mi.visitLdcInsn(new Handle(H_INVOKEVIRTUAL, className, javaName, setterDesc(memInfo), false));
|
||||
}
|
||||
// property = AccessorProperty.create(key, flags, getter, setter);
|
||||
mi.invokeStatic(ACCESSORPROPERTY_TYPE, ACCESSORPROPERTY_CREATE, ACCESSORPROPERTY_CREATE_DESC);
|
||||
@ -336,7 +334,6 @@ public class ClassGenerator {
|
||||
// stack: Collection
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
static void linkerAddGetterSetter(final MethodGenerator mi, final String className, final MemberInfo getter, final MemberInfo setter) {
|
||||
final String propertyName = getter.getName();
|
||||
// stack: Collection
|
||||
@ -349,13 +346,13 @@ public class ClassGenerator {
|
||||
mi.push(getter.getAttributes());
|
||||
// setup getter method handle
|
||||
mi.visitLdcInsn(new Handle(H_INVOKESTATIC, className,
|
||||
getter.getJavaName(), getter.getJavaDesc()));
|
||||
getter.getJavaName(), getter.getJavaDesc(), false));
|
||||
// setup setter method handle
|
||||
if (setter == null) {
|
||||
mi.pushNull();
|
||||
} else {
|
||||
mi.visitLdcInsn(new Handle(H_INVOKESTATIC, className,
|
||||
setter.getJavaName(), setter.getJavaDesc()));
|
||||
setter.getJavaName(), setter.getJavaDesc(), false));
|
||||
}
|
||||
// property = AccessorProperty.create(key, flags, getter, setter);
|
||||
mi.invokeStatic(ACCESSORPROPERTY_TYPE, ACCESSORPROPERTY_CREATE, ACCESSORPROPERTY_CREATE_DESC);
|
||||
|
@ -178,7 +178,6 @@ public class ConstructorGenerator extends ClassGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private void callSuper(final MethodGenerator mi) {
|
||||
String superClass, superDesc;
|
||||
mi.loadThis();
|
||||
@ -192,7 +191,7 @@ public class ConstructorGenerator extends ClassGenerator {
|
||||
superClass = SCRIPTFUNCTION_TYPE;
|
||||
superDesc = (memberCount > 0) ? SCRIPTFUNCTION_INIT_DESC4 : SCRIPTFUNCTION_INIT_DESC3;
|
||||
mi.loadLiteral(constructor.getName());
|
||||
mi.visitLdcInsn(new Handle(H_INVOKESTATIC, scriptClassInfo.getJavaName(), constructor.getJavaName(), constructor.getJavaDesc()));
|
||||
mi.visitLdcInsn(new Handle(H_INVOKESTATIC, scriptClassInfo.getJavaName(), constructor.getJavaName(), constructor.getJavaDesc(), false));
|
||||
loadMap(mi);
|
||||
mi.memberInfoArray(scriptClassInfo.getJavaName(), specs); //pushes null if specs empty
|
||||
}
|
||||
|
@ -390,7 +390,6 @@ public class MethodGenerator extends MethodVisitor {
|
||||
return EMPTY_LINK_LOGIC_TYPE.equals(type);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
void memberInfoArray(final String className, final List<MemberInfo> mis) {
|
||||
if (mis.isEmpty()) {
|
||||
pushNull();
|
||||
@ -405,7 +404,7 @@ public class MethodGenerator extends MethodVisitor {
|
||||
push(pos++);
|
||||
visitTypeInsn(NEW, SPECIALIZATION_TYPE);
|
||||
dup();
|
||||
visitLdcInsn(new Handle(H_INVOKESTATIC, className, mi.getJavaName(), mi.getJavaDesc()));
|
||||
visitLdcInsn(new Handle(H_INVOKESTATIC, className, mi.getJavaName(), mi.getJavaDesc(), false));
|
||||
final Type linkLogicClass = mi.getLinkLogicClass();
|
||||
final boolean linkLogic = !linkLogicIsEmpty(linkLogicClass);
|
||||
final String ctor = linkLogic ? SPECIALIZATION_INIT3 : SPECIALIZATION_INIT2;
|
||||
|
142
nashorn/samples/checknames.js
Normal file
142
nashorn/samples/checknames.js
Normal file
@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* - Neither the name of Oracle nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
// Simple Java identifier name pattern checker. You can check
|
||||
// class, method and variable names in java sources to confirm
|
||||
// to specified patterns. Default check functions just check for
|
||||
// 'too short' names. You can customize checkXYZName functions to
|
||||
// have arbitrary name pattern checks.
|
||||
|
||||
// Usage: jjs checknames.js -- <directory>
|
||||
|
||||
if (arguments.length == 0) {
|
||||
print("Usage: jjs checknames.js -- <directory>");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Java types used
|
||||
var File = Java.type("java.io.File");
|
||||
var Files = Java.type("java.nio.file.Files");
|
||||
var StringArray = Java.type("java.lang.String[]");
|
||||
var ToolProvider = Java.type("javax.tools.ToolProvider");
|
||||
var Tree = Java.type("com.sun.source.tree.Tree");
|
||||
var Trees = Java.type("com.sun.source.util.Trees");
|
||||
var TreeScanner = Java.type("com.sun.source.util.TreeScanner");
|
||||
|
||||
// replace these checkXYZ functions with checks you want!
|
||||
function checkClassName(name) {
|
||||
return name.length < 3;
|
||||
}
|
||||
|
||||
function checkMethodName(name) {
|
||||
return name.length < 3;
|
||||
}
|
||||
|
||||
function checkVarName(name) {
|
||||
return name.length < 3;
|
||||
}
|
||||
|
||||
function checkNames() {
|
||||
// get the system compiler tool
|
||||
var compiler = ToolProvider.systemJavaCompiler;
|
||||
// get standard file manager
|
||||
var fileMgr = compiler.getStandardFileManager(null, null, null);
|
||||
// Using Java.to convert script array (arguments) to a Java String[]
|
||||
var compUnits = fileMgr.getJavaFileObjects(Java.to(arguments, StringArray));
|
||||
// create a new compilation task
|
||||
var task = compiler.getTask(null, fileMgr, null, null, null, compUnits);
|
||||
var sourcePositions = Trees.instance(task).sourcePositions;
|
||||
// subclass SimpleTreeVisitor
|
||||
var NameChecker = Java.extend(TreeScanner);
|
||||
|
||||
var visitor = new NameChecker() {
|
||||
report: function(node) {
|
||||
var pos = sourcePositions.getStartPosition(this.compUnit, node);
|
||||
var line = this.lineMap.getLineNumber(pos);
|
||||
var col = this.lineMap.getColumnNumber(pos);
|
||||
print("Too short name: " + node.name + " @ " + this.fileName + ":" + line + ":" + col);
|
||||
},
|
||||
|
||||
// override to capture information on current compilation unit
|
||||
visitCompilationUnit: function(compUnit, p) {
|
||||
this.compUnit = compUnit;
|
||||
this.lineMap = compUnit.lineMap;
|
||||
this.fileName = compUnit.sourceFile.name;
|
||||
|
||||
return Java.super(visitor).visitCompilationUnit(compUnit, p);
|
||||
},
|
||||
|
||||
// override to check class name
|
||||
visitClass: function(node, p) {
|
||||
if (checkClassName(node.simpleName.toString())) {
|
||||
this.report(node);
|
||||
}
|
||||
|
||||
return Java.super(visitor).visitClass(node, p);
|
||||
},
|
||||
|
||||
// override to check method name
|
||||
visitMethod: function(node, p) {
|
||||
if (checkMethodName(node.name.toString())) {
|
||||
this.report(node);
|
||||
}
|
||||
|
||||
return Java.super(visitor).visitMethod(node, p);
|
||||
},
|
||||
|
||||
// override to check variable name
|
||||
visitVariable: function(node, p) {
|
||||
if (checkVarName(node.name.toString())) {
|
||||
this.report(node);
|
||||
}
|
||||
|
||||
return Java.super(visitor).visitVariable(node, p);
|
||||
}
|
||||
}
|
||||
|
||||
for each (var cu in task.parse()) {
|
||||
cu.accept(visitor, null);
|
||||
}
|
||||
}
|
||||
|
||||
// for each ".java" file in directory (recursively).
|
||||
function main(dir) {
|
||||
var totalCount = 0;
|
||||
Files.walk(dir.toPath()).
|
||||
forEach(function(p) {
|
||||
var name = p.toFile().absolutePath;
|
||||
if (name.endsWith(".java")) {
|
||||
checkNames(p);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
main(new File(arguments[0]));
|
@ -28,7 +28,6 @@ package jdk.nashorn.internal;
|
||||
/**
|
||||
* Class that exposes the current state of asserts.
|
||||
*/
|
||||
@SuppressWarnings("all")
|
||||
public final class AssertsEnabled {
|
||||
private static boolean assertsEnabled = false;
|
||||
static {
|
||||
|
@ -32,6 +32,7 @@ import static jdk.internal.org.objectweb.asm.Opcodes.GETFIELD;
|
||||
import static jdk.internal.org.objectweb.asm.Opcodes.GETSTATIC;
|
||||
import static jdk.internal.org.objectweb.asm.Opcodes.GOTO;
|
||||
import static jdk.internal.org.objectweb.asm.Opcodes.H_INVOKESTATIC;
|
||||
import static jdk.internal.org.objectweb.asm.Opcodes.H_INVOKEINTERFACE;
|
||||
import static jdk.internal.org.objectweb.asm.Opcodes.IFEQ;
|
||||
import static jdk.internal.org.objectweb.asm.Opcodes.IFGE;
|
||||
import static jdk.internal.org.objectweb.asm.Opcodes.IFGT;
|
||||
@ -170,12 +171,10 @@ public class MethodEmitter {
|
||||
}
|
||||
|
||||
/** Bootstrap for normal indy:s */
|
||||
@SuppressWarnings("deprecation")
|
||||
private static final Handle LINKERBOOTSTRAP = new Handle(H_INVOKESTATIC, Bootstrap.BOOTSTRAP.className(), Bootstrap.BOOTSTRAP.name(), Bootstrap.BOOTSTRAP.descriptor());
|
||||
private static final Handle LINKERBOOTSTRAP = new Handle(H_INVOKESTATIC, Bootstrap.BOOTSTRAP.className(), Bootstrap.BOOTSTRAP.name(), Bootstrap.BOOTSTRAP.descriptor(), false);
|
||||
|
||||
/** Bootstrap for array populators */
|
||||
@SuppressWarnings("deprecation")
|
||||
private static final Handle POPULATE_ARRAY_BOOTSTRAP = new Handle(H_INVOKESTATIC, RewriteException.BOOTSTRAP.className(), RewriteException.BOOTSTRAP.name(), RewriteException.BOOTSTRAP.descriptor());
|
||||
private static final Handle POPULATE_ARRAY_BOOTSTRAP = new Handle(H_INVOKESTATIC, RewriteException.BOOTSTRAP.className(), RewriteException.BOOTSTRAP.name(), RewriteException.BOOTSTRAP.descriptor(), false);
|
||||
|
||||
/**
|
||||
* Constructor - internal use from ClassEmitter only
|
||||
@ -1007,10 +1006,10 @@ public class MethodEmitter {
|
||||
*
|
||||
* @return the method emitter
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
MethodEmitter loadHandle(final String className, final String methodName, final String descName, final EnumSet<Flag> flags) {
|
||||
final int flag = Flag.getValue(flags);
|
||||
debug("load handle ");
|
||||
pushType(Type.OBJECT.ldc(method, new Handle(Flag.getValue(flags), className, methodName, descName)));
|
||||
pushType(Type.OBJECT.ldc(method, new Handle(flag, className, methodName, descName, flag == H_INVOKEINTERFACE)));
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -2474,14 +2474,14 @@ public final class Global extends Scope {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FindProperty findProperty(final Object key, final boolean deep, final ScriptObject start) {
|
||||
if (lexicalScope != null && start != this && start.isScope()) {
|
||||
protected FindProperty findProperty(final Object key, final boolean deep, boolean isScope, final ScriptObject start) {
|
||||
if (lexicalScope != null && isScope) {
|
||||
final FindProperty find = lexicalScope.findProperty(key, false);
|
||||
if (find != null) {
|
||||
return find;
|
||||
}
|
||||
}
|
||||
return super.findProperty(key, deep, start);
|
||||
return super.findProperty(key, deep, isScope, start);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -2854,8 +2854,7 @@ public final class Global extends Scope {
|
||||
sb.append("$Constructor");
|
||||
|
||||
final Class<?> funcClass = Class.forName(sb.toString());
|
||||
@SuppressWarnings("deprecation")
|
||||
final T res = clazz.cast(funcClass.newInstance());
|
||||
final T res = clazz.cast(funcClass.getDeclaredConstructor().newInstance());
|
||||
|
||||
if (res instanceof ScriptFunction) {
|
||||
// All global constructor prototypes are not-writable,
|
||||
@ -2871,8 +2870,12 @@ public final class Global extends Scope {
|
||||
res.setIsBuiltin();
|
||||
|
||||
return res;
|
||||
} catch (final ClassNotFoundException | InstantiationException | IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (final Exception e) {
|
||||
if (e instanceof RuntimeException) {
|
||||
throw (RuntimeException)e;
|
||||
} else {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2882,14 +2885,17 @@ public final class Global extends Scope {
|
||||
final String className = PACKAGE_PREFIX + name + "$Prototype";
|
||||
|
||||
final Class<?> funcClass = Class.forName(className);
|
||||
@SuppressWarnings("deprecation")
|
||||
final ScriptObject res = (ScriptObject) funcClass.newInstance();
|
||||
final ScriptObject res = (ScriptObject) funcClass.getDeclaredConstructor().newInstance();
|
||||
|
||||
res.setIsBuiltin();
|
||||
res.setInitialProto(prototype);
|
||||
return res;
|
||||
} catch (final ClassNotFoundException | InstantiationException | IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (final Exception e) {
|
||||
if (e instanceof RuntimeException) {
|
||||
throw (RuntimeException)e;
|
||||
} else {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -775,7 +775,7 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
|
||||
* @return FindPropertyData or null if not found.
|
||||
*/
|
||||
public final FindProperty findProperty(final Object key, final boolean deep) {
|
||||
return findProperty(key, deep, this);
|
||||
return findProperty(key, deep, false, this);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -791,12 +791,12 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
|
||||
* @see jdk.nashorn.internal.objects.NativeArray
|
||||
*
|
||||
* @param key Property key.
|
||||
* @param deep Whether the search should look up proto chain.
|
||||
* @param deep true if the search should look up proto chain
|
||||
* @param isScope true if this is a scope access
|
||||
* @param start the object on which the lookup was originally initiated
|
||||
*
|
||||
* @return FindPropertyData or null if not found.
|
||||
*/
|
||||
protected FindProperty findProperty(final Object key, final boolean deep, final ScriptObject start) {
|
||||
protected FindProperty findProperty(final Object key, final boolean deep, boolean isScope, final ScriptObject start) {
|
||||
|
||||
final PropertyMap selfMap = getMap();
|
||||
final Property property = selfMap.findProperty(key);
|
||||
@ -807,7 +807,7 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
|
||||
|
||||
if (deep) {
|
||||
final ScriptObject myProto = getProto();
|
||||
final FindProperty find = myProto == null ? null : myProto.findProperty(key, true, start);
|
||||
final FindProperty find = myProto == null ? null : myProto.findProperty(key, true, isScope, start);
|
||||
// checkSharedProtoMap must be invoked after myProto.checkSharedProtoMap to propagate
|
||||
// shared proto invalidation up the prototype chain. It also must be invoked when prototype is null.
|
||||
checkSharedProtoMap();
|
||||
@ -1977,7 +1977,7 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
|
||||
return findMegaMorphicGetMethod(desc, name, operation == StandardOperation.GET_METHOD);
|
||||
}
|
||||
|
||||
final FindProperty find = findProperty(name, true);
|
||||
final FindProperty find = findProperty(name, true, NashornCallSiteDescriptor.isScope(desc), this);
|
||||
MethodHandle mh;
|
||||
|
||||
if (find == null) {
|
||||
@ -2035,7 +2035,7 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
|
||||
}
|
||||
|
||||
private static GuardedInvocation findMegaMorphicGetMethod(final CallSiteDescriptor desc, final String name, final boolean isMethod) {
|
||||
Context.getContextTrusted().getLogger(ObjectClassGenerator.class).warning("Megamorphic getter: " + desc + " " + name + " " +isMethod);
|
||||
Context.getContextTrusted().getLogger(ObjectClassGenerator.class).warning("Megamorphic getter: ", desc, " ", name + " ", isMethod);
|
||||
final MethodHandle invoker = MH.insertArguments(MEGAMORPHIC_GET, 1, name, isMethod, NashornCallSiteDescriptor.isScope(desc));
|
||||
final MethodHandle guard = getScriptObjectGuard(desc.getMethodType(), true);
|
||||
return new GuardedInvocation(invoker, guard);
|
||||
@ -2043,7 +2043,7 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private Object megamorphicGet(final String key, final boolean isMethod, final boolean isScope) {
|
||||
final FindProperty find = findProperty(key, true);
|
||||
final FindProperty find = findProperty(key, true, isScope, this);
|
||||
if (find != null) {
|
||||
return find.getObjectValue();
|
||||
}
|
||||
@ -2181,7 +2181,7 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
|
||||
*
|
||||
* toString = function() { print("global toString"); } // don't affect Object.prototype.toString
|
||||
*/
|
||||
FindProperty find = findProperty(name, true, this);
|
||||
FindProperty find = findProperty(name, true, NashornCallSiteDescriptor.isScope(desc), this);
|
||||
|
||||
// If it's not a scope search, then we don't want any inherited properties except those with user defined accessors.
|
||||
if (find != null && find.isInherited() && !find.getProperty().isAccessorProperty()) {
|
||||
@ -2258,6 +2258,7 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
|
||||
}
|
||||
|
||||
private GuardedInvocation findMegaMorphicSetMethod(final CallSiteDescriptor desc, final String name) {
|
||||
Context.getContextTrusted().getLogger(ObjectClassGenerator.class).warning("Megamorphic setter: ", desc, " ", name);
|
||||
final MethodType type = desc.getMethodType().insertParameterTypes(1, Object.class);
|
||||
//never bother with ClassCastExceptionGuard for megamorphic callsites
|
||||
final GuardedInvocation inv = findSetIndexMethod(getClass(), desc, false, type);
|
||||
@ -2734,7 +2735,7 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
|
||||
if (isValidArrayIndex(index)) {
|
||||
for (ScriptObject object = this; ; ) {
|
||||
if (object.getMap().containsArrayKeys()) {
|
||||
final FindProperty find = object.findProperty(key, false, this);
|
||||
final FindProperty find = object.findProperty(key, false);
|
||||
|
||||
if (find != null) {
|
||||
return getIntValue(find, programPoint);
|
||||
@ -2805,7 +2806,7 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
|
||||
if (isValidArrayIndex(index)) {
|
||||
for (ScriptObject object = this; ; ) {
|
||||
if (object.getMap().containsArrayKeys()) {
|
||||
final FindProperty find = object.findProperty(key, false, this);
|
||||
final FindProperty find = object.findProperty(key, false);
|
||||
if (find != null) {
|
||||
return getDoubleValue(find, programPoint);
|
||||
}
|
||||
@ -2875,7 +2876,7 @@ public abstract class ScriptObject implements PropertyAccess, Cloneable {
|
||||
if (isValidArrayIndex(index)) {
|
||||
for (ScriptObject object = this; ; ) {
|
||||
if (object.getMap().containsArrayKeys()) {
|
||||
final FindProperty find = object.findProperty(key, false, this);
|
||||
final FindProperty find = object.findProperty(key, false);
|
||||
|
||||
if (find != null) {
|
||||
return find.getObjectValue();
|
||||
|
@ -704,7 +704,17 @@ public final class ScriptRuntime {
|
||||
|
||||
if (property != null) {
|
||||
if (obj instanceof ScriptObject) {
|
||||
obj = ((ScriptObject)obj).get(property);
|
||||
// this is a scope identifier
|
||||
assert property instanceof String;
|
||||
final ScriptObject sobj = (ScriptObject) obj;
|
||||
|
||||
final FindProperty find = sobj.findProperty(property, true, true, sobj);
|
||||
if (find != null) {
|
||||
obj = find.getObjectValue();
|
||||
} else {
|
||||
obj = sobj.invokeNoSuchProperty(property, false, UnwarrantedOptimismException.INVALID_PROGRAM_POINT);
|
||||
}
|
||||
|
||||
if(Global.isLocationPropertyPlaceholder(obj)) {
|
||||
if(CompilerConstants.__LINE__.name().equals(property)) {
|
||||
obj = 0;
|
||||
|
@ -193,20 +193,20 @@ public final class WithObject extends Scope {
|
||||
*
|
||||
* @param key Property key.
|
||||
* @param deep Whether the search should look up proto chain.
|
||||
* @param isScope true if is this a scope access
|
||||
* @param start the object on which the lookup was originally initiated
|
||||
*
|
||||
* @return FindPropertyData or null if not found.
|
||||
*/
|
||||
@Override
|
||||
protected FindProperty findProperty(final Object key, final boolean deep, final ScriptObject start) {
|
||||
protected FindProperty findProperty(final Object key, final boolean deep, boolean isScope, final ScriptObject start) {
|
||||
// We call findProperty on 'expression' with 'expression' itself as start parameter.
|
||||
// This way in ScriptObject.setObject we can tell the property is from a 'with' expression
|
||||
// (as opposed from another non-scope object in the proto chain such as Object.prototype).
|
||||
final FindProperty exprProperty = expression.findProperty(key, true, expression);
|
||||
final FindProperty exprProperty = expression.findProperty(key, true, false, expression);
|
||||
if (exprProperty != null) {
|
||||
return exprProperty;
|
||||
}
|
||||
return super.findProperty(key, deep, start);
|
||||
return super.findProperty(key, deep, isScope, start);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -191,18 +191,16 @@ final class JavaAdapterBytecodeGenerator {
|
||||
private static final Call RUN = interfaceCallNoLookup(Runnable.class, "run", void.class);
|
||||
|
||||
// ASM handle to the bootstrap method
|
||||
@SuppressWarnings("deprecation")
|
||||
private static final Handle BOOTSTRAP_HANDLE = new Handle(H_INVOKESTATIC,
|
||||
Type.getInternalName(JavaAdapterServices.class), "bootstrap",
|
||||
MethodType.methodType(CallSite.class, Lookup.class, String.class,
|
||||
MethodType.class, int.class).toMethodDescriptorString());
|
||||
MethodType.class, int.class).toMethodDescriptorString(), false);
|
||||
|
||||
// ASM handle to the bootstrap method for array populator
|
||||
@SuppressWarnings("deprecation")
|
||||
private static final Handle CREATE_ARRAY_BOOTSTRAP_HANDLE = new Handle(H_INVOKESTATIC,
|
||||
Type.getInternalName(JavaAdapterServices.class), "createArrayBootstrap",
|
||||
MethodType.methodType(CallSite.class, Lookup.class, String.class,
|
||||
MethodType.class).toMethodDescriptorString());
|
||||
MethodType.class).toMethodDescriptorString(), false);
|
||||
|
||||
// Field type names used in the generated bytecode
|
||||
private static final String SCRIPT_OBJECT_TYPE_DESCRIPTOR = SCRIPT_OBJECT_TYPE.getDescriptor();
|
||||
@ -1061,13 +1059,12 @@ final class JavaAdapterBytecodeGenerator {
|
||||
endMethod(mv);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private void generateFinalizerOverride() {
|
||||
final InstructionAdapter mv = new InstructionAdapter(cw.visitMethod(ACC_PUBLIC, "finalize",
|
||||
VOID_METHOD_DESCRIPTOR, null, null));
|
||||
// Overridden finalizer will take a MethodHandle to the finalizer delegating method, ...
|
||||
mv.aconst(new Handle(Opcodes.H_INVOKESTATIC, generatedClassName, FINALIZER_DELEGATE_NAME,
|
||||
FINALIZER_DELEGATE_METHOD_DESCRIPTOR));
|
||||
FINALIZER_DELEGATE_METHOD_DESCRIPTOR, false));
|
||||
mv.visitVarInsn(ALOAD, 0);
|
||||
// ...and invoke it through JavaAdapterServices.invokeNoPermissions
|
||||
INVOKE_NO_PERMISSIONS.invoke(mv);
|
||||
|
@ -46,8 +46,8 @@ import static org.testng.Assert.assertEquals;
|
||||
public class LexicalBindingTest {
|
||||
|
||||
final static String LANGUAGE_ES6 = "--language=es6";
|
||||
final static int NUMBER_OF_CONTEXTS = 20;
|
||||
final static int MEGAMORPHIC_LOOP_COUNT = 20;
|
||||
final static int NUMBER_OF_CONTEXTS = 40;
|
||||
final static int MEGAMORPHIC_LOOP_COUNT = 40;
|
||||
|
||||
/**
|
||||
* Test access to global var-declared variables for shared script classes with multiple globals.
|
||||
@ -57,19 +57,21 @@ public class LexicalBindingTest {
|
||||
final NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
|
||||
final ScriptEngine e = factory.getScriptEngine();
|
||||
final ScriptContext[] contexts = new ScriptContext[NUMBER_OF_CONTEXTS];
|
||||
final String sharedScript = "foo";
|
||||
final String sharedScript1 = "foo";
|
||||
final String sharedScript2 = "bar = foo; bar";
|
||||
|
||||
|
||||
for (int i = 0; i < NUMBER_OF_CONTEXTS; i++) {
|
||||
final ScriptContext context = contexts[i] = new SimpleScriptContext();
|
||||
final Bindings b = e.createBindings();
|
||||
context.setBindings(b, ScriptContext.ENGINE_SCOPE);
|
||||
assertEquals(e.eval("var foo = '" + i + "';", context), null);
|
||||
assertEquals(e.eval("var foo = '" + i + "'; var bar;", context), null);
|
||||
}
|
||||
|
||||
for (int i = 0; i < NUMBER_OF_CONTEXTS; i++) {
|
||||
final ScriptContext context = contexts[i];
|
||||
assertEquals(e.eval(sharedScript, context), String.valueOf(i));
|
||||
assertEquals(e.eval(sharedScript1, context), String.valueOf(i));
|
||||
assertEquals(e.eval(sharedScript2, context), String.valueOf(i));
|
||||
}
|
||||
}
|
||||
|
||||
@ -81,19 +83,21 @@ public class LexicalBindingTest {
|
||||
final NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
|
||||
final ScriptEngine e = factory.getScriptEngine(LANGUAGE_ES6);
|
||||
final ScriptContext[] contexts = new ScriptContext[NUMBER_OF_CONTEXTS];
|
||||
final String sharedScript = "foo";
|
||||
final String sharedScript1 = "foo";
|
||||
final String sharedScript2 = "bar = foo; bar";
|
||||
|
||||
|
||||
for (int i = 0; i < NUMBER_OF_CONTEXTS; i++) {
|
||||
final ScriptContext context = contexts[i] = new SimpleScriptContext();
|
||||
final Bindings b = e.createBindings();
|
||||
context.setBindings(b, ScriptContext.ENGINE_SCOPE);
|
||||
assertEquals(e.eval("let foo = '" + i + "';", context), null);
|
||||
assertEquals(e.eval("let foo = '" + i + "'; let bar; ", context), null);
|
||||
}
|
||||
|
||||
for (int i = 0; i < NUMBER_OF_CONTEXTS; i++) {
|
||||
final ScriptContext context = contexts[i];
|
||||
assertEquals(e.eval(sharedScript, context), String.valueOf(i));
|
||||
assertEquals(e.eval(sharedScript1, context), String.valueOf(i));
|
||||
assertEquals(e.eval(sharedScript2, context), String.valueOf(i));
|
||||
}
|
||||
}
|
||||
|
||||
@ -182,6 +186,27 @@ public class LexicalBindingTest {
|
||||
assertEquals(e.eval(sharedScript, newCtxt), "newer context");
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure lexically defined variables are accessible in other scripts.
|
||||
*/
|
||||
@Test
|
||||
public void lexicalScopeTest() throws ScriptException {
|
||||
final NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
|
||||
final ScriptEngine e = factory.getScriptEngine(LANGUAGE_ES6);
|
||||
|
||||
e.eval("let x; const y = 'world';");
|
||||
|
||||
assertEquals(e.eval("x = 'hello'"), "hello");
|
||||
assertEquals(e.eval("typeof x"), "string");
|
||||
assertEquals(e.eval("typeof y"), "string");
|
||||
assertEquals(e.eval("x"), "hello");
|
||||
assertEquals(e.eval("y"), "world");
|
||||
assertEquals(e.eval("typeof this.x"), "undefined");
|
||||
assertEquals(e.eval("typeof this.y"), "undefined");
|
||||
assertEquals(e.eval("this.x"), null);
|
||||
assertEquals(e.eval("this.y"), null);
|
||||
}
|
||||
|
||||
private static class ScriptRunner implements Runnable {
|
||||
|
||||
final ScriptEngine engine;
|
||||
|
Loading…
x
Reference in New Issue
Block a user