mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-05 11:15:13 +00:00
8057691: Nashorn: let & const declarations are not shared between scripts
Reviewed-by: lagergren, attila
This commit is contained in:
parent
35268dc495
commit
b5ae347f9c
@ -356,6 +356,10 @@ final class AssignSymbols extends NodeVisitor<LexicalContext> implements Loggabl
|
||||
throwParserException(ECMAErrors.getMessage("syntax.error.redeclare.variable", name), origin);
|
||||
} else {
|
||||
symbol.setHasBeenDeclared();
|
||||
// Set scope flag on top-level block scoped symbols
|
||||
if (function.isProgram() && function.getBody() == block) {
|
||||
symbol.setIsScope();
|
||||
}
|
||||
}
|
||||
} else if ((flags & IS_INTERNAL) != 0) {
|
||||
// Always create a new definition.
|
||||
@ -540,7 +544,7 @@ final class AssignSymbols extends NodeVisitor<LexicalContext> implements Loggabl
|
||||
final int flags;
|
||||
if (varNode.isAnonymousFunctionDeclaration()) {
|
||||
flags = IS_INTERNAL;
|
||||
} else if (lc.getCurrentFunction().isProgram()) {
|
||||
} else if (!varNode.isBlockScoped() && lc.getCurrentFunction().isProgram()) {
|
||||
flags = IS_SCOPE;
|
||||
} else {
|
||||
flags = 0;
|
||||
|
||||
@ -152,6 +152,10 @@ public class MapCreator<T> {
|
||||
flags |= Property.NOT_WRITABLE;
|
||||
}
|
||||
|
||||
if (symbol.isBlockScoped()) {
|
||||
flags |= Property.IS_LEXICAL_BINDING;
|
||||
}
|
||||
|
||||
// Mark symbol as needing declaration. Access before declaration will throw a ReferenceError.
|
||||
if (symbol.isBlockScoped() && symbol.isScope()) {
|
||||
flags |= Property.NEEDS_DECLARATION;
|
||||
|
||||
@ -34,6 +34,7 @@ import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.lang.invoke.SwitchPoint;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
@ -44,6 +45,7 @@ import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import javax.script.ScriptContext;
|
||||
import javax.script.ScriptEngine;
|
||||
import jdk.internal.dynalink.CallSiteDescriptor;
|
||||
import jdk.internal.dynalink.linker.GuardedInvocation;
|
||||
import jdk.internal.dynalink.linker.LinkRequest;
|
||||
import jdk.nashorn.api.scripting.ClassFilter;
|
||||
@ -54,6 +56,8 @@ import jdk.nashorn.internal.objects.annotations.Property;
|
||||
import jdk.nashorn.internal.objects.annotations.ScriptClass;
|
||||
import jdk.nashorn.internal.runtime.ConsString;
|
||||
import jdk.nashorn.internal.runtime.Context;
|
||||
import jdk.nashorn.internal.runtime.ECMAErrors;
|
||||
import jdk.nashorn.internal.runtime.GlobalConstants;
|
||||
import jdk.nashorn.internal.runtime.GlobalFunctions;
|
||||
import jdk.nashorn.internal.runtime.JSType;
|
||||
import jdk.nashorn.internal.runtime.NativeJavaPackage;
|
||||
@ -69,6 +73,7 @@ import jdk.nashorn.internal.runtime.Specialization;
|
||||
import jdk.nashorn.internal.runtime.arrays.ArrayData;
|
||||
import jdk.nashorn.internal.runtime.linker.Bootstrap;
|
||||
import jdk.nashorn.internal.runtime.linker.InvokeByName;
|
||||
import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
|
||||
import jdk.nashorn.internal.runtime.regexp.RegExpResult;
|
||||
import jdk.nashorn.internal.scripts.JO;
|
||||
|
||||
@ -410,13 +415,14 @@ public final class Global extends ScriptObject implements Scope {
|
||||
// Used to store the last RegExp result to support deprecated RegExp constructor properties
|
||||
private RegExpResult lastRegExpResult;
|
||||
|
||||
private static final MethodHandle EVAL = findOwnMH_S("eval", Object.class, Object.class, Object.class);
|
||||
private static final MethodHandle NO_SUCH_PROPERTY = findOwnMH_S(NO_SUCH_PROPERTY_NAME, Object.class, Object.class, Object.class);
|
||||
private static final MethodHandle PRINT = findOwnMH_S("print", Object.class, Object.class, Object[].class);
|
||||
private static final MethodHandle PRINTLN = findOwnMH_S("println", Object.class, Object.class, Object[].class);
|
||||
private static final MethodHandle LOAD = findOwnMH_S("load", Object.class, Object.class, Object.class);
|
||||
private static final MethodHandle LOADWITHNEWGLOBAL = findOwnMH_S("loadWithNewGlobal", Object.class, Object.class, Object[].class);
|
||||
private static final MethodHandle EXIT = findOwnMH_S("exit", Object.class, Object.class, Object.class);
|
||||
private static final MethodHandle EVAL = findOwnMH_S("eval", Object.class, Object.class, Object.class);
|
||||
private static final MethodHandle NO_SUCH_PROPERTY = findOwnMH_S(NO_SUCH_PROPERTY_NAME, Object.class, Object.class, Object.class);
|
||||
private static final MethodHandle PRINT = findOwnMH_S("print", Object.class, Object.class, Object[].class);
|
||||
private static final MethodHandle PRINTLN = findOwnMH_S("println", Object.class, Object.class, Object[].class);
|
||||
private static final MethodHandle LOAD = findOwnMH_S("load", Object.class, Object.class, Object.class);
|
||||
private static final MethodHandle LOAD_WITH_NEW_GLOBAL = findOwnMH_S("loadWithNewGlobal", Object.class, Object.class, Object[].class);
|
||||
private static final MethodHandle EXIT = findOwnMH_S("exit", Object.class, Object.class, Object.class);
|
||||
private static final MethodHandle LEXICAL_SCOPE_FILTER = findOwnMH_S("lexicalScopeFilter", Object.class, Object.class);
|
||||
|
||||
// initialized by nasgen
|
||||
private static PropertyMap $nasgenmap$;
|
||||
@ -429,6 +435,12 @@ public final class Global extends ScriptObject implements Scope {
|
||||
// current ScriptEngine associated - can be null.
|
||||
private ScriptEngine engine;
|
||||
|
||||
// ES6 global lexical scope.
|
||||
private final LexicalScope lexicalScope;
|
||||
|
||||
// Switchpoint for non-constant global callsites in the presence of ES6 lexical scope.
|
||||
private SwitchPoint lexicalScopeSwitchPoint;
|
||||
|
||||
/**
|
||||
* Set the current script context
|
||||
* @param scontext script context
|
||||
@ -466,6 +478,7 @@ public final class Global extends ScriptObject implements Scope {
|
||||
super(checkAndGetMap(context));
|
||||
this.context = context;
|
||||
this.setIsScope();
|
||||
this.lexicalScope = context.getEnv()._es6 ? new LexicalScope(this) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1693,6 +1706,133 @@ public final class Global extends ScriptObject implements Scope {
|
||||
splitState = state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the ES6 global scope for lexically declared bindings.
|
||||
* @return the ES6 lexical global scope.
|
||||
*/
|
||||
public final ScriptObject getLexicalScope() {
|
||||
assert context.getEnv()._es6;
|
||||
return lexicalScope;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBoundProperties(final ScriptObject source, final jdk.nashorn.internal.runtime.Property[] properties) {
|
||||
PropertyMap ownMap = getMap();
|
||||
LexicalScope lexicalScope = null;
|
||||
PropertyMap lexicalMap = null;
|
||||
boolean hasLexicalDefinitions = false;
|
||||
|
||||
if (context.getEnv()._es6) {
|
||||
lexicalScope = (LexicalScope) getLexicalScope();
|
||||
lexicalMap = lexicalScope.getMap();
|
||||
|
||||
for (final jdk.nashorn.internal.runtime.Property property : properties) {
|
||||
if (property.isLexicalBinding()) {
|
||||
hasLexicalDefinitions = true;
|
||||
}
|
||||
// ES6 15.1.8 steps 6. and 7.
|
||||
final jdk.nashorn.internal.runtime.Property globalProperty = ownMap.findProperty(property.getKey());
|
||||
if (globalProperty != null && !globalProperty.isConfigurable() && property.isLexicalBinding()) {
|
||||
throw ECMAErrors.syntaxError("redeclare.variable", property.getKey());
|
||||
}
|
||||
final jdk.nashorn.internal.runtime.Property lexicalProperty = lexicalMap.findProperty(property.getKey());
|
||||
if (lexicalProperty != null && !property.isConfigurable()) {
|
||||
throw ECMAErrors.syntaxError("redeclare.variable", property.getKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (final jdk.nashorn.internal.runtime.Property property : properties) {
|
||||
if (property.isLexicalBinding()) {
|
||||
assert lexicalScope != null;
|
||||
lexicalMap = lexicalScope.addBoundProperty(lexicalMap, source, property);
|
||||
|
||||
if (ownMap.findProperty(property.getKey()) != null) {
|
||||
// If property exists in the global object invalidate any global constant call sites.
|
||||
invalidateGlobalConstant(property.getKey());
|
||||
}
|
||||
} else {
|
||||
ownMap = addBoundProperty(ownMap, source, property);
|
||||
}
|
||||
}
|
||||
|
||||
setMap(ownMap);
|
||||
|
||||
if (hasLexicalDefinitions) {
|
||||
lexicalScope.setMap(lexicalMap);
|
||||
invalidateLexicalSwitchPoint();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public GuardedInvocation findGetMethod(final CallSiteDescriptor desc, final LinkRequest request, final String operator) {
|
||||
final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
|
||||
final boolean isScope = NashornCallSiteDescriptor.isScope(desc);
|
||||
|
||||
if (lexicalScope != null && isScope && !NashornCallSiteDescriptor.isApplyToCall(desc)) {
|
||||
if (lexicalScope.hasOwnProperty(name)) {
|
||||
return lexicalScope.findGetMethod(desc, request, operator);
|
||||
}
|
||||
}
|
||||
|
||||
final GuardedInvocation invocation = super.findGetMethod(desc, request, operator);
|
||||
|
||||
// We want to avoid adding our generic lexical scope switchpoint to global constant invocations,
|
||||
// because those are invalidated per-key in the addBoundProperties method above.
|
||||
// We therefor check if the invocation does already have a switchpoint and the property is non-inherited,
|
||||
// assuming this only applies to global constants. If other non-inherited properties will
|
||||
// start using switchpoints some time in the future we'll have to revisit this.
|
||||
if (isScope && context.getEnv()._es6 && (invocation.getSwitchPoints() == null || !hasOwnProperty(name))) {
|
||||
return invocation.addSwitchPoint(getLexicalScopeSwitchPoint());
|
||||
}
|
||||
|
||||
return invocation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GuardedInvocation findSetMethod(final CallSiteDescriptor desc, final LinkRequest request) {
|
||||
final boolean isScope = NashornCallSiteDescriptor.isScope(desc);
|
||||
|
||||
if (lexicalScope != null && isScope) {
|
||||
final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
|
||||
if (lexicalScope.hasOwnProperty(name)) {
|
||||
return lexicalScope.findSetMethod(desc, request);
|
||||
}
|
||||
}
|
||||
|
||||
final GuardedInvocation invocation = super.findSetMethod(desc, request);
|
||||
|
||||
if (isScope && context.getEnv()._es6) {
|
||||
return invocation.addSwitchPoint(getLexicalScopeSwitchPoint());
|
||||
}
|
||||
|
||||
return invocation;
|
||||
}
|
||||
|
||||
private synchronized SwitchPoint getLexicalScopeSwitchPoint() {
|
||||
SwitchPoint switchPoint = lexicalScopeSwitchPoint;
|
||||
if (switchPoint == null || switchPoint.hasBeenInvalidated()) {
|
||||
switchPoint = lexicalScopeSwitchPoint = new SwitchPoint();
|
||||
}
|
||||
return switchPoint;
|
||||
}
|
||||
|
||||
private synchronized void invalidateLexicalSwitchPoint() {
|
||||
if (lexicalScopeSwitchPoint != null) {
|
||||
context.getLogger(GlobalConstants.class).info("Invalidating non-constant globals on lexical scope update");
|
||||
SwitchPoint.invalidateAll(new SwitchPoint[]{ lexicalScopeSwitchPoint });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static Object lexicalScopeFilter(final Object self) {
|
||||
if (self instanceof Global) {
|
||||
return ((Global) self).getLexicalScope();
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
private <T extends ScriptObject> T initConstructorAndSwitchPoint(final String name, final Class<T> clazz) {
|
||||
final T func = initConstructor(name, clazz);
|
||||
tagBuiltinProperties(name, func);
|
||||
@ -1737,7 +1877,7 @@ public final class Global extends ScriptObject implements Scope {
|
||||
this.unescape = ScriptFunctionImpl.makeFunction("unescape", GlobalFunctions.UNESCAPE);
|
||||
this.print = ScriptFunctionImpl.makeFunction("print", env._print_no_newline ? PRINT : PRINTLN);
|
||||
this.load = ScriptFunctionImpl.makeFunction("load", LOAD);
|
||||
this.loadWithNewGlobal = ScriptFunctionImpl.makeFunction("loadWithNewGlobal", LOADWITHNEWGLOBAL);
|
||||
this.loadWithNewGlobal = ScriptFunctionImpl.makeFunction("loadWithNewGlobal", LOAD_WITH_NEW_GLOBAL);
|
||||
this.exit = ScriptFunctionImpl.makeFunction("exit", EXIT);
|
||||
this.quit = ScriptFunctionImpl.makeFunction("quit", EXIT);
|
||||
|
||||
@ -2203,4 +2343,36 @@ public final class Global extends ScriptObject implements Scope {
|
||||
protected boolean isGlobal() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* A class representing the ES6 global lexical scope.
|
||||
*/
|
||||
private static class LexicalScope extends ScriptObject {
|
||||
|
||||
LexicalScope(final ScriptObject proto) {
|
||||
super(proto, PropertyMap.newMap());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GuardedInvocation findGetMethod(final CallSiteDescriptor desc, final LinkRequest request, final String operator) {
|
||||
return filterInvocation(super.findGetMethod(desc, request, operator));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GuardedInvocation findSetMethod(final CallSiteDescriptor desc, final LinkRequest request) {
|
||||
return filterInvocation(super.findSetMethod(desc, request));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PropertyMap addBoundProperty(final PropertyMap propMap, final ScriptObject source, final jdk.nashorn.internal.runtime.Property property) {
|
||||
// We override this method just to make it callable by Global
|
||||
return super.addBoundProperty(propMap, source, property);
|
||||
}
|
||||
|
||||
private static GuardedInvocation filterInvocation(final GuardedInvocation invocation) {
|
||||
final MethodType type = invocation.getInvocation().type();
|
||||
return invocation.asType(type.changeParameterType(0, Object.class)).filterArguments(0, LEXICAL_SCOPE_FILTER);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -703,26 +703,12 @@ loop:
|
||||
Collections.<IdentNode>emptyList());
|
||||
lc.push(script);
|
||||
final ParserContextBlockNode body = newBlock();
|
||||
// If ES6 block scope is enabled add a per-script block for top-level LET and CONST declarations.
|
||||
final int startLine = start;
|
||||
final ParserContextBlockNode outer = useBlockScope() ? newBlock() : null;
|
||||
functionDeclarations = new ArrayList<>();
|
||||
|
||||
try {
|
||||
sourceElements(allowPropertyFunction);
|
||||
addFunctionDeclarations(script);
|
||||
} finally {
|
||||
if (outer != null) {
|
||||
restoreBlock(outer);
|
||||
appendStatement(new BlockStatement(
|
||||
startLine,
|
||||
new Block(
|
||||
functionToken,
|
||||
startLine, outer.getFlags(),
|
||||
outer.getStatements())));
|
||||
}
|
||||
}
|
||||
functionDeclarations = new ArrayList<>();
|
||||
sourceElements(allowPropertyFunction);
|
||||
addFunctionDeclarations(script);
|
||||
functionDeclarations = null;
|
||||
|
||||
restoreBlock(body);
|
||||
body.setFlag(Block.NEEDS_SCOPE);
|
||||
final Block programBody = new Block(functionToken, functionLine, body.getFlags(), body.getStatements());
|
||||
|
||||
@ -84,14 +84,17 @@ public abstract class Property implements Serializable {
|
||||
public static final int IS_NASGEN_PRIMITIVE = 1 << 6;
|
||||
|
||||
/** Is this a builtin property, e.g. Function.prototype.apply */
|
||||
public static final int IS_BUILTIN = 1 << 7;
|
||||
public static final int IS_BUILTIN = 1 << 7;
|
||||
|
||||
/** Is this property bound to a receiver? This means get/set operations will be delegated to
|
||||
* a statically defined object instead of the object passed as callsite parameter. */
|
||||
public static final int IS_BOUND = 1 << 7;
|
||||
public static final int IS_BOUND = 1 << 8;
|
||||
|
||||
/** Is this a lexically scoped LET or CONST variable that is dead until it is declared. */
|
||||
public static final int NEEDS_DECLARATION = 1 << 8;
|
||||
public static final int NEEDS_DECLARATION = 1 << 9;
|
||||
|
||||
/** Is this property an ES6 lexical binding? */
|
||||
public static final int IS_LEXICAL_BINDING = 1 << 10;
|
||||
|
||||
/** Property key. */
|
||||
private final String key;
|
||||
@ -714,4 +717,12 @@ public abstract class Property implements Serializable {
|
||||
public boolean isFunctionDeclaration() {
|
||||
return (flags & IS_FUNCTION_DECLARATION) == IS_FUNCTION_DECLARATION;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this a property defined by ES6 let or const?
|
||||
* @return true if this property represents a lexical binding.
|
||||
*/
|
||||
public boolean isLexicalBinding() {
|
||||
return (flags & IS_LEXICAL_BINDING) == IS_LEXICAL_BINDING;
|
||||
}
|
||||
}
|
||||
|
||||
@ -304,31 +304,46 @@ public abstract class ScriptObject implements PropertyAccess {
|
||||
PropertyMap newMap = this.getMap();
|
||||
|
||||
for (final Property property : properties) {
|
||||
final String key = property.getKey();
|
||||
final Property oldProp = newMap.findProperty(key);
|
||||
if (oldProp == null) {
|
||||
if (property instanceof UserAccessorProperty) {
|
||||
// Note: we copy accessor functions to this object which is semantically different from binding.
|
||||
final UserAccessorProperty prop = this.newUserAccessors(key, property.getFlags(), property.getGetterFunction(source), property.getSetterFunction(source));
|
||||
newMap = newMap.addPropertyNoHistory(prop);
|
||||
} else {
|
||||
newMap = newMap.addPropertyBind((AccessorProperty)property, source);
|
||||
}
|
||||
} else {
|
||||
// See ECMA section 10.5 Declaration Binding Instantiation
|
||||
// step 5 processing each function declaration.
|
||||
if (property.isFunctionDeclaration() && !oldProp.isConfigurable()) {
|
||||
if (oldProp instanceof UserAccessorProperty ||
|
||||
!(oldProp.isWritable() && oldProp.isEnumerable())) {
|
||||
throw typeError("cant.redefine.property", key, ScriptRuntime.safeToString(this));
|
||||
}
|
||||
}
|
||||
}
|
||||
newMap = addBoundProperty(newMap, source, property);
|
||||
}
|
||||
|
||||
this.setMap(newMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a bound property from {@code source}, using the interim property map {@code propMap}, and return the
|
||||
* new interim property map.
|
||||
*
|
||||
* @param propMap the property map
|
||||
* @param source the source object
|
||||
* @param property the property to be added
|
||||
* @return the new property map
|
||||
*/
|
||||
protected PropertyMap addBoundProperty(final PropertyMap propMap, final ScriptObject source, final Property property) {
|
||||
PropertyMap newMap = propMap;
|
||||
final String key = property.getKey();
|
||||
final Property oldProp = newMap.findProperty(key);
|
||||
if (oldProp == null) {
|
||||
if (property instanceof UserAccessorProperty) {
|
||||
// Note: we copy accessor functions to this object which is semantically different from binding.
|
||||
final UserAccessorProperty prop = this.newUserAccessors(key, property.getFlags(), property.getGetterFunction(source), property.getSetterFunction(source));
|
||||
newMap = newMap.addPropertyNoHistory(prop);
|
||||
} else {
|
||||
newMap = newMap.addPropertyBind((AccessorProperty)property, source);
|
||||
}
|
||||
} else {
|
||||
// See ECMA section 10.5 Declaration Binding Instantiation
|
||||
// step 5 processing each function declaration.
|
||||
if (property.isFunctionDeclaration() && !oldProp.isConfigurable()) {
|
||||
if (oldProp instanceof UserAccessorProperty ||
|
||||
!(oldProp.isWritable() && oldProp.isEnumerable())) {
|
||||
throw typeError("cant.redefine.property", key, ScriptRuntime.safeToString(this));
|
||||
}
|
||||
}
|
||||
}
|
||||
return newMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy all properties from the array with their receiver bound to the source.
|
||||
*
|
||||
@ -510,7 +525,11 @@ public abstract class ScriptObject implements PropertyAccess {
|
||||
}
|
||||
}
|
||||
|
||||
private void invalidateGlobalConstant(final String key) {
|
||||
/**
|
||||
* Invalidate any existing global constant method handles that may exist for {@code key}.
|
||||
* @param key the property name
|
||||
*/
|
||||
protected void invalidateGlobalConstant(final String key) {
|
||||
final GlobalConstants globalConstants = getGlobalConstants();
|
||||
if (globalConstants != null) {
|
||||
globalConstants.delete(key);
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
SyntaxError: test/script/basic/es6/const-redeclare-extra.js#36:8<eval>:3:8 Variable "x" has already been declared
|
||||
var x = {};
|
||||
^
|
||||
SyntaxError: test/script/basic/es6/const-redeclare-extra.js#36:8<eval>:2:8 Variable "x" has already been declared
|
||||
var x = 2;
|
||||
^
|
||||
SyntaxError: test/script/basic/es6/const-redeclare-extra.js#36:8<eval>:2:13 Variable "x" has already been declared
|
||||
function x () {}
|
||||
^
|
||||
SyntaxError: test/script/basic/es6/const-redeclare-extra.js#36:8<eval>:3:10 Variable "x" has already been declared
|
||||
const x = {};
|
||||
^
|
||||
SyntaxError: test/script/basic/es6/const-redeclare-extra.js#36:8<eval>:3:10 Variable "x" has already been declared
|
||||
const x = 5;
|
||||
^
|
||||
|
||||
@ -26,7 +26,8 @@
|
||||
*
|
||||
* @test
|
||||
* @run
|
||||
* @option --language=es6 */
|
||||
* @option --language=es6
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@ top level function
|
||||
block function
|
||||
print local defs: 20 30
|
||||
imported var: 1
|
||||
ReferenceError: "b" is not defined
|
||||
ReferenceError: "c" is not defined
|
||||
imported let: 2
|
||||
imported const: 3
|
||||
top level function
|
||||
ReferenceError: "block" is not defined
|
||||
|
||||
@ -4,12 +4,12 @@ SyntaxError: test/script/basic/es6/let-redeclare-extra.js#35:8<eval>:2:8 Variabl
|
||||
SyntaxError: test/script/basic/es6/let-redeclare-extra.js#35:8<eval>:3:8 Variable "x" has already been declared
|
||||
var x = 2;
|
||||
^
|
||||
SyntaxError: test/script/basic/es6/let-redeclare-extra.js#35:8<eval>:2:8 Variable "x" has already been declared
|
||||
var x = 2;
|
||||
SyntaxError: test/script/basic/es6/let-redeclare-extra.js#35:8<eval>:3:8 Variable "x" has already been declared
|
||||
let x = undefined;
|
||||
^
|
||||
SyntaxError: test/script/basic/es6/let-redeclare-extra.js#35:8<eval>:2:10 Variable "x" has already been declared
|
||||
const x = function (){};
|
||||
^
|
||||
SyntaxError: test/script/basic/es6/let-redeclare-extra.js#35:8<eval>:3:13 Variable "a" has already been declared
|
||||
function a () {};
|
||||
^
|
||||
SyntaxError: test/script/basic/es6/let-redeclare-extra.js#35:8<eval>:2:8 Variable "a" has already been declared
|
||||
let a = 2;
|
||||
^
|
||||
|
||||
34
nashorn/test/script/basic/es6/lexical-toplevel-def.js
Normal file
34
nashorn/test/script/basic/es6/lexical-toplevel-def.js
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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-8057691: Nashorn: let & const declarations are not shared between scripts
|
||||
*
|
||||
* @subtest
|
||||
*/
|
||||
|
||||
var VAR = "VAR";
|
||||
let LET = "LET";
|
||||
const CONST = "CONST";
|
||||
function FUNC() {}
|
||||
this.GLOBAL = "GLOBAL";
|
||||
51
nashorn/test/script/basic/es6/lexical-toplevel-print.js
Normal file
51
nashorn/test/script/basic/es6/lexical-toplevel-print.js
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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-8057691: Nashorn: let & const declarations are not shared between scripts
|
||||
*
|
||||
* @subtest
|
||||
*/
|
||||
|
||||
print(VAR);
|
||||
print(LET);
|
||||
print(CONST);
|
||||
print(FUNC);
|
||||
print(GLOBAL);
|
||||
print(this.VAR);
|
||||
print(this.LET); // undefined
|
||||
print(this.CONST); // undefined
|
||||
print(this.FUNC);
|
||||
print(this.GLOBAL);
|
||||
print("VAR" in this);
|
||||
print("LET" in this); // false
|
||||
print("CONST" in this); // false
|
||||
print("FUNC" in this);
|
||||
print("GLOBAL" in this);
|
||||
|
||||
try {
|
||||
LET = LET + "LET";
|
||||
CONST = CONST + "CONST";
|
||||
} catch (e) {
|
||||
print(String(e).replace(/\\/g, "/"));
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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-8057691: Nashorn: let & const declarations are not shared between scripts
|
||||
*
|
||||
* @subtest
|
||||
*/
|
||||
|
||||
function LET() {}
|
||||
var SHOULD_NOT_EXIST = 10;
|
||||
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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-8057691: Nashorn: let & const declarations are not shared between scripts
|
||||
*
|
||||
* @subtest
|
||||
*/
|
||||
|
||||
let Object = "LEXICAL BUILTIN";
|
||||
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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-8057691: Nashorn: let & const declarations are not shared between scripts
|
||||
*
|
||||
* @subtest
|
||||
*/
|
||||
|
||||
let FUNC = 10;
|
||||
var SHOULD_NOT_EXIST = 10;
|
||||
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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-8057691: Nashorn: let & const declarations are not shared between scripts
|
||||
*
|
||||
* @subtest
|
||||
*/
|
||||
|
||||
let GLOBAL = "LEXICAL GLOBAL";
|
||||
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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-8057691: Nashorn: let & const declarations are not shared between scripts
|
||||
*
|
||||
* @subtest
|
||||
*/
|
||||
|
||||
let VAR = 10;
|
||||
var SHOULD_NOT_EXIST = 10;
|
||||
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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-8057691: Nashorn: let & const declarations are not shared between scripts
|
||||
*
|
||||
* @subtest
|
||||
*/
|
||||
|
||||
var LET = 10;
|
||||
var SHOULD_NOT_EXIST = 10;
|
||||
78
nashorn/test/script/basic/es6/lexical-toplevel-redeclare.js
Normal file
78
nashorn/test/script/basic/es6/lexical-toplevel-redeclare.js
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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-8057691: Nashorn: let & const declarations are not shared between scripts
|
||||
*
|
||||
* @test
|
||||
* @run
|
||||
* @option -scripting
|
||||
* @option --language=es6
|
||||
*/
|
||||
|
||||
load(__DIR__ + "lexical-toplevel-def.js");
|
||||
|
||||
var global = this;
|
||||
|
||||
function tryIt (code) {
|
||||
try {
|
||||
eval(code)
|
||||
} catch (e) {
|
||||
print(String(e).replace(/\\/g, "/"))
|
||||
}
|
||||
}
|
||||
|
||||
function loadScript(script) {
|
||||
print(script);
|
||||
try {
|
||||
load(__DIR__ + script);
|
||||
} catch (e) {
|
||||
print(String(e).replace(/\\/g, "/"));
|
||||
}
|
||||
print(VAR);
|
||||
print(LET);
|
||||
print(CONST);
|
||||
print(FUNC);
|
||||
print(GLOBAL);
|
||||
print(global.VAR);
|
||||
print(global.LET);
|
||||
print(global.CONST);
|
||||
print(global.FUNC);
|
||||
print(global.GLOBAL);
|
||||
try {
|
||||
print(SHOULD_NOT_EXIST);
|
||||
} catch (e) {
|
||||
print(String(e).replace(/\\/g, "/"));
|
||||
}
|
||||
print(global.SHOULD_NOT_EXIST);
|
||||
print(Object);
|
||||
print(global.Object);
|
||||
print();
|
||||
}
|
||||
|
||||
loadScript("lexical-toplevel-redeclare-var-on-let.js");
|
||||
loadScript("lexical-toplevel-redeclare-func-on-let.js");
|
||||
loadScript("lexical-toplevel-redeclare-let-on-var.js");
|
||||
loadScript("lexical-toplevel-redeclare-let-on-func.js");
|
||||
loadScript("lexical-toplevel-redeclare-let-on-builtin.js");
|
||||
loadScript("lexical-toplevel-redeclare-let-on-global.js");
|
||||
@ -0,0 +1,100 @@
|
||||
lexical-toplevel-redeclare-var-on-let.js
|
||||
SyntaxError: Variable "LET" has already been declared
|
||||
VAR
|
||||
LET
|
||||
CONST
|
||||
function FUNC() {}
|
||||
GLOBAL
|
||||
VAR
|
||||
undefined
|
||||
undefined
|
||||
function FUNC() {}
|
||||
GLOBAL
|
||||
ReferenceError: "SHOULD_NOT_EXIST" is not defined
|
||||
undefined
|
||||
function Object() { [native code] }
|
||||
function Object() { [native code] }
|
||||
|
||||
lexical-toplevel-redeclare-func-on-let.js
|
||||
SyntaxError: Variable "LET" has already been declared
|
||||
VAR
|
||||
LET
|
||||
CONST
|
||||
function FUNC() {}
|
||||
GLOBAL
|
||||
VAR
|
||||
undefined
|
||||
undefined
|
||||
function FUNC() {}
|
||||
GLOBAL
|
||||
ReferenceError: "SHOULD_NOT_EXIST" is not defined
|
||||
undefined
|
||||
function Object() { [native code] }
|
||||
function Object() { [native code] }
|
||||
|
||||
lexical-toplevel-redeclare-let-on-var.js
|
||||
SyntaxError: Variable "VAR" has already been declared
|
||||
VAR
|
||||
LET
|
||||
CONST
|
||||
function FUNC() {}
|
||||
GLOBAL
|
||||
VAR
|
||||
undefined
|
||||
undefined
|
||||
function FUNC() {}
|
||||
GLOBAL
|
||||
ReferenceError: "SHOULD_NOT_EXIST" is not defined
|
||||
undefined
|
||||
function Object() { [native code] }
|
||||
function Object() { [native code] }
|
||||
|
||||
lexical-toplevel-redeclare-let-on-func.js
|
||||
SyntaxError: Variable "FUNC" has already been declared
|
||||
VAR
|
||||
LET
|
||||
CONST
|
||||
function FUNC() {}
|
||||
GLOBAL
|
||||
VAR
|
||||
undefined
|
||||
undefined
|
||||
function FUNC() {}
|
||||
GLOBAL
|
||||
ReferenceError: "SHOULD_NOT_EXIST" is not defined
|
||||
undefined
|
||||
function Object() { [native code] }
|
||||
function Object() { [native code] }
|
||||
|
||||
lexical-toplevel-redeclare-let-on-builtin.js
|
||||
VAR
|
||||
LET
|
||||
CONST
|
||||
function FUNC() {}
|
||||
GLOBAL
|
||||
VAR
|
||||
undefined
|
||||
undefined
|
||||
function FUNC() {}
|
||||
GLOBAL
|
||||
ReferenceError: "SHOULD_NOT_EXIST" is not defined
|
||||
undefined
|
||||
LEXICAL BUILTIN
|
||||
function Object() { [native code] }
|
||||
|
||||
lexical-toplevel-redeclare-let-on-global.js
|
||||
VAR
|
||||
LET
|
||||
CONST
|
||||
function FUNC() {}
|
||||
LEXICAL GLOBAL
|
||||
VAR
|
||||
undefined
|
||||
undefined
|
||||
function FUNC() {}
|
||||
GLOBAL
|
||||
ReferenceError: "SHOULD_NOT_EXIST" is not defined
|
||||
undefined
|
||||
LEXICAL BUILTIN
|
||||
function Object() { [native code] }
|
||||
|
||||
35
nashorn/test/script/basic/es6/lexical-toplevel.js
Normal file
35
nashorn/test/script/basic/es6/lexical-toplevel.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-8057691: Nashorn: let & const declarations are not shared between scripts
|
||||
*
|
||||
* @test
|
||||
* @run
|
||||
* @option --language=es6
|
||||
*/
|
||||
|
||||
load(__DIR__ + "lexical-toplevel-def.js");
|
||||
|
||||
load(__DIR__ + "lexical-toplevel-print.js");
|
||||
load(__DIR__ + "lexical-toplevel-print.js");
|
||||
30
nashorn/test/script/basic/es6/lexical-toplevel.js.EXPECTED
Normal file
30
nashorn/test/script/basic/es6/lexical-toplevel.js.EXPECTED
Normal file
@ -0,0 +1,30 @@
|
||||
VAR
|
||||
LET
|
||||
CONST
|
||||
function FUNC() {}
|
||||
GLOBAL
|
||||
VAR
|
||||
undefined
|
||||
undefined
|
||||
function FUNC() {}
|
||||
GLOBAL
|
||||
true
|
||||
false
|
||||
false
|
||||
true
|
||||
true
|
||||
VAR
|
||||
LETLET
|
||||
CONST
|
||||
function FUNC() {}
|
||||
GLOBAL
|
||||
VAR
|
||||
undefined
|
||||
undefined
|
||||
function FUNC() {}
|
||||
GLOBAL
|
||||
true
|
||||
false
|
||||
false
|
||||
true
|
||||
true
|
||||
@ -0,0 +1,212 @@
|
||||
/*
|
||||
* 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. 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 jdk.nashorn.api.scripting.NashornScriptEngineFactory;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import javax.script.Bindings;
|
||||
import javax.script.ScriptContext;
|
||||
import javax.script.ScriptEngine;
|
||||
import javax.script.ScriptException;
|
||||
import javax.script.SimpleScriptContext;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* Top-level lexical binding tests.
|
||||
*
|
||||
* @test
|
||||
* @run testng jdk.nashorn.internal.runtime.LexicalBindingTest
|
||||
*/
|
||||
@SuppressWarnings("javadoc")
|
||||
public class LexicalBindingTest {
|
||||
|
||||
final static String LANGUAGE_ES6 = "--language=es6";
|
||||
final static int NUMBER_OF_CONTEXTS = 20;
|
||||
final static int MEGAMORPHIC_LOOP_COUNT = 20;
|
||||
|
||||
/**
|
||||
* Test access to global var-declared variables for shared script classes with multiple globals.
|
||||
*/
|
||||
@Test
|
||||
public static void megamorphicVarTest() throws ScriptException, InterruptedException {
|
||||
final NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
|
||||
final ScriptEngine e = factory.getScriptEngine();
|
||||
final ScriptContext[] contexts = new ScriptContext[NUMBER_OF_CONTEXTS];
|
||||
final String sharedScript = "foo";
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
for (int i = 0; i < NUMBER_OF_CONTEXTS; i++) {
|
||||
final ScriptContext context = contexts[i];
|
||||
assertEquals(e.eval(sharedScript, context), String.valueOf(i));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test access to global lexically declared variables for shared script classes with multiple globals.
|
||||
*/
|
||||
@Test
|
||||
public static void megamorphicMultiGlobalLetTest() throws ScriptException, InterruptedException {
|
||||
final NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
|
||||
final ScriptEngine e = factory.getScriptEngine(LANGUAGE_ES6);
|
||||
final ScriptContext[] contexts = new ScriptContext[NUMBER_OF_CONTEXTS];
|
||||
final String sharedScript = "foo";
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
for (int i = 0; i < NUMBER_OF_CONTEXTS; i++) {
|
||||
final ScriptContext context = contexts[i];
|
||||
assertEquals(e.eval(sharedScript, context), String.valueOf(i));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test access to global lexically declared variables for shared script classes with single global.
|
||||
*/
|
||||
@Test
|
||||
public static void megamorphicSingleGlobalLetTest() throws ScriptException, InterruptedException {
|
||||
final NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
|
||||
final ScriptEngine e = factory.getScriptEngine(LANGUAGE_ES6);
|
||||
final String sharedGetterScript = "foo";
|
||||
final String sharedSetterScript = "foo = 1";
|
||||
|
||||
for (int i = 0; i < MEGAMORPHIC_LOOP_COUNT; i++) {
|
||||
assertEquals(e.eval(sharedSetterScript), 1);
|
||||
assertEquals(e.eval(sharedGetterScript), 1);
|
||||
assertEquals(e.eval("delete foo; a" + i + " = 1; foo = " + i + ";"), i);
|
||||
assertEquals(e.eval(sharedGetterScript), i);
|
||||
}
|
||||
|
||||
assertEquals(e.eval("let foo = 'foo';"), null);
|
||||
assertEquals(e.eval(sharedGetterScript), "foo");
|
||||
assertEquals(e.eval(sharedSetterScript), 1);
|
||||
assertEquals(e.eval(sharedGetterScript), 1);
|
||||
assertEquals(e.eval("this.foo"), MEGAMORPHIC_LOOP_COUNT - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test access to global lexically declared variables for shared script classes with single global.
|
||||
*/
|
||||
@Test
|
||||
public static void megamorphicInheritedGlobalLetTest() throws ScriptException, InterruptedException {
|
||||
final NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
|
||||
final ScriptEngine e = factory.getScriptEngine(LANGUAGE_ES6);
|
||||
final String sharedGetterScript = "foo";
|
||||
final String sharedSetterScript = "foo = 1";
|
||||
|
||||
for (int i = 0; i < MEGAMORPHIC_LOOP_COUNT; i++) {
|
||||
assertEquals(e.eval(sharedSetterScript), 1);
|
||||
assertEquals(e.eval(sharedGetterScript), 1);
|
||||
assertEquals(e.eval("delete foo; a" + i + " = 1; Object.prototype.foo = " + i + ";"), i);
|
||||
assertEquals(e.eval(sharedGetterScript), i);
|
||||
}
|
||||
|
||||
assertEquals(e.eval("let foo = 'foo';"), null);
|
||||
assertEquals(e.eval(sharedGetterScript), "foo");
|
||||
assertEquals(e.eval(sharedSetterScript), 1);
|
||||
assertEquals(e.eval(sharedGetterScript), 1);
|
||||
assertEquals(e.eval("this.foo"), MEGAMORPHIC_LOOP_COUNT - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test multi-threaded access to global lexically declared variables for shared script classes with multiple globals.
|
||||
*/
|
||||
@Test
|
||||
public static void multiThreadedLetTest() throws ScriptException, InterruptedException {
|
||||
final NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
|
||||
final ScriptEngine e = factory.getScriptEngine(LANGUAGE_ES6);
|
||||
final Bindings b = e.createBindings();
|
||||
final ScriptContext origContext = e.getContext();
|
||||
final ScriptContext newCtxt = new SimpleScriptContext();
|
||||
newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
|
||||
final String sharedScript = "foo";
|
||||
|
||||
assertEquals(e.eval("let foo = 'original context';", origContext), null);
|
||||
assertEquals(e.eval("let foo = 'new context';", newCtxt), null);
|
||||
|
||||
final Thread t1 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000));
|
||||
final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "new context", 1000));
|
||||
t1.start();
|
||||
t2.start();
|
||||
t1.join();
|
||||
t2.join();
|
||||
|
||||
assertEquals(e.eval("foo = 'newer context';", newCtxt), "newer context");
|
||||
final Thread t3 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000));
|
||||
final Thread t4 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "newer context", 1000));
|
||||
|
||||
t3.start();
|
||||
t4.start();
|
||||
t3.join();
|
||||
t4.join();
|
||||
|
||||
assertEquals(e.eval(sharedScript), "original context");
|
||||
assertEquals(e.eval(sharedScript, newCtxt), "newer context");
|
||||
}
|
||||
|
||||
private static class ScriptRunner implements Runnable {
|
||||
|
||||
final ScriptEngine engine;
|
||||
final ScriptContext context;
|
||||
final String source;
|
||||
final Object expected;
|
||||
final int iterations;
|
||||
|
||||
ScriptRunner(final ScriptEngine engine, final ScriptContext context, final String source, final Object expected, final int iterations) {
|
||||
this.engine = engine;
|
||||
this.context = context;
|
||||
this.source = source;
|
||||
this.expected = expected;
|
||||
this.iterations = iterations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
assertEquals(engine.eval(source, context), expected);
|
||||
}
|
||||
} catch (final ScriptException se) {
|
||||
throw new RuntimeException(se);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user