nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Context.java
author hannesw
Sat, 19 Sep 2015 16:04:28 +0200
changeset 32781 d8f34ffbbc7a
parent 32697 d8416054e691
child 32786 dedf2b6ea495
permissions -rw-r--r--
8135190: Method code too large in Babel browser.js script Reviewed-by: attila, sundar
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     1
/*
16151
97c1e756ae1e 8005663: Update copyright year to 2013
jlaskey
parents: 16147
diff changeset
     2
 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     4
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    10
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    15
 * accompanied this code).
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    16
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    20
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    23
 * questions.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    24
 */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    25
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    26
package jdk.nashorn.internal.runtime;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    27
32696
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
    28
import static jdk.internal.org.objectweb.asm.Opcodes.V1_7;
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
    29
import static jdk.nashorn.internal.codegen.CompilerConstants.CONSTANTS;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 23076
diff changeset
    30
import static jdk.nashorn.internal.codegen.CompilerConstants.CREATE_PROGRAM_FUNCTION;
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
    31
import static jdk.nashorn.internal.codegen.CompilerConstants.SOURCE;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    32
import static jdk.nashorn.internal.codegen.CompilerConstants.STRICT_MODE;
26764
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26508
diff changeset
    33
import static jdk.nashorn.internal.runtime.CodeStore.newCodeStore;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    34
import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    35
import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
    36
import static jdk.nashorn.internal.runtime.Source.sourceFor;
27369
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
    37
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    38
import java.io.File;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    39
import java.io.IOException;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    40
import java.io.PrintWriter;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    41
import java.lang.invoke.MethodHandle;
24783
b5c31bfe1496 8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents: 24779
diff changeset
    42
import java.lang.invoke.MethodHandles;
b5c31bfe1496 8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents: 24779
diff changeset
    43
import java.lang.invoke.MethodType;
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
    44
import java.lang.invoke.SwitchPoint;
32696
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
    45
import java.lang.ref.Reference;
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
    46
import java.lang.ref.ReferenceQueue;
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
    47
import java.lang.ref.SoftReference;
32696
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
    48
import java.lang.ref.WeakReference;
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
    49
import java.lang.reflect.Field;
19088
153f268bfa72 8021122: Not all callables are handled for toString and other function valued properties
sundar
parents: 19085
diff changeset
    50
import java.lang.reflect.Modifier;
16254
2ed824fc93be 8008554: load was broken for URLs
lagergren
parents: 16251
diff changeset
    51
import java.net.MalformedURLException;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    52
import java.net.URL;
19097
f544a2ea40ef 8021262: Make nashorn access checks consistent with underlying dynalink
sundar
parents: 19088
diff changeset
    53
import java.security.AccessControlContext;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    54
import java.security.AccessController;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    55
import java.security.CodeSigner;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    56
import java.security.CodeSource;
19097
f544a2ea40ef 8021262: Make nashorn access checks consistent with underlying dynalink
sundar
parents: 19088
diff changeset
    57
import java.security.Permissions;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    58
import java.security.PrivilegedAction;
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
    59
import java.security.PrivilegedActionException;
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
    60
import java.security.PrivilegedExceptionAction;
19097
f544a2ea40ef 8021262: Make nashorn access checks consistent with underlying dynalink
sundar
parents: 19088
diff changeset
    61
import java.security.ProtectionDomain;
24769
attila
parents: 24759 24282
diff changeset
    62
import java.util.Collection;
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
    63
import java.util.HashMap;
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
    64
import java.util.LinkedHashMap;
18334
47413e8d71b5 8016618: script mirror object access should be improved
sundar
parents: 18328
diff changeset
    65
import java.util.Map;
28785
a503c972d4bd 8072595: nashorn should not use obj.getClass() for null checks
sundar
parents: 28441
diff changeset
    66
import java.util.Objects;
32696
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
    67
import java.util.concurrent.ConcurrentHashMap;
22669
75563515567f 8032681: Issues with Nashorn
attila
parents: 22389
diff changeset
    68
import java.util.concurrent.atomic.AtomicLong;
27369
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
    69
import java.util.concurrent.atomic.AtomicReference;
32696
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
    70
import java.util.concurrent.atomic.LongAdder;
24769
attila
parents: 24759 24282
diff changeset
    71
import java.util.function.Consumer;
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
    72
import java.util.function.Supplier;
24731
ab0c8fc915ae 8038406: Testability: as a first step of moving loggers away from the process global space, the Debug object now supports logging POJOs from log entries as an event queue, which can be introspected from test scripts. This is way better than screen scraping brittle and subject-to-change log output.
lagergren
parents: 24727
diff changeset
    73
import java.util.logging.Level;
30975
a71c56056f02 8081609: engine.eval call from a java method which was called from a previous engine.eval results in wrong ScriptContext being used.
sundar
parents: 30513
diff changeset
    74
import javax.script.ScriptContext;
25422
199a23bee487 8049524: Global object initialization via javax.script API should be minimal
sundar
parents: 25243
diff changeset
    75
import javax.script.ScriptEngine;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    76
import jdk.internal.org.objectweb.asm.ClassReader;
32696
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
    77
import jdk.internal.org.objectweb.asm.ClassWriter;
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
    78
import jdk.internal.org.objectweb.asm.Opcodes;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    79
import jdk.internal.org.objectweb.asm.util.CheckClassAdapter;
26071
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
    80
import jdk.nashorn.api.scripting.ClassFilter;
17979
adae4d39ee07 8015945: loadWithNewGlobal return value has to be properly wrapped
sundar
parents: 17976
diff changeset
    81
import jdk.nashorn.api.scripting.ScriptObjectMirror;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    82
import jdk.nashorn.internal.codegen.Compiler;
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24745
diff changeset
    83
import jdk.nashorn.internal.codegen.Compiler.CompilationPhases;
16240
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents: 16233
diff changeset
    84
import jdk.nashorn.internal.codegen.ObjectClassGenerator;
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16230
diff changeset
    85
import jdk.nashorn.internal.ir.FunctionNode;
16240
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents: 16233
diff changeset
    86
import jdk.nashorn.internal.ir.debug.ASTWriter;
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16230
diff changeset
    87
import jdk.nashorn.internal.ir.debug.PrintVisitor;
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
    88
import jdk.nashorn.internal.lookup.MethodHandleFactory;
18851
bdb92c95f886 8019947: inherited property invalidation does not work with two globals in same context
sundar
parents: 18618
diff changeset
    89
import jdk.nashorn.internal.objects.Global;
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16230
diff changeset
    90
import jdk.nashorn.internal.parser.Parser;
24742
a9afb384e654 8040655: When processing a RewriteException debug object, the return value has already been reset to null. We need to catch this value before that.
lagergren
parents: 24733
diff changeset
    91
import jdk.nashorn.internal.runtime.events.RuntimeEvent;
24744
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24742
diff changeset
    92
import jdk.nashorn.internal.runtime.logging.DebugLogger;
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
    93
import jdk.nashorn.internal.runtime.logging.Loggable;
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
    94
import jdk.nashorn.internal.runtime.logging.Logger;
24769
attila
parents: 24759 24282
diff changeset
    95
import jdk.nashorn.internal.runtime.options.LoggingOption.LoggerInfo;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    96
import jdk.nashorn.internal.runtime.options.Options;
32696
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
    97
import sun.misc.Unsafe;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    98
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    99
/**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   100
 * This class manages the global state of execution. Context is immutable.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   101
 */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   102
public final class Context {
19459
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   103
    // nashorn specific security runtime access permission names
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   104
    /**
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   105
     * Permission needed to pass arbitrary nashorn command line options when creating Context.
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   106
     */
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   107
    public static final String NASHORN_SET_CONFIG      = "nashorn.setConfig";
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   108
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   109
    /**
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   110
     * Permission needed to create Nashorn Context instance.
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   111
     */
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   112
    public static final String NASHORN_CREATE_CONTEXT  = "nashorn.createContext";
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   113
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   114
    /**
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   115
     * Permission needed to create Nashorn Global instance.
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   116
     */
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   117
    public static final String NASHORN_CREATE_GLOBAL   = "nashorn.createGlobal";
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   118
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   119
    /**
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   120
     * Permission to get current Nashorn Context from thread local storage.
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   121
     */
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   122
    public static final String NASHORN_GET_CONTEXT     = "nashorn.getContext";
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   123
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   124
    /**
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   125
     * Permission to use Java reflection/jsr292 from script code.
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   126
     */
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   127
    public static final String NASHORN_JAVA_REFLECTION = "nashorn.JavaReflection";
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   128
22389
ea3dda90768c 8032060: PropertyMap of Error objects is not stable
sundar
parents: 20933
diff changeset
   129
    /**
ea3dda90768c 8032060: PropertyMap of Error objects is not stable
sundar
parents: 20933
diff changeset
   130
     * Permission to enable nashorn debug mode.
ea3dda90768c 8032060: PropertyMap of Error objects is not stable
sundar
parents: 20933
diff changeset
   131
     */
ea3dda90768c 8032060: PropertyMap of Error objects is not stable
sundar
parents: 20933
diff changeset
   132
    public static final String NASHORN_DEBUG_MODE = "nashorn.debugMode";
ea3dda90768c 8032060: PropertyMap of Error objects is not stable
sundar
parents: 20933
diff changeset
   133
20564
f353da961684 8025629: load function should support a way to load scripts from classpath
sundar
parents: 19895
diff changeset
   134
    // nashorn load psuedo URL prefixes
f353da961684 8025629: load function should support a way to load scripts from classpath
sundar
parents: 19895
diff changeset
   135
    private static final String LOAD_CLASSPATH = "classpath:";
f353da961684 8025629: load function should support a way to load scripts from classpath
sundar
parents: 19895
diff changeset
   136
    private static final String LOAD_FX = "fx:";
f353da961684 8025629: load function should support a way to load scripts from classpath
sundar
parents: 19895
diff changeset
   137
    private static final String LOAD_NASHORN = "nashorn:";
f353da961684 8025629: load function should support a way to load scripts from classpath
sundar
parents: 19895
diff changeset
   138
32696
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   139
    private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   140
    private static final MethodType CREATE_PROGRAM_FUNCTION_TYPE = MethodType.methodType(ScriptFunction.class, ScriptObject.class);
24783
b5c31bfe1496 8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents: 24779
diff changeset
   141
32696
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   142
    private static final LongAdder NAMED_INSTALLED_SCRIPT_COUNT = new LongAdder();
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   143
    private static final LongAdder ANONYMOUS_INSTALLED_SCRIPT_COUNT = new LongAdder();
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   144
    private static final boolean DISABLE_VM_ANONYMOUS_CLASSES = Options.getBooleanProperty("nashorn.disableVmAnonymousClasses");
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
   145
    /**
29834
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 28785
diff changeset
   146
     * Should scripts use only object slots for fields, or dual long/object slots? The default
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 28785
diff changeset
   147
     * behaviour is to couple this to optimistic types, using dual representation if optimistic types are enabled
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 28785
diff changeset
   148
     * and single field representation otherwise. This can be overridden by setting either the "nashorn.fields.objects"
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 28785
diff changeset
   149
     * or "nashorn.fields.dual" system property.
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 28785
diff changeset
   150
     */
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 28785
diff changeset
   151
    private final FieldMode fieldMode;
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 28785
diff changeset
   152
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 28785
diff changeset
   153
    private static enum FieldMode {
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 28785
diff changeset
   154
        /** Value for automatic field representation depending on optimistic types setting */
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 28785
diff changeset
   155
        AUTO,
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 28785
diff changeset
   156
        /** Value for object field representation regardless of optimistic types setting */
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 28785
diff changeset
   157
        OBJECTS,
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 28785
diff changeset
   158
        /** Value for dual primitive/object field representation regardless of optimistic types setting */
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 28785
diff changeset
   159
        DUAL
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 28785
diff changeset
   160
    }
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 28785
diff changeset
   161
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 28785
diff changeset
   162
    /**
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
   163
     * Keeps track of which builtin prototypes and properties have been relinked
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
   164
     * Currently we are conservative and associate the name of a builtin class with all
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
   165
     * its properties, so it's enough to invalidate a property to break all assumptions
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
   166
     * about a prototype. This can be changed to a more fine grained approach, but no one
32534
b3ec7f3b3c2a 8136349: Typos patch for nashorn sources submitted on Sep 10, 2015
sundar
parents: 32530
diff changeset
   167
     * ever needs this, given the very rare occurrence of swapping out only parts of
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
   168
     * a builtin v.s. the entire builtin object
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
   169
     */
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
   170
    private final Map<String, SwitchPoint> builtinSwitchPoints = new HashMap<>();
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
   171
19622
b042dad0de96 8023228: Debugger information gather is too slow.
jlaskey
parents: 19472
diff changeset
   172
    /* Force DebuggerSupport to be loaded. */
b042dad0de96 8023228: Debugger information gather is too slow.
jlaskey
parents: 19472
diff changeset
   173
    static {
b042dad0de96 8023228: Debugger information gather is too slow.
jlaskey
parents: 19472
diff changeset
   174
        DebuggerSupport.FORCELOAD = true;
b042dad0de96 8023228: Debugger information gather is too slow.
jlaskey
parents: 19472
diff changeset
   175
    }
b042dad0de96 8023228: Debugger information gather is too slow.
jlaskey
parents: 19472
diff changeset
   176
32696
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   177
    static long getNamedInstalledScriptCount() {
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   178
        return NAMED_INSTALLED_SCRIPT_COUNT.sum();
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   179
    }
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   180
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   181
    static long getAnonymousInstalledScriptCount() {
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   182
        return ANONYMOUS_INSTALLED_SCRIPT_COUNT.sum();
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   183
    }
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   184
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16230
diff changeset
   185
    /**
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16230
diff changeset
   186
     * ContextCodeInstaller that has the privilege of installing classes in the Context.
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16230
diff changeset
   187
     * Can only be instantiated from inside the context and is opaque to other classes
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16230
diff changeset
   188
     */
32696
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   189
    private abstract static class ContextCodeInstaller implements CodeInstaller {
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   190
        final Context context;
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   191
        final CodeSource codeSource;
27207
1f26a24d639a 8060724: ant test262parallel in Nashorn spends a significant amount of time after almost all the tests are run
hannesw
parents: 27102
diff changeset
   192
32696
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   193
        ContextCodeInstaller(final Context context, final CodeSource codeSource) {
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   194
            this.context = context;
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16230
diff changeset
   195
            this.codeSource = codeSource;
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16230
diff changeset
   196
        }
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16230
diff changeset
   197
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16230
diff changeset
   198
        @Override
32530
20aa15248117 8135262: Sanitize CodeInstaller API
attila
parents: 31199
diff changeset
   199
        public Context getContext() {
20aa15248117 8135262: Sanitize CodeInstaller API
attila
parents: 31199
diff changeset
   200
            return context;
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16230
diff changeset
   201
        }
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16230
diff changeset
   202
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16230
diff changeset
   203
        @Override
24769
attila
parents: 24759 24282
diff changeset
   204
        public void initialize(final Collection<Class<?>> classes, final Source source, final Object[] constants) {
26248
9e9455565f77 8055954: Do not parallelize class installation
attila
parents: 26071
diff changeset
   205
            try {
9e9455565f77 8055954: Do not parallelize class installation
attila
parents: 26071
diff changeset
   206
                AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
   207
                    @Override
26248
9e9455565f77 8055954: Do not parallelize class installation
attila
parents: 26071
diff changeset
   208
                    public Void run() throws Exception {
9e9455565f77 8055954: Do not parallelize class installation
attila
parents: 26071
diff changeset
   209
                        for (final Class<?> clazz : classes) {
9e9455565f77 8055954: Do not parallelize class installation
attila
parents: 26071
diff changeset
   210
                            //use reflection to write source and constants table to installed classes
9e9455565f77 8055954: Do not parallelize class installation
attila
parents: 26071
diff changeset
   211
                            final Field sourceField = clazz.getDeclaredField(SOURCE.symbolName());
9e9455565f77 8055954: Do not parallelize class installation
attila
parents: 26071
diff changeset
   212
                            sourceField.setAccessible(true);
9e9455565f77 8055954: Do not parallelize class installation
attila
parents: 26071
diff changeset
   213
                            sourceField.set(null, source);
24769
attila
parents: 24759 24282
diff changeset
   214
26248
9e9455565f77 8055954: Do not parallelize class installation
attila
parents: 26071
diff changeset
   215
                            final Field constantsField = clazz.getDeclaredField(CONSTANTS.symbolName());
9e9455565f77 8055954: Do not parallelize class installation
attila
parents: 26071
diff changeset
   216
                            constantsField.setAccessible(true);
9e9455565f77 8055954: Do not parallelize class installation
attila
parents: 26071
diff changeset
   217
                            constantsField.set(null, constants);
24769
attila
parents: 24759 24282
diff changeset
   218
                        }
26248
9e9455565f77 8055954: Do not parallelize class installation
attila
parents: 26071
diff changeset
   219
                        return null;
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
   220
                    }
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
   221
                });
26248
9e9455565f77 8055954: Do not parallelize class installation
attila
parents: 26071
diff changeset
   222
            } catch (final PrivilegedActionException e) {
9e9455565f77 8055954: Do not parallelize class installation
attila
parents: 26071
diff changeset
   223
                throw new RuntimeException(e);
9e9455565f77 8055954: Do not parallelize class installation
attila
parents: 26071
diff changeset
   224
            }
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16230
diff changeset
   225
        }
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16256
diff changeset
   226
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16256
diff changeset
   227
        @Override
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16256
diff changeset
   228
        public void verify(final byte[] code) {
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16256
diff changeset
   229
            context.verify(code);
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16256
diff changeset
   230
        }
18862
8b6a01b38cb8 8020224: LinkageError: attempted duplicate class definition when --loader-per-compiler=false
sundar
parents: 18860
diff changeset
   231
8b6a01b38cb8 8020224: LinkageError: attempted duplicate class definition when --loader-per-compiler=false
sundar
parents: 18860
diff changeset
   232
        @Override
8b6a01b38cb8 8020224: LinkageError: attempted duplicate class definition when --loader-per-compiler=false
sundar
parents: 18860
diff changeset
   233
        public long getUniqueScriptId() {
8b6a01b38cb8 8020224: LinkageError: attempted duplicate class definition when --loader-per-compiler=false
sundar
parents: 18860
diff changeset
   234
            return context.getUniqueScriptId();
8b6a01b38cb8 8020224: LinkageError: attempted duplicate class definition when --loader-per-compiler=false
sundar
parents: 18860
diff changeset
   235
        }
20929
f2bd18181940 8026167: Class cache/reuse of 'eval' scripts results in ClassCastException in some cases.
sundar
parents: 20928
diff changeset
   236
f2bd18181940 8026167: Class cache/reuse of 'eval' scripts results in ClassCastException in some cases.
sundar
parents: 20928
diff changeset
   237
        @Override
26508
b40ef4386b01 8057021: UserAccessorProperty guards fail with multiple globals
hannesw
parents: 26504
diff changeset
   238
        public void storeScript(final String cacheKey, final Source source, final String mainClassName,
26067
b32ccc3a76c9 8055199: Tidy up Nashorn codebase for code standards (August 2014)
attila
parents: 26065
diff changeset
   239
                                final Map<String,byte[]> classBytes, final Map<Integer, FunctionInitializer> initializers,
26055
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25422
diff changeset
   240
                                final Object[] constants, final int compilationId) {
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
   241
            if (context.codeStore != null) {
26764
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26508
diff changeset
   242
                context.codeStore.store(cacheKey, source, mainClassName, classBytes, initializers, constants, compilationId);
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
   243
            }
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
   244
        }
26055
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25422
diff changeset
   245
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25422
diff changeset
   246
        @Override
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25422
diff changeset
   247
        public StoredScript loadScript(final Source source, final String functionKey) {
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25422
diff changeset
   248
            if (context.codeStore != null) {
26764
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26508
diff changeset
   249
                return context.codeStore.load(source, functionKey);
26055
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25422
diff changeset
   250
            }
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25422
diff changeset
   251
            return null;
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25422
diff changeset
   252
        }
26891
aee38d04254a 8059346: Single class loader is used to load compiled bytecode
attila
parents: 26886
diff changeset
   253
aee38d04254a 8059346: Single class loader is used to load compiled bytecode
attila
parents: 26886
diff changeset
   254
        @Override
32530
20aa15248117 8135262: Sanitize CodeInstaller API
attila
parents: 31199
diff changeset
   255
        public boolean isCompatibleWith(final CodeInstaller other) {
26891
aee38d04254a 8059346: Single class loader is used to load compiled bytecode
attila
parents: 26886
diff changeset
   256
            if (other instanceof ContextCodeInstaller) {
aee38d04254a 8059346: Single class loader is used to load compiled bytecode
attila
parents: 26886
diff changeset
   257
                final ContextCodeInstaller cci = (ContextCodeInstaller)other;
aee38d04254a 8059346: Single class loader is used to load compiled bytecode
attila
parents: 26886
diff changeset
   258
                return cci.context == context && cci.codeSource == codeSource;
aee38d04254a 8059346: Single class loader is used to load compiled bytecode
attila
parents: 26886
diff changeset
   259
            }
aee38d04254a 8059346: Single class loader is used to load compiled bytecode
attila
parents: 26886
diff changeset
   260
            return false;
aee38d04254a 8059346: Single class loader is used to load compiled bytecode
attila
parents: 26886
diff changeset
   261
        }
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16230
diff changeset
   262
    }
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16230
diff changeset
   263
32696
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   264
    private static class NamedContextCodeInstaller extends ContextCodeInstaller {
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   265
        private final ScriptLoader loader;
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   266
        private int usageCount = 0;
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   267
        private int bytesDefined = 0;
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   268
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   269
        // We reuse this installer for 10 compilations or 200000 defined bytes. Usually the first condition
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   270
        // will occur much earlier, the second is a safety measure for very large scripts/functions.
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   271
        private final static int MAX_USAGES = 10;
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   272
        private final static int MAX_BYTES_DEFINED = 200_000;
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   273
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   274
        private NamedContextCodeInstaller(final Context context, final CodeSource codeSource, final ScriptLoader loader) {
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   275
            super(context, codeSource);
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   276
            this.loader = loader;
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   277
        }
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   278
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   279
        @Override
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   280
        public Class<?> install(final String className, final byte[] bytecode) {
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   281
            usageCount++;
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   282
            bytesDefined += bytecode.length;
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   283
            NAMED_INSTALLED_SCRIPT_COUNT.increment();
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   284
            return loader.installClass(Compiler.binaryName(className), bytecode, codeSource);
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   285
        }
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   286
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   287
        @Override
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   288
        public CodeInstaller getOnDemandCompilationInstaller() {
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   289
            // Reuse this installer if we're within our limits.
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   290
            if (usageCount < MAX_USAGES && bytesDefined < MAX_BYTES_DEFINED) {
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   291
                return this;
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   292
            }
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   293
            return new NamedContextCodeInstaller(context, codeSource, context.createNewLoader());
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   294
        }
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   295
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   296
        @Override
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   297
        public CodeInstaller getMultiClassCodeInstaller() {
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   298
            // This installer is perfectly suitable for installing multiple classes that reference each other
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   299
            // as it produces classes with resolvable names, all defined in a single class loader.
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   300
            return this;
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   301
        }
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   302
    }
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   303
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   304
    private final Map<CodeSource, Reference<Class<?>>> anonymousHostClasses = new ConcurrentHashMap<>();
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   305
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   306
    private static final class AnonymousContextCodeInstaller extends ContextCodeInstaller {
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   307
        private static final Unsafe UNSAFE = getUnsafe();
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   308
        private static final String ANONYMOUS_HOST_CLASS_NAME = Compiler.SCRIPTS_PACKAGE.replace('/', '.') + ".AnonymousHost";
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   309
        private static final byte[] ANONYMOUS_HOST_CLASS_BYTES = getAnonymousHostClassBytes();
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   310
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   311
        private final Class<?> hostClass;
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   312
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   313
        private AnonymousContextCodeInstaller(final Context context, final CodeSource codeSource) {
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   314
            super(context, codeSource);
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   315
            hostClass = getAnonymousHostClass();
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   316
        }
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   317
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   318
        @Override
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   319
        public Class<?> install(final String className, final byte[] bytecode) {
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   320
            ANONYMOUS_INSTALLED_SCRIPT_COUNT.increment();
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   321
            return UNSAFE.defineAnonymousClass(hostClass, bytecode, null);
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   322
        }
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   323
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   324
        @Override
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   325
        public CodeInstaller getOnDemandCompilationInstaller() {
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   326
            // This code loader can be indefinitely reused for on-demand recompilations for the same code source.
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   327
            return this;
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   328
        }
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   329
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   330
        @Override
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   331
        public CodeInstaller getMultiClassCodeInstaller() {
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   332
            // This code loader can not be used to install multiple classes that reference each other, as they
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   333
            // would have no resolvable names. Therefore, in such situation we must revert to an installer that
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   334
            // produces named classes.
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   335
            return new NamedContextCodeInstaller(context, codeSource, context.createNewLoader());
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   336
        }
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   337
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   338
        private Class<?> getAnonymousHostClass() {
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   339
            final Reference<Class<?>> ref = context.anonymousHostClasses.get(codeSource);
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   340
            if (ref != null) {
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   341
                final Class<?> existingHostClass = ref.get();
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   342
                if (existingHostClass != null) {
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   343
                    return existingHostClass;
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   344
                }
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   345
            }
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   346
            final Class<?> newHostClass = context.createNewLoader().installClass(ANONYMOUS_HOST_CLASS_NAME, ANONYMOUS_HOST_CLASS_BYTES, codeSource);
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   347
            context.anonymousHostClasses.put(codeSource, new WeakReference<>(newHostClass));
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   348
            return newHostClass;
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   349
        }
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   350
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   351
        private static final byte[] getAnonymousHostClassBytes() {
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   352
            final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   353
            cw.visit(V1_7, Opcodes.ACC_INTERFACE | Opcodes.ACC_ABSTRACT, ANONYMOUS_HOST_CLASS_NAME.replace('.', '/'), null, "java/lang/Object", null);
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   354
            cw.visitEnd();
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   355
            return cw.toByteArray();
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   356
        }
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   357
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   358
        private static Unsafe getUnsafe() {
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   359
            return AccessController.doPrivileged(new PrivilegedAction<Unsafe>() {
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   360
                @Override
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   361
                public Unsafe run() {
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   362
                    try {
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   363
                        final Field theUnsafeField = Unsafe.class.getDeclaredField("theUnsafe");
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   364
                        theUnsafeField.setAccessible(true);
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   365
                        return (Unsafe)theUnsafeField.get(null);
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   366
                    } catch (final ReflectiveOperationException e) {
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   367
                        throw new RuntimeException(e);
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   368
                    }
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   369
                }
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   370
            });
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   371
        }
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   372
    }
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   373
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   374
    /** Is Context global debug mode enabled ? */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   375
    public static final boolean DEBUG = Options.getBooleanProperty("nashorn.debug");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   376
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
   377
    private static final ThreadLocal<Global> currentGlobal = new ThreadLocal<>();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   378
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
   379
    // in-memory cache for loaded classes
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
   380
    private ClassCache classCache;
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
   381
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
   382
    // persistent code store
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
   383
    private CodeStore codeStore;
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
   384
27369
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
   385
    // A factory for linking global properties as constant method handles. It is created when the first Global
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
   386
    // is created, and invalidated forever once the second global is created.
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
   387
    private final AtomicReference<GlobalConstants> globalConstantsRef = new AtomicReference<>();
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
   388
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   389
    /**
16188
d6390b0ea32a 8006678: Avoid too many Context.getGlobal() calls
sundar
parents: 16185
diff changeset
   390
     * Get the current global scope
d6390b0ea32a 8006678: Avoid too many Context.getGlobal() calls
sundar
parents: 16185
diff changeset
   391
     * @return the current global scope
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   392
     */
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
   393
    public static Global getGlobal() {
17231
734f61d5a097 8012612: Compile failed
sundar
parents: 16947
diff changeset
   394
        // This class in a package.access protected package.
734f61d5a097 8012612: Compile failed
sundar
parents: 16947
diff changeset
   395
        // Trusted code only can call this method.
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
   396
        return currentGlobal.get();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   397
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   398
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   399
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   400
     * Set the current global scope
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   401
     * @param global the global scope
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   402
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   403
    public static void setGlobal(final ScriptObject global) {
18851
bdb92c95f886 8019947: inherited property invalidation does not work with two globals in same context
sundar
parents: 18618
diff changeset
   404
        if (global != null && !(global instanceof Global)) {
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
   405
            throw new IllegalArgumentException("not a global!");
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   406
        }
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
   407
        setGlobal((Global)global);
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
   408
    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   409
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
   410
    /**
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
   411
     * Set the current global scope
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
   412
     * @param global the global scope
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
   413
     */
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
   414
    public static void setGlobal(final Global global) {
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
   415
        // This class in a package.access protected package.
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
   416
        // Trusted code only can call this method.
24733
1e825be55fd1 8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents: 24731
diff changeset
   417
        assert getGlobal() != global;
1e825be55fd1 8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents: 24731
diff changeset
   418
        //same code can be cached between globals, then we need to invalidate method handle constants
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
   419
        if (global != null) {
27369
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
   420
            final GlobalConstants globalConstants = getContext(global).getGlobalConstants();
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
   421
            if (globalConstants != null) {
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
   422
                globalConstants.invalidateAll();
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
   423
            }
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
   424
        }
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
   425
        currentGlobal.set(global);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   426
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   427
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   428
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   429
     * Get context of the current global
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   430
     * @return current global scope's context.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   431
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   432
    public static Context getContext() {
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   433
        final SecurityManager sm = System.getSecurityManager();
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   434
        if (sm != null) {
19459
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   435
            sm.checkPermission(new RuntimePermission(NASHORN_GET_CONTEXT));
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   436
        }
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   437
        return getContextTrusted();
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   438
    }
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   439
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   440
    /**
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   441
     * Get current context's error writer
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   442
     *
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   443
     * @return error writer of the current context
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   444
     */
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   445
    public static PrintWriter getCurrentErr() {
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
   446
        final ScriptObject global = getGlobal();
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   447
        return (global != null)? global.getContext().getErr() : new PrintWriter(System.err);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   448
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   449
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   450
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   451
     * Output text to this Context's error stream
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   452
     * @param str text to write
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   453
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   454
    public static void err(final String str) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   455
        err(str, true);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   456
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   457
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   458
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   459
     * Output text to this Context's error stream, optionally with
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   460
     * a newline afterwards
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   461
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   462
     * @param str  text to write
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   463
     * @param crlf write a carriage return/new line after text
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   464
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   465
    public static void err(final String str, final boolean crlf) {
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   466
        final PrintWriter err = Context.getCurrentErr();
16155
a8ab83cbaa49 8005788: Loggers and their corresponding system properties not working correctly
lagergren
parents: 16151
diff changeset
   467
        if (err != null) {
a8ab83cbaa49 8005788: Loggers and their corresponding system properties not working correctly
lagergren
parents: 16151
diff changeset
   468
            if (crlf) {
a8ab83cbaa49 8005788: Loggers and their corresponding system properties not working correctly
lagergren
parents: 16151
diff changeset
   469
                err.println(str);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   470
            } else {
16155
a8ab83cbaa49 8005788: Loggers and their corresponding system properties not working correctly
lagergren
parents: 16151
diff changeset
   471
                err.print(str);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   472
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   473
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   474
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   475
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16256
diff changeset
   476
    /** Current environment. */
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16256
diff changeset
   477
    private final ScriptEnvironment env;
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16256
diff changeset
   478
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16256
diff changeset
   479
    /** is this context in strict mode? Cached from env. as this is used heavily. */
18328
ebd24057f163 8015355: Array.prototype functions don't honour non-writable length and / or index properties
sundar
parents: 18321
diff changeset
   480
    final boolean _strict;
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16256
diff changeset
   481
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   482
    /** class loader to resolve classes from script. */
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   483
    private final ClassLoader  appLoader;
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   484
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   485
    /** Class loader to load classes from -classpath option, if set. */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   486
    private final ClassLoader  classPathLoader;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   487
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   488
    /** Class loader to load classes compiled from scripts. */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   489
    private final ScriptLoader scriptLoader;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   490
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   491
    /** Current error manager. */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   492
    private final ErrorManager errors;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   493
18862
8b6a01b38cb8 8020224: LinkageError: attempted duplicate class definition when --loader-per-compiler=false
sundar
parents: 18860
diff changeset
   494
    /** Unique id for script. Used only when --loader-per-compile=false */
18864
c701b823ed9e 8020276: interface checks in Invocable.getInterface implementation
sundar
parents: 18862
diff changeset
   495
    private final AtomicLong uniqueScriptId;
18862
8b6a01b38cb8 8020224: LinkageError: attempted duplicate class definition when --loader-per-compiler=false
sundar
parents: 18860
diff changeset
   496
26071
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   497
    /** Optional class filter to use for Java classes. Can be null. */
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   498
    private final ClassFilter classFilter;
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   499
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   500
    private static final ClassLoader myLoader = Context.class.getClassLoader();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   501
    private static final StructureLoader sharedLoader;
19459
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   502
20933
89748612fd1d 8026250: Logging nullpointer bugfix and javadoc warnings
lagergren
parents: 20929
diff changeset
   503
    /*package-private*/ @SuppressWarnings("static-method")
89748612fd1d 8026250: Logging nullpointer bugfix and javadoc warnings
lagergren
parents: 20929
diff changeset
   504
    ClassLoader getSharedLoader() {
19895
965b12eb322e 8024619: JDBC java.sql.DriverManager is not usable from JS script
sundar
parents: 19884
diff changeset
   505
        return sharedLoader;
965b12eb322e 8024619: JDBC java.sql.DriverManager is not usable from JS script
sundar
parents: 19884
diff changeset
   506
    }
965b12eb322e 8024619: JDBC java.sql.DriverManager is not usable from JS script
sundar
parents: 19884
diff changeset
   507
19459
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   508
    private static AccessControlContext createNoPermAccCtxt() {
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   509
        return new AccessControlContext(new ProtectionDomain[] { new ProtectionDomain(null, new Permissions()) });
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   510
    }
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   511
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   512
    private static AccessControlContext createPermAccCtxt(final String permName) {
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   513
        final Permissions perms = new Permissions();
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   514
        perms.add(new RuntimePermission(permName));
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   515
        return new AccessControlContext(new ProtectionDomain[] { new ProtectionDomain(null, perms) });
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   516
    }
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   517
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   518
    private static final AccessControlContext NO_PERMISSIONS_ACC_CTXT = createNoPermAccCtxt();
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   519
    private static final AccessControlContext CREATE_LOADER_ACC_CTXT  = createPermAccCtxt("createClassLoader");
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   520
    private static final AccessControlContext CREATE_GLOBAL_ACC_CTXT  = createPermAccCtxt(NASHORN_CREATE_GLOBAL);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   521
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   522
    static {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   523
        sharedLoader = AccessController.doPrivileged(new PrivilegedAction<StructureLoader>() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   524
            @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   525
            public StructureLoader run() {
19895
965b12eb322e 8024619: JDBC java.sql.DriverManager is not usable from JS script
sundar
parents: 19884
diff changeset
   526
                return new StructureLoader(myLoader);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   527
            }
19459
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   528
        }, CREATE_LOADER_ACC_CTXT);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   529
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   530
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   531
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   532
     * ThrowErrorManager that throws ParserException upon error conditions.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   533
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   534
    public static class ThrowErrorManager extends ErrorManager {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   535
        @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   536
        public void error(final String message) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   537
            throw new ParserException(message);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   538
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   539
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   540
        @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   541
        public void error(final ParserException e) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   542
            throw e;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   543
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   544
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   545
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   546
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   547
     * Constructor
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   548
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   549
     * @param options options from command line or Context creator
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   550
     * @param errors  error manger
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   551
     * @param appLoader application class loader
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   552
     */
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   553
    public Context(final Options options, final ErrorManager errors, final ClassLoader appLoader) {
29834
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 28785
diff changeset
   554
        this(options, errors, appLoader, null);
26071
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   555
    }
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   556
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   557
    /**
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   558
     * Constructor
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   559
     *
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   560
     * @param options options from command line or Context creator
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   561
     * @param errors  error manger
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   562
     * @param appLoader application class loader
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   563
     * @param classFilter class filter to use
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   564
     */
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   565
    public Context(final Options options, final ErrorManager errors, final ClassLoader appLoader, final ClassFilter classFilter) {
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   566
        this(options, errors, new PrintWriter(System.out, true), new PrintWriter(System.err, true), appLoader, classFilter);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   567
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   568
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   569
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   570
     * Constructor
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   571
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   572
     * @param options options from command line or Context creator
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   573
     * @param errors  error manger
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   574
     * @param out     output writer for this Context
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   575
     * @param err     error writer for this Context
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   576
     * @param appLoader application class loader
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   577
     */
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   578
    public Context(final Options options, final ErrorManager errors, final PrintWriter out, final PrintWriter err, final ClassLoader appLoader) {
26071
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   579
        this(options, errors, out, err, appLoader, (ClassFilter)null);
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   580
    }
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   581
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   582
    /**
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   583
     * Constructor
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   584
     *
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   585
     * @param options options from command line or Context creator
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   586
     * @param errors  error manger
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   587
     * @param out     output writer for this Context
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   588
     * @param err     error writer for this Context
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   589
     * @param appLoader application class loader
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   590
     * @param classFilter class filter to use
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   591
     */
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   592
    public Context(final Options options, final ErrorManager errors, final PrintWriter out, final PrintWriter err, final ClassLoader appLoader, final ClassFilter classFilter) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   593
        final SecurityManager sm = System.getSecurityManager();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   594
        if (sm != null) {
19459
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   595
            sm.checkPermission(new RuntimePermission(NASHORN_CREATE_CONTEXT));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   596
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   597
26071
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   598
        this.classFilter = classFilter;
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16256
diff changeset
   599
        this.env       = new ScriptEnvironment(options, out, err);
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16256
diff changeset
   600
        this._strict   = env._strict;
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   601
        this.appLoader = appLoader;
18864
c701b823ed9e 8020276: interface checks in Invocable.getInterface implementation
sundar
parents: 18862
diff changeset
   602
        if (env._loader_per_compile) {
c701b823ed9e 8020276: interface checks in Invocable.getInterface implementation
sundar
parents: 18862
diff changeset
   603
            this.scriptLoader = null;
c701b823ed9e 8020276: interface checks in Invocable.getInterface implementation
sundar
parents: 18862
diff changeset
   604
            this.uniqueScriptId = null;
c701b823ed9e 8020276: interface checks in Invocable.getInterface implementation
sundar
parents: 18862
diff changeset
   605
        } else {
c701b823ed9e 8020276: interface checks in Invocable.getInterface implementation
sundar
parents: 18862
diff changeset
   606
            this.scriptLoader = createNewLoader();
c701b823ed9e 8020276: interface checks in Invocable.getInterface implementation
sundar
parents: 18862
diff changeset
   607
            this.uniqueScriptId = new AtomicLong();
c701b823ed9e 8020276: interface checks in Invocable.getInterface implementation
sundar
parents: 18862
diff changeset
   608
        }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   609
        this.errors    = errors;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   610
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   611
        // if user passed -classpath option, make a class loader with that and set it as
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   612
        // thread context class loader so that script can access classes from that path.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   613
        final String classPath = options.getString("classpath");
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 23076
diff changeset
   614
        if (!env._compile_only && classPath != null && !classPath.isEmpty()) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   615
            // make sure that caller can create a class loader.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   616
            if (sm != null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   617
                sm.checkPermission(new RuntimePermission("createClassLoader"));
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   618
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   619
            this.classPathLoader = NashornLoader.createClassLoader(classPath);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   620
        } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   621
            this.classPathLoader = null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   622
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   623
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
   624
        final int cacheSize = env._class_cache_size;
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
   625
        if (cacheSize > 0) {
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26982
diff changeset
   626
            classCache = new ClassCache(this, cacheSize);
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
   627
        }
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
   628
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
   629
        if (env._persistent_cache) {
27530
518b8ae2dbb9 8064789: Nashorn should just warn on code store instantiation error
hannesw
parents: 27369
diff changeset
   630
            codeStore = newCodeStore(this);
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
   631
        }
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
   632
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   633
        // print version info if asked.
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16256
diff changeset
   634
        if (env._version) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   635
            getErr().println("nashorn " + Version.version());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   636
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   637
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16256
diff changeset
   638
        if (env._fullversion) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   639
            getErr().println("nashorn full version " + Version.fullVersion());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   640
        }
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
   641
29834
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 28785
diff changeset
   642
        if (Options.getBooleanProperty("nashorn.fields.dual")) {
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 28785
diff changeset
   643
            fieldMode = FieldMode.DUAL;
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 28785
diff changeset
   644
        } else if (Options.getBooleanProperty("nashorn.fields.objects")) {
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 28785
diff changeset
   645
            fieldMode = FieldMode.OBJECTS;
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 28785
diff changeset
   646
        } else {
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 28785
diff changeset
   647
            fieldMode = FieldMode.AUTO;
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 28785
diff changeset
   648
        }
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 28785
diff changeset
   649
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
   650
        initLoggers();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   651
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   652
26071
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   653
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   654
    /**
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   655
     * Get the class filter for this context
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   656
     * @return class filter
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   657
     */
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   658
    public ClassFilter getClassFilter() {
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   659
        return classFilter;
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   660
    }
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   661
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   662
    /**
27369
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
   663
     * Returns the factory for constant method handles for global properties. The returned factory can be
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
   664
     * invalidated if this Context has more than one Global.
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
   665
     * @return the factory for constant method handles for global properties.
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
   666
     */
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
   667
    GlobalConstants getGlobalConstants() {
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
   668
        return globalConstantsRef.get();
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
   669
    }
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
   670
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
   671
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   672
     * Get the error manager for this context
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   673
     * @return error manger
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   674
     */
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   675
    public ErrorManager getErrorManager() {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   676
        return errors;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   677
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   678
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   679
    /**
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16256
diff changeset
   680
     * Get the script environment for this context
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16256
diff changeset
   681
     * @return script environment
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16256
diff changeset
   682
     */
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16256
diff changeset
   683
    public ScriptEnvironment getEnv() {
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16256
diff changeset
   684
        return env;
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16256
diff changeset
   685
    }
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16256
diff changeset
   686
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16256
diff changeset
   687
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   688
     * Get the output stream for this context
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   689
     * @return output print writer
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   690
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   691
    public PrintWriter getOut() {
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16256
diff changeset
   692
        return env.getOut();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   693
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   694
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   695
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   696
     * Get the error stream for this context
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   697
     * @return error print writer
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   698
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   699
    public PrintWriter getErr() {
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16256
diff changeset
   700
        return env.getErr();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   701
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   702
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16196
diff changeset
   703
    /**
29834
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 28785
diff changeset
   704
     * Should scripts compiled by this context use dual field representation?
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 28785
diff changeset
   705
     * @return true if using dual fields, false for object-only fields
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 28785
diff changeset
   706
     */
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 28785
diff changeset
   707
    public boolean useDualFields() {
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 28785
diff changeset
   708
        return fieldMode == FieldMode.DUAL || (fieldMode == FieldMode.AUTO && env._optimistic_types);
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 28785
diff changeset
   709
    }
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 28785
diff changeset
   710
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 28785
diff changeset
   711
    /**
16188
d6390b0ea32a 8006678: Avoid too many Context.getGlobal() calls
sundar
parents: 16185
diff changeset
   712
     * Get the PropertyMap of the current global scope
d6390b0ea32a 8006678: Avoid too many Context.getGlobal() calls
sundar
parents: 16185
diff changeset
   713
     * @return the property map of the current global scope
d6390b0ea32a 8006678: Avoid too many Context.getGlobal() calls
sundar
parents: 16185
diff changeset
   714
     */
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16196
diff changeset
   715
    public static PropertyMap getGlobalMap() {
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
   716
        return Context.getGlobal().getMap();
16188
d6390b0ea32a 8006678: Avoid too many Context.getGlobal() calls
sundar
parents: 16185
diff changeset
   717
    }
d6390b0ea32a 8006678: Avoid too many Context.getGlobal() calls
sundar
parents: 16185
diff changeset
   718
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   719
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   720
     * Compile a top level script.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   721
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   722
     * @param source the source
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   723
     * @param scope  the scope
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   724
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   725
     * @return top level function for script
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   726
     */
16230
c38c724d82e7 8008103: Source object should maintain URL of the script source as a private field
sundar
parents: 16226
diff changeset
   727
    public ScriptFunction compileScript(final Source source, final ScriptObject scope) {
c38c724d82e7 8008103: Source object should maintain URL of the script source as a private field
sundar
parents: 16226
diff changeset
   728
        return compileScript(source, scope, this.errors);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   729
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   730
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   731
    /**
24282
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   732
     * Interface to represent compiled code that can be re-used across many
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   733
     * global scope instances
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   734
     */
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   735
    public static interface MultiGlobalCompiledScript {
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   736
        /**
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   737
         * Obtain script function object for a specific global scope object.
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   738
         *
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   739
         * @param newGlobal global scope for which function object is obtained
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   740
         * @return script function for script level expressions
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   741
         */
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   742
        public ScriptFunction getFunction(final Global newGlobal);
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   743
    }
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   744
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   745
    /**
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   746
     * Compile a top level script.
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   747
     *
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   748
     * @param source the script source
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   749
     * @return reusable compiled script across many global scopes.
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   750
     */
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   751
    public MultiGlobalCompiledScript compileScript(final Source source) {
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   752
        final Class<?> clazz = compile(source, this.errors, this._strict);
24783
b5c31bfe1496 8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents: 24779
diff changeset
   753
        final MethodHandle createProgramFunctionHandle = getCreateProgramFunctionHandle(clazz);
24282
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   754
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   755
        return new MultiGlobalCompiledScript() {
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   756
            @Override
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   757
            public ScriptFunction getFunction(final Global newGlobal) {
24783
b5c31bfe1496 8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents: 24779
diff changeset
   758
                return invokeCreateProgramFunctionHandle(createProgramFunctionHandle, newGlobal);
24282
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   759
            }
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   760
        };
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   761
    }
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   762
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   763
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   764
     * Entry point for {@code eval}
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   765
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   766
     * @param initialScope The scope of this eval call
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   767
     * @param string       Evaluated code as a String
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   768
     * @param callThis     "this" to be passed to the evaluated code
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   769
     * @param location     location of the eval call
25240
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   770
     * @return the return value of the {@code eval}
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   771
     */
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   772
    public Object eval(final ScriptObject initialScope, final String string,
31192
1e019aeea9b5 8087211: Indirect evals should be strict with -strict option
sundar
parents: 30975
diff changeset
   773
            final Object callThis, final Object location) {
1e019aeea9b5 8087211: Indirect evals should be strict with -strict option
sundar
parents: 30975
diff changeset
   774
        return eval(initialScope, string, callThis, location, false, false);
25240
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   775
    }
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   776
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   777
    /**
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   778
     * Entry point for {@code eval}
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   779
     *
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   780
     * @param initialScope The scope of this eval call
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   781
     * @param string       Evaluated code as a String
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   782
     * @param callThis     "this" to be passed to the evaluated code
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   783
     * @param location     location of the eval call
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   784
     * @param strict       is this {@code eval} call from a strict mode code?
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   785
     * @param evalCall     is this called from "eval" builtin?
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   786
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   787
     * @return the return value of the {@code eval}
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   788
     */
25240
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   789
    public Object eval(final ScriptObject initialScope, final String string,
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   790
            final Object callThis, final Object location, final boolean strict, final boolean evalCall) {
24725
7bb1f687a852 8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents: 24719
diff changeset
   791
        final String  file       = location == UNDEFINED || location == null ? "<eval>" : location.toString();
25240
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   792
        final Source  source     = sourceFor(file, string, evalCall);
31192
1e019aeea9b5 8087211: Indirect evals should be strict with -strict option
sundar
parents: 30975
diff changeset
   793
        // is this direct 'eval' builtin call?
1e019aeea9b5 8087211: Indirect evals should be strict with -strict option
sundar
parents: 30975
diff changeset
   794
        final boolean directEval = evalCall && (location != UNDEFINED);
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
   795
        final Global  global = Context.getGlobal();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   796
        ScriptObject scope = initialScope;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   797
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   798
        // ECMA section 10.1.1 point 2 says eval code is strict if it begins
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   799
        // with "use strict" directive or eval direct call itself is made
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   800
        // from from strict mode code. We are passed with caller's strict mode.
31192
1e019aeea9b5 8087211: Indirect evals should be strict with -strict option
sundar
parents: 30975
diff changeset
   801
        // Nashorn extension: any 'eval' is unconditionally strict when -strict is specified.
1e019aeea9b5 8087211: Indirect evals should be strict with -strict option
sundar
parents: 30975
diff changeset
   802
        boolean strictFlag = strict || this._strict;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   803
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   804
        Class<?> clazz = null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   805
        try {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   806
            clazz = compile(source, new ThrowErrorManager(), strictFlag);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   807
        } catch (final ParserException e) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   808
            e.throwAsEcmaException(global);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   809
            return null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   810
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   811
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   812
        if (!strictFlag) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   813
            // We need to get strict mode flag from compiled class. This is
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   814
            // because eval code may start with "use strict" directive.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   815
            try {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 17231
diff changeset
   816
                strictFlag = clazz.getField(STRICT_MODE.symbolName()).getBoolean(null);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   817
            } catch (final NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   818
                //ignored
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   819
                strictFlag = false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   820
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   821
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   822
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   823
        // In strict mode, eval does not instantiate variables and functions
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   824
        // in the caller's environment. A new environment is created!
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   825
        if (strictFlag) {
31195
4ff0587b9ed1 8098807: Strict eval throws ClassCastException with large scripts
hannesw
parents: 31192
diff changeset
   826
            // Create a new scope object with given scope as its prototype
4ff0587b9ed1 8098807: Strict eval throws ClassCastException with large scripts
hannesw
parents: 31192
diff changeset
   827
            scope = newScope(scope);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   828
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   829
24725
7bb1f687a852 8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents: 24719
diff changeset
   830
        final ScriptFunction func = getProgramFunction(clazz, scope);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   831
        Object evalThis;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   832
        if (directEval) {
28441
beb75d5da248 8068985: Wrong 'this' bound to eval call within a function when caller's 'this' is a Java object
sundar
parents: 27530
diff changeset
   833
            evalThis = (callThis != UNDEFINED && callThis != null) || strictFlag ? callThis : global;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   834
        } else {
31192
1e019aeea9b5 8087211: Indirect evals should be strict with -strict option
sundar
parents: 30975
diff changeset
   835
            // either indirect evalCall or non-eval (Function, engine.eval, ScriptObjectMirror.eval..)
1e019aeea9b5 8087211: Indirect evals should be strict with -strict option
sundar
parents: 30975
diff changeset
   836
            evalThis = callThis;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   837
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   838
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   839
        return ScriptRuntime.apply(func, evalThis);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   840
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   841
31195
4ff0587b9ed1 8098807: Strict eval throws ClassCastException with large scripts
hannesw
parents: 31192
diff changeset
   842
    private static ScriptObject newScope(final ScriptObject callerScope) {
31199
17932ffc49b5 8098808: Convert Scope from interface to class
hannesw
parents: 31196
diff changeset
   843
        return new Scope(callerScope, PropertyMap.newMap(Scope.class));
31195
4ff0587b9ed1 8098807: Strict eval throws ClassCastException with large scripts
hannesw
parents: 31192
diff changeset
   844
    }
4ff0587b9ed1 8098807: Strict eval throws ClassCastException with large scripts
hannesw
parents: 31192
diff changeset
   845
17518
2225a4f929c0 8013477: Node.setSymbol needs to be copy on write - enable IR snapshots for recompilation based on callsite type specialization. [not enabled by default, hidden by a flag for now]
lagergren
parents: 17513
diff changeset
   846
    private static Source loadInternal(final String srcStr, final String prefix, final String resourcePath) {
17244
041afba4cec5 8012251: jjs should support -fx option
jlaskey
parents: 17233
diff changeset
   847
        if (srcStr.startsWith(prefix)) {
041afba4cec5 8012251: jjs should support -fx option
jlaskey
parents: 17233
diff changeset
   848
            final String resource = resourcePath + srcStr.substring(prefix.length());
041afba4cec5 8012251: jjs should support -fx option
jlaskey
parents: 17233
diff changeset
   849
            // NOTE: even sandbox scripts should be able to load scripts in nashorn: scheme
041afba4cec5 8012251: jjs should support -fx option
jlaskey
parents: 17233
diff changeset
   850
            // These scripts are always available and are loaded from nashorn.jar's resources.
041afba4cec5 8012251: jjs should support -fx option
jlaskey
parents: 17233
diff changeset
   851
            return AccessController.doPrivileged(
041afba4cec5 8012251: jjs should support -fx option
jlaskey
parents: 17233
diff changeset
   852
                    new PrivilegedAction<Source>() {
041afba4cec5 8012251: jjs should support -fx option
jlaskey
parents: 17233
diff changeset
   853
                        @Override
041afba4cec5 8012251: jjs should support -fx option
jlaskey
parents: 17233
diff changeset
   854
                        public Source run() {
041afba4cec5 8012251: jjs should support -fx option
jlaskey
parents: 17233
diff changeset
   855
                            try {
041afba4cec5 8012251: jjs should support -fx option
jlaskey
parents: 17233
diff changeset
   856
                                final URL resURL = Context.class.getResource(resource);
24769
attila
parents: 24759 24282
diff changeset
   857
                                return resURL != null ? sourceFor(srcStr, resURL) : null;
17244
041afba4cec5 8012251: jjs should support -fx option
jlaskey
parents: 17233
diff changeset
   858
                            } catch (final IOException exp) {
041afba4cec5 8012251: jjs should support -fx option
jlaskey
parents: 17233
diff changeset
   859
                                return null;
041afba4cec5 8012251: jjs should support -fx option
jlaskey
parents: 17233
diff changeset
   860
                            }
041afba4cec5 8012251: jjs should support -fx option
jlaskey
parents: 17233
diff changeset
   861
                        }
041afba4cec5 8012251: jjs should support -fx option
jlaskey
parents: 17233
diff changeset
   862
                    });
041afba4cec5 8012251: jjs should support -fx option
jlaskey
parents: 17233
diff changeset
   863
        }
041afba4cec5 8012251: jjs should support -fx option
jlaskey
parents: 17233
diff changeset
   864
041afba4cec5 8012251: jjs should support -fx option
jlaskey
parents: 17233
diff changeset
   865
        return null;
041afba4cec5 8012251: jjs should support -fx option
jlaskey
parents: 17233
diff changeset
   866
    }
041afba4cec5 8012251: jjs should support -fx option
jlaskey
parents: 17233
diff changeset
   867
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   868
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   869
     * Implementation of {@code load} Nashorn extension. Load a script file from a source
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   870
     * expression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   871
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   872
     * @param scope  the scope
16230
c38c724d82e7 8008103: Source object should maintain URL of the script source as a private field
sundar
parents: 16226
diff changeset
   873
     * @param from   source expression for script
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   874
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   875
     * @return return value for load call (undefined)
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   876
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   877
     * @throws IOException if source cannot be found or loaded
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   878
     */
31196
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   879
    public Object load(final Object scope, final Object from) throws IOException {
24725
7bb1f687a852 8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents: 24719
diff changeset
   880
        final Object src = from instanceof ConsString ? from.toString() : from;
16230
c38c724d82e7 8008103: Source object should maintain URL of the script source as a private field
sundar
parents: 16226
diff changeset
   881
        Source source = null;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   882
16230
c38c724d82e7 8008103: Source object should maintain URL of the script source as a private field
sundar
parents: 16226
diff changeset
   883
        // load accepts a String (which could be a URL or a file name), a File, a URL
c38c724d82e7 8008103: Source object should maintain URL of the script source as a private field
sundar
parents: 16226
diff changeset
   884
        // or a ScriptObject that has "name" and "source" (string valued) properties.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   885
        if (src instanceof String) {
16251
4a5d15b2f168 8008166: URL handling was broken on windows, causing "load" to malfunction
lagergren
parents: 16245
diff changeset
   886
            final String srcStr = (String)src;
20564
f353da961684 8025629: load function should support a way to load scripts from classpath
sundar
parents: 19895
diff changeset
   887
            if (srcStr.startsWith(LOAD_CLASSPATH)) {
24725
7bb1f687a852 8033334: Make sure that scope depth information is maintained in the RecompilableScriptFunctionDatas, to avoid unnecessary slow proto linkage when doing on demand compilation
lagergren
parents: 24719
diff changeset
   888
                final URL url = getResourceURL(srcStr.substring(LOAD_CLASSPATH.length()));
24769
attila
parents: 24759 24282
diff changeset
   889
                source = url != null ? sourceFor(url.toString(), url) : null;
20564
f353da961684 8025629: load function should support a way to load scripts from classpath
sundar
parents: 19895
diff changeset
   890
            } else {
f353da961684 8025629: load function should support a way to load scripts from classpath
sundar
parents: 19895
diff changeset
   891
                final File file = new File(srcStr);
f353da961684 8025629: load function should support a way to load scripts from classpath
sundar
parents: 19895
diff changeset
   892
                if (srcStr.indexOf(':') != -1) {
f353da961684 8025629: load function should support a way to load scripts from classpath
sundar
parents: 19895
diff changeset
   893
                    if ((source = loadInternal(srcStr, LOAD_NASHORN, "resources/")) == null &&
f353da961684 8025629: load function should support a way to load scripts from classpath
sundar
parents: 19895
diff changeset
   894
                        (source = loadInternal(srcStr, LOAD_FX, "resources/fx/")) == null) {
f353da961684 8025629: load function should support a way to load scripts from classpath
sundar
parents: 19895
diff changeset
   895
                        URL url;
f353da961684 8025629: load function should support a way to load scripts from classpath
sundar
parents: 19895
diff changeset
   896
                        try {
f353da961684 8025629: load function should support a way to load scripts from classpath
sundar
parents: 19895
diff changeset
   897
                            //check for malformed url. if malformed, it may still be a valid file
f353da961684 8025629: load function should support a way to load scripts from classpath
sundar
parents: 19895
diff changeset
   898
                            url = new URL(srcStr);
f353da961684 8025629: load function should support a way to load scripts from classpath
sundar
parents: 19895
diff changeset
   899
                        } catch (final MalformedURLException e) {
f353da961684 8025629: load function should support a way to load scripts from classpath
sundar
parents: 19895
diff changeset
   900
                            url = file.toURI().toURL();
f353da961684 8025629: load function should support a way to load scripts from classpath
sundar
parents: 19895
diff changeset
   901
                        }
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   902
                        source = sourceFor(url.toString(), url);
16254
2ed824fc93be 8008554: load was broken for URLs
lagergren
parents: 16251
diff changeset
   903
                    }
20564
f353da961684 8025629: load function should support a way to load scripts from classpath
sundar
parents: 19895
diff changeset
   904
                } else if (file.isFile()) {
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   905
                    source = sourceFor(srcStr, file);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   906
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   907
            }
16230
c38c724d82e7 8008103: Source object should maintain URL of the script source as a private field
sundar
parents: 16226
diff changeset
   908
        } else if (src instanceof File && ((File)src).isFile()) {
c38c724d82e7 8008103: Source object should maintain URL of the script source as a private field
sundar
parents: 16226
diff changeset
   909
            final File file = (File)src;
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   910
            source = sourceFor(file.getName(), file);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   911
        } else if (src instanceof URL) {
16230
c38c724d82e7 8008103: Source object should maintain URL of the script source as a private field
sundar
parents: 16226
diff changeset
   912
            final URL url = (URL)src;
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   913
            source = sourceFor(url.toString(), url);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   914
        } else if (src instanceof ScriptObject) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   915
            final ScriptObject sobj = (ScriptObject)src;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   916
            if (sobj.has("script") && sobj.has("name")) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   917
                final String script = JSType.toString(sobj.get("script"));
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   918
                final String name   = JSType.toString(sobj.get("name"));
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   919
                source = sourceFor(name, script);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   920
            }
18334
47413e8d71b5 8016618: script mirror object access should be improved
sundar
parents: 18328
diff changeset
   921
        } else if (src instanceof Map) {
19097
f544a2ea40ef 8021262: Make nashorn access checks consistent with underlying dynalink
sundar
parents: 19088
diff changeset
   922
            final Map<?,?> map = (Map<?,?>)src;
18334
47413e8d71b5 8016618: script mirror object access should be improved
sundar
parents: 18328
diff changeset
   923
            if (map.containsKey("script") && map.containsKey("name")) {
47413e8d71b5 8016618: script mirror object access should be improved
sundar
parents: 18328
diff changeset
   924
                final String script = JSType.toString(map.get("script"));
47413e8d71b5 8016618: script mirror object access should be improved
sundar
parents: 18328
diff changeset
   925
                final String name   = JSType.toString(map.get("name"));
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   926
                source = sourceFor(name, script);
18334
47413e8d71b5 8016618: script mirror object access should be improved
sundar
parents: 18328
diff changeset
   927
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   928
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   929
16230
c38c724d82e7 8008103: Source object should maintain URL of the script source as a private field
sundar
parents: 16226
diff changeset
   930
        if (source != null) {
31196
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   931
            if (scope instanceof ScriptObject && ((ScriptObject)scope).isScope()) {
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   932
                final ScriptObject sobj = (ScriptObject)scope;
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   933
                // passed object is a script object
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   934
                // Global is the only user accessible scope ScriptObject
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   935
                assert sobj.isGlobal() : "non-Global scope object!!";
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   936
                return evaluateSource(source, sobj, sobj);
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   937
            } else if (scope == null || scope == UNDEFINED) {
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   938
                // undefined or null scope. Use current global instance.
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   939
                final Global global = getGlobal();
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   940
                return evaluateSource(source, global, global);
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   941
            } else {
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   942
                /*
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   943
                 * Arbitrary object passed for scope.
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   944
                 * Indirect load that is equivalent to:
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   945
                 *
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   946
                 *    (function(scope, source) {
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   947
                 *        with (scope) {
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   948
                 *            eval(<script_from_source>);
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   949
                 *        }
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   950
                 *    })(scope, source);
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   951
                 */
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   952
                final Global global = getGlobal();
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   953
                // Create a new object. This is where all declarations
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   954
                // (var, function) from the evaluated code go.
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   955
                // make global to be its __proto__ so that global
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   956
                // definitions are accessible to the evaluated code.
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   957
                final ScriptObject evalScope = newScope(global);
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   958
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   959
                // finally, make a WithObject around user supplied scope object
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   960
                // so that it's properties are accessible as variables.
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   961
                final ScriptObject withObj = ScriptRuntime.openWith(evalScope, scope);
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   962
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   963
                // evaluate given source with 'withObj' as scope
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   964
                // but use global object as "this".
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   965
                return evaluateSource(source, withObj, global);
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   966
            }
16230
c38c724d82e7 8008103: Source object should maintain URL of the script source as a private field
sundar
parents: 16226
diff changeset
   967
        }
c38c724d82e7 8008103: Source object should maintain URL of the script source as a private field
sundar
parents: 16226
diff changeset
   968
16256
f2d9a0c49914 8007002: Replace implicit exception throwing methods with explicit throws - simplify control flow and remove useless code
lagergren
parents: 16254
diff changeset
   969
        throw typeError("cant.load.script", ScriptRuntime.safeToString(from));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   970
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   971
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   972
    /**
17974
a2818f17324e 8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents: 17524
diff changeset
   973
     * Implementation of {@code loadWithNewGlobal} Nashorn extension. Load a script file from a source
a2818f17324e 8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents: 17524
diff changeset
   974
     * expression, after creating a new global scope.
a2818f17324e 8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents: 17524
diff changeset
   975
     *
a2818f17324e 8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents: 17524
diff changeset
   976
     * @param from source expression for script
18321
b2ceadf211cb 8016239: loadWithNewGlobal should support user supplied arguments from the caller
sundar
parents: 17982
diff changeset
   977
     * @param args (optional) arguments to be passed to the loaded script
17974
a2818f17324e 8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents: 17524
diff changeset
   978
     *
a2818f17324e 8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents: 17524
diff changeset
   979
     * @return return value for load call (undefined)
a2818f17324e 8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents: 17524
diff changeset
   980
     *
a2818f17324e 8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents: 17524
diff changeset
   981
     * @throws IOException if source cannot be found or loaded
a2818f17324e 8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents: 17524
diff changeset
   982
     */
18321
b2ceadf211cb 8016239: loadWithNewGlobal should support user supplied arguments from the caller
sundar
parents: 17982
diff changeset
   983
    public Object loadWithNewGlobal(final Object from, final Object...args) throws IOException {
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
   984
        final Global oldGlobal = getGlobal();
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
   985
        final Global newGlobal = AccessController.doPrivileged(new PrivilegedAction<Global>() {
17976
5615a31822a1 8015814: loadWithNewGlobal needs to wrap createGlobal in AccessController.doPrivileged
jlaskey
parents: 17974
diff changeset
   986
           @Override
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
   987
           public Global run() {
17976
5615a31822a1 8015814: loadWithNewGlobal needs to wrap createGlobal in AccessController.doPrivileged
jlaskey
parents: 17974
diff changeset
   988
               try {
19459
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   989
                   return newGlobal();
17976
5615a31822a1 8015814: loadWithNewGlobal needs to wrap createGlobal in AccessController.doPrivileged
jlaskey
parents: 17974
diff changeset
   990
               } catch (final RuntimeException e) {
5615a31822a1 8015814: loadWithNewGlobal needs to wrap createGlobal in AccessController.doPrivileged
jlaskey
parents: 17974
diff changeset
   991
                   if (Context.DEBUG) {
5615a31822a1 8015814: loadWithNewGlobal needs to wrap createGlobal in AccessController.doPrivileged
jlaskey
parents: 17974
diff changeset
   992
                       e.printStackTrace();
5615a31822a1 8015814: loadWithNewGlobal needs to wrap createGlobal in AccessController.doPrivileged
jlaskey
parents: 17974
diff changeset
   993
                   }
5615a31822a1 8015814: loadWithNewGlobal needs to wrap createGlobal in AccessController.doPrivileged
jlaskey
parents: 17974
diff changeset
   994
                   throw e;
5615a31822a1 8015814: loadWithNewGlobal needs to wrap createGlobal in AccessController.doPrivileged
jlaskey
parents: 17974
diff changeset
   995
               }
5615a31822a1 8015814: loadWithNewGlobal needs to wrap createGlobal in AccessController.doPrivileged
jlaskey
parents: 17974
diff changeset
   996
           }
19459
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   997
        }, CREATE_GLOBAL_ACC_CTXT);
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   998
        // initialize newly created Global instance
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   999
        initGlobal(newGlobal);
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
  1000
        setGlobal(newGlobal);
17974
a2818f17324e 8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents: 17524
diff changeset
  1001
18874
8ba96bd382d3 8020463: Input argument array wrapping in loadWithNewGlobal is wrong
sundar
parents: 18865
diff changeset
  1002
        final Object[] wrapped = args == null? ScriptRuntime.EMPTY_ARRAY :  ScriptObjectMirror.wrapArray(args, oldGlobal);
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
  1003
        newGlobal.put("arguments", newGlobal.wrapAsObject(wrapped), env._strict);
18321
b2ceadf211cb 8016239: loadWithNewGlobal should support user supplied arguments from the caller
sundar
parents: 17982
diff changeset
  1004
17974
a2818f17324e 8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents: 17524
diff changeset
  1005
        try {
18874
8ba96bd382d3 8020463: Input argument array wrapping in loadWithNewGlobal is wrong
sundar
parents: 18865
diff changeset
  1006
            // wrap objects from newGlobal's world as mirrors - but if result
8ba96bd382d3 8020463: Input argument array wrapping in loadWithNewGlobal is wrong
sundar
parents: 18865
diff changeset
  1007
            // is from oldGlobal's world, unwrap it!
8ba96bd382d3 8020463: Input argument array wrapping in loadWithNewGlobal is wrong
sundar
parents: 18865
diff changeset
  1008
            return ScriptObjectMirror.unwrap(ScriptObjectMirror.wrap(load(newGlobal, from), newGlobal), oldGlobal);
17974
a2818f17324e 8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents: 17524
diff changeset
  1009
        } finally {
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
  1010
            setGlobal(oldGlobal);
17974
a2818f17324e 8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents: 17524
diff changeset
  1011
        }
a2818f17324e 8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents: 17524
diff changeset
  1012
    }
a2818f17324e 8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents: 17524
diff changeset
  1013
a2818f17324e 8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents: 17524
diff changeset
  1014
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1015
     * Load or get a structure class. Structure class names are based on the number of parameter fields
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1016
     * and {@link AccessorProperty} fields in them. Structure classes are used to represent ScriptObjects
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1017
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1018
     * @see ObjectClassGenerator
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1019
     * @see AccessorProperty
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1020
     * @see ScriptObject
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1021
     *
16275
d5d430071b22 8009379: Remove $ from generated class names
jlaskey
parents: 16272
diff changeset
  1022
     * @param fullName  full name of class, e.g. jdk.nashorn.internal.objects.JO2P1 contains 2 fields and 1 parameter.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1023
     *
16272
675a0caf75bc 8009263: Fix all javadoc errors in nashorn code
sundar
parents: 16262
diff changeset
  1024
     * @return the {@code Class<?>} for this structure
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1025
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1026
     * @throws ClassNotFoundException if structure class cannot be resolved
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1027
     */
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 23076
diff changeset
  1028
    @SuppressWarnings("unchecked")
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 23076
diff changeset
  1029
    public static Class<? extends ScriptObject> forStructureClass(final String fullName) throws ClassNotFoundException {
19895
965b12eb322e 8024619: JDBC java.sql.DriverManager is not usable from JS script
sundar
parents: 19884
diff changeset
  1030
        if (System.getSecurityManager() != null && !StructureLoader.isStructureClass(fullName)) {
19097
f544a2ea40ef 8021262: Make nashorn access checks consistent with underlying dynalink
sundar
parents: 19088
diff changeset
  1031
            throw new ClassNotFoundException(fullName);
f544a2ea40ef 8021262: Make nashorn access checks consistent with underlying dynalink
sundar
parents: 19088
diff changeset
  1032
        }
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 23076
diff changeset
  1033
        return (Class<? extends ScriptObject>)Class.forName(fullName, true, sharedLoader);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1034
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1035
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1036
    /**
32781
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32697
diff changeset
  1037
     * Is {@code className} the name of a structure class?
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32697
diff changeset
  1038
     *
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32697
diff changeset
  1039
     * @param className a class name
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32697
diff changeset
  1040
     * @return true if className is a structure class name
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32697
diff changeset
  1041
     */
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32697
diff changeset
  1042
    public static boolean isStructureClass(final String className) {
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32697
diff changeset
  1043
        return StructureLoader.isStructureClass(className);
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32697
diff changeset
  1044
    }
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32697
diff changeset
  1045
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32697
diff changeset
  1046
    /**
20567
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1047
     * Checks that the given Class can be accessed from no permissions context.
18865
8844964e5fc5 8020325: static property does not work on accessible, public classes
sundar
parents: 18864
diff changeset
  1048
     *
20567
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1049
     * @param clazz Class object
23374
f470afc89c6c 8015958: DataView constructor is not defined
sundar
parents: 23372
diff changeset
  1050
     * @throws SecurityException if not accessible
18865
8844964e5fc5 8020325: static property does not work on accessible, public classes
sundar
parents: 18864
diff changeset
  1051
     */
20928
3ff39d5c8c08 8026137: Fix Issues with Binary Evaluation Order
lagergren
parents: 20567
diff changeset
  1052
    public static void checkPackageAccess(final Class<?> clazz) {
20567
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1053
        final SecurityManager sm = System.getSecurityManager();
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1054
        if (sm != null) {
20928
3ff39d5c8c08 8026137: Fix Issues with Binary Evaluation Order
lagergren
parents: 20567
diff changeset
  1055
            Class<?> bottomClazz = clazz;
3ff39d5c8c08 8026137: Fix Issues with Binary Evaluation Order
lagergren
parents: 20567
diff changeset
  1056
            while (bottomClazz.isArray()) {
20567
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1057
                bottomClazz = bottomClazz.getComponentType();
18865
8844964e5fc5 8020325: static property does not work on accessible, public classes
sundar
parents: 18864
diff changeset
  1058
            }
20567
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1059
            checkPackageAccess(sm, bottomClazz.getName());
18865
8844964e5fc5 8020325: static property does not work on accessible, public classes
sundar
parents: 18864
diff changeset
  1060
        }
8844964e5fc5 8020325: static property does not work on accessible, public classes
sundar
parents: 18864
diff changeset
  1061
    }
8844964e5fc5 8020325: static property does not work on accessible, public classes
sundar
parents: 18864
diff changeset
  1062
8844964e5fc5 8020325: static property does not work on accessible, public classes
sundar
parents: 18864
diff changeset
  1063
    /**
22669
75563515567f 8032681: Issues with Nashorn
attila
parents: 22389
diff changeset
  1064
     * Checks that the given package name can be accessed from no permissions context.
75563515567f 8032681: Issues with Nashorn
attila
parents: 22389
diff changeset
  1065
     *
75563515567f 8032681: Issues with Nashorn
attila
parents: 22389
diff changeset
  1066
     * @param pkgName package name
23374
f470afc89c6c 8015958: DataView constructor is not defined
sundar
parents: 23372
diff changeset
  1067
     * @throws SecurityException if not accessible
22669
75563515567f 8032681: Issues with Nashorn
attila
parents: 22389
diff changeset
  1068
     */
75563515567f 8032681: Issues with Nashorn
attila
parents: 22389
diff changeset
  1069
    public static void checkPackageAccess(final String pkgName) {
75563515567f 8032681: Issues with Nashorn
attila
parents: 22389
diff changeset
  1070
        final SecurityManager sm = System.getSecurityManager();
75563515567f 8032681: Issues with Nashorn
attila
parents: 22389
diff changeset
  1071
        if (sm != null) {
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1072
            checkPackageAccess(sm, pkgName.endsWith(".") ? pkgName : pkgName + ".");
22669
75563515567f 8032681: Issues with Nashorn
attila
parents: 22389
diff changeset
  1073
        }
75563515567f 8032681: Issues with Nashorn
attila
parents: 22389
diff changeset
  1074
    }
75563515567f 8032681: Issues with Nashorn
attila
parents: 22389
diff changeset
  1075
75563515567f 8032681: Issues with Nashorn
attila
parents: 22389
diff changeset
  1076
    /**
19097
f544a2ea40ef 8021262: Make nashorn access checks consistent with underlying dynalink
sundar
parents: 19088
diff changeset
  1077
     * Checks that the given package can be accessed from no permissions context.
19088
153f268bfa72 8021122: Not all callables are handled for toString and other function valued properties
sundar
parents: 19085
diff changeset
  1078
     *
20567
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1079
     * @param sm current security manager instance
19088
153f268bfa72 8021122: Not all callables are handled for toString and other function valued properties
sundar
parents: 19085
diff changeset
  1080
     * @param fullName fully qualified package name
20567
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1081
     * @throw SecurityException if not accessible
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1082
     */
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1083
    private static void checkPackageAccess(final SecurityManager sm, final String fullName) {
28785
a503c972d4bd 8072595: nashorn should not use obj.getClass() for null checks
sundar
parents: 28441
diff changeset
  1084
        Objects.requireNonNull(sm);
20567
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1085
        final int index = fullName.lastIndexOf('.');
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1086
        if (index != -1) {
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1087
            final String pkgName = fullName.substring(0, index);
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1088
            AccessController.doPrivileged(new PrivilegedAction<Void>() {
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1089
                @Override
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1090
                public Void run() {
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1091
                    sm.checkPackageAccess(pkgName);
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1092
                    return null;
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1093
                }
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1094
            }, NO_PERMISSIONS_ACC_CTXT);
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1095
        }
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1096
    }
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1097
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1098
    /**
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1099
     * Checks that the given Class can be accessed from no permissions context.
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1100
     *
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1101
     * @param clazz Class object
19088
153f268bfa72 8021122: Not all callables are handled for toString and other function valued properties
sundar
parents: 19085
diff changeset
  1102
     * @return true if package is accessible, false otherwise
153f268bfa72 8021122: Not all callables are handled for toString and other function valued properties
sundar
parents: 19085
diff changeset
  1103
     */
20928
3ff39d5c8c08 8026137: Fix Issues with Binary Evaluation Order
lagergren
parents: 20567
diff changeset
  1104
    private static boolean isAccessiblePackage(final Class<?> clazz) {
19088
153f268bfa72 8021122: Not all callables are handled for toString and other function valued properties
sundar
parents: 19085
diff changeset
  1105
        try {
20567
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1106
            checkPackageAccess(clazz);
19088
153f268bfa72 8021122: Not all callables are handled for toString and other function valued properties
sundar
parents: 19085
diff changeset
  1107
            return true;
153f268bfa72 8021122: Not all callables are handled for toString and other function valued properties
sundar
parents: 19085
diff changeset
  1108
        } catch (final SecurityException se) {
153f268bfa72 8021122: Not all callables are handled for toString and other function valued properties
sundar
parents: 19085
diff changeset
  1109
            return false;
153f268bfa72 8021122: Not all callables are handled for toString and other function valued properties
sundar
parents: 19085
diff changeset
  1110
        }
153f268bfa72 8021122: Not all callables are handled for toString and other function valued properties
sundar
parents: 19085
diff changeset
  1111
    }
153f268bfa72 8021122: Not all callables are handled for toString and other function valued properties
sundar
parents: 19085
diff changeset
  1112
153f268bfa72 8021122: Not all callables are handled for toString and other function valued properties
sundar
parents: 19085
diff changeset
  1113
    /**
19097
f544a2ea40ef 8021262: Make nashorn access checks consistent with underlying dynalink
sundar
parents: 19088
diff changeset
  1114
     * Checks that the given Class is public and it can be accessed from no permissions context.
19088
153f268bfa72 8021122: Not all callables are handled for toString and other function valued properties
sundar
parents: 19085
diff changeset
  1115
     *
153f268bfa72 8021122: Not all callables are handled for toString and other function valued properties
sundar
parents: 19085
diff changeset
  1116
     * @param clazz Class object to check
153f268bfa72 8021122: Not all callables are handled for toString and other function valued properties
sundar
parents: 19085
diff changeset
  1117
     * @return true if Class is accessible, false otherwise
153f268bfa72 8021122: Not all callables are handled for toString and other function valued properties
sundar
parents: 19085
diff changeset
  1118
     */
153f268bfa72 8021122: Not all callables are handled for toString and other function valued properties
sundar
parents: 19085
diff changeset
  1119
    public static boolean isAccessibleClass(final Class<?> clazz) {
20567
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1120
        return Modifier.isPublic(clazz.getModifiers()) && Context.isAccessiblePackage(clazz);
19088
153f268bfa72 8021122: Not all callables are handled for toString and other function valued properties
sundar
parents: 19085
diff changeset
  1121
    }
153f268bfa72 8021122: Not all callables are handled for toString and other function valued properties
sundar
parents: 19085
diff changeset
  1122
153f268bfa72 8021122: Not all callables are handled for toString and other function valued properties
sundar
parents: 19085
diff changeset
  1123
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1124
     * Lookup a Java class. This is used for JSR-223 stuff linking in from
17524
703643aeb0d6 8013914: Removed explicit LineNumberNodes that were too brittle when code moves around, and also introduced unnecessary footprint. Introduced the Statement node and fixed dead code elimination issues that were discovered by the absense of labels for LineNumberNodes.
lagergren
parents: 17519
diff changeset
  1125
     * {@code jdk.nashorn.internal.objects.NativeJava} and {@code jdk.nashorn.internal.runtime.NativeJavaPackage}
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1126
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1127
     * @param fullName full name of class to load
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1128
     *
16272
675a0caf75bc 8009263: Fix all javadoc errors in nashorn code
sundar
parents: 16262
diff changeset
  1129
     * @return the {@code Class<?>} for the name
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1130
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1131
     * @throws ClassNotFoundException if class cannot be resolved
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1132
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1133
    public Class<?> findClass(final String fullName) throws ClassNotFoundException {
20567
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1134
        if (fullName.indexOf('[') != -1 || fullName.indexOf('/') != -1) {
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1135
            // don't allow array class names or internal names.
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1136
            throw new ClassNotFoundException(fullName);
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1137
        }
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1138
26071
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
  1139
        // give chance to ClassFilter to filter out, if present
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
  1140
        if (classFilter != null && !classFilter.exposeToScripts(fullName)) {
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
  1141
            throw new ClassNotFoundException(fullName);
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
  1142
        }
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
  1143
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1144
        // check package access as soon as possible!
20567
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1145
        final SecurityManager sm = System.getSecurityManager();
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1146
        if (sm != null) {
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1147
            checkPackageAccess(sm, fullName);
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1148
        }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1149
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
  1150
        // try the script -classpath loader, if that is set
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1151
        if (classPathLoader != null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1152
            try {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1153
                return Class.forName(fullName, true, classPathLoader);
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
  1154
            } catch (final ClassNotFoundException ignored) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1155
                // ignore, continue search
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1156
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1157
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1158
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
  1159
        // Try finding using the "app" loader.
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
  1160
        return Class.forName(fullName, true, appLoader);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1161
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1162
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1163
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1164
     * Hook to print stack trace for a {@link Throwable} that occurred during
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1165
     * execution
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1166
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1167
     * @param t throwable for which to dump stack
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1168
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1169
    public static void printStackTrace(final Throwable t) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1170
        if (Context.DEBUG) {
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
  1171
            t.printStackTrace(Context.getCurrentErr());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1172
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1173
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1174
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1175
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1176
     * Verify generated bytecode before emission. This is called back from the
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16256
diff changeset
  1177
     * {@link ObjectClassGenerator} or the {@link Compiler}. If the "--verify-code" parameter
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1178
     * hasn't been given, this is a nop
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1179
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1180
     * Note that verification may load classes -- we don't want to do that unless
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1181
     * user specified verify option. We check it here even though caller
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1182
     * may have already checked that flag
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1183
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1184
     * @param bytecode bytecode to verify
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1185
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1186
    public void verify(final byte[] bytecode) {
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16256
diff changeset
  1187
        if (env._verify_code) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1188
            // No verification when security manager is around as verifier
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1189
            // may load further classes - which should be avoided.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1190
            if (System.getSecurityManager() == null) {
19098
473dfe87bb7b 8021294: --verify-code option results in AnalyzerException
sundar
parents: 19097
diff changeset
  1191
                CheckClassAdapter.verify(new ClassReader(bytecode), sharedLoader, false, new PrintWriter(System.err, true));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1192
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1193
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1194
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1195
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1196
    /**
16211
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16201
diff changeset
  1197
     * Create and initialize a new global scope object.
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16201
diff changeset
  1198
     *
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16201
diff changeset
  1199
     * @return the initialized global scope object.
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16201
diff changeset
  1200
     */
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
  1201
    public Global createGlobal() {
16211
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16201
diff changeset
  1202
        return initGlobal(newGlobal());
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16201
diff changeset
  1203
    }
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16201
diff changeset
  1204
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16201
diff changeset
  1205
    /**
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16201
diff changeset
  1206
     * Create a new uninitialized global scope object
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1207
     * @return the global script object
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1208
     */
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
  1209
    public Global newGlobal() {
27369
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1210
        createOrInvalidateGlobalConstants();
19085
066c9e5afd79 8020731: Revisit checkPermission calls in Context class
sundar
parents: 18874
diff changeset
  1211
        return new Global(this);
16211
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16201
diff changeset
  1212
    }
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16201
diff changeset
  1213
27369
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1214
    private void createOrInvalidateGlobalConstants() {
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1215
        for (;;) {
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1216
            final GlobalConstants currentGlobalConstants = getGlobalConstants();
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1217
            if (currentGlobalConstants != null) {
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1218
                // Subsequent invocation; we're creating our second or later Global. GlobalConstants is not safe to use
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1219
                // with more than one Global, as the constant method handle linkages it creates create a coupling
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1220
                // between the Global and the call sites in the compiled code.
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1221
                currentGlobalConstants.invalidateForever();
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1222
                return;
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1223
            }
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1224
            final GlobalConstants newGlobalConstants = new GlobalConstants(getLogger(GlobalConstants.class));
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1225
            if (globalConstantsRef.compareAndSet(null, newGlobalConstants)) {
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1226
                // First invocation; we're creating the first Global in this Context. Create the GlobalConstants object
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1227
                // for this Context.
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1228
                return;
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1229
            }
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1230
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1231
            // If we reach here, then we started out as the first invocation, but another concurrent invocation won the
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1232
            // CAS race. We'll just let the loop repeat and invalidate the CAS race winner.
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1233
        }
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1234
    }
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1235
16211
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16201
diff changeset
  1236
    /**
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16201
diff changeset
  1237
     * Initialize given global scope object.
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16201
diff changeset
  1238
     *
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16230
diff changeset
  1239
     * @param global the global
25422
199a23bee487 8049524: Global object initialization via javax.script API should be minimal
sundar
parents: 25243
diff changeset
  1240
     * @param engine the associated ScriptEngine instance, can be null
30975
a71c56056f02 8081609: engine.eval call from a java method which was called from a previous engine.eval results in wrong ScriptContext being used.
sundar
parents: 30513
diff changeset
  1241
     * @param ctxt the initial ScriptContext, can be null
16211
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16201
diff changeset
  1242
     * @return the initialized global scope object.
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16201
diff changeset
  1243
     */
30975
a71c56056f02 8081609: engine.eval call from a java method which was called from a previous engine.eval results in wrong ScriptContext being used.
sundar
parents: 30513
diff changeset
  1244
    public Global initGlobal(final Global global, final ScriptEngine engine, final ScriptContext ctxt) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1245
        // Need only minimal global object, if we are just compiling.
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16256
diff changeset
  1246
        if (!env._compile_only) {
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
  1247
            final Global oldGlobal = Context.getGlobal();
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
  1248
            try {
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
  1249
                Context.setGlobal(global);
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
  1250
                // initialize global scope with builtin global objects
30975
a71c56056f02 8081609: engine.eval call from a java method which was called from a previous engine.eval results in wrong ScriptContext being used.
sundar
parents: 30513
diff changeset
  1251
                global.initBuiltinObjects(engine, ctxt);
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
  1252
            } finally {
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
  1253
                Context.setGlobal(oldGlobal);
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
  1254
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1255
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1256
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1257
        return global;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1258
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1259
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1260
    /**
25422
199a23bee487 8049524: Global object initialization via javax.script API should be minimal
sundar
parents: 25243
diff changeset
  1261
     * Initialize given global scope object.
199a23bee487 8049524: Global object initialization via javax.script API should be minimal
sundar
parents: 25243
diff changeset
  1262
     *
199a23bee487 8049524: Global object initialization via javax.script API should be minimal
sundar
parents: 25243
diff changeset
  1263
     * @param global the global
199a23bee487 8049524: Global object initialization via javax.script API should be minimal
sundar
parents: 25243
diff changeset
  1264
     * @return the initialized global scope object.
199a23bee487 8049524: Global object initialization via javax.script API should be minimal
sundar
parents: 25243
diff changeset
  1265
     */
199a23bee487 8049524: Global object initialization via javax.script API should be minimal
sundar
parents: 25243
diff changeset
  1266
    public Global initGlobal(final Global global) {
30975
a71c56056f02 8081609: engine.eval call from a java method which was called from a previous engine.eval results in wrong ScriptContext being used.
sundar
parents: 30513
diff changeset
  1267
        return initGlobal(global, null, null);
25422
199a23bee487 8049524: Global object initialization via javax.script API should be minimal
sundar
parents: 25243
diff changeset
  1268
    }
199a23bee487 8049524: Global object initialization via javax.script API should be minimal
sundar
parents: 25243
diff changeset
  1269
199a23bee487 8049524: Global object initialization via javax.script API should be minimal
sundar
parents: 25243
diff changeset
  1270
    /**
16188
d6390b0ea32a 8006678: Avoid too many Context.getGlobal() calls
sundar
parents: 16185
diff changeset
  1271
     * Return the current global's context
d6390b0ea32a 8006678: Avoid too many Context.getGlobal() calls
sundar
parents: 16185
diff changeset
  1272
     * @return current global's context
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
  1273
     */
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
  1274
    static Context getContextTrusted() {
27369
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1275
        return getContext(getGlobal());
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
  1276
    }
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
  1277
24769
attila
parents: 24759 24282
diff changeset
  1278
    static Context getContextTrustedOrNull() {
attila
parents: 24759 24282
diff changeset
  1279
        final Global global = Context.getGlobal();
27369
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1280
        return global == null ? null : getContext(global);
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1281
    }
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1282
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1283
    private static Context getContext(final Global global) {
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1284
        // We can't invoke Global.getContext() directly, as it's a protected override, and Global isn't in our package.
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1285
        // In order to access the method, we must cast it to ScriptObject first (which is in our package) and then let
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1286
        // virtual invocation do its thing.
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1287
        return ((ScriptObject)global).getContext();
24769
attila
parents: 24759 24282
diff changeset
  1288
    }
attila
parents: 24759 24282
diff changeset
  1289
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
  1290
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1291
     * Try to infer Context instance from the Class. If we cannot,
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1292
     * then get it from the thread local variable.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1293
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1294
     * @param clazz the class
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1295
     * @return context
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1296
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1297
    static Context fromClass(final Class<?> clazz) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1298
        final ClassLoader loader = clazz.getClassLoader();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1299
19895
965b12eb322e 8024619: JDBC java.sql.DriverManager is not usable from JS script
sundar
parents: 19884
diff changeset
  1300
        if (loader instanceof ScriptLoader) {
965b12eb322e 8024619: JDBC java.sql.DriverManager is not usable from JS script
sundar
parents: 19884
diff changeset
  1301
            return ((ScriptLoader)loader).getContext();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1302
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1303
19895
965b12eb322e 8024619: JDBC java.sql.DriverManager is not usable from JS script
sundar
parents: 19884
diff changeset
  1304
        return Context.getContextTrusted();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1305
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1306
20928
3ff39d5c8c08 8026137: Fix Issues with Binary Evaluation Order
lagergren
parents: 20567
diff changeset
  1307
    private URL getResourceURL(final String resName) {
20564
f353da961684 8025629: load function should support a way to load scripts from classpath
sundar
parents: 19895
diff changeset
  1308
        // try the classPathLoader if we have and then
f353da961684 8025629: load function should support a way to load scripts from classpath
sundar
parents: 19895
diff changeset
  1309
        // try the appLoader if non-null.
f353da961684 8025629: load function should support a way to load scripts from classpath
sundar
parents: 19895
diff changeset
  1310
        if (classPathLoader != null) {
f353da961684 8025629: load function should support a way to load scripts from classpath
sundar
parents: 19895
diff changeset
  1311
            return classPathLoader.getResource(resName);
f353da961684 8025629: load function should support a way to load scripts from classpath
sundar
parents: 19895
diff changeset
  1312
        } else if (appLoader != null) {
f353da961684 8025629: load function should support a way to load scripts from classpath
sundar
parents: 19895
diff changeset
  1313
            return appLoader.getResource(resName);
f353da961684 8025629: load function should support a way to load scripts from classpath
sundar
parents: 19895
diff changeset
  1314
        }
f353da961684 8025629: load function should support a way to load scripts from classpath
sundar
parents: 19895
diff changeset
  1315
f353da961684 8025629: load function should support a way to load scripts from classpath
sundar
parents: 19895
diff changeset
  1316
        return null;
f353da961684 8025629: load function should support a way to load scripts from classpath
sundar
parents: 19895
diff changeset
  1317
    }
f353da961684 8025629: load function should support a way to load scripts from classpath
sundar
parents: 19895
diff changeset
  1318
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1319
    private Object evaluateSource(final Source source, final ScriptObject scope, final ScriptObject thiz) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1320
        ScriptFunction script = null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1321
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1322
        try {
16230
c38c724d82e7 8008103: Source object should maintain URL of the script source as a private field
sundar
parents: 16226
diff changeset
  1323
            script = compileScript(source, scope, new Context.ThrowErrorManager());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1324
        } catch (final ParserException e) {
16188
d6390b0ea32a 8006678: Avoid too many Context.getGlobal() calls
sundar
parents: 16185
diff changeset
  1325
            e.throwAsEcmaException();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1326
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1327
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1328
        return ScriptRuntime.apply(script, thiz);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1329
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1330
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 23076
diff changeset
  1331
    private static ScriptFunction getProgramFunction(final Class<?> script, final ScriptObject scope) {
24879
d316854e4249 8046215: Running uncompilable scripts throws NullPointerException
hannesw
parents: 24783
diff changeset
  1332
        if (script == null) {
d316854e4249 8046215: Running uncompilable scripts throws NullPointerException
hannesw
parents: 24783
diff changeset
  1333
            return null;
d316854e4249 8046215: Running uncompilable scripts throws NullPointerException
hannesw
parents: 24783
diff changeset
  1334
        }
24783
b5c31bfe1496 8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents: 24779
diff changeset
  1335
        return invokeCreateProgramFunctionHandle(getCreateProgramFunctionHandle(script), scope);
b5c31bfe1496 8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents: 24779
diff changeset
  1336
    }
24282
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
  1337
24783
b5c31bfe1496 8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents: 24779
diff changeset
  1338
    private static MethodHandle getCreateProgramFunctionHandle(final Class<?> script) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1339
        try {
24783
b5c31bfe1496 8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents: 24779
diff changeset
  1340
            return LOOKUP.findStatic(script, CREATE_PROGRAM_FUNCTION.symbolName(), CREATE_PROGRAM_FUNCTION_TYPE);
b5c31bfe1496 8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents: 24779
diff changeset
  1341
        } catch (NoSuchMethodException | IllegalAccessException e) {
b5c31bfe1496 8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents: 24779
diff changeset
  1342
            throw new AssertionError("Failed to retrieve a handle for the program function for " + script.getName(), e);
b5c31bfe1496 8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents: 24779
diff changeset
  1343
        }
b5c31bfe1496 8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents: 24779
diff changeset
  1344
    }
b5c31bfe1496 8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents: 24779
diff changeset
  1345
b5c31bfe1496 8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents: 24779
diff changeset
  1346
    private static ScriptFunction invokeCreateProgramFunctionHandle(final MethodHandle createProgramFunctionHandle, final ScriptObject scope) {
b5c31bfe1496 8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents: 24779
diff changeset
  1347
        try {
b5c31bfe1496 8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents: 24779
diff changeset
  1348
            return (ScriptFunction)createProgramFunctionHandle.invokeExact(scope);
b5c31bfe1496 8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents: 24779
diff changeset
  1349
        } catch (final RuntimeException|Error e) {
b5c31bfe1496 8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents: 24779
diff changeset
  1350
            throw e;
b5c31bfe1496 8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents: 24779
diff changeset
  1351
        } catch (final Throwable t) {
b5c31bfe1496 8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents: 24779
diff changeset
  1352
            throw new AssertionError("Failed to create a program function", t);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1353
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1354
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1355
16230
c38c724d82e7 8008103: Source object should maintain URL of the script source as a private field
sundar
parents: 16226
diff changeset
  1356
    private ScriptFunction compileScript(final Source source, final ScriptObject scope, final ErrorManager errMan) {
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 23076
diff changeset
  1357
        return getProgramFunction(compile(source, errMan, this._strict), scope);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1358
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1359
16230
c38c724d82e7 8008103: Source object should maintain URL of the script source as a private field
sundar
parents: 16226
diff changeset
  1360
    private synchronized Class<?> compile(final Source source, final ErrorManager errMan, final boolean strict) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1361
        // start with no errors, no warnings.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1362
        errMan.reset();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1363
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1364
        Class<?> script = findCachedClass(source);
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1365
        if (script != null) {
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1366
            final DebugLogger log = getLogger(Compiler.class);
24744
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24742
diff changeset
  1367
            if (log.isEnabled()) {
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24742
diff changeset
  1368
                log.fine(new RuntimeEvent<>(Level.INFO, source), "Code cache hit for ", source, " avoiding recompile.");
24731
ab0c8fc915ae 8038406: Testability: as a first step of moving loggers away from the process global space, the Debug object now supports logging POJOs from log entries as an event queue, which can be introspected from test scripts. This is way better than screen scraping brittle and subject-to-change log output.
lagergren
parents: 24727
diff changeset
  1369
            }
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1370
            return script;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1371
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1372
26055
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25422
diff changeset
  1373
        StoredScript storedScript = null;
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
  1374
        FunctionNode functionNode = null;
30389
35e1a33f3d12 8078612: Persistent code cache should support more configurations
hannesw
parents: 30056
diff changeset
  1375
        // Don't use code store if optimistic types is enabled but lazy compilation is not.
35e1a33f3d12 8078612: Persistent code cache should support more configurations
hannesw
parents: 30056
diff changeset
  1376
        // This would store a full script compilation with many wrong optimistic assumptions that would
35e1a33f3d12 8078612: Persistent code cache should support more configurations
hannesw
parents: 30056
diff changeset
  1377
        // do more harm than good on later runs with both optimistic types and lazy compilation enabled.
35e1a33f3d12 8078612: Persistent code cache should support more configurations
hannesw
parents: 30056
diff changeset
  1378
        final boolean useCodeStore = codeStore != null && !env._parse_only && (!env._optimistic_types || env._lazy_compilation);
35e1a33f3d12 8078612: Persistent code cache should support more configurations
hannesw
parents: 30056
diff changeset
  1379
        final String cacheKey = useCodeStore ? CodeStore.getCacheKey("script", null) : null;
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
  1380
26055
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25422
diff changeset
  1381
        if (useCodeStore) {
26764
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26508
diff changeset
  1382
            storedScript = codeStore.load(source, cacheKey);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1383
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1384
26055
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25422
diff changeset
  1385
        if (storedScript == null) {
30513
14cefab8350f 8080090: -d option should dump script source as well
sundar
parents: 30389
diff changeset
  1386
            if (env._dest_dir != null) {
14cefab8350f 8080090: -d option should dump script source as well
sundar
parents: 30389
diff changeset
  1387
                source.dump(env._dest_dir);
14cefab8350f 8080090: -d option should dump script source as well
sundar
parents: 30389
diff changeset
  1388
            }
14cefab8350f 8080090: -d option should dump script source as well
sundar
parents: 30389
diff changeset
  1389
24769
attila
parents: 24759 24282
diff changeset
  1390
            functionNode = new Parser(env, source, errMan, strict, getLogger(Parser.class)).parse();
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
  1391
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26248
diff changeset
  1392
            if (errMan.hasErrors()) {
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
  1393
                return null;
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
  1394
            }
16240
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents: 16233
diff changeset
  1395
26065
d15adb218527 8055107: Extension directives to turn on callsite profiling, tracing, AST print and other debug features locally
sundar
parents: 26055
diff changeset
  1396
            if (env._print_ast || functionNode.getFlag(FunctionNode.IS_PRINT_AST)) {
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
  1397
                getErr().println(new ASTWriter(functionNode));
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
  1398
            }
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
  1399
26065
d15adb218527 8055107: Extension directives to turn on callsite profiling, tracing, AST print and other debug features locally
sundar
parents: 26055
diff changeset
  1400
            if (env._print_parse || functionNode.getFlag(FunctionNode.IS_PRINT_PARSE)) {
24769
attila
parents: 24759 24282
diff changeset
  1401
                getErr().println(new PrintVisitor(functionNode, true, false));
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
  1402
            }
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16230
diff changeset
  1403
        }
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16230
diff changeset
  1404
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 17231
diff changeset
  1405
        if (env._parse_only) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 17231
diff changeset
  1406
            return null;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 17231
diff changeset
  1407
        }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 17231
diff changeset
  1408
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16230
diff changeset
  1409
        final URL          url    = source.getURL();
23076
8660ebaaa2f2 8033924: Default permissions are not given for eval code
sundar
parents: 22669
diff changeset
  1410
        final CodeSource   cs     = new CodeSource(url, (CodeSigner[])null);
32696
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
  1411
        final CodeInstaller installer;
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
  1412
        if (DISABLE_VM_ANONYMOUS_CLASSES || env._persistent_cache || !env._lazy_compilation) {
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
  1413
            // Persistent code cache and eager compilation preclude use of VM anonymous classes
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
  1414
            final ScriptLoader loader = env._loader_per_compile ? createNewLoader() : scriptLoader;
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
  1415
            installer = new NamedContextCodeInstaller(this, cs, loader);
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
  1416
        } else {
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
  1417
            installer = new AnonymousContextCodeInstaller(this, cs);
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
  1418
        }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1419
26055
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25422
diff changeset
  1420
        if (storedScript == null) {
24769
attila
parents: 24759 24282
diff changeset
  1421
            final CompilationPhases phases = Compiler.CompilationPhases.COMPILE_ALL;
24759
31aed7d9c02a 8034206: Make parts of code pipeline reusable in order to facilitate faster warmup and faster lazy compilation.
lagergren
parents: 24745
diff changeset
  1422
32530
20aa15248117 8135262: Sanitize CodeInstaller API
attila
parents: 31199
diff changeset
  1423
            final Compiler compiler = Compiler.forInitialCompilation(
24769
attila
parents: 24759 24282
diff changeset
  1424
                    installer,
attila
parents: 24759 24282
diff changeset
  1425
                    source,
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26248
diff changeset
  1426
                    errMan,
24769
attila
parents: 24759 24282
diff changeset
  1427
                    strict | functionNode.isStrict());
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16230
diff changeset
  1428
26055
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25422
diff changeset
  1429
            final FunctionNode compiledFunction = compiler.compile(functionNode, phases);
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26248
diff changeset
  1430
            if (errMan.hasErrors()) {
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26248
diff changeset
  1431
                return null;
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26248
diff changeset
  1432
            }
26055
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25422
diff changeset
  1433
            script = compiledFunction.getRootClass();
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25422
diff changeset
  1434
            compiler.persistClassInfo(cacheKey, compiledFunction);
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
  1435
        } else {
26055
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25422
diff changeset
  1436
            Compiler.updateCompilationId(storedScript.getCompilationId());
30056
06d201382b55 8053905: Eager code generation fails for earley boyer with split threshold set to 1000
hannesw
parents: 29834
diff changeset
  1437
            script = storedScript.installScript(source, installer);
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
  1438
        }
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16230
diff changeset
  1439
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1440
        cacheClass(source, script);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1441
        return script;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1442
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1443
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1444
    private ScriptLoader createNewLoader() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1445
        return AccessController.doPrivileged(
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1446
             new PrivilegedAction<ScriptLoader>() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1447
                @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1448
                public ScriptLoader run() {
19895
965b12eb322e 8024619: JDBC java.sql.DriverManager is not usable from JS script
sundar
parents: 19884
diff changeset
  1449
                    return new ScriptLoader(appLoader, Context.this);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1450
                }
19459
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
  1451
             }, CREATE_LOADER_ACC_CTXT);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1452
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1453
18864
c701b823ed9e 8020276: interface checks in Invocable.getInterface implementation
sundar
parents: 18862
diff changeset
  1454
    private long getUniqueScriptId() {
c701b823ed9e 8020276: interface checks in Invocable.getInterface implementation
sundar
parents: 18862
diff changeset
  1455
        return uniqueScriptId.getAndIncrement();
18862
8b6a01b38cb8 8020224: LinkageError: attempted duplicate class definition when --loader-per-compiler=false
sundar
parents: 18860
diff changeset
  1456
    }
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1457
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
  1458
    /**
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1459
     * Cache for compiled script classes.
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1460
     */
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1461
    @SuppressWarnings("serial")
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26982
diff changeset
  1462
    @Logger(name="classcache")
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26982
diff changeset
  1463
    private static class ClassCache extends LinkedHashMap<Source, ClassReference> implements Loggable {
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1464
        private final int size;
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1465
        private final ReferenceQueue<Class<?>> queue;
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26982
diff changeset
  1466
        private final DebugLogger log;
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1467
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26982
diff changeset
  1468
        ClassCache(final Context context, final int size) {
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1469
            super(size, 0.75f, true);
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1470
            this.size = size;
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1471
            this.queue = new ReferenceQueue<>();
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26982
diff changeset
  1472
            this.log   = initLogger(context);
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1473
        }
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1474
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1475
        void cache(final Source source, final Class<?> clazz) {
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26982
diff changeset
  1476
            if (log.isEnabled()) {
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26982
diff changeset
  1477
                log.info("Caching ", source, " in class cache");
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26982
diff changeset
  1478
            }
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1479
            put(source, new ClassReference(clazz, queue, source));
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1480
        }
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1481
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1482
        @Override
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1483
        protected boolean removeEldestEntry(final Map.Entry<Source, ClassReference> eldest) {
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1484
            return size() > size;
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1485
        }
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1486
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1487
        @Override
24731
ab0c8fc915ae 8038406: Testability: as a first step of moving loggers away from the process global space, the Debug object now supports logging POJOs from log entries as an event queue, which can be introspected from test scripts. This is way better than screen scraping brittle and subject-to-change log output.
lagergren
parents: 24727
diff changeset
  1488
        public ClassReference get(final Object key) {
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1489
            for (ClassReference ref; (ref = (ClassReference)queue.poll()) != null; ) {
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26982
diff changeset
  1490
                final Source source = ref.source;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26982
diff changeset
  1491
                if (log.isEnabled()) {
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26982
diff changeset
  1492
                    log.info("Evicting ", source, " from class cache.");
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26982
diff changeset
  1493
                }
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26982
diff changeset
  1494
                remove(source);
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26982
diff changeset
  1495
            }
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26982
diff changeset
  1496
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26982
diff changeset
  1497
            final ClassReference ref = super.get(key);
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26982
diff changeset
  1498
            if (ref != null && log.isEnabled()) {
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26982
diff changeset
  1499
                log.info("Retrieved class reference for ", ref.source, " from class cache");
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1500
            }
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26982
diff changeset
  1501
            return ref;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26982
diff changeset
  1502
        }
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26982
diff changeset
  1503
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26982
diff changeset
  1504
        @Override
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26982
diff changeset
  1505
        public DebugLogger initLogger(final Context context) {
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26982
diff changeset
  1506
            return context.getLogger(getClass());
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26982
diff changeset
  1507
        }
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26982
diff changeset
  1508
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26982
diff changeset
  1509
        @Override
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26982
diff changeset
  1510
        public DebugLogger getLogger() {
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26982
diff changeset
  1511
            return log;
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1512
        }
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1513
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1514
    }
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1515
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1516
    private static class ClassReference extends SoftReference<Class<?>> {
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1517
        private final Source source;
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1518
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1519
        ClassReference(final Class<?> clazz, final ReferenceQueue<Class<?>> queue, final Source source) {
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1520
            super(clazz, queue);
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1521
            this.source = source;
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1522
        }
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1523
    }
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1524
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1525
    // Class cache management
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1526
    private Class<?> findCachedClass(final Source source) {
24731
ab0c8fc915ae 8038406: Testability: as a first step of moving loggers away from the process global space, the Debug object now supports logging POJOs from log entries as an event queue, which can be introspected from test scripts. This is way better than screen scraping brittle and subject-to-change log output.
lagergren
parents: 24727
diff changeset
  1527
        final ClassReference ref = classCache == null ? null : classCache.get(source);
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1528
        return ref != null ? ref.get() : null;
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1529
    }
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1530
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1531
    private void cacheClass(final Source source, final Class<?> clazz) {
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1532
        if (classCache != null) {
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1533
            classCache.cache(source, clazz);
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1534
        }
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1535
    }
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1536
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1537
    // logging
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1538
    private final Map<String, DebugLogger> loggers = new HashMap<>();
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1539
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1540
    private void initLoggers() {
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1541
        ((Loggable)MethodHandleFactory.getFunctionality()).initLogger(this);
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1542
    }
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1543
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1544
    /**
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1545
     * Get a logger, given a loggable class
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1546
     * @param clazz a Loggable class
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1547
     * @return debuglogger associated with that class
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1548
     */
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1549
    public DebugLogger getLogger(final Class<? extends Loggable> clazz) {
24993
b707d46bae40 8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents: 24879
diff changeset
  1550
        return getLogger(clazz, null);
b707d46bae40 8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents: 24879
diff changeset
  1551
    }
b707d46bae40 8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents: 24879
diff changeset
  1552
b707d46bae40 8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents: 24879
diff changeset
  1553
    /**
b707d46bae40 8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents: 24879
diff changeset
  1554
     * Get a logger, given a loggable class
b707d46bae40 8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents: 24879
diff changeset
  1555
     * @param clazz a Loggable class
b707d46bae40 8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents: 24879
diff changeset
  1556
     * @param initHook an init hook - if this is the first time the logger is created in the context, run the init hook
b707d46bae40 8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents: 24879
diff changeset
  1557
     * @return debuglogger associated with that class
b707d46bae40 8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents: 24879
diff changeset
  1558
     */
b707d46bae40 8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents: 24879
diff changeset
  1559
    public DebugLogger getLogger(final Class<? extends Loggable> clazz, final Consumer<DebugLogger> initHook) {
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1560
        final String name = getLoggerName(clazz);
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1561
        DebugLogger logger = loggers.get(name);
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1562
        if (logger == null) {
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1563
            if (!env.hasLogger(name)) {
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1564
                return DebugLogger.DISABLED_LOGGER;
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1565
            }
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1566
            final LoggerInfo info = env._loggers.get(name);
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1567
            logger = new DebugLogger(name, info.getLevel(), info.isQuiet());
24993
b707d46bae40 8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents: 24879
diff changeset
  1568
            if (initHook != null) {
b707d46bae40 8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents: 24879
diff changeset
  1569
                initHook.accept(logger);
b707d46bae40 8046898: Make sure that lazy compilation is the default, remove redundant "enable lazy compilation" flags, added warning message if compile logging is enabled and lazy is switched off. Verified existing test suite code coverage equivalence between lazy and eager.
lagergren
parents: 24879
diff changeset
  1570
            }
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1571
            loggers.put(name, logger);
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1572
        }
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1573
        return logger;
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1574
    }
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1575
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1576
    /**
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1577
     * Given a Loggable class, weave debug info info a method handle for that logger.
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1578
     * Level.INFO is used
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1579
     *
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1580
     * @param clazz loggable
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1581
     * @param mh    method handle
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1582
     * @param text  debug printout to add
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1583
     *
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1584
     * @return instrumented method handle, or null if logger not enabled
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1585
     */
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1586
    public MethodHandle addLoggingToHandle(final Class<? extends Loggable> clazz, final MethodHandle mh, final Supplier<String> text) {
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1587
        return addLoggingToHandle(clazz, Level.INFO, mh, Integer.MAX_VALUE, false, text);
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1588
    }
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1589
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1590
    /**
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1591
     * Given a Loggable class, weave debug info info a method handle for that logger.
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1592
     *
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1593
     * @param clazz            loggable
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1594
     * @param level            log level
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1595
     * @param mh               method handle
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1596
     * @param paramStart       first parameter to print
32534
b3ec7f3b3c2a 8136349: Typos patch for nashorn sources submitted on Sep 10, 2015
sundar
parents: 32530
diff changeset
  1597
     * @param printReturnValue should we print the return value?
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1598
     * @param text             debug printout to add
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1599
     *
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1600
     * @return instrumented method handle, or null if logger not enabled
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1601
     */
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1602
    public MethodHandle addLoggingToHandle(final Class<? extends Loggable> clazz, final Level level, final MethodHandle mh, final int paramStart, final boolean printReturnValue, final Supplier<String> text) {
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1603
        final DebugLogger log = getLogger(clazz);
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1604
        if (log.isEnabled()) {
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1605
            return MethodHandleFactory.addDebugPrintout(log, level, mh, paramStart, printReturnValue, text.get());
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1606
        }
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1607
        return mh;
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1608
    }
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1609
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1610
    private static String getLoggerName(final Class<?> clazz) {
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1611
        Class<?> current = clazz;
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1612
        while (current != null) {
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1613
            final Logger log = current.getAnnotation(Logger.class);
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1614
            if (log != null) {
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1615
                assert !"".equals(log.name());
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1616
                return log.name();
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1617
            }
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1618
            current = current.getSuperclass();
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1619
        }
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1620
        assert false;
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1621
        return null;
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1622
    }
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1623
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
  1624
    /**
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
  1625
     * This is a special kind of switchpoint used to guard builtin
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
  1626
     * properties and prototypes. In the future it might contain
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
  1627
     * logic to e.g. multiple switchpoint classes.
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
  1628
     */
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
  1629
    public static final class BuiltinSwitchPoint extends SwitchPoint {
26886
18c744ab4df2 8059211: Changed ArrayData.length accessor to use the protected field and fixed javadoc warnings related to this
lagergren
parents: 26768
diff changeset
  1630
        //empty
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
  1631
    }
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
  1632
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
  1633
    /**
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
  1634
     * Create a new builtin switchpoint and return it
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
  1635
     * @param name key name
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
  1636
     * @return new builtin switchpoint
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
  1637
     */
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
  1638
    public SwitchPoint newBuiltinSwitchPoint(final String name) {
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
  1639
        assert builtinSwitchPoints.get(name) == null;
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
  1640
        final SwitchPoint sp = new BuiltinSwitchPoint();
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
  1641
        builtinSwitchPoints.put(name, sp);
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
  1642
        return sp;
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
  1643
    }
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
  1644
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
  1645
    /**
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
  1646
     * Return the builtin switchpoint for a particular key name
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
  1647
     * @param name key name
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
  1648
     * @return builtin switchpoint or null if none
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
  1649
     */
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
  1650
    public SwitchPoint getBuiltinSwitchPoint(final String name) {
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
  1651
        return builtinSwitchPoints.get(name);
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
  1652
    }
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
  1653
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1654
}