This commit is contained in:
Athijegannathan Sundararajan 2013-08-27 19:26:48 +05:30
commit 13568cb462
58 changed files with 1261 additions and 138 deletions

View File

@ -27,7 +27,6 @@ package jdk.nashorn.internal.tools.nasgen;
import static jdk.internal.org.objectweb.asm.Opcodes.ACC_FINAL;
import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PUBLIC;
import static jdk.internal.org.objectweb.asm.Opcodes.ACC_SUPER;
import static jdk.internal.org.objectweb.asm.Opcodes.H_INVOKESTATIC;
import static jdk.internal.org.objectweb.asm.Opcodes.V1_7;
import static jdk.nashorn.internal.tools.nasgen.StringConstants.CONSTRUCTOR_SUFFIX;

View File

@ -27,7 +27,6 @@ package jdk.nashorn.internal.tools.nasgen;
import static jdk.internal.org.objectweb.asm.Opcodes.ALOAD;
import static jdk.internal.org.objectweb.asm.Opcodes.DUP;
import static jdk.internal.org.objectweb.asm.Opcodes.GETSTATIC;
import static jdk.internal.org.objectweb.asm.Opcodes.INVOKESPECIAL;
import static jdk.internal.org.objectweb.asm.Opcodes.INVOKESTATIC;
import static jdk.internal.org.objectweb.asm.Opcodes.NEW;

View File

@ -16,8 +16,9 @@ default value of the flag is false, unless otherwise specified.
SYSTEM PROPERTY: -Dnashorn.args=<string>
This property takes as its value a space separated list of Nashorn
command line options that should be passed to Nashorn. This might be useful
in environments where it is hard to tell how a nashorn.jar is launched.
command line options that should be passed to Nashorn. This might be
useful in environments where it is hard to tell how a nashorn.jar is
launched.
Example:
@ -43,6 +44,10 @@ The default value is 0x8000 (32768).
SYSTEM PROPERTY: -Dnashorn.compiler.intarithmetic
(and integer arithmetic in general)
<currently disabled - this is being refactored for update releases>
Arithmetic operations in Nashorn (except bitwise ones) typically
coerce the operands to doubles (as per the JavaScript spec). To switch
this off and remain in integer mode, for example for "var x = a&b; var
@ -65,13 +70,382 @@ is faster than just using doubles directly, even if the int operation
does not overflow. Getting access to a JVM intrinsic that does branch
on overflow would probably alleviate this.
There is also a problem with this optimistic approach if the symbol
happens to reside in a local variable slot in the bytecode, as those
are strongly typed. Then we would need to split large sections of
control flow, so this is probably not the right way to go, while range
analysis is. There is a large difference between integer bytecode
without overflow checks and double bytecode. The former is
significantly faster.
The future:
We are transitioning to an optimistic type system that uses int
arithmetic everywhere until proven wrong. The problem here is mostly
catch an overflow exception and rolling back the state to a new method
with less optimistic assumptions for an operation at a particular
program point. This will most likely not be in the Java 8.0 release
but likely end up in an update release
For Java 8, several java.lang.Math methods like addExact, subExact and
mulExact are available to help us. Experiments intrinsifying these
show a lot of promise, and we have devised a system that basically
does on stack replacement with exceptions in bytecode to revert
erroneous assumptions. An explanation of how this works and what we
are doing can be found here:
http://www.slideshare.net/lagergren/lagergren-jvmls2013final
Experiments with this show significant ~x2-3 performance increases on
pretty much everything, provided that optimistic assumptions don't
fail much. It will affect warmup time negatively, depending on how
many erroneous too optimistic assumptions are placed in the code at
compile time. We don't think this will be much of an issue.
For example for a small benchmark that repeatedly executes this
method taken from the Crypto Octane benchmark
function am3(i,x,w,j,c,n) {
var this_array = this.array;
var w_array = w.array;
var xl = x&0x3fff, xh = x>>14;
while(--n >= 0) {
var l = this_array[i]&0x3fff;
var h = this_array[i++]>>14;
var m = xh*l+h*xl;
l = xl*l+((m&0x3fff)<<14)+w_array[j]+c;
c = (l>>28)+(m>>14)+xh*h;
w_array[j++] = l&0xfffffff;
}
return c;
}
The performance increase more than doubles. We are also working hard
with the code generation team in the Java Virtual Machine to fix
things that are lacking in invokedynamic performance, which is another
area where a lot of ongoing performance work takes place
"Pessimistic" bytecode for am3, guaranteed to be semantically correct:
// access flags 0x9
public static am3(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
L0
LINENUMBER 12 L0
ALOAD 0
INVOKEDYNAMIC dyn:getProp|getElem|getMethod:array(Ljava/lang/Object;)Ljava/lang/Object; [
// handle kind 0x6 : INVOKESTATIC
jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;)
// arguments:
0
]
ASTORE 8
L1
LINENUMBER 13 L1
ALOAD 3
INVOKEDYNAMIC dyn:getProp|getElem|getMethod:array(Ljava/lang/Object;)Ljava/lang/Object; [
// handle kind 0x6 : INVOKESTATIC
jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;)
// arguments:
0
]
ASTORE 9
L2
LINENUMBER 14 L2
ALOAD 2
INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toInt32 (Ljava/lang/Object;)I
SIPUSH 16383
IAND
ISTORE 10
ALOAD 2
INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toInt32 (Ljava/lang/Object;)I
BIPUSH 14
ISHR
ISTORE 11
L3
LINENUMBER 15 L3
GOTO L4
L5
LINENUMBER 16 L5
FRAME FULL [java/lang/Object java/lang/Object java/lang/Object java/lang/Object java/lang/Object java/lang/Object java/lang/Double T java/lang/Object java/lang/Object I I] []
ALOAD 8
ALOAD 1
INVOKEDYNAMIC dyn:getElem|getProp|getMethod(Ljava/lang/Object;Ljava/lang/Object;)I [
// handle kind 0x6 : INVOKESTATIC
jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;)
// arguments:
0
]
SIPUSH 16383
IAND
INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;
ASTORE 12
L6
LINENUMBER 17 L6
ALOAD 8
ALOAD 1
INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toNumber (Ljava/lang/Object;)D
DUP2
DCONST_1
DADD
INVOKESTATIC java/lang/Double.valueOf (D)Ljava/lang/Double;
ASTORE 1
INVOKEDYNAMIC dyn:getElem|getProp|getMethod(Ljava/lang/Object;D)I [
// handle kind 0x6 : INVOKESTATIC
jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;)
// arguments:
0
]
BIPUSH 14
ISHR
ISTORE 13
L7
LINENUMBER 18 L7
ILOAD 11
I2D
ALOAD 12
INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toNumber (Ljava/lang/Object;)D
DMUL
ILOAD 13
I2D
ILOAD 10
I2D
DMUL
DADD
DSTORE 14
L8
LINENUMBER 19 L8
ILOAD 10
I2D
ALOAD 12
INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toNumber (Ljava/lang/Object;)D
DMUL
DLOAD 14
INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toInt32 (D)I
SIPUSH 16383
IAND
BIPUSH 14
ISHL
I2D
DADD
ALOAD 9
ALOAD 4
INVOKEDYNAMIC dyn:getElem|getProp|getMethod(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; [
// handle kind 0x6 : INVOKESTATIC
jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;)
// arguments:
0
]
INVOKEDYNAMIC ADD:ODO_D(DLjava/lang/Object;)Ljava/lang/Object; [
// handle kind 0x6 : INVOKESTATIC
jdk/nashorn/internal/runtime/linker/Bootstrap.runtimeBootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;)
// arguments: none
]
ALOAD 5
INVOKEDYNAMIC ADD:OOO_I(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; [
// handle kind 0x6 : INVOKESTATIC
jdk/nashorn/internal/runtime/linker/Bootstrap.runtimeBootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;)
// arguments: none
]
ASTORE 12
L9
LINENUMBER 20 L9
ALOAD 12
INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toInt32 (Ljava/lang/Object;)I
BIPUSH 28
ISHR
I2D
DLOAD 14
INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toInt32 (D)I
BIPUSH 14
ISHR
I2D
DADD
ILOAD 11
I2D
ILOAD 13
I2D
DMUL
DADD
INVOKESTATIC java/lang/Double.valueOf (D)Ljava/lang/Double;
ASTORE 5
L10
LINENUMBER 21 L10
ALOAD 9
ALOAD 4
INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toNumber (Ljava/lang/Object;)D
DUP2
DCONST_1
DADD
INVOKESTATIC java/lang/Double.valueOf (D)Ljava/lang/Double;
ASTORE 4
ALOAD 12
INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toInt32 (Ljava/lang/Object;)I
LDC 268435455
IAND
INVOKEDYNAMIC dyn:setElem|setProp(Ljava/lang/Object;DI)V [
// handle kind 0x6 : INVOKESTATIC
jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;)
// arguments:
0
]
L4
FRAME FULL [java/lang/Object java/lang/Object java/lang/Object java/lang/Object java/lang/Object java/lang/Object java/lang/Object T java/lang/Object java/lang/Object I I] []
ALOAD 6
INVOKESTATIC jdk/nashorn/internal/runtime/JSType.toNumber (Ljava/lang/Object;)D
LDC -1.0
DADD
DUP2
INVOKESTATIC java/lang/Double.valueOf (D)Ljava/lang/Double;
ASTORE 6
DCONST_0
DCMPL
IFGE L5
L11
LINENUMBER 24 L11
ALOAD 5
ARETURN
"Optimistic" bytecode that requires invalidation on e.g overflow. Factor
x2-3 speedup:
public static am3(Ljava/lang/Object;IILjava/lang/Object;III)I
L0
LINENUMBER 12 L0
ALOAD 0
INVOKEDYNAMIC dyn:getProp|getElem|getMethod:array(Ljava/lang/Object;)Ljava/lang/Object; [
// handle kind 0x6 : INVOKESTATIC
jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;)
// arguments:
0
]
ASTORE 8
L1
LINENUMBER 13 L1
ALOAD 3
INVOKEDYNAMIC dyn:getProp|getElem|getMethod:array(Ljava/lang/Object;)Ljava/lang/Object; [
// handle kind 0x6 : INVOKESTATIC
jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;)
// arguments:
0
]
ASTORE 9
L2
LINENUMBER 14 L2
ILOAD 2
SIPUSH 16383
IAND
ISTORE 10
ILOAD 2
BIPUSH 14
ISHR
ISTORE 11
L3
LINENUMBER 15 L3
GOTO L4
L5
LINENUMBER 16 L5
FRAME FULL [java/lang/Object I I java/lang/Object I I I T java/lang/Object java/lang/Object I I] []
ALOAD 8
ILOAD 1
INVOKEDYNAMIC dyn:getElem|getProp|getMethod(Ljava/lang/Object;I)I [
// handle kind 0x6 : INVOKESTATIC
jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;)
// arguments:
0
]
SIPUSH 16383
IAND
ISTORE 12
L6
LINENUMBER 17 L6
ALOAD 8
ILOAD 1
DUP
ICONST_1
IADD
ISTORE 1
INVOKEDYNAMIC dyn:getElem|getProp|getMethod(Ljava/lang/Object;I)I [
// handle kind 0x6 : INVOKESTATIC
jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;)
// arguments:
0
]
BIPUSH 14
ISHR
ISTORE 13
L7
LINENUMBER 18 L7
ILOAD 11
ILOAD 12
BIPUSH 8
INVOKESTATIC jdk/nashorn/internal/runtime/JSType.mulExact (III)I
ILOAD 13
ILOAD 10
BIPUSH 9
INVOKESTATIC jdk/nashorn/internal/runtime/JSType.mulExact (III)I
IADD
ISTORE 14
L8
LINENUMBER 19 L8
ILOAD 10
ILOAD 12
BIPUSH 11
INVOKESTATIC jdk/nashorn/internal/runtime/JSType.mulExact (III)I
ILOAD 14
SIPUSH 16383
IAND
BIPUSH 14
ISHL
IADD
ALOAD 9
ILOAD 4
INVOKEDYNAMIC dyn:getElem|getProp|getMethod(Ljava/lang/Object;I)I [
// handle kind 0x6 : INVOKESTATIC
jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;)
// arguments:
0
]
IADD
ILOAD 5
IADD
ISTORE 12
L9
LINENUMBER 20 L9
ILOAD 12
BIPUSH 28
ISHR
ILOAD 14
BIPUSH 14
ISHR
IADD
ILOAD 11
ILOAD 13
BIPUSH 21
INVOKESTATIC jdk/nashorn/internal/runtime/JSType.mulExact (III)I
IADD
ISTORE 5
L10
LINENUMBER 21 L10
ALOAD 9
ILOAD 4
DUP
ICONST_1
IADD
ISTORE 4
ILOAD 12
LDC 268435455
IAND
INVOKEDYNAMIC dyn:setElem|setProp(Ljava/lang/Object;II)V [
// handle kind 0x6 : INVOKESTATIC
jdk/nashorn/internal/runtime/linker/Bootstrap.bootstrap((Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;I)Ljava/lang/invoke/CallSite;)
// arguments:
0
]
L4
FRAME SAME
ILOAD 6
ICONST_M1
IADD
DUP
ISTORE 6
ICONST_0
IF_ICMPGE L5
L11
LINENUMBER 24 L11
ILOAD 5
IRETURN
SYSTEM PROPERTY: -Dnashorn.codegen.debug, -Dnashorn.codegen.debug.trace=<x>
@ -167,7 +541,7 @@ we can determine by types at compile time is a combinatorial explosion
of byte code (try it e.g. on all the variants of am3 in the Octane
benchmark crypto.js). Thus, this needs to be lazy
3) Possibly optimistic callsite writes, something on the form
3) Optimistic callsite writes, something on the form
x = y; //x is a field known to be a primitive. y is only an object as
far as we can tell
@ -189,6 +563,12 @@ only.
We still have to deal with objects vs primitives for local bytecode
slots, possibly through code copying and versioning.
The Future:
We expect the usefulness of dual fields to increase significantly
after the optimistic type system described in the section on
integer arithmetic above is implemented.
SYSTEM PROPERTY: -Dnashorn.compiler.symbol.trace=[<x>[,*]],
-Dnashorn.compiler.symbol.stacktrace=[<x>[,*]]
@ -211,7 +591,7 @@ traces will be displayed upon symbol changes according to the same
semantics.
SYSTEM PROPERTY: nashorn.lexer.xmlliterals
SYSTEM PROPERTY: -Dnashorn.lexer.xmlliterals
If this property it set, it means that the Lexer should attempt to
parse XML literals, which would otherwise generate syntax
@ -222,7 +602,7 @@ XML literals, when this is enabled, end up as standard LiteralNodes in
the IR.
SYSTEM_PROPERTY: nashorn.debug
SYSTEM_PROPERTY: -Dnashorn.debug
If this property is set to true, Nashorn runs in Debug mode. Debug
mode is slightly slower, as for example statistics counters are enabled
@ -269,8 +649,8 @@ when a callsite has to be relinked, due to a previous assumption of
object layout being invalidated.
SYSTEM PROPERTY: nashorn.methodhandles.debug,
nashorn.methodhandles.debug=create
SYSTEM PROPERTY: -Dnashorn.methodhandles.debug,
-Dnashorn.methodhandles.debug=create
If this property is enabled, each MethodHandle related call that uses
the java.lang.invoke package gets its MethodHandle intercepted and an
@ -286,7 +666,7 @@ instrumentation will be shown for method handles upon creation time
rather than at runtime usage.
SYSTEM PROPERTY: nashorn.methodhandles.debug.stacktrace
SYSTEM PROPERTY: -Dnashorn.methodhandles.debug.stacktrace
This does the same as nashorn.methodhandles.debug, but when enabled
also dumps the stack trace for every instrumented method handle
@ -297,14 +677,13 @@ See the description of the codegen logger below for a more verbose
description of this option
SYSTEM PROPERTY: nashorn.scriptfunction.specialization.disable
SYSTEM PROPERTY: -Dnashorn.scriptfunction.specialization.disable
There are several "fast path" implementations of constructors and
functions in the NativeObject classes that, in their original form,
take a variable amount of arguments. Said functions are also declared
to take Object parameters in their original form, as this is what the
JavaScript specification mandates.
However, we often know quite a lot more at a callsite of one of these
functions. For example, Math.min is called with a fixed number (2) of
integer arguments. The overhead of boxing these ints to Objects and
@ -331,7 +710,7 @@ use any specialized function or constructor for native objects, but
just call the generic one.
SYSTEM PROPERTY: nashorn.tcs.miss.samplePercent=<x>
SYSTEM PROPERTY: -Dnashorn.tcs.miss.samplePercent=<x>
When running with the trace callsite option (-tcs), Nashorn will count
and instrument any callsite misses that require relinking. As the
@ -341,7 +720,7 @@ should be logged. Typically this is set to 1 or 5 (percent). 1% is the
default value.
SYSTEM_PROPERTY: nashorn.profilefile=<filename>
SYSTEM_PROPERTY: -Dnashorn.profilefile=<filename>
When running with the profile callsite options (-pcs), Nashorn will
dump profiling data for all callsites to stderr as a shutdown hook. To
@ -349,15 +728,35 @@ instead redirect this to a file, specify the path to the file using
this system property.
SYSTEM_PROPERTY: nashorn.regexp.impl=[jdk|joni]
SYSTEM_PROPERTY: -Dnashorn.regexp.impl=[jdk|joni]
This property defines the regular expression engine to be used by
Nashorn. The default implementation is "jdk" which is based on the
Nashorn. Set this flag to "jdk" to get an implementation based on the
JDK's java.util.regex package. Set this property to "joni" to install
an implementation based on Joni, the regular expression engine used by
the JRuby project.
the JRuby project. The default value for this flag is "joni"
SYSTEM PROPERTY: -Dnashorn.time
This enables timers for various phases of script compilation. The timers
will be dumped when the Nashorn process exits. We see a percentage value
of how much time was spent not executing bytecode (i.e. compilation and
internal tasks) at the end of the report.
Here is an example:
[JavaScript Parsing] 61 ms
[Constant Folding] 11 ms
[Control Flow Lowering] 26 ms
[Type Attribution] 81 ms
[Range Analysis] 0 ms
[Code Splitting] 29 ms
[Type Finalization] 19 ms
[Bytecode Generation] 189 ms
[Code Installation] 7 ms
Total runtime: 508 ms (Non-runtime: 423 ms [83%])
===============
2. The loggers.
===============
@ -442,6 +841,9 @@ generated that neg?"
The --log=codegen option is equivalent to setting the system variable
"nashorn.codegen.debug" to true.
* fold
Shows constant folding taking place before lowering
* lower
@ -484,3 +886,160 @@ getter and setter in the program, show arguments, return values
etc. It will also show the internal representation of respective field
(Object in the normal case, unless running with the dual field
representation)
=======================
3. Undocumented options
=======================
Here follows a short description of undocumented options for Nashorn.
To see a list of all undocumented options, use the (undocumented) flag
"-xhelp".
i.e. jjs -xhelp or java -jar nashorn.jar -xhelp
Undocumented options are not guaranteed to work, run correctly or be
bug free. They are experimental and for internal or debugging use.
They are also subject to change without notice.
In practice, though, all options below not explicitly documented as
EXPERIMENTAL can be relied upon, for example --dump-on-error is useful
for any JavaScript/Nashorn developer, but there is no guarantee.
A short summary follows:
-D (-Dname=value. Set a system property. This option can be repeated.)
-ccs, --class-cache-size (Size of the Class cache size per global scope.)
-cp, -classpath (-cp path. Specify where to find user class files.)
-co, --compile-only (Compile script without running. Exit after compilation)
param: [true|false] default: false
-d, --dump-debug-dir (specify a destination directory to dump class files.
This must be combined with the --compile-only option to work)
param: <path>
--debug-lines (Generate line number table in .class files.)
param: [true|false] default: true
--debug-locals (Generate local variable table in .class files.)
param: [true|false] default: false
-doe, -dump-on-error (Dump a stack trace on errors.)
param: [true|false] default: false
--early-lvalue-error (invalid lvalue expressions should be reported as early errors.)
param: [true|false] default: true
--empty-statements (Preserve empty statements in AST.)
param: [true|false] default: false
-fv, -fullversion (Print full version info of Nashorn.)
param: [true|false] default: false
--function-statement-error (Report an error when function declaration is used as a statement.)
param: [true|false] default: false
--function-statement-warning (Warn when function declaration is used as a statement.)
param: [true|false] default: false
-fx (Launch script as an fx application.)
param: [true|false] default: false
--global-per-engine (Use single Global instance per script engine instance.)
param: [true|false] default: false
-h, -help (Print help for command line flags.)
param: [true|false] default: false
--lazy-compilation (EXPERIMENTAL: Use lazy code generation strategies - do not compile
the entire script at once.)
param: [true|false] default: false
--loader-per-compile (Create a new class loader per compile.)
param: [true|false] default: true
-l, --locale (Set Locale for script execution.)
param: <locale> default: en-US
--log (Enable logging of a given level for a given number of sub systems.
[for example: --log=fields:finest,codegen:info])
param: <module:level>,*
-nj, --no-java (No Java support)
param: [true|false] default: false
-nse, --no-syntax-extensions (No non-standard syntax extensions)
param: [true|false] default: false
-nta, --no-typed-arrays (No Typed arrays support)
param: [true|false] default: false
--parse-only (Parse without compiling.)
param: [true|false] default: false
--print-ast (Print abstract syntax tree.)
param: [true|false] default: false
--print-code (Print bytecode.)
param: [true|false] default: false
--print-lower-ast (Print lowered abstract syntax tree.)
param: [true|false] default: false
--print-lower-parse (Print the parse tree after lowering.)
param: [true|false] default: false
--print-mem-usage (Print memory usage of IR after each compile stage.)
param: [true|false] default: false
--print-no-newline (Print function will not print new line char.)
param: [true|false] default: false
--print-parse (Print the parse tree.)
param: [true|false] default: false
--print-symbols (Print the symbol table.)
param: [true|false] default: false
-pcs, --profile-callsites (Dump callsite profile data.)
param: [true|false] default: false
--range-analysis (EXPERIMENTAL: Do range analysis using known compile time types,
and try to narrow number types)
param: [true|false] default: false
-scripting (Enable scripting features.)
param: [true|false] default: false
--specialize-calls (EXPERIMENTAL: Specialize all or a set of method according
to callsite parameter types)
param: [=function_1,...,function_n]
--stderr (Redirect stderr to a filename or to another tty, e.g. stdout)
param: <output console>
--stdout (Redirect stdout to a filename or to another tty, e.g. stderr)
param: <output console>
-strict (Run scripts in strict mode.)
param: [true|false] default: false
-t, -timezone (Set timezone for script execution.)
param: <timezone> default: Europe/Stockholm
-tcs, --trace-callsites (Enable callsite trace mode. Options are: miss [trace callsite misses]
enterexit [trace callsite enter/exit], objects [print object properties])
param: [=[option,]*]
--verify-code (Verify byte code before running.)
param: [true|false] default: false
-v, -version (Print version info of Nashorn.)
param: [true|false] default: false
-xhelp (Print extended help for command line flags.)
param: [true|false] default: false

View File

@ -121,7 +121,6 @@ public class ChainedCallSite extends AbstractRelinkableCallSite {
* to change the value. If your override returns a value less than 1, the code will break.
* @return the maximum number of method handles in the chain.
*/
@SuppressWarnings("static-method")
protected int getMaxChainLength() {
return 8;
}

View File

@ -133,7 +133,7 @@ public class DefaultBootstrapper {
* @param type the method signature at the call site
* @return a new {@link MonomorphicCallSite} linked with the default dynamic linker.
*/
public static CallSite publicBootstrap(@SuppressWarnings("unused") MethodHandles.Lookup caller, String name, MethodType type) {
public static CallSite publicBootstrap(MethodHandles.Lookup caller, String name, MethodType type) {
return bootstrapInternal(MethodHandles.publicLookup(), name, type);
}

View File

@ -97,6 +97,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import jdk.internal.dynalink.CallSiteDescriptor;
import jdk.internal.dynalink.beans.GuardedInvocationComponent.ValidationType;
import jdk.internal.dynalink.linker.GuardedInvocation;

View File

@ -148,6 +148,7 @@ class OverloadedDynamicMethod extends DynamicMethod {
}
}
@SuppressWarnings("fallthrough")
@Override
public MethodHandle getInvocation(final CallSiteDescriptor callSiteDescriptor, final LinkerServices linkerServices) {
final MethodType callSiteType = callSiteDescriptor.getMethodType();

View File

@ -124,6 +124,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
}
// load engine.js and return content as a char[]
@SuppressWarnings("resource")
private static char[] loadEngineJSSource() {
final String script = "resources/engine.js";
try {
@ -212,9 +213,8 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
// just create normal SimpleBindings.
// We use same 'global' for all Bindings.
return new SimpleBindings();
} else {
return createGlobalMirror(null);
}
return createGlobalMirror(null);
}
// Compilable methods

View File

@ -390,6 +390,15 @@ public final class ScriptObjectMirror extends JSObject implements Bindings {
});
}
/**
* ECMA [[Class]] property
*
* @return ECMA [[Class]] property value of this object
*/
public String getClassName() {
return sobj.getClassName();
}
/**
* ECMA 8.12.1 [[GetOwnProperty]] (P)
*

View File

@ -414,30 +414,34 @@ enum CompilationPhase {
compiler.getCodeInstaller().verify(bytecode);
}
// should code be dumped to disk - only valid in compile_only
// mode?
// should code be dumped to disk - only valid in compile_only mode?
if (env._dest_dir != null && env._compile_only) {
final String fileName = className.replace('.', File.separatorChar) + ".class";
final int index = fileName.lastIndexOf(File.separatorChar);
final int index = fileName.lastIndexOf(File.separatorChar);
final File dir;
if (index != -1) {
final File dir = new File(fileName.substring(0, index));
try {
if (!dir.exists() && !dir.mkdirs()) {
throw new IOException(dir.toString());
}
final File file = new File(env._dest_dir, fileName);
try (final FileOutputStream fos = new FileOutputStream(file)) {
fos.write(bytecode);
}
} catch (final IOException e) {
Compiler.LOG.warning("Skipping class dump for ",
className,
": ",
ECMAErrors.getMessage(
"io.error.cant.write",
dir.toString()));
dir = new File(env._dest_dir, fileName.substring(0, index));
} else {
dir = new File(env._dest_dir);
}
try {
if (!dir.exists() && !dir.mkdirs()) {
throw new IOException(dir.toString());
}
final File file = new File(env._dest_dir, fileName);
try (final FileOutputStream fos = new FileOutputStream(file)) {
fos.write(bytecode);
}
Compiler.LOG.info("Wrote class to '" + file.getAbsolutePath() + '\'');
} catch (final IOException e) {
Compiler.LOG.warning("Skipping class dump for ",
className,
": ",
ECMAErrors.getMessage(
"io.error.cant.write",
dir.toString()));
}
}
}

View File

@ -40,6 +40,7 @@ import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.Callable;
import jdk.nashorn.api.scripting.ScriptObjectMirror;
import jdk.nashorn.internal.objects.annotations.Attribute;
import jdk.nashorn.internal.objects.annotations.Constructor;
@ -632,6 +633,7 @@ public final class NativeArray extends ScriptObject {
return new NativeArray(list.toArray());
}
@SuppressWarnings("null")
private static void concatToList(final ArrayList<Object> list, final Object obj) {
final boolean isScriptArray = isArray(obj);
final boolean isScriptObject = isScriptArray || obj instanceof ScriptObject;

View File

@ -73,6 +73,11 @@ final class NativeArrayBuffer extends ScriptObject {
this(Arrays.copyOfRange(other.buffer, begin, end));
}
@Override
public String getClassName() {
return "ArrayBuffer";
}
@Getter(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE)
public static Object byteLength(final Object self) {
return ((NativeArrayBuffer)self).buffer.length;

View File

@ -144,6 +144,11 @@ public final class NativeFloat32Array extends ArrayBufferView {
super(buffer, byteOffset, length);
}
@Override
public String getClassName() {
return "Float32Array";
}
@Override
protected Factory factory() {
return FACTORY;

View File

@ -154,6 +154,11 @@ public final class NativeFloat64Array extends ArrayBufferView {
super(buffer, byteOffset, length);
}
@Override
public String getClassName() {
return "Float64Array";
}
@Override
protected Factory factory() {
return FACTORY;

View File

@ -108,6 +108,11 @@ public final class NativeInt16Array extends ArrayBufferView {
super(buffer, byteOffset, byteLength);
}
@Override
public String getClassName() {
return "Int16Array";
}
@Override
protected Factory factory() {
return FACTORY;

View File

@ -111,6 +111,11 @@ public final class NativeInt32Array extends ArrayBufferView {
super(buffer, byteOffset, length);
}
@Override
public String getClassName() {
return "Int32Array";
}
@Override
protected Factory factory() {
return FACTORY;

View File

@ -101,6 +101,11 @@ public final class NativeInt8Array extends ArrayBufferView {
super(buffer, byteOffset, length);
}
@Override
public String getClassName() {
return "Int8Array";
}
@Override
protected Factory factory() {
return FACTORY;

View File

@ -669,15 +669,43 @@ public final class NativeObject {
final List<AccessorProperty> properties = new ArrayList<>(propertyNames.size() + methodNames.size());
for(final String methodName: methodNames) {
properties.add(AccessorProperty.create(methodName, Property.NOT_WRITABLE,
getBoundBeanMethodGetter(source, getBeanOperation(linker, "dyn:getMethod:" + methodName, getterType, source)),
null));
final MethodHandle method;
try {
method = getBeanOperation(linker, "dyn:getMethod:" + methodName, getterType, source);
} catch(final IllegalAccessError e) {
// Presumably, this was a caller sensitive method. Ignore it and carry on.
continue;
}
properties.add(AccessorProperty.create(methodName, Property.NOT_WRITABLE, getBoundBeanMethodGetter(source,
method), null));
}
for(final String propertyName: propertyNames) {
MethodHandle getter;
if(readablePropertyNames.contains(propertyName)) {
try {
getter = getBeanOperation(linker, "dyn:getProp:" + propertyName, getterType, source);
} catch(final IllegalAccessError e) {
// Presumably, this was a caller sensitive method. Ignore it and carry on.
getter = Lookup.EMPTY_GETTER;
}
} else {
getter = Lookup.EMPTY_GETTER;
}
final boolean isWritable = writablePropertyNames.contains(propertyName);
properties.add(AccessorProperty.create(propertyName, isWritable ? 0 : Property.NOT_WRITABLE,
readablePropertyNames.contains(propertyName) ? getBeanOperation(linker, "dyn:getProp:" + propertyName, getterType, source) : Lookup.EMPTY_GETTER,
isWritable ? getBeanOperation(linker, "dyn:setProp:" + propertyName, setterType, source) : Lookup.EMPTY_SETTER));
MethodHandle setter;
if(isWritable) {
try {
setter = getBeanOperation(linker, "dyn:setProp:" + propertyName, setterType, source);
} catch(final IllegalAccessError e) {
// Presumably, this was a caller sensitive method. Ignore it and carry on.
setter = Lookup.EMPTY_SETTER;
}
} else {
setter = Lookup.EMPTY_SETTER;
}
if(getter != Lookup.EMPTY_GETTER || setter != Lookup.EMPTY_SETTER) {
properties.add(AccessorProperty.create(propertyName, isWritable ? 0 : Property.NOT_WRITABLE, getter, setter));
}
}
targetObj.addBoundProperties(source, properties.toArray(new AccessorProperty[properties.size()]));

View File

@ -65,10 +65,9 @@ public final class NativeRegExp extends ScriptObject {
private RegExp regexp;
// Reference to global object needed to support static RegExp properties
private Global globalObject;
private final Global globalObject;
// initialized by nasgen
@SuppressWarnings("unused")
private static PropertyMap $nasgenmap$;
static PropertyMap getInitialMap() {

View File

@ -1058,9 +1058,8 @@ public final class NativeString extends ScriptObject {
public static Object trim(final Object self) {
final String str = checkObjectToString(self);
final int len = str.length();
int start = 0;
int end = len - 1;
int end = str.length() - 1;
while (start <= end && ScriptRuntime.isJSWhitespace(str.charAt(start))) {
start++;
@ -1069,7 +1068,45 @@ public final class NativeString extends ScriptObject {
end--;
}
return start == 0 && end + 1 == len ? str : str.substring(start, end + 1);
return str.substring(start, end + 1);
}
/**
* Nashorn extension: String.prototype.trimLeft ( )
* @param self self reference
* @return string trimmed left from whitespace
*/
@Function(attributes = Attribute.NOT_ENUMERABLE)
public static Object trimLeft(final Object self) {
final String str = checkObjectToString(self);
int start = 0;
int end = str.length() - 1;
while (start <= end && ScriptRuntime.isJSWhitespace(str.charAt(start))) {
start++;
}
return str.substring(start, end + 1);
}
/**
* Nashorn extension: String.prototype.trimRight ( )
* @param self self reference
* @return string trimmed right from whitespace
*/
@Function(attributes = Attribute.NOT_ENUMERABLE)
public static Object trimRight(final Object self) {
final String str = checkObjectToString(self);
int start = 0;
int end = str.length() - 1;
while (end >= start && ScriptRuntime.isJSWhitespace(str.charAt(end))) {
end--;
}
return str.substring(start, end + 1);
}
private static Object newObj(final Object self, final CharSequence str) {

View File

@ -107,6 +107,11 @@ public final class NativeUint16Array extends ArrayBufferView {
super(buffer, byteOffset, length);
}
@Override
public String getClassName() {
return "Uint16Array";
}
@Override
protected Factory factory() {
return FACTORY;

View File

@ -126,6 +126,11 @@ public final class NativeUint32Array extends ArrayBufferView {
super(buffer, byteOffset, length);
}
@Override
public String getClassName() {
return "Uint32Array";
}
@Override
protected Factory factory() {
return FACTORY;

View File

@ -100,6 +100,11 @@ public final class NativeUint8Array extends ArrayBufferView {
super(buffer, byteOffset, length);
}
@Override
public String getClassName() {
return "Uint8Array";
}
@Override
protected Factory factory() {
return FACTORY;

View File

@ -117,6 +117,11 @@ public final class NativeUint8ClampedArray extends ArrayBufferView {
super(buffer, byteOffset, length);
}
@Override
public String getClassName() {
return "Uint8ClampedArray";
}
@Override
protected Factory factory() {
return FACTORY;

View File

@ -284,7 +284,7 @@ public enum TokenType {
@Override
public String toString() {
return name;
return getNameOrType();
}
static {

View File

@ -894,7 +894,6 @@ public final class Context {
return script;
}
@SuppressWarnings("static-method")
private ScriptLoader createNewLoader() {
return AccessController.doPrivileged(
new PrivilegedAction<ScriptLoader>() {

View File

@ -44,6 +44,7 @@ final class DebuggerSupport {
* Hook to force the loading of the DebuggerValueDesc class so that it is
* available to external debuggers.
*/
@SuppressWarnings("unused")
DebuggerValueDesc forceLoad = new DebuggerValueDesc(null, false, null, null);
}
@ -77,6 +78,27 @@ final class DebuggerSupport {
return Context.getGlobalTrusted();
}
/**
* Call eval on the current global.
* @param scope Scope to use.
* @param self Receiver to use.
* @param string String to evaluate.
* @param returnException true if exceptions are to be returned.
* @return Result of eval as string, or, an exception or null depending on returnException.
*/
static Object eval(final ScriptObject scope, final Object self, final String string, final boolean returnException) {
final ScriptObject global = Context.getGlobalTrusted();
final ScriptObject initialScope = scope != null ? scope : global;
final Object callThis = self != null ? self : global;
final Context context = global.getContext();
try {
return context.eval(initialScope, string, callThis, ScriptRuntime.UNDEFINED, false);
} catch (Throwable ex) {
return returnException ? ex : null;
}
}
/**
* This method returns a bulk description of an object's properties.
* @param object Script object to be displayed by the debugger.
@ -111,9 +133,8 @@ final class DebuggerSupport {
if (value instanceof ScriptObject && !(value instanceof ScriptFunction)) {
final ScriptObject object = (ScriptObject)value;
return new DebuggerValueDesc(name, !object.isEmpty(), value, objectAsString(object, all, duplicates));
} else {
return new DebuggerValueDesc(name, false, value, valueAsString(value));
}
return new DebuggerValueDesc(name, false, value, valueAsString(value));
}
/**
@ -135,7 +156,7 @@ final class DebuggerSupport {
for (int i = 0; i < keys.length; i++) {
final String key = keys[i];
descs[i] = valueInfo(key, object.get(key), true, duplicates);
descs[i] = valueInfo(key, object.get(key), all, duplicates);
}
duplicates.remove(object);
@ -172,7 +193,7 @@ final class DebuggerSupport {
}
if (valueAsObject instanceof ScriptObject && !(valueAsObject instanceof ScriptFunction)) {
final String objectString = objectAsString((ScriptObject)valueAsObject, true, duplicates);
final String objectString = objectAsString((ScriptObject)valueAsObject, all, duplicates);
sb.append(objectString != null ? objectString : "{...}");
} else {
sb.append(valueAsString(valueAsObject));
@ -199,7 +220,7 @@ final class DebuggerSupport {
final String valueAsString = descs[i].valueAsString;
sb.append(descs[i].key);
sb.append(": ");
sb.append(descs[i].valueAsString);
sb.append(valueAsString);
}
}
@ -239,9 +260,8 @@ final class DebuggerSupport {
case FUNCTION:
if (value instanceof ScriptFunction) {
return ((ScriptFunction)value).toSource();
} else {
return value.toString();
}
return value.toString();
default:
return value.toString();

View File

@ -52,6 +52,7 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import jdk.internal.dynalink.CallSiteDescriptor;
import jdk.internal.dynalink.linker.GuardedInvocation;
import jdk.internal.dynalink.linker.LinkRequest;
@ -1149,12 +1150,12 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
if (newProto == null || newProto instanceof ScriptObject) {
// check for circularity
ScriptObject proto = (ScriptObject)newProto;
while (proto != null) {
if (proto == this) {
ScriptObject p = (ScriptObject)newProto;
while (p != null) {
if (p == this) {
throw typeError("circular.__proto__.set", ScriptRuntime.safeToString(this));
}
proto = proto.getProto();
p = p.getProto();
}
setProto((ScriptObject)newProto);
} else {
@ -2017,6 +2018,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
* @param request the link request
* @return GuardedInvocation to be invoked at call site.
*/
@SuppressWarnings("null")
public GuardedInvocation noSuchProperty(final CallSiteDescriptor desc, final LinkRequest request) {
final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
final FindProperty find = findProperty(NO_SUCH_PROPERTY_NAME, true);

View File

@ -190,6 +190,8 @@ public final class ScriptRuntime {
case FUNCTION:
if (self instanceof ScriptObject) {
className = ((ScriptObject)self).getClassName();
} else if (self instanceof ScriptObjectMirror) {
className = ((ScriptObjectMirror)self).getClassName();
} else {
className = self.getClass().getName();
}

View File

@ -39,7 +39,6 @@ import jdk.nashorn.internal.runtime.regexp.joni.constants.NodeType;
import jdk.nashorn.internal.runtime.regexp.joni.constants.OPCode;
import jdk.nashorn.internal.runtime.regexp.joni.constants.OPSize;
import jdk.nashorn.internal.runtime.regexp.joni.constants.TargetInfo;
import jdk.nashorn.internal.runtime.regexp.joni.encoding.CharacterType;
final class ArrayCompiler extends Compiler {
private int[] code;
@ -345,6 +344,7 @@ final class ArrayCompiler extends Compiler {
private static final int QUANTIFIER_EXPAND_LIMIT_SIZE = 50; // was 50
@SuppressWarnings("unused")
private static boolean cknOn(int ckn) {
return ckn > 0;
}
@ -879,6 +879,7 @@ final class ArrayCompiler extends Compiler {
}
}
@SuppressWarnings("unused")
private void addStateCheckNum(int num) {
addInt(num);
}
@ -887,6 +888,7 @@ final class ArrayCompiler extends Compiler {
addInt(addr);
}
@SuppressWarnings("unused")
private void addAbsAddr(int addr) {
addInt(addr);
}

View File

@ -29,6 +29,7 @@ public final class BitSet {
final int[] bits = new int[BITSET_SIZE];
private static final int BITS_TO_STRING_WRAP = 4;
@Override
public String toString() {
StringBuilder buffer = new StringBuilder();
buffer.append("BitSet");

View File

@ -26,7 +26,6 @@ import static jdk.nashorn.internal.runtime.regexp.joni.Option.isFindNotEmpty;
import static jdk.nashorn.internal.runtime.regexp.joni.Option.isNotBol;
import static jdk.nashorn.internal.runtime.regexp.joni.Option.isNotEol;
import static jdk.nashorn.internal.runtime.regexp.joni.Option.isPosixRegion;
import static jdk.nashorn.internal.runtime.regexp.joni.EncodingHelper.isCrnl;
import static jdk.nashorn.internal.runtime.regexp.joni.EncodingHelper.isNewLine;
import jdk.nashorn.internal.runtime.regexp.joni.ast.CClassNode;
@ -96,6 +95,7 @@ class ByteCodeMachine extends StackMachine {
}
}
@Override
protected final int matchAt(int range, int sstart, int sprev) {
this.range = range;
this.sstart = sstart;
@ -499,7 +499,7 @@ class ByteCodeMachine extends StackMachine {
private void opAnyChar() {
if (s >= range) {opFail(); return;}
if (chars[s] == EncodingHelper.NEW_LINE) {opFail(); return;}
if (isNewLine(chars[s])) {opFail(); return;}
s++;
sprev = sbegin; // break;
}
@ -537,7 +537,7 @@ class ByteCodeMachine extends StackMachine {
while (s < range) {
char b = chars[s];
if (c == b) pushAlt(ip + 1, s, sprev);
if (b == EncodingHelper.NEW_LINE) {opFail(); return;}
if (isNewLine(b)) {opFail(); return;}
sprev = s;
s++;
}
@ -616,7 +616,7 @@ class ByteCodeMachine extends StackMachine {
if (s == str) {
if (isNotBol(msaOptions)) opFail();
return;
} else if (EncodingHelper.isNewLine(chars, sprev, end) && s != end) {
} else if (isNewLine(chars, sprev, end) && s != end) {
return;
}
opFail();
@ -625,7 +625,7 @@ class ByteCodeMachine extends StackMachine {
private void opEndLine() {
if (s == end) {
if (Config.USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE) {
if (str == end || !EncodingHelper.isNewLine(chars, sprev, end)) {
if (str == end || !isNewLine(chars, sprev, end)) {
if (isNotEol(msaOptions)) opFail();
}
return;
@ -633,7 +633,7 @@ class ByteCodeMachine extends StackMachine {
if (isNotEol(msaOptions)) opFail();
return;
}
} else if (isNewLine(chars, s, end) || (Config.USE_CRNL_AS_LINE_TERMINATOR && isCrnl(chars, s, end))) {
} else if (isNewLine(chars, s, end)) {
return;
}
opFail();
@ -652,9 +652,6 @@ class ByteCodeMachine extends StackMachine {
}
} else if (isNewLine(chars, s, end) && s + 1 == end) {
return;
} else if (Config.USE_CRNL_AS_LINE_TERMINATOR && isCrnl(chars, s, end)) {
int ss = s + 2;
if (ss == end) return;
}
opFail();
}
@ -731,8 +728,6 @@ class ByteCodeMachine extends StackMachine {
// STRING_CMP
while(n-- > 0) if (chars[pstart++] != chars[s++]) {opFail(); return;}
int len;
// beyond string check
if (sprev < range) {
while (sprev + 1 < s) sprev++;
@ -768,7 +763,6 @@ class ByteCodeMachine extends StackMachine {
if (!stringCmpIC(regex.caseFoldFlag, pstart, this, n, end)) {opFail(); return;}
s = value;
int len;
// if (sprev < chars.length)
while (sprev + 1 < s) sprev++;
}
@ -796,8 +790,6 @@ class ByteCodeMachine extends StackMachine {
s = swork;
int len;
// beyond string check
if (sprev < range) {
while (sprev + 1 < s) sprev++;
@ -829,7 +821,6 @@ class ByteCodeMachine extends StackMachine {
if (!stringCmpIC(regex.caseFoldFlag, pstart, this, n, end)) continue loop; // STRING_CMP_VALUE_IC
s = value;
int len;
// if (sprev < chars.length)
while (sprev + 1 < s) sprev++;
@ -902,7 +893,6 @@ class ByteCodeMachine extends StackMachine {
sprev = s;
if (backrefMatchAtNestedLevel(ic != 0, regex.caseFoldFlag, level, tlen, ip)) { // (s) and (end) implicit
int len;
while (sprev + 1 < s) sprev++;
ip += tlen; // * SIZE_MEMNUM
} else {

View File

@ -58,6 +58,7 @@ public final class CodeRangeBuffer implements Cloneable {
used = orig.used;
}
@Override
public String toString() {
StringBuilder buf = new StringBuilder();
buf.append("CodeRange");

View File

@ -29,7 +29,6 @@ public interface Config {
final int INTERNAL_ENC_CASE_FOLD_MULTI_CHAR = (1<<30);
final int ENC_CASE_FOLD_MIN = INTERNAL_ENC_CASE_FOLD_MULTI_CHAR;
final int ENC_CASE_FOLD_DEFAULT = ENC_CASE_FOLD_MIN;
final boolean USE_CRNL_AS_LINE_TERMINATOR = false;
final boolean USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT = true; /* /(?:()|())*\2/ */
final boolean USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE = true; /* /\n$/ =~ "\n" */

View File

@ -24,10 +24,12 @@ import jdk.nashorn.internal.runtime.regexp.joni.encoding.IntHolder;
import java.util.Arrays;
public class EncodingHelper {
public final class EncodingHelper {
public final static char NEW_LINE = 0xa;
public final static char RETURN = 0xd;
final static int NEW_LINE = 0x000a;
final static int RETURN = 0x000d;
final static int LINE_SEPARATOR = 0x2028;
final static int PARAGRAPH_SEPARATOR = 0x2029;
final static char[] EMPTYCHARS = new char[0];
final static int[][] codeRanges = new int[15][];
@ -64,15 +66,11 @@ public class EncodingHelper {
}
public static boolean isNewLine(int code) {
return code == NEW_LINE;
return code == NEW_LINE || code == RETURN || code == LINE_SEPARATOR || code == PARAGRAPH_SEPARATOR;
}
public static boolean isNewLine(char[] chars, int p, int end) {
return p < end && chars[p] == NEW_LINE;
}
public static boolean isCrnl(char[] chars, int p, int end) {
return p + 1 < end && chars[p] == RETURN && chars[p + 1] == NEW_LINE;
return p < end && isNewLine(chars[p]);
}
// Encoding.prevCharHead
@ -194,7 +192,7 @@ public class EncodingHelper {
int type;
switch (ctype) {
case CharacterType.NEWLINE:
return code == EncodingHelper.NEW_LINE;
return isNewLine(code);
case CharacterType.ALPHA:
return (1 << Character.getType(code) & CharacterType.ALPHA_MASK) != 0;
case CharacterType.BLANK:

View File

@ -139,6 +139,7 @@ class Lexer extends ScannerSupport {
}
}
@SuppressWarnings("fallthrough")
/* \M-, \C-, \c, or \... */
private int fetchEscapedValue() {
if (!left()) {
@ -731,7 +732,7 @@ class Lexer extends ScannerSupport {
if (syntax.opLineAnchor()) fetchTokenFor_anchor(isSingleline(env.option) ? AnchorType.BEGIN_BUF : AnchorType.BEGIN_LINE);
break;
case '$':
if (syntax.opLineAnchor()) fetchTokenFor_anchor(isSingleline(env.option) ? AnchorType.SEMI_END_BUF : AnchorType.END_LINE);
if (syntax.opLineAnchor()) fetchTokenFor_anchor(isSingleline(env.option) ? AnchorType.END_BUF : AnchorType.END_LINE);
break;
case '[':
if (syntax.opBracketCC()) token.type = TokenType.CC_CC_OPEN;

View File

@ -141,7 +141,7 @@ public abstract class Matcher extends IntHolder {
continue retry;
}
}
} else if (!EncodingHelper.isNewLine(chars, p, end) && (!Config.USE_CRNL_AS_LINE_TERMINATOR || !EncodingHelper.isCrnl(chars, p, end))) {
} else if (!EncodingHelper.isNewLine(chars, p, end)) {
//if () break;
// goto retry_gate;
pprev = p;
@ -226,7 +226,7 @@ public abstract class Matcher extends IntHolder {
continue retry;
}
}
} else if (!EncodingHelper.isNewLine(chars, p, end) && (!Config.USE_CRNL_AS_LINE_TERMINATOR || !EncodingHelper.isCrnl(chars, p, end))) {
} else if (!EncodingHelper.isNewLine(chars, p, end)) {
p = EncodingHelper.prevCharHead(adjrange, p);
if (p == -1) return false;
continue retry;
@ -330,12 +330,6 @@ public abstract class Matcher extends IntHolder {
maxSemiEnd = end;
if (EncodingHelper.isNewLine(chars, preEnd, end)) {
minSemiEnd = preEnd;
if (Config.USE_CRNL_AS_LINE_TERMINATOR) {
preEnd = EncodingHelper.stepBack(str, preEnd, 1);
if (preEnd != -1 && EncodingHelper.isCrnl(chars, preEnd, end)) {
minSemiEnd = preEnd;
}
}
if (minSemiEnd > str && start <= minSemiEnd) {
// !goto end_buf;!
if (endBuf(start, range, minSemiEnd, maxSemiEnd)) return -1; // mismatch_no_msa;

View File

@ -297,8 +297,6 @@ class Parser extends Lexer {
throw new SyntaxException(ERR_END_PATTERN_IN_GROUP);
}
boolean listCapture = false;
fetch();
switch(c) {
case ':': /* (?:...) grouping only */

View File

@ -32,6 +32,7 @@ public final class Region {
this.end = new int[num];
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Region: \n");

View File

@ -21,9 +21,6 @@ package jdk.nashorn.internal.runtime.regexp.joni;
import jdk.nashorn.internal.runtime.regexp.joni.encoding.IntHolder;
import jdk.nashorn.internal.runtime.regexp.joni.exception.ErrorMessages;
import jdk.nashorn.internal.runtime.regexp.joni.exception.InternalException;
import jdk.nashorn.internal.runtime.regexp.joni.exception.SyntaxException;
import jdk.nashorn.internal.runtime.regexp.joni.exception.ValueException;
abstract class ScannerSupport extends IntHolder implements ErrorMessages {

View File

@ -28,14 +28,17 @@ public abstract class SearchAlgorithm {
public static final SearchAlgorithm NONE = new SearchAlgorithm() {
@Override
public final String getName() {
return "NONE";
}
@Override
public final int search(Regex regex, char[] text, int textP, int textEnd, int textRange) {
return textP;
}
@Override
public final int searchBackward(Regex regex, char[] text, int textP, int adjustText, int textEnd, int textStart, int s_, int range_) {
return textP;
}
@ -44,10 +47,12 @@ public abstract class SearchAlgorithm {
public static final SearchAlgorithm SLOW = new SearchAlgorithm() {
@Override
public final String getName() {
return "EXACT";
}
@Override
public final int search(Regex regex, char[] text, int textP, int textEnd, int textRange) {
char[] target = regex.exact;
int targetP = regex.exactP;
@ -78,6 +83,7 @@ public abstract class SearchAlgorithm {
return -1;
}
@Override
public final int searchBackward(Regex regex, char[] text, int textP, int adjustText, int textEnd, int textStart, int s_, int range_) {
char[] target = regex.exact;
int targetP = regex.exactP;
@ -114,10 +120,12 @@ public abstract class SearchAlgorithm {
this.caseFoldFlag = regex.caseFoldFlag;
}
@Override
public final String getName() {
return "EXACT_IC";
}
@Override
public final int search(Regex regex, char[] text, int textP, int textEnd, int textRange) {
char[] target = regex.exact;
int targetP = regex.exactP;
@ -136,6 +144,7 @@ public abstract class SearchAlgorithm {
return -1;
}
@Override
public final int searchBackward(Regex regex, char[] text, int textP, int adjustText, int textEnd, int textStart, int s_, int range_) {
char[] target = regex.exact;
int targetP = regex.exactP;
@ -163,14 +172,16 @@ public abstract class SearchAlgorithm {
}
return true;
}
};
}
public static final SearchAlgorithm BM = new SearchAlgorithm() {
@Override
public final String getName() {
return "EXACT_BM";
}
@Override
public final int search(Regex regex, char[] text, int textP, int textEnd, int textRange) {
char[] target = regex.exact;
int targetP = regex.exactP;
@ -212,6 +223,7 @@ public abstract class SearchAlgorithm {
private static final int BM_BACKWARD_SEARCH_LENGTH_THRESHOLD = 100;
@Override
public final int searchBackward(Regex regex, char[] text, int textP, int adjustText, int textEnd, int textStart, int s_, int range_) {
char[] target = regex.exact;
int targetP = regex.exactP;
@ -263,10 +275,12 @@ public abstract class SearchAlgorithm {
public static final SearchAlgorithm MAP = new SearchAlgorithm() {
@Override
public final String getName() {
return "MAP";
}
@Override
public final int search(Regex regex, char[] text, int textP, int textEnd, int textRange) {
byte[] map = regex.map;
int s = textP;
@ -278,6 +292,7 @@ public abstract class SearchAlgorithm {
return -1;
}
@Override
public final int searchBackward(Regex regex, char[] text, int textP, int adjustText, int textEnd, int textStart, int s_, int range_) {
byte[] map = regex.map;
int s = textStart;

View File

@ -458,7 +458,7 @@ abstract class StackMachine extends Matcher implements StackType {
isNull = 0;
break;
} else if (endp != s) {
isNull = -1;; /* empty, but position changed */
isNull = -1; /* empty, but position changed */
}
}
k++;

View File

@ -24,6 +24,7 @@ package jdk.nashorn.internal.runtime.regexp.joni;
*/
public interface WarnCallback {
WarnCallback DEFAULT = new WarnCallback() {
@Override
public void warn(String message) {
System.err.println(message);
}

View File

@ -19,7 +19,6 @@
*/
package jdk.nashorn.internal.runtime.regexp.joni.ast;
import jdk.nashorn.internal.runtime.regexp.joni.Config;
import jdk.nashorn.internal.runtime.regexp.joni.Option;
import jdk.nashorn.internal.runtime.regexp.joni.constants.EncloseType;

View File

@ -35,7 +35,7 @@ public abstract class Node implements NodeType {
}
protected void setChild(Node tgt){} // default definition
protected Node getChild(){return null;}; // default definition
protected Node getChild(){return null;} // default definition
public void swap(Node with) {
Node tmp;
@ -74,6 +74,7 @@ public abstract class Node implements NodeType {
return getName() + ":0x" + Integer.toHexString(System.identityHashCode(this));
}
@Override
public final String toString() {
StringBuilder s = new StringBuilder();
s.append("<" + getAddressName() + " (" + (parent == null ? "NULL" : parent.getAddressName()) + ")>");

View File

@ -223,6 +223,7 @@ public final class QuantifierNode extends StateNode {
other.target = null; // remove target from reduced quantifier
}
@SuppressWarnings("fallthrough")
public int setQuantifier(Node tgt, boolean group, ScanEnvironment env, char[] chars, int p, int end) {
if (lower == 1 && upper == 1) return 1;

View File

@ -19,8 +19,6 @@
*/
package jdk.nashorn.internal.runtime.regexp.joni.exception;
import jdk.nashorn.internal.runtime.regexp.joni.Config;
public interface ErrorMessages {
/* from jcodings */

View File

@ -288,7 +288,7 @@ nashorn.option.print.symbols = { \
nashorn.option.range.analysis = { \
name="--range-analysis", \
is_undocumented=true, \
desc="Do range analysis using known compile time types, and try to narrow number types" \
desc="EXPERIMENTAL: Do range analysis using known compile time types, and try to narrow number types" \
}
nashorn.option.D = { \
@ -307,12 +307,12 @@ nashorn.option.scripting = { \
desc="Enable scripting features." \
}
nashorn.option.specialize.calls = { \
name="--specialize-calls", \
is_undocumented=true, \
type=String, \
params="[=function_1,...,function_n]", \
desc="Specialize all or a set of method according to callsite parameter types" \
nashorn.option.specialize.calls = { \
name="--specialize-calls", \
is_undocumented=true, \
type=String, \
params="[=function_1,...,function_n]", \
desc="EXPERIMENTAL: Specialize all or a set of method according to callsite parameter types" \
}
nashorn.option.stdout = { \

View File

@ -445,7 +445,7 @@ public class Shell {
continue;
}
if (res != null && res != ScriptRuntime.UNDEFINED) {
if (res != ScriptRuntime.UNDEFINED) {
err.println(JSType.toString(res));
}
}

View File

@ -0,0 +1,171 @@
/*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* 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-8019987: String trimRight and trimLeft could be defined.
*
* @test
* @run
*/
var TESTSTRING = "abcde";
var SPACES = " ";
var TESTSTRING_LEFT_SPACES = SPACES + TESTSTRING;
var TESTSTRING_RIGHT_SPACES = TESTSTRING + SPACES;
var TESTSTRING_BOTH_SPACES = SPACES + TESTSTRING + SPACES;
var TESTSTRING_MIDDLE_SPACES = TESTSTRING + SPACES + TESTSTRING;
var WHITESPACE =
" \t" + // space and tab
"\n\r" + // newline and return
"\u2028" + // line separator
"\u2029" + // paragraph separator
"\u000b" + // tabulation line
"\u000c" + // ff (ctrl-l)
"\u00a0" + // Latin-1 space
"\u1680" + // Ogham space mark
"\u180e" + // separator, Mongolian vowel
"\u2000" + // en quad
"\u2001" + // em quad
"\u2002" + // en space
"\u2003" + // em space
"\u2004" + // three-per-em space
"\u2005" + // four-per-em space
"\u2006" + // six-per-em space
"\u2007" + // figure space
"\u2008" + // punctuation space
"\u2009" + // thin space
"\u200a" + // hair space
"\u202f" + // narrow no-break space
"\u205f" + // medium mathematical space
"\u3000" + // ideographic space
"\ufeff"; // byte order mark
var TESTSTRING_LEFT_WHITESPACE = WHITESPACE + TESTSTRING;
var TESTSTRING_RIGHT_WHITESPACE = TESTSTRING + WHITESPACE;
var TESTSTRING_BOTH_WHITESPACE = WHITESPACE + TESTSTRING + WHITESPACE;
var TESTSTRING_MIDDLE_WHITESPACE = TESTSTRING + WHITESPACE + TESTSTRING;
function escape(string) {
var sb = new java.lang.StringBuilder();
sb.append("\"");
for (var i = 0; i < string.length; i++) {
var ch = string.charAt(i);
switch (ch) {
case '\\':
sb.append("\\\\");
break;
case '"':
sb.append("\\\"");
break;
case '\'':
sb.append("\\\'");
break;
case '\b':
sb.append("\\b");
break;
case '\f':
sb.append("\\f");
break;
case '\n':
sb.append("\\n");
break;
case '\r':
sb.append("\\r");
break;
case '\t':
sb.append("\\t");
break;
default:
var code = string.charCodeAt(i);
if (code < 0x20 || code >= 0xFF) {
sb.append("\\u");
var hex = java.lang.Integer.toHexString(code);
for (var i = hex.length; i < 4; i++) {
sb.append('0');
}
sb.append(hex);
} else {
sb.append(ch);
}
break;
}
}
sb.append("\"");
return sb.toString();
}
var count = 0;
function test(expected, trimmed) {
count++;
if (trimmed != expected) {
print(count + ": Expected: " + escape(expected) + ", found: " + escape(trimmed));
}
}
test("", SPACES.trim());
test("", SPACES.trimLeft());
test("", SPACES.trimRight());
test(TESTSTRING, TESTSTRING_LEFT_SPACES.trim());
test(TESTSTRING, TESTSTRING_LEFT_SPACES.trimLeft());
test(TESTSTRING_LEFT_SPACES, TESTSTRING_LEFT_SPACES.trimRight());
test(TESTSTRING, TESTSTRING_RIGHT_SPACES.trim());
test(TESTSTRING_RIGHT_SPACES, TESTSTRING_RIGHT_SPACES.trimLeft());
test(TESTSTRING, TESTSTRING_RIGHT_SPACES.trimRight());
test(TESTSTRING, TESTSTRING_BOTH_SPACES.trim());
test(TESTSTRING_RIGHT_SPACES, TESTSTRING_BOTH_SPACES.trimLeft());
test(TESTSTRING_LEFT_SPACES, TESTSTRING_BOTH_SPACES.trimRight());
test(TESTSTRING_MIDDLE_SPACES, TESTSTRING_MIDDLE_SPACES.trim());
test(TESTSTRING_MIDDLE_SPACES, TESTSTRING_MIDDLE_SPACES.trimLeft());
test(TESTSTRING_MIDDLE_SPACES, TESTSTRING_MIDDLE_SPACES.trimRight());
test("", WHITESPACE.trim());
test("", WHITESPACE.trimLeft());
test("", WHITESPACE.trimRight());
test(TESTSTRING, TESTSTRING_LEFT_WHITESPACE.trim());
test(TESTSTRING, TESTSTRING_LEFT_WHITESPACE.trimLeft());
test(TESTSTRING_LEFT_WHITESPACE, TESTSTRING_LEFT_WHITESPACE.trimRight());
test(TESTSTRING, TESTSTRING_RIGHT_WHITESPACE.trim());
test(TESTSTRING_RIGHT_WHITESPACE, TESTSTRING_RIGHT_WHITESPACE.trimLeft());
test(TESTSTRING, TESTSTRING_RIGHT_WHITESPACE.trimRight());
test(TESTSTRING, TESTSTRING_BOTH_WHITESPACE.trim());
test(TESTSTRING_RIGHT_WHITESPACE, TESTSTRING_BOTH_WHITESPACE.trimLeft());
test(TESTSTRING_LEFT_WHITESPACE, TESTSTRING_BOTH_WHITESPACE.trimRight());
test(TESTSTRING_MIDDLE_WHITESPACE, TESTSTRING_MIDDLE_WHITESPACE.trim());
test(TESTSTRING_MIDDLE_WHITESPACE, TESTSTRING_MIDDLE_WHITESPACE.trimLeft());
test(TESTSTRING_MIDDLE_WHITESPACE, TESTSTRING_MIDDLE_WHITESPACE.trimRight());

View File

@ -0,0 +1,109 @@
/*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* 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-8023650: Regexp m flag does not recognize CRNL or CR
*
* @test
* @run
*/
if (!/^Connection: close$/m.test('\r\n\r\nConnection: close\r\n\r\n')) {
throw new Error();
}
if (!/^Connection: close$/m.test('\n\nConnection: close\n\n')) {
throw new Error();
}
if (!/^Connection: close$/m.test('\r\rConnection: close\r\r')) {
throw new Error();
}
if (!/^Connection: close$/m.test('\u2028\u2028Connection: close\u2028\u2028')) {
throw new Error();
}
if (!/^Connection: close$/m.test('\u2029\u2029Connection: close\u2029\u2029')) {
throw new Error();
}
var result = /a(.*)/.exec("a\r");
if (!result || result[0] != 'a' || result[1] != '') {
throw new Error();
}
result = /a(.*)/m.exec("a\r");
if (!result || result[0] != 'a' || result[1] != '') {
throw new Error();
}
result = /a(.*)/.exec("a\n");
if (!result || result[0] != 'a' || result[1] != '') {
throw new Error();
}
result = /a(.*)/m.exec("a\n");
if (!result || result[0] != 'a' || result[1] != '') {
throw new Error();
}
result = /a(.*)/.exec("a\r\n");
if (!result || result[0] != 'a' || result[1] != '') {
throw new Error();
}
result = /a(.*)/m.exec("a\r\n");
if (!result || result[0] != 'a' || result[1] != '') {
throw new Error();
}
result = /a(.*)/.exec("a\u2028");
if (!result || result[0] != 'a' || result[1] != '') {
throw new Error();
}
result = /a(.*)/m.exec("a\u2029");
if (!result || result[0] != 'a' || result[1] != '') {
throw new Error();
}
if (/a$/.test("a\n")) {
throw new Error();
}
if (/a$/.test("a\r")) {
throw new Error();
}
if (/a$/.test("a\r\n")) {
throw new Error();
}
if (/a$/.test("a\u2028")) {
throw new Error();
}
if (/a$/.test("a\u2029")) {
throw new Error();
}

View File

@ -0,0 +1,38 @@
/*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* 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-8023780: Gracefully handle @CS methods while binding bean properties
*
* @test
* @run
*/
var obj = {}
Object.bindProperties(obj, java.lang.Thread.currentThread());
print(typeof obj.getName === "function")
print(typeof obj.getCurrentContext === "undefined")
print(Object.hasOwnProperty("name"))
print(!Object.hasOwnProperty("currentContext"))

View File

@ -0,0 +1,4 @@
true
true
true
true

View File

@ -0,0 +1,66 @@
/*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* 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-8023784: Object.prototype.toString should contain the class name for all instances
*
* @test
* @run
*/
// two parts to this bug -- typed array don't have proper [[Class]] property
print(Object.prototype.toString.call(new ArrayBuffer(1)));
print(Object.prototype.toString.call(new Int8Array(1)));
print(Object.prototype.toString.call(new Int16Array(1)));
print(Object.prototype.toString.call(new Int32Array(1)));
print(Object.prototype.toString.call(new Uint8Array(1)));
print(Object.prototype.toString.call(new Uint8ClampedArray(1)));
print(Object.prototype.toString.call(new Uint16Array(1)));
print(Object.prototype.toString.call(new Uint32Array(1)));
print(Object.prototype.toString.call(new Float32Array(1)));
print(Object.prototype.toString.call(new Float64Array(1)));
// second part is that Object.prototype.toString does not handle mirror
// in the manner expected.
var global = loadWithNewGlobal({
name: "test",
script: "this"
});
print(Object.prototype.toString.call(new global.Object()));
print(Object.prototype.toString.call(new global.Array()));
print(Object.prototype.toString.call(new global.RegExp()));
print(Object.prototype.toString.call(new global.Error("error!")));
print(Object.prototype.toString.call(global.Object));
print(Object.prototype.toString.call(new global.ArrayBuffer(1)));
print(Object.prototype.toString.call(new global.Int8Array(1)));
print(Object.prototype.toString.call(new global.Int16Array(1)));
print(Object.prototype.toString.call(new global.Int32Array(1)));
print(Object.prototype.toString.call(new global.Uint8Array(1)));
print(Object.prototype.toString.call(new global.Uint8ClampedArray(1)));
print(Object.prototype.toString.call(new global.Uint16Array(1)));
print(Object.prototype.toString.call(new global.Uint32Array(1)));
print(Object.prototype.toString.call(new global.Float32Array(1)));
print(Object.prototype.toString.call(new global.Float64Array(1)));

View File

@ -0,0 +1,25 @@
[object ArrayBuffer]
[object Int8Array]
[object Int16Array]
[object Int32Array]
[object Uint8Array]
[object Uint8ClampedArray]
[object Uint16Array]
[object Uint32Array]
[object Float32Array]
[object Float64Array]
[object Object]
[object Array]
[object RegExp]
[object Error]
[object Function]
[object ArrayBuffer]
[object Int8Array]
[object Int16Array]
[object Int32Array]
[object Uint8Array]
[object Uint8ClampedArray]
[object Uint16Array]
[object Uint32Array]
[object Float32Array]
[object Float64Array]

View File

@ -1,5 +1,5 @@
8 8 true undefined
[object Object] [object Object] [object Object]
[object ArrayBuffer] [object ArrayBuffer] [object Int8Array]
0 8 8 1
0 8 8 1
0 8 8 1

View File

@ -30,6 +30,7 @@ import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.lang.reflect.Method;
@ -400,8 +401,7 @@ public class ScriptEngineTest {
exp.printStackTrace();
fail(exp.getMessage());
}
// dos2unix - fix line endings if running on windows
assertEquals(sw.toString().replaceAll("\r", ""), "hello world\n");
assertEquals(sw.toString(), println("hello world"));
}
@Test
@ -490,8 +490,7 @@ public class ScriptEngineTest {
fail(t.getMessage());
}
// dos2unix - fix line endings if running on windows
assertEquals(sw.toString().replaceAll("\r", ""), "hello\n");
assertEquals(sw.toString(), println("hello"));
}
@Test
@ -508,7 +507,14 @@ public class ScriptEngineTest {
fail(t.getMessage());
}
// dos2unix - fix line endings if running on windows
assertEquals(sw.toString().replaceAll("\r", ""), "34 true hello\n");
assertEquals(sw.toString(), println("34 true hello"));
}
private static final String LINE_SEPARATOR = System.getProperty("line.separator");
// Returns String that would be the result of calling PrintWriter.println
// of the given String. (This is to handle platform specific newline).
private static String println(final String str) {
return str + LINE_SEPARATOR;
}
}

View File

@ -32,13 +32,9 @@ import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Application;
import javafx.stage.Stage;
import javax.script.Invocable;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
import javax.script.ScriptEngineManager;
@ -180,6 +176,7 @@ public class FXShell extends Application {
*
* @return Last evaluation result (discarded.)
*/
@SuppressWarnings("resource")
private Object load(String path) {
try {
FileInputStream file = new FileInputStream(path);