nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Context.java
author attila
Mon, 09 Nov 2015 14:03:37 +0100
changeset 33684 1bfe8ffd9baf
parent 33538 82c57d427fa1
child 33685 343aaf358c21
permissions -rw-r--r--
8141541: Simplify Nashorn's Context class loader handling Reviewed-by: hannesw, 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;
33538
82c57d427fa1 8141446: Cache Class.forName for permanently loaded classes
attila
parents: 32895
diff changeset
    67
import java.util.concurrent.ConcurrentHashMap;
82c57d427fa1 8141446: Cache Class.forName for permanently loaded classes
attila
parents: 32895
diff changeset
    68
import java.util.concurrent.ConcurrentMap;
22669
75563515567f 8032681: Issues with Nashorn
attila
parents: 22389
diff changeset
    69
import java.util.concurrent.atomic.AtomicLong;
27369
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
    70
import java.util.concurrent.atomic.AtomicReference;
32696
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
    71
import java.util.concurrent.atomic.LongAdder;
24769
attila
parents: 24759 24282
diff changeset
    72
import java.util.function.Consumer;
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
    73
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
    74
import java.util.logging.Level;
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();
32895
5a09b2d3d73a 8138882: Performance regression due to anonymous classloading
hannesw
parents: 32893
diff changeset
   144
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
32786
dedf2b6ea495 8136700: Make sure Context.anonymousHostClasses doesn't grow unbounded
attila
parents: 32781
diff changeset
   304
    private final Map<CodeSource, HostClassReference> anonymousHostClasses = new HashMap<>();
dedf2b6ea495 8136700: Make sure Context.anonymousHostClasses doesn't grow unbounded
attila
parents: 32781
diff changeset
   305
    private final ReferenceQueue<Class<?>> anonymousHostClassesRefQueue = new ReferenceQueue<>();
dedf2b6ea495 8136700: Make sure Context.anonymousHostClasses doesn't grow unbounded
attila
parents: 32781
diff changeset
   306
dedf2b6ea495 8136700: Make sure Context.anonymousHostClasses doesn't grow unbounded
attila
parents: 32781
diff changeset
   307
    private static class HostClassReference extends WeakReference<Class<?>> {
dedf2b6ea495 8136700: Make sure Context.anonymousHostClasses doesn't grow unbounded
attila
parents: 32781
diff changeset
   308
        final CodeSource codeSource;
dedf2b6ea495 8136700: Make sure Context.anonymousHostClasses doesn't grow unbounded
attila
parents: 32781
diff changeset
   309
dedf2b6ea495 8136700: Make sure Context.anonymousHostClasses doesn't grow unbounded
attila
parents: 32781
diff changeset
   310
        HostClassReference(final CodeSource codeSource, final Class<?> clazz, final ReferenceQueue<Class<?>> refQueue) {
dedf2b6ea495 8136700: Make sure Context.anonymousHostClasses doesn't grow unbounded
attila
parents: 32781
diff changeset
   311
            super(clazz, refQueue);
dedf2b6ea495 8136700: Make sure Context.anonymousHostClasses doesn't grow unbounded
attila
parents: 32781
diff changeset
   312
            this.codeSource = codeSource;
dedf2b6ea495 8136700: Make sure Context.anonymousHostClasses doesn't grow unbounded
attila
parents: 32781
diff changeset
   313
        }
dedf2b6ea495 8136700: Make sure Context.anonymousHostClasses doesn't grow unbounded
attila
parents: 32781
diff changeset
   314
    }
dedf2b6ea495 8136700: Make sure Context.anonymousHostClasses doesn't grow unbounded
attila
parents: 32781
diff changeset
   315
dedf2b6ea495 8136700: Make sure Context.anonymousHostClasses doesn't grow unbounded
attila
parents: 32781
diff changeset
   316
    private synchronized Class<?> getAnonymousHostClass(final CodeSource codeSource) {
dedf2b6ea495 8136700: Make sure Context.anonymousHostClasses doesn't grow unbounded
attila
parents: 32781
diff changeset
   317
        // Remove cleared entries
dedf2b6ea495 8136700: Make sure Context.anonymousHostClasses doesn't grow unbounded
attila
parents: 32781
diff changeset
   318
        for(;;) {
dedf2b6ea495 8136700: Make sure Context.anonymousHostClasses doesn't grow unbounded
attila
parents: 32781
diff changeset
   319
            final HostClassReference clearedRef = (HostClassReference)anonymousHostClassesRefQueue.poll();
dedf2b6ea495 8136700: Make sure Context.anonymousHostClasses doesn't grow unbounded
attila
parents: 32781
diff changeset
   320
            if (clearedRef == null) {
dedf2b6ea495 8136700: Make sure Context.anonymousHostClasses doesn't grow unbounded
attila
parents: 32781
diff changeset
   321
                break;
dedf2b6ea495 8136700: Make sure Context.anonymousHostClasses doesn't grow unbounded
attila
parents: 32781
diff changeset
   322
            }
dedf2b6ea495 8136700: Make sure Context.anonymousHostClasses doesn't grow unbounded
attila
parents: 32781
diff changeset
   323
            anonymousHostClasses.remove(clearedRef.codeSource, clearedRef);
dedf2b6ea495 8136700: Make sure Context.anonymousHostClasses doesn't grow unbounded
attila
parents: 32781
diff changeset
   324
        }
dedf2b6ea495 8136700: Make sure Context.anonymousHostClasses doesn't grow unbounded
attila
parents: 32781
diff changeset
   325
dedf2b6ea495 8136700: Make sure Context.anonymousHostClasses doesn't grow unbounded
attila
parents: 32781
diff changeset
   326
        // Try to find an existing host class
dedf2b6ea495 8136700: Make sure Context.anonymousHostClasses doesn't grow unbounded
attila
parents: 32781
diff changeset
   327
        final Reference<Class<?>> ref = anonymousHostClasses.get(codeSource);
dedf2b6ea495 8136700: Make sure Context.anonymousHostClasses doesn't grow unbounded
attila
parents: 32781
diff changeset
   328
        if (ref != null) {
dedf2b6ea495 8136700: Make sure Context.anonymousHostClasses doesn't grow unbounded
attila
parents: 32781
diff changeset
   329
            final Class<?> existingHostClass = ref.get();
dedf2b6ea495 8136700: Make sure Context.anonymousHostClasses doesn't grow unbounded
attila
parents: 32781
diff changeset
   330
            if (existingHostClass != null) {
dedf2b6ea495 8136700: Make sure Context.anonymousHostClasses doesn't grow unbounded
attila
parents: 32781
diff changeset
   331
                return existingHostClass;
dedf2b6ea495 8136700: Make sure Context.anonymousHostClasses doesn't grow unbounded
attila
parents: 32781
diff changeset
   332
            }
dedf2b6ea495 8136700: Make sure Context.anonymousHostClasses doesn't grow unbounded
attila
parents: 32781
diff changeset
   333
        }
dedf2b6ea495 8136700: Make sure Context.anonymousHostClasses doesn't grow unbounded
attila
parents: 32781
diff changeset
   334
dedf2b6ea495 8136700: Make sure Context.anonymousHostClasses doesn't grow unbounded
attila
parents: 32781
diff changeset
   335
        // Define a new host class if existing is not found
dedf2b6ea495 8136700: Make sure Context.anonymousHostClasses doesn't grow unbounded
attila
parents: 32781
diff changeset
   336
        final Class<?> newHostClass = createNewLoader().installClass(
dedf2b6ea495 8136700: Make sure Context.anonymousHostClasses doesn't grow unbounded
attila
parents: 32781
diff changeset
   337
                // NOTE: we're defining these constants in AnonymousContextCodeInstaller so they are not
dedf2b6ea495 8136700: Make sure Context.anonymousHostClasses doesn't grow unbounded
attila
parents: 32781
diff changeset
   338
                // initialized if we don't use AnonymousContextCodeInstaller. As this method is only ever
dedf2b6ea495 8136700: Make sure Context.anonymousHostClasses doesn't grow unbounded
attila
parents: 32781
diff changeset
   339
                // invoked from AnonymousContextCodeInstaller, this is okay.
dedf2b6ea495 8136700: Make sure Context.anonymousHostClasses doesn't grow unbounded
attila
parents: 32781
diff changeset
   340
                AnonymousContextCodeInstaller.ANONYMOUS_HOST_CLASS_NAME,
dedf2b6ea495 8136700: Make sure Context.anonymousHostClasses doesn't grow unbounded
attila
parents: 32781
diff changeset
   341
                AnonymousContextCodeInstaller.ANONYMOUS_HOST_CLASS_BYTES, codeSource);
dedf2b6ea495 8136700: Make sure Context.anonymousHostClasses doesn't grow unbounded
attila
parents: 32781
diff changeset
   342
        anonymousHostClasses.put(codeSource, new HostClassReference(codeSource, newHostClass, anonymousHostClassesRefQueue));
dedf2b6ea495 8136700: Make sure Context.anonymousHostClasses doesn't grow unbounded
attila
parents: 32781
diff changeset
   343
        return newHostClass;
dedf2b6ea495 8136700: Make sure Context.anonymousHostClasses doesn't grow unbounded
attila
parents: 32781
diff changeset
   344
    }
32696
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
    private static final class AnonymousContextCodeInstaller extends ContextCodeInstaller {
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   347
        private static final Unsafe UNSAFE = getUnsafe();
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   348
        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
   349
        private static final byte[] ANONYMOUS_HOST_CLASS_BYTES = getAnonymousHostClassBytes();
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 final Class<?> hostClass;
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   352
32786
dedf2b6ea495 8136700: Make sure Context.anonymousHostClasses doesn't grow unbounded
attila
parents: 32781
diff changeset
   353
        private AnonymousContextCodeInstaller(final Context context, final CodeSource codeSource, final Class<?> hostClass) {
32696
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   354
            super(context, codeSource);
32786
dedf2b6ea495 8136700: Make sure Context.anonymousHostClasses doesn't grow unbounded
attila
parents: 32781
diff changeset
   355
            this.hostClass = hostClass;
32696
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
        @Override
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   359
        public Class<?> install(final String className, final byte[] bytecode) {
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   360
            ANONYMOUS_INSTALLED_SCRIPT_COUNT.increment();
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   361
            return UNSAFE.defineAnonymousClass(hostClass, bytecode, null);
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   362
        }
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   363
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   364
        @Override
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   365
        public CodeInstaller getOnDemandCompilationInstaller() {
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   366
            // 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
   367
            return this;
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
        @Override
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   371
        public CodeInstaller getMultiClassCodeInstaller() {
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   372
            // 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
   373
            // 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
   374
            // produces named classes.
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   375
            return new NamedContextCodeInstaller(context, codeSource, context.createNewLoader());
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   376
        }
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   377
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   378
        private static final byte[] getAnonymousHostClassBytes() {
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   379
            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
   380
            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
   381
            cw.visitEnd();
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   382
            return cw.toByteArray();
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   383
        }
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   384
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   385
        private static Unsafe getUnsafe() {
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   386
            return AccessController.doPrivileged(new PrivilegedAction<Unsafe>() {
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   387
                @Override
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   388
                public Unsafe run() {
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   389
                    try {
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   390
                        final Field theUnsafeField = Unsafe.class.getDeclaredField("theUnsafe");
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   391
                        theUnsafeField.setAccessible(true);
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   392
                        return (Unsafe)theUnsafeField.get(null);
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   393
                    } catch (final ReflectiveOperationException e) {
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   394
                        throw new RuntimeException(e);
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   395
                    }
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   396
                }
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   397
            });
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   398
        }
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   399
    }
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
   400
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   401
    /** Is Context global debug mode enabled ? */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   402
    public static final boolean DEBUG = Options.getBooleanProperty("nashorn.debug");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   403
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
   404
    private static final ThreadLocal<Global> currentGlobal = new ThreadLocal<>();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   405
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
   406
    // in-memory cache for loaded classes
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
   407
    private ClassCache classCache;
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
   408
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
   409
    // persistent code store
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
   410
    private CodeStore codeStore;
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
   411
27369
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
   412
    // 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
   413
    // 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
   414
    private final AtomicReference<GlobalConstants> globalConstantsRef = new AtomicReference<>();
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
   415
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   416
    /**
16188
d6390b0ea32a 8006678: Avoid too many Context.getGlobal() calls
sundar
parents: 16185
diff changeset
   417
     * Get the current global scope
d6390b0ea32a 8006678: Avoid too many Context.getGlobal() calls
sundar
parents: 16185
diff changeset
   418
     * @return the current global scope
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   419
     */
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
   420
    public static Global getGlobal() {
17231
734f61d5a097 8012612: Compile failed
sundar
parents: 16947
diff changeset
   421
        // This class in a package.access protected package.
734f61d5a097 8012612: Compile failed
sundar
parents: 16947
diff changeset
   422
        // Trusted code only can call this method.
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
   423
        return currentGlobal.get();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   424
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   425
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   426
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   427
     * Set the current global scope
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   428
     * @param global the global scope
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   429
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   430
    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
   431
        if (global != null && !(global instanceof Global)) {
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
   432
            throw new IllegalArgumentException("not a global!");
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   433
        }
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
   434
        setGlobal((Global)global);
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
   435
    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   436
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
   437
    /**
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
   438
     * Set the current global scope
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
   439
     * @param global the global scope
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
   440
     */
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
   441
    public static void setGlobal(final Global global) {
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
   442
        // This class in a package.access protected package.
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
   443
        // 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
   444
        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
   445
        //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
   446
        if (global != null) {
27369
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
   447
            final GlobalConstants globalConstants = getContext(global).getGlobalConstants();
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
   448
            if (globalConstants != null) {
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
   449
                globalConstants.invalidateAll();
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
   450
            }
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
   451
        }
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
   452
        currentGlobal.set(global);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   453
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   454
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   455
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   456
     * Get context of the current global
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   457
     * @return current global scope's context.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   458
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   459
    public static Context getContext() {
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   460
        final SecurityManager sm = System.getSecurityManager();
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   461
        if (sm != null) {
19459
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   462
            sm.checkPermission(new RuntimePermission(NASHORN_GET_CONTEXT));
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   463
        }
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   464
        return getContextTrusted();
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   465
    }
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   466
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   467
    /**
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   468
     * Get current context's error writer
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   469
     *
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   470
     * @return error writer of the current context
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   471
     */
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   472
    public static PrintWriter getCurrentErr() {
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
   473
        final ScriptObject global = getGlobal();
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   474
        return (global != null)? global.getContext().getErr() : new PrintWriter(System.err);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   475
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   476
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   477
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   478
     * Output text to this Context's error stream
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   479
     * @param str text to write
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   480
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   481
    public static void err(final String str) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   482
        err(str, true);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   483
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   484
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   485
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   486
     * Output text to this Context's error stream, optionally with
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   487
     * a newline afterwards
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   488
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   489
     * @param str  text to write
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   490
     * @param crlf write a carriage return/new line after text
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   491
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   492
    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
   493
        final PrintWriter err = Context.getCurrentErr();
16155
a8ab83cbaa49 8005788: Loggers and their corresponding system properties not working correctly
lagergren
parents: 16151
diff changeset
   494
        if (err != null) {
a8ab83cbaa49 8005788: Loggers and their corresponding system properties not working correctly
lagergren
parents: 16151
diff changeset
   495
            if (crlf) {
a8ab83cbaa49 8005788: Loggers and their corresponding system properties not working correctly
lagergren
parents: 16151
diff changeset
   496
                err.println(str);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   497
            } else {
16155
a8ab83cbaa49 8005788: Loggers and their corresponding system properties not working correctly
lagergren
parents: 16151
diff changeset
   498
                err.print(str);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   499
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   500
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   501
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   502
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16256
diff changeset
   503
    /** Current environment. */
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16256
diff changeset
   504
    private final ScriptEnvironment env;
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16256
diff changeset
   505
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16256
diff changeset
   506
    /** 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
   507
    final boolean _strict;
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16256
diff changeset
   508
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   509
    /** class loader to resolve classes from script. */
33684
1bfe8ffd9baf 8141541: Simplify Nashorn's Context class loader handling
attila
parents: 33538
diff changeset
   510
    private final ClassLoader appLoader;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   511
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   512
    /** Class loader to load classes compiled from scripts. */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   513
    private final ScriptLoader scriptLoader;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   514
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   515
    /** Current error manager. */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   516
    private final ErrorManager errors;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   517
18862
8b6a01b38cb8 8020224: LinkageError: attempted duplicate class definition when --loader-per-compiler=false
sundar
parents: 18860
diff changeset
   518
    /** 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
   519
    private final AtomicLong uniqueScriptId;
18862
8b6a01b38cb8 8020224: LinkageError: attempted duplicate class definition when --loader-per-compiler=false
sundar
parents: 18860
diff changeset
   520
26071
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   521
    /** Optional class filter to use for Java classes. Can be null. */
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   522
    private final ClassFilter classFilter;
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   523
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   524
    private static final ClassLoader myLoader = Context.class.getClassLoader();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   525
    private static final StructureLoader sharedLoader;
33538
82c57d427fa1 8141446: Cache Class.forName for permanently loaded classes
attila
parents: 32895
diff changeset
   526
    private static final ConcurrentMap<String, Class<?>> structureClasses = new ConcurrentHashMap<>();
19459
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   527
20933
89748612fd1d 8026250: Logging nullpointer bugfix and javadoc warnings
lagergren
parents: 20929
diff changeset
   528
    /*package-private*/ @SuppressWarnings("static-method")
89748612fd1d 8026250: Logging nullpointer bugfix and javadoc warnings
lagergren
parents: 20929
diff changeset
   529
    ClassLoader getSharedLoader() {
19895
965b12eb322e 8024619: JDBC java.sql.DriverManager is not usable from JS script
sundar
parents: 19884
diff changeset
   530
        return sharedLoader;
965b12eb322e 8024619: JDBC java.sql.DriverManager is not usable from JS script
sundar
parents: 19884
diff changeset
   531
    }
965b12eb322e 8024619: JDBC java.sql.DriverManager is not usable from JS script
sundar
parents: 19884
diff changeset
   532
19459
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   533
    private static AccessControlContext createNoPermAccCtxt() {
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   534
        return new AccessControlContext(new ProtectionDomain[] { new ProtectionDomain(null, new Permissions()) });
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   535
    }
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   536
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   537
    private static AccessControlContext createPermAccCtxt(final String permName) {
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   538
        final Permissions perms = new Permissions();
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   539
        perms.add(new RuntimePermission(permName));
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   540
        return new AccessControlContext(new ProtectionDomain[] { new ProtectionDomain(null, perms) });
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   541
    }
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   542
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   543
    private static final AccessControlContext NO_PERMISSIONS_ACC_CTXT = createNoPermAccCtxt();
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   544
    private static final AccessControlContext CREATE_LOADER_ACC_CTXT  = createPermAccCtxt("createClassLoader");
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   545
    private static final AccessControlContext CREATE_GLOBAL_ACC_CTXT  = createPermAccCtxt(NASHORN_CREATE_GLOBAL);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   546
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   547
    static {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   548
        sharedLoader = AccessController.doPrivileged(new PrivilegedAction<StructureLoader>() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   549
            @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   550
            public StructureLoader run() {
19895
965b12eb322e 8024619: JDBC java.sql.DriverManager is not usable from JS script
sundar
parents: 19884
diff changeset
   551
                return new StructureLoader(myLoader);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   552
            }
19459
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   553
        }, CREATE_LOADER_ACC_CTXT);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   554
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   555
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   556
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   557
     * ThrowErrorManager that throws ParserException upon error conditions.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   558
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   559
    public static class ThrowErrorManager extends ErrorManager {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   560
        @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   561
        public void error(final String message) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   562
            throw new ParserException(message);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   563
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   564
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   565
        @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   566
        public void error(final ParserException e) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   567
            throw e;
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
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   571
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   572
     * Constructor
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   573
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   574
     * @param options options from command line or Context creator
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   575
     * @param errors  error manger
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 ClassLoader appLoader) {
29834
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 28785
diff changeset
   579
        this(options, errors, appLoader, null);
26071
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 appLoader application class loader
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   588
     * @param classFilter class filter to use
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   589
     */
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   590
    public Context(final Options options, final ErrorManager errors, final ClassLoader appLoader, final ClassFilter classFilter) {
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   591
        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
   592
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   593
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   594
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   595
     * Constructor
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   596
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   597
     * @param options options from command line or Context creator
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   598
     * @param errors  error manger
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   599
     * @param out     output writer for this Context
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   600
     * @param err     error writer for this Context
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   601
     * @param appLoader application class loader
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   602
     */
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   603
    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
   604
        this(options, errors, out, err, appLoader, (ClassFilter)null);
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   605
    }
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   606
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   607
    /**
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   608
     * Constructor
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   609
     *
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   610
     * @param options options from command line or Context creator
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   611
     * @param errors  error manger
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   612
     * @param out     output writer for this Context
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   613
     * @param err     error writer for this Context
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   614
     * @param appLoader application class loader
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   615
     * @param classFilter class filter to use
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   616
     */
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   617
    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
   618
        final SecurityManager sm = System.getSecurityManager();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   619
        if (sm != null) {
19459
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
   620
            sm.checkPermission(new RuntimePermission(NASHORN_CREATE_CONTEXT));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   621
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   622
26071
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   623
        this.classFilter = classFilter;
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16256
diff changeset
   624
        this.env       = new ScriptEnvironment(options, out, err);
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16256
diff changeset
   625
        this._strict   = env._strict;
18864
c701b823ed9e 8020276: interface checks in Invocable.getInterface implementation
sundar
parents: 18862
diff changeset
   626
        if (env._loader_per_compile) {
c701b823ed9e 8020276: interface checks in Invocable.getInterface implementation
sundar
parents: 18862
diff changeset
   627
            this.scriptLoader = null;
c701b823ed9e 8020276: interface checks in Invocable.getInterface implementation
sundar
parents: 18862
diff changeset
   628
            this.uniqueScriptId = null;
c701b823ed9e 8020276: interface checks in Invocable.getInterface implementation
sundar
parents: 18862
diff changeset
   629
        } else {
c701b823ed9e 8020276: interface checks in Invocable.getInterface implementation
sundar
parents: 18862
diff changeset
   630
            this.scriptLoader = createNewLoader();
c701b823ed9e 8020276: interface checks in Invocable.getInterface implementation
sundar
parents: 18862
diff changeset
   631
            this.uniqueScriptId = new AtomicLong();
c701b823ed9e 8020276: interface checks in Invocable.getInterface implementation
sundar
parents: 18862
diff changeset
   632
        }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   633
        this.errors    = errors;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   634
33684
1bfe8ffd9baf 8141541: Simplify Nashorn's Context class loader handling
attila
parents: 33538
diff changeset
   635
        // if user passed -classpath option, make a URLClassLoader with that and
1bfe8ffd9baf 8141541: Simplify Nashorn's Context class loader handling
attila
parents: 33538
diff changeset
   636
        // the app loader as the parent.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   637
        final String classPath = options.getString("classpath");
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 23076
diff changeset
   638
        if (!env._compile_only && classPath != null && !classPath.isEmpty()) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   639
            // make sure that caller can create a class loader.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   640
            if (sm != null) {
33684
1bfe8ffd9baf 8141541: Simplify Nashorn's Context class loader handling
attila
parents: 33538
diff changeset
   641
                sm.checkCreateClassLoader();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   642
            }
33684
1bfe8ffd9baf 8141541: Simplify Nashorn's Context class loader handling
attila
parents: 33538
diff changeset
   643
            this.appLoader = NashornLoader.createClassLoader(classPath, appLoader);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   644
        } else {
33684
1bfe8ffd9baf 8141541: Simplify Nashorn's Context class loader handling
attila
parents: 33538
diff changeset
   645
            this.appLoader = appLoader;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   646
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   647
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
   648
        final int cacheSize = env._class_cache_size;
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
   649
        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
   650
            classCache = new ClassCache(this, cacheSize);
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
   651
        }
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
   652
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
   653
        if (env._persistent_cache) {
27530
518b8ae2dbb9 8064789: Nashorn should just warn on code store instantiation error
hannesw
parents: 27369
diff changeset
   654
            codeStore = newCodeStore(this);
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
   655
        }
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
   656
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   657
        // print version info if asked.
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16256
diff changeset
   658
        if (env._version) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   659
            getErr().println("nashorn " + Version.version());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   660
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   661
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16256
diff changeset
   662
        if (env._fullversion) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   663
            getErr().println("nashorn full version " + Version.fullVersion());
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   664
        }
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
   665
29834
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 28785
diff changeset
   666
        if (Options.getBooleanProperty("nashorn.fields.dual")) {
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 28785
diff changeset
   667
            fieldMode = FieldMode.DUAL;
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 28785
diff changeset
   668
        } else if (Options.getBooleanProperty("nashorn.fields.objects")) {
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 28785
diff changeset
   669
            fieldMode = FieldMode.OBJECTS;
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 28785
diff changeset
   670
        } else {
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 28785
diff changeset
   671
            fieldMode = FieldMode.AUTO;
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 28785
diff changeset
   672
        }
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 28785
diff changeset
   673
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
   674
        initLoggers();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   675
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   676
26071
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   677
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   678
    /**
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   679
     * Get the class filter for this context
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   680
     * @return class filter
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   681
     */
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   682
    public ClassFilter getClassFilter() {
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   683
        return classFilter;
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   684
    }
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
   685
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   686
    /**
27369
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
   687
     * 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
   688
     * 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
   689
     * @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
   690
     */
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
   691
    GlobalConstants getGlobalConstants() {
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
   692
        return globalConstantsRef.get();
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
   693
    }
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
   694
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
   695
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   696
     * Get the error manager for this context
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   697
     * @return error manger
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   698
     */
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
   699
    public ErrorManager getErrorManager() {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   700
        return errors;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   701
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   702
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   703
    /**
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16256
diff changeset
   704
     * Get the script environment for this context
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16256
diff changeset
   705
     * @return script environment
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16256
diff changeset
   706
     */
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16256
diff changeset
   707
    public ScriptEnvironment getEnv() {
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16256
diff changeset
   708
        return env;
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16256
diff changeset
   709
    }
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16256
diff changeset
   710
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16256
diff changeset
   711
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   712
     * Get the output stream for this context
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   713
     * @return output print writer
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   714
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   715
    public PrintWriter getOut() {
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16256
diff changeset
   716
        return env.getOut();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   717
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   718
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   719
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   720
     * Get the error stream for this context
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   721
     * @return error print writer
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   722
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   723
    public PrintWriter getErr() {
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16256
diff changeset
   724
        return env.getErr();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   725
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   726
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16196
diff changeset
   727
    /**
29834
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 28785
diff changeset
   728
     * 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
   729
     * @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
   730
     */
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 28785
diff changeset
   731
    public boolean useDualFields() {
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 28785
diff changeset
   732
        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
   733
    }
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 28785
diff changeset
   734
f678f348c947 8067215: Disable dual fields when not using optimistic types
hannesw
parents: 28785
diff changeset
   735
    /**
16188
d6390b0ea32a 8006678: Avoid too many Context.getGlobal() calls
sundar
parents: 16185
diff changeset
   736
     * Get the PropertyMap of the current global scope
d6390b0ea32a 8006678: Avoid too many Context.getGlobal() calls
sundar
parents: 16185
diff changeset
   737
     * @return the property map of the current global scope
d6390b0ea32a 8006678: Avoid too many Context.getGlobal() calls
sundar
parents: 16185
diff changeset
   738
     */
16201
889ddb179cdf 8007062: Split Lower up into Lower/Attr/FinalizeTypes. Integrate AccessSpecalizer into FinalizeTypes.
lagergren
parents: 16196
diff changeset
   739
    public static PropertyMap getGlobalMap() {
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
   740
        return Context.getGlobal().getMap();
16188
d6390b0ea32a 8006678: Avoid too many Context.getGlobal() calls
sundar
parents: 16185
diff changeset
   741
    }
d6390b0ea32a 8006678: Avoid too many Context.getGlobal() calls
sundar
parents: 16185
diff changeset
   742
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   743
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   744
     * Compile a top level script.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   745
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   746
     * @param source the source
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   747
     * @param scope  the scope
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   748
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   749
     * @return top level function for script
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   750
     */
16230
c38c724d82e7 8008103: Source object should maintain URL of the script source as a private field
sundar
parents: 16226
diff changeset
   751
    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
   752
        return compileScript(source, scope, this.errors);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   753
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   754
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   755
    /**
24282
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   756
     * 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
   757
     * global scope instances
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   758
     */
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   759
    public static interface MultiGlobalCompiledScript {
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
         * Obtain script function object for a specific global scope object.
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
         * @param newGlobal global scope for which function object is obtained
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   764
         * @return script function for script level expressions
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   765
         */
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   766
        public ScriptFunction getFunction(final Global newGlobal);
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   767
    }
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   768
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   769
    /**
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   770
     * Compile a top level script.
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   771
     *
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   772
     * @param source the script source
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   773
     * @return reusable compiled script across many global scopes.
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   774
     */
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   775
    public MultiGlobalCompiledScript compileScript(final Source source) {
32895
5a09b2d3d73a 8138882: Performance regression due to anonymous classloading
hannesw
parents: 32893
diff changeset
   776
        final Class<?> clazz = compile(source, this.errors, this._strict, false);
24783
b5c31bfe1496 8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents: 24779
diff changeset
   777
        final MethodHandle createProgramFunctionHandle = getCreateProgramFunctionHandle(clazz);
24282
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   778
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   779
        return new MultiGlobalCompiledScript() {
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   780
            @Override
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   781
            public ScriptFunction getFunction(final Global newGlobal) {
24783
b5c31bfe1496 8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents: 24779
diff changeset
   782
                return invokeCreateProgramFunctionHandle(createProgramFunctionHandle, newGlobal);
24282
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   783
            }
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   784
        };
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   785
    }
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   786
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
   787
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   788
     * Entry point for {@code eval}
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   789
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   790
     * @param initialScope The scope of this eval call
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   791
     * @param string       Evaluated code as a String
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   792
     * @param callThis     "this" to be passed to the evaluated code
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   793
     * @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
   794
     * @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
   795
     */
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   796
    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
   797
            final Object callThis, final Object location) {
1e019aeea9b5 8087211: Indirect evals should be strict with -strict option
sundar
parents: 30975
diff changeset
   798
        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
   799
    }
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   800
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   801
    /**
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   802
     * Entry point for {@code eval}
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   803
     *
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   804
     * @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
   805
     * @param string       Evaluated code as a String
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   806
     * @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
   807
     * @param location     location of the eval call
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   808
     * @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
   809
     * @param evalCall     is this called from "eval" builtin?
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   810
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   811
     * @return the return value of the {@code eval}
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   812
     */
25240
f92c14b1ca11 8047959: bindings created for declarations in eval code are not mutable
sundar
parents: 24993
diff changeset
   813
    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
   814
            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
   815
        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
   816
        final Source  source     = sourceFor(file, string, evalCall);
31192
1e019aeea9b5 8087211: Indirect evals should be strict with -strict option
sundar
parents: 30975
diff changeset
   817
        // is this direct 'eval' builtin call?
1e019aeea9b5 8087211: Indirect evals should be strict with -strict option
sundar
parents: 30975
diff changeset
   818
        final boolean directEval = evalCall && (location != UNDEFINED);
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
   819
        final Global  global = Context.getGlobal();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   820
        ScriptObject scope = initialScope;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   821
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   822
        // ECMA section 10.1.1 point 2 says eval code is strict if it begins
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   823
        // with "use strict" directive or eval direct call itself is made
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   824
        // 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
   825
        // 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
   826
        boolean strictFlag = strict || this._strict;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   827
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   828
        Class<?> clazz = null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   829
        try {
32895
5a09b2d3d73a 8138882: Performance regression due to anonymous classloading
hannesw
parents: 32893
diff changeset
   830
            clazz = compile(source, new ThrowErrorManager(), strictFlag, true);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   831
        } catch (final ParserException e) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   832
            e.throwAsEcmaException(global);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   833
            return null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   834
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   835
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   836
        if (!strictFlag) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   837
            // We need to get strict mode flag from compiled class. This is
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   838
            // because eval code may start with "use strict" directive.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   839
            try {
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 17231
diff changeset
   840
                strictFlag = clazz.getField(STRICT_MODE.symbolName()).getBoolean(null);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   841
            } catch (final NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   842
                //ignored
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   843
                strictFlag = false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   844
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   845
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   846
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   847
        // In strict mode, eval does not instantiate variables and functions
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   848
        // in the caller's environment. A new environment is created!
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   849
        if (strictFlag) {
31195
4ff0587b9ed1 8098807: Strict eval throws ClassCastException with large scripts
hannesw
parents: 31192
diff changeset
   850
            // 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
   851
            scope = newScope(scope);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   852
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   853
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
   854
        final ScriptFunction func = getProgramFunction(clazz, scope);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   855
        Object evalThis;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   856
        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
   857
            evalThis = (callThis != UNDEFINED && callThis != null) || strictFlag ? callThis : global;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   858
        } else {
31192
1e019aeea9b5 8087211: Indirect evals should be strict with -strict option
sundar
parents: 30975
diff changeset
   859
            // 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
   860
            evalThis = callThis;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   861
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   862
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   863
        return ScriptRuntime.apply(func, evalThis);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   864
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   865
31195
4ff0587b9ed1 8098807: Strict eval throws ClassCastException with large scripts
hannesw
parents: 31192
diff changeset
   866
    private static ScriptObject newScope(final ScriptObject callerScope) {
31199
17932ffc49b5 8098808: Convert Scope from interface to class
hannesw
parents: 31196
diff changeset
   867
        return new Scope(callerScope, PropertyMap.newMap(Scope.class));
31195
4ff0587b9ed1 8098807: Strict eval throws ClassCastException with large scripts
hannesw
parents: 31192
diff changeset
   868
    }
4ff0587b9ed1 8098807: Strict eval throws ClassCastException with large scripts
hannesw
parents: 31192
diff changeset
   869
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
   870
    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
   871
        if (srcStr.startsWith(prefix)) {
041afba4cec5 8012251: jjs should support -fx option
jlaskey
parents: 17233
diff changeset
   872
            final String resource = resourcePath + srcStr.substring(prefix.length());
041afba4cec5 8012251: jjs should support -fx option
jlaskey
parents: 17233
diff changeset
   873
            // 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
   874
            // 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
   875
            return AccessController.doPrivileged(
041afba4cec5 8012251: jjs should support -fx option
jlaskey
parents: 17233
diff changeset
   876
                    new PrivilegedAction<Source>() {
041afba4cec5 8012251: jjs should support -fx option
jlaskey
parents: 17233
diff changeset
   877
                        @Override
041afba4cec5 8012251: jjs should support -fx option
jlaskey
parents: 17233
diff changeset
   878
                        public Source run() {
041afba4cec5 8012251: jjs should support -fx option
jlaskey
parents: 17233
diff changeset
   879
                            try {
041afba4cec5 8012251: jjs should support -fx option
jlaskey
parents: 17233
diff changeset
   880
                                final URL resURL = Context.class.getResource(resource);
24769
attila
parents: 24759 24282
diff changeset
   881
                                return resURL != null ? sourceFor(srcStr, resURL) : null;
17244
041afba4cec5 8012251: jjs should support -fx option
jlaskey
parents: 17233
diff changeset
   882
                            } catch (final IOException exp) {
041afba4cec5 8012251: jjs should support -fx option
jlaskey
parents: 17233
diff changeset
   883
                                return null;
041afba4cec5 8012251: jjs should support -fx option
jlaskey
parents: 17233
diff changeset
   884
                            }
041afba4cec5 8012251: jjs should support -fx option
jlaskey
parents: 17233
diff changeset
   885
                        }
041afba4cec5 8012251: jjs should support -fx option
jlaskey
parents: 17233
diff changeset
   886
                    });
041afba4cec5 8012251: jjs should support -fx option
jlaskey
parents: 17233
diff changeset
   887
        }
041afba4cec5 8012251: jjs should support -fx option
jlaskey
parents: 17233
diff changeset
   888
041afba4cec5 8012251: jjs should support -fx option
jlaskey
parents: 17233
diff changeset
   889
        return null;
041afba4cec5 8012251: jjs should support -fx option
jlaskey
parents: 17233
diff changeset
   890
    }
041afba4cec5 8012251: jjs should support -fx option
jlaskey
parents: 17233
diff changeset
   891
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   892
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   893
     * Implementation of {@code load} Nashorn extension. Load a script file from a source
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   894
     * expression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   895
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   896
     * @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
   897
     * @param from   source expression for script
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   898
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   899
     * @return return value for load call (undefined)
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   900
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   901
     * @throws IOException if source cannot be found or loaded
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   902
     */
31196
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   903
    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
   904
        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
   905
        Source source = null;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   906
16230
c38c724d82e7 8008103: Source object should maintain URL of the script source as a private field
sundar
parents: 16226
diff changeset
   907
        // 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
   908
        // or a ScriptObject that has "name" and "source" (string valued) properties.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   909
        if (src instanceof String) {
16251
4a5d15b2f168 8008166: URL handling was broken on windows, causing "load" to malfunction
lagergren
parents: 16245
diff changeset
   910
            final String srcStr = (String)src;
20564
f353da961684 8025629: load function should support a way to load scripts from classpath
sundar
parents: 19895
diff changeset
   911
            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
   912
                final URL url = getResourceURL(srcStr.substring(LOAD_CLASSPATH.length()));
24769
attila
parents: 24759 24282
diff changeset
   913
                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
   914
            } else {
f353da961684 8025629: load function should support a way to load scripts from classpath
sundar
parents: 19895
diff changeset
   915
                final File file = new File(srcStr);
f353da961684 8025629: load function should support a way to load scripts from classpath
sundar
parents: 19895
diff changeset
   916
                if (srcStr.indexOf(':') != -1) {
f353da961684 8025629: load function should support a way to load scripts from classpath
sundar
parents: 19895
diff changeset
   917
                    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
   918
                        (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
   919
                        URL url;
f353da961684 8025629: load function should support a way to load scripts from classpath
sundar
parents: 19895
diff changeset
   920
                        try {
f353da961684 8025629: load function should support a way to load scripts from classpath
sundar
parents: 19895
diff changeset
   921
                            //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
   922
                            url = new URL(srcStr);
f353da961684 8025629: load function should support a way to load scripts from classpath
sundar
parents: 19895
diff changeset
   923
                        } catch (final MalformedURLException e) {
f353da961684 8025629: load function should support a way to load scripts from classpath
sundar
parents: 19895
diff changeset
   924
                            url = file.toURI().toURL();
f353da961684 8025629: load function should support a way to load scripts from classpath
sundar
parents: 19895
diff changeset
   925
                        }
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   926
                        source = sourceFor(url.toString(), url);
16254
2ed824fc93be 8008554: load was broken for URLs
lagergren
parents: 16251
diff changeset
   927
                    }
20564
f353da961684 8025629: load function should support a way to load scripts from classpath
sundar
parents: 19895
diff changeset
   928
                } else if (file.isFile()) {
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   929
                    source = sourceFor(srcStr, file);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   930
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   931
            }
16230
c38c724d82e7 8008103: Source object should maintain URL of the script source as a private field
sundar
parents: 16226
diff changeset
   932
        } 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
   933
            final File file = (File)src;
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   934
            source = sourceFor(file.getName(), file);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   935
        } 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
   936
            final URL url = (URL)src;
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   937
            source = sourceFor(url.toString(), url);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   938
        } else if (src instanceof ScriptObject) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   939
            final ScriptObject sobj = (ScriptObject)src;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   940
            if (sobj.has("script") && sobj.has("name")) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   941
                final String script = JSType.toString(sobj.get("script"));
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   942
                final String name   = JSType.toString(sobj.get("name"));
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   943
                source = sourceFor(name, script);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   944
            }
18334
47413e8d71b5 8016618: script mirror object access should be improved
sundar
parents: 18328
diff changeset
   945
        } else if (src instanceof Map) {
19097
f544a2ea40ef 8021262: Make nashorn access checks consistent with underlying dynalink
sundar
parents: 19088
diff changeset
   946
            final Map<?,?> map = (Map<?,?>)src;
18334
47413e8d71b5 8016618: script mirror object access should be improved
sundar
parents: 18328
diff changeset
   947
            if (map.containsKey("script") && map.containsKey("name")) {
47413e8d71b5 8016618: script mirror object access should be improved
sundar
parents: 18328
diff changeset
   948
                final String script = JSType.toString(map.get("script"));
47413e8d71b5 8016618: script mirror object access should be improved
sundar
parents: 18328
diff changeset
   949
                final String name   = JSType.toString(map.get("name"));
24206
40c6d45af73f 8040078: Avoid repeated reading of source for cached loads
hannesw
parents: 23767
diff changeset
   950
                source = sourceFor(name, script);
18334
47413e8d71b5 8016618: script mirror object access should be improved
sundar
parents: 18328
diff changeset
   951
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   952
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   953
16230
c38c724d82e7 8008103: Source object should maintain URL of the script source as a private field
sundar
parents: 16226
diff changeset
   954
        if (source != null) {
31196
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   955
            if (scope instanceof ScriptObject && ((ScriptObject)scope).isScope()) {
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   956
                final ScriptObject sobj = (ScriptObject)scope;
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   957
                // passed object is a script object
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   958
                // Global is the only user accessible scope ScriptObject
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   959
                assert sobj.isGlobal() : "non-Global scope object!!";
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   960
                return evaluateSource(source, sobj, sobj);
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   961
            } else if (scope == null || scope == UNDEFINED) {
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   962
                // undefined or null scope. Use current global instance.
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   963
                final Global global = getGlobal();
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   964
                return evaluateSource(source, global, global);
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   965
            } else {
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   966
                /*
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   967
                 * Arbitrary object passed for scope.
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   968
                 * Indirect load that is equivalent to:
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   969
                 *
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   970
                 *    (function(scope, source) {
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   971
                 *        with (scope) {
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   972
                 *            eval(<script_from_source>);
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   973
                 *        }
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   974
                 *    })(scope, source);
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   975
                 */
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   976
                final Global global = getGlobal();
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   977
                // 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
   978
                // (var, function) from the evaluated code go.
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   979
                // 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
   980
                // definitions are accessible to the evaluated code.
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   981
                final ScriptObject evalScope = newScope(global);
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   982
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   983
                // 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
   984
                // 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
   985
                final ScriptObject withObj = ScriptRuntime.openWith(evalScope, scope);
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   986
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   987
                // evaluate given source with 'withObj' as scope
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   988
                // but use global object as "this".
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   989
                return evaluateSource(source, withObj, global);
2ab121636a13 8098578: Global scope is not accessible with indirect load call
sundar
parents: 31195
diff changeset
   990
            }
16230
c38c724d82e7 8008103: Source object should maintain URL of the script source as a private field
sundar
parents: 16226
diff changeset
   991
        }
c38c724d82e7 8008103: Source object should maintain URL of the script source as a private field
sundar
parents: 16226
diff changeset
   992
16256
f2d9a0c49914 8007002: Replace implicit exception throwing methods with explicit throws - simplify control flow and remove useless code
lagergren
parents: 16254
diff changeset
   993
        throw typeError("cant.load.script", ScriptRuntime.safeToString(from));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   994
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   995
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   996
    /**
17974
a2818f17324e 8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents: 17524
diff changeset
   997
     * 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
   998
     * 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
   999
     *
a2818f17324e 8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents: 17524
diff changeset
  1000
     * @param from source expression for script
18321
b2ceadf211cb 8016239: loadWithNewGlobal should support user supplied arguments from the caller
sundar
parents: 17982
diff changeset
  1001
     * @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
  1002
     *
a2818f17324e 8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents: 17524
diff changeset
  1003
     * @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
  1004
     *
a2818f17324e 8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents: 17524
diff changeset
  1005
     * @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
  1006
     */
18321
b2ceadf211cb 8016239: loadWithNewGlobal should support user supplied arguments from the caller
sundar
parents: 17982
diff changeset
  1007
    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
  1008
        final Global oldGlobal = getGlobal();
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
  1009
        final Global newGlobal = AccessController.doPrivileged(new PrivilegedAction<Global>() {
17976
5615a31822a1 8015814: loadWithNewGlobal needs to wrap createGlobal in AccessController.doPrivileged
jlaskey
parents: 17974
diff changeset
  1010
           @Override
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
  1011
           public Global run() {
17976
5615a31822a1 8015814: loadWithNewGlobal needs to wrap createGlobal in AccessController.doPrivileged
jlaskey
parents: 17974
diff changeset
  1012
               try {
19459
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
  1013
                   return newGlobal();
17976
5615a31822a1 8015814: loadWithNewGlobal needs to wrap createGlobal in AccessController.doPrivileged
jlaskey
parents: 17974
diff changeset
  1014
               } catch (final RuntimeException e) {
5615a31822a1 8015814: loadWithNewGlobal needs to wrap createGlobal in AccessController.doPrivileged
jlaskey
parents: 17974
diff changeset
  1015
                   if (Context.DEBUG) {
5615a31822a1 8015814: loadWithNewGlobal needs to wrap createGlobal in AccessController.doPrivileged
jlaskey
parents: 17974
diff changeset
  1016
                       e.printStackTrace();
5615a31822a1 8015814: loadWithNewGlobal needs to wrap createGlobal in AccessController.doPrivileged
jlaskey
parents: 17974
diff changeset
  1017
                   }
5615a31822a1 8015814: loadWithNewGlobal needs to wrap createGlobal in AccessController.doPrivileged
jlaskey
parents: 17974
diff changeset
  1018
                   throw e;
5615a31822a1 8015814: loadWithNewGlobal needs to wrap createGlobal in AccessController.doPrivileged
jlaskey
parents: 17974
diff changeset
  1019
               }
5615a31822a1 8015814: loadWithNewGlobal needs to wrap createGlobal in AccessController.doPrivileged
jlaskey
parents: 17974
diff changeset
  1020
           }
19459
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
  1021
        }, CREATE_GLOBAL_ACC_CTXT);
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
  1022
        // initialize newly created Global instance
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
  1023
        initGlobal(newGlobal);
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
  1024
        setGlobal(newGlobal);
17974
a2818f17324e 8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents: 17524
diff changeset
  1025
18874
8ba96bd382d3 8020463: Input argument array wrapping in loadWithNewGlobal is wrong
sundar
parents: 18865
diff changeset
  1026
        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
  1027
        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
  1028
17974
a2818f17324e 8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents: 17524
diff changeset
  1029
        try {
18874
8ba96bd382d3 8020463: Input argument array wrapping in loadWithNewGlobal is wrong
sundar
parents: 18865
diff changeset
  1030
            // 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
  1031
            // is from oldGlobal's world, unwrap it!
8ba96bd382d3 8020463: Input argument array wrapping in loadWithNewGlobal is wrong
sundar
parents: 18865
diff changeset
  1032
            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
  1033
        } finally {
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
  1034
            setGlobal(oldGlobal);
17974
a2818f17324e 8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents: 17524
diff changeset
  1035
        }
a2818f17324e 8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents: 17524
diff changeset
  1036
    }
a2818f17324e 8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents: 17524
diff changeset
  1037
a2818f17324e 8015741: Need a global.load function that starts with a new global scope.
jlaskey
parents: 17524
diff changeset
  1038
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1039
     * 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
  1040
     * and {@link AccessorProperty} fields in them. Structure classes are used to represent ScriptObjects
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1041
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1042
     * @see ObjectClassGenerator
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1043
     * @see AccessorProperty
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1044
     * @see ScriptObject
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1045
     *
16275
d5d430071b22 8009379: Remove $ from generated class names
jlaskey
parents: 16272
diff changeset
  1046
     * @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
  1047
     *
16272
675a0caf75bc 8009263: Fix all javadoc errors in nashorn code
sundar
parents: 16262
diff changeset
  1048
     * @return the {@code Class<?>} for this structure
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1049
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1050
     * @throws ClassNotFoundException if structure class cannot be resolved
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1051
     */
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 23076
diff changeset
  1052
    @SuppressWarnings("unchecked")
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 23076
diff changeset
  1053
    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
  1054
        if (System.getSecurityManager() != null && !StructureLoader.isStructureClass(fullName)) {
19097
f544a2ea40ef 8021262: Make nashorn access checks consistent with underlying dynalink
sundar
parents: 19088
diff changeset
  1055
            throw new ClassNotFoundException(fullName);
f544a2ea40ef 8021262: Make nashorn access checks consistent with underlying dynalink
sundar
parents: 19088
diff changeset
  1056
        }
33538
82c57d427fa1 8141446: Cache Class.forName for permanently loaded classes
attila
parents: 32895
diff changeset
  1057
        return (Class<? extends ScriptObject>)structureClasses.computeIfAbsent(fullName, (name) -> {
82c57d427fa1 8141446: Cache Class.forName for permanently loaded classes
attila
parents: 32895
diff changeset
  1058
            try {
82c57d427fa1 8141446: Cache Class.forName for permanently loaded classes
attila
parents: 32895
diff changeset
  1059
                return Class.forName(name, true, sharedLoader);
82c57d427fa1 8141446: Cache Class.forName for permanently loaded classes
attila
parents: 32895
diff changeset
  1060
            } catch (final ClassNotFoundException e) {
82c57d427fa1 8141446: Cache Class.forName for permanently loaded classes
attila
parents: 32895
diff changeset
  1061
                throw new AssertionError(e);
82c57d427fa1 8141446: Cache Class.forName for permanently loaded classes
attila
parents: 32895
diff changeset
  1062
            }
82c57d427fa1 8141446: Cache Class.forName for permanently loaded classes
attila
parents: 32895
diff changeset
  1063
        });
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1064
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1065
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1066
    /**
32781
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32697
diff changeset
  1067
     * 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
  1068
     *
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32697
diff changeset
  1069
     * @param className a class name
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32697
diff changeset
  1070
     * @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
  1071
     */
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32697
diff changeset
  1072
    public static boolean isStructureClass(final String className) {
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32697
diff changeset
  1073
        return StructureLoader.isStructureClass(className);
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32697
diff changeset
  1074
    }
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32697
diff changeset
  1075
d8f34ffbbc7a 8135190: Method code too large in Babel browser.js script
hannesw
parents: 32697
diff changeset
  1076
    /**
20567
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1077
     * 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
  1078
     *
20567
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1079
     * @param clazz Class object
23374
f470afc89c6c 8015958: DataView constructor is not defined
sundar
parents: 23372
diff changeset
  1080
     * @throws SecurityException if not accessible
18865
8844964e5fc5 8020325: static property does not work on accessible, public classes
sundar
parents: 18864
diff changeset
  1081
     */
20928
3ff39d5c8c08 8026137: Fix Issues with Binary Evaluation Order
lagergren
parents: 20567
diff changeset
  1082
    public static void checkPackageAccess(final Class<?> clazz) {
20567
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1083
        final SecurityManager sm = System.getSecurityManager();
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1084
        if (sm != null) {
20928
3ff39d5c8c08 8026137: Fix Issues with Binary Evaluation Order
lagergren
parents: 20567
diff changeset
  1085
            Class<?> bottomClazz = clazz;
3ff39d5c8c08 8026137: Fix Issues with Binary Evaluation Order
lagergren
parents: 20567
diff changeset
  1086
            while (bottomClazz.isArray()) {
20567
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1087
                bottomClazz = bottomClazz.getComponentType();
18865
8844964e5fc5 8020325: static property does not work on accessible, public classes
sundar
parents: 18864
diff changeset
  1088
            }
20567
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1089
            checkPackageAccess(sm, bottomClazz.getName());
18865
8844964e5fc5 8020325: static property does not work on accessible, public classes
sundar
parents: 18864
diff changeset
  1090
        }
8844964e5fc5 8020325: static property does not work on accessible, public classes
sundar
parents: 18864
diff changeset
  1091
    }
8844964e5fc5 8020325: static property does not work on accessible, public classes
sundar
parents: 18864
diff changeset
  1092
8844964e5fc5 8020325: static property does not work on accessible, public classes
sundar
parents: 18864
diff changeset
  1093
    /**
22669
75563515567f 8032681: Issues with Nashorn
attila
parents: 22389
diff changeset
  1094
     * Checks that the given package name can be accessed from no permissions context.
75563515567f 8032681: Issues with Nashorn
attila
parents: 22389
diff changeset
  1095
     *
75563515567f 8032681: Issues with Nashorn
attila
parents: 22389
diff changeset
  1096
     * @param pkgName package name
23374
f470afc89c6c 8015958: DataView constructor is not defined
sundar
parents: 23372
diff changeset
  1097
     * @throws SecurityException if not accessible
22669
75563515567f 8032681: Issues with Nashorn
attila
parents: 22389
diff changeset
  1098
     */
75563515567f 8032681: Issues with Nashorn
attila
parents: 22389
diff changeset
  1099
    public static void checkPackageAccess(final String pkgName) {
75563515567f 8032681: Issues with Nashorn
attila
parents: 22389
diff changeset
  1100
        final SecurityManager sm = System.getSecurityManager();
75563515567f 8032681: Issues with Nashorn
attila
parents: 22389
diff changeset
  1101
        if (sm != null) {
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1102
            checkPackageAccess(sm, pkgName.endsWith(".") ? pkgName : pkgName + ".");
22669
75563515567f 8032681: Issues with Nashorn
attila
parents: 22389
diff changeset
  1103
        }
75563515567f 8032681: Issues with Nashorn
attila
parents: 22389
diff changeset
  1104
    }
75563515567f 8032681: Issues with Nashorn
attila
parents: 22389
diff changeset
  1105
75563515567f 8032681: Issues with Nashorn
attila
parents: 22389
diff changeset
  1106
    /**
19097
f544a2ea40ef 8021262: Make nashorn access checks consistent with underlying dynalink
sundar
parents: 19088
diff changeset
  1107
     * 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
  1108
     *
20567
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1109
     * @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
  1110
     * @param fullName fully qualified package name
20567
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1111
     * @throw SecurityException if not accessible
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1112
     */
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1113
    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
  1114
        Objects.requireNonNull(sm);
20567
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1115
        final int index = fullName.lastIndexOf('.');
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1116
        if (index != -1) {
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1117
            final String pkgName = fullName.substring(0, index);
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1118
            AccessController.doPrivileged(new PrivilegedAction<Void>() {
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1119
                @Override
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1120
                public Void run() {
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1121
                    sm.checkPackageAccess(pkgName);
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1122
                    return null;
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1123
                }
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1124
            }, NO_PERMISSIONS_ACC_CTXT);
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1125
        }
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1126
    }
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1127
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1128
    /**
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1129
     * Checks that the given Class can be accessed from no permissions context.
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1130
     *
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1131
     * @param clazz Class object
19088
153f268bfa72 8021122: Not all callables are handled for toString and other function valued properties
sundar
parents: 19085
diff changeset
  1132
     * @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
  1133
     */
20928
3ff39d5c8c08 8026137: Fix Issues with Binary Evaluation Order
lagergren
parents: 20567
diff changeset
  1134
    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
  1135
        try {
20567
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1136
            checkPackageAccess(clazz);
19088
153f268bfa72 8021122: Not all callables are handled for toString and other function valued properties
sundar
parents: 19085
diff changeset
  1137
            return true;
153f268bfa72 8021122: Not all callables are handled for toString and other function valued properties
sundar
parents: 19085
diff changeset
  1138
        } catch (final SecurityException se) {
153f268bfa72 8021122: Not all callables are handled for toString and other function valued properties
sundar
parents: 19085
diff changeset
  1139
            return false;
153f268bfa72 8021122: Not all callables are handled for toString and other function valued properties
sundar
parents: 19085
diff changeset
  1140
        }
153f268bfa72 8021122: Not all callables are handled for toString and other function valued properties
sundar
parents: 19085
diff changeset
  1141
    }
153f268bfa72 8021122: Not all callables are handled for toString and other function valued properties
sundar
parents: 19085
diff changeset
  1142
153f268bfa72 8021122: Not all callables are handled for toString and other function valued properties
sundar
parents: 19085
diff changeset
  1143
    /**
19097
f544a2ea40ef 8021262: Make nashorn access checks consistent with underlying dynalink
sundar
parents: 19088
diff changeset
  1144
     * 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
  1145
     *
153f268bfa72 8021122: Not all callables are handled for toString and other function valued properties
sundar
parents: 19085
diff changeset
  1146
     * @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
  1147
     * @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
  1148
     */
153f268bfa72 8021122: Not all callables are handled for toString and other function valued properties
sundar
parents: 19085
diff changeset
  1149
    public static boolean isAccessibleClass(final Class<?> clazz) {
20567
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1150
        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
  1151
    }
153f268bfa72 8021122: Not all callables are handled for toString and other function valued properties
sundar
parents: 19085
diff changeset
  1152
153f268bfa72 8021122: Not all callables are handled for toString and other function valued properties
sundar
parents: 19085
diff changeset
  1153
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1154
     * 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
  1155
     * {@code jdk.nashorn.internal.objects.NativeJava} and {@code jdk.nashorn.internal.runtime.NativeJavaPackage}
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1156
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1157
     * @param fullName full name of class to load
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1158
     *
16272
675a0caf75bc 8009263: Fix all javadoc errors in nashorn code
sundar
parents: 16262
diff changeset
  1159
     * @return the {@code Class<?>} for the name
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1160
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1161
     * @throws ClassNotFoundException if class cannot be resolved
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1162
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1163
    public Class<?> findClass(final String fullName) throws ClassNotFoundException {
20567
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1164
        if (fullName.indexOf('[') != -1 || fullName.indexOf('/') != -1) {
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1165
            // don't allow array class names or internal names.
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1166
            throw new ClassNotFoundException(fullName);
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1167
        }
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1168
26071
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
  1169
        // give chance to ClassFilter to filter out, if present
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
  1170
        if (classFilter != null && !classFilter.exposeToScripts(fullName)) {
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
  1171
            throw new ClassNotFoundException(fullName);
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
  1172
        }
430e39f6731f 8050078: Nashorn ClassFilter Support
sundar
parents: 26068
diff changeset
  1173
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1174
        // check package access as soon as possible!
20567
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1175
        final SecurityManager sm = System.getSecurityManager();
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1176
        if (sm != null) {
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1177
            checkPackageAccess(sm, fullName);
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20564
diff changeset
  1178
        }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1179
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
  1180
        // Try finding using the "app" loader.
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
  1181
        return Class.forName(fullName, true, appLoader);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1182
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1183
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1184
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1185
     * Hook to print stack trace for a {@link Throwable} that occurred during
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1186
     * execution
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1187
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1188
     * @param t throwable for which to dump stack
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1189
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1190
    public static void printStackTrace(final Throwable t) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1191
        if (Context.DEBUG) {
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
  1192
            t.printStackTrace(Context.getCurrentErr());
16147
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
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1197
     * 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
  1198
     * {@link ObjectClassGenerator} or the {@link Compiler}. If the "--verify-code" parameter
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1199
     * hasn't been given, this is a nop
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1200
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1201
     * Note that verification may load classes -- we don't want to do that unless
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1202
     * user specified verify option. We check it here even though caller
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1203
     * may have already checked that flag
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1204
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1205
     * @param bytecode bytecode to verify
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1206
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1207
    public void verify(final byte[] bytecode) {
16262
75513555e603 8008731: Separate configuration environment (options, error/output writer etc.) from Context
sundar
parents: 16256
diff changeset
  1208
        if (env._verify_code) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1209
            // No verification when security manager is around as verifier
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1210
            // may load further classes - which should be avoided.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1211
            if (System.getSecurityManager() == null) {
19098
473dfe87bb7b 8021294: --verify-code option results in AnalyzerException
sundar
parents: 19097
diff changeset
  1212
                CheckClassAdapter.verify(new ClassReader(bytecode), sharedLoader, false, new PrintWriter(System.err, true));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1213
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1214
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1215
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1216
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1217
    /**
16211
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16201
diff changeset
  1218
     * Create and initialize a new global scope object.
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16201
diff changeset
  1219
     *
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16201
diff changeset
  1220
     * @return the initialized global scope object.
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16201
diff changeset
  1221
     */
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
  1222
    public Global createGlobal() {
16211
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16201
diff changeset
  1223
        return initGlobal(newGlobal());
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16201
diff changeset
  1224
    }
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16201
diff changeset
  1225
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16201
diff changeset
  1226
    /**
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16201
diff changeset
  1227
     * Create a new uninitialized global scope object
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1228
     * @return the global script object
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1229
     */
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
  1230
    public Global newGlobal() {
27369
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1231
        createOrInvalidateGlobalConstants();
19085
066c9e5afd79 8020731: Revisit checkPermission calls in Context class
sundar
parents: 18874
diff changeset
  1232
        return new Global(this);
16211
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16201
diff changeset
  1233
    }
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16201
diff changeset
  1234
27369
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1235
    private void createOrInvalidateGlobalConstants() {
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1236
        for (;;) {
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1237
            final GlobalConstants currentGlobalConstants = getGlobalConstants();
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1238
            if (currentGlobalConstants != null) {
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1239
                // 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
  1240
                // 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
  1241
                // 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
  1242
                currentGlobalConstants.invalidateForever();
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1243
                return;
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1244
            }
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1245
            final GlobalConstants newGlobalConstants = new GlobalConstants(getLogger(GlobalConstants.class));
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1246
            if (globalConstantsRef.compareAndSet(null, newGlobalConstants)) {
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1247
                // 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
  1248
                // for this Context.
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1249
                return;
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1250
            }
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1251
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1252
            // 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
  1253
            // 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
  1254
        }
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1255
    }
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1256
16211
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16201
diff changeset
  1257
    /**
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16201
diff changeset
  1258
     * Initialize given global scope object.
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16201
diff changeset
  1259
     *
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16230
diff changeset
  1260
     * @param global the global
25422
199a23bee487 8049524: Global object initialization via javax.script API should be minimal
sundar
parents: 25243
diff changeset
  1261
     * @param engine the associated ScriptEngine instance, can be null
16211
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16201
diff changeset
  1262
     * @return the initialized global scope object.
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16201
diff changeset
  1263
     */
32893
665eb8283882 8138616: invokeFunction fails if function calls a function defined in GLOBAL_SCOPE
sundar
parents: 32786
diff changeset
  1264
    public Global initGlobal(final Global global, final ScriptEngine engine) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1265
        // 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
  1266
        if (!env._compile_only) {
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
  1267
            final Global oldGlobal = Context.getGlobal();
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
  1268
            try {
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
  1269
                Context.setGlobal(global);
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
  1270
                // initialize global scope with builtin global objects
32893
665eb8283882 8138616: invokeFunction fails if function calls a function defined in GLOBAL_SCOPE
sundar
parents: 32786
diff changeset
  1271
                global.initBuiltinObjects(engine);
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
  1272
            } finally {
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 23374
diff changeset
  1273
                Context.setGlobal(oldGlobal);
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
  1274
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1275
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1276
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1277
        return global;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1278
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1279
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1280
    /**
25422
199a23bee487 8049524: Global object initialization via javax.script API should be minimal
sundar
parents: 25243
diff changeset
  1281
     * Initialize given global scope object.
199a23bee487 8049524: Global object initialization via javax.script API should be minimal
sundar
parents: 25243
diff changeset
  1282
     *
199a23bee487 8049524: Global object initialization via javax.script API should be minimal
sundar
parents: 25243
diff changeset
  1283
     * @param global the global
199a23bee487 8049524: Global object initialization via javax.script API should be minimal
sundar
parents: 25243
diff changeset
  1284
     * @return the initialized global scope object.
199a23bee487 8049524: Global object initialization via javax.script API should be minimal
sundar
parents: 25243
diff changeset
  1285
     */
199a23bee487 8049524: Global object initialization via javax.script API should be minimal
sundar
parents: 25243
diff changeset
  1286
    public Global initGlobal(final Global global) {
32893
665eb8283882 8138616: invokeFunction fails if function calls a function defined in GLOBAL_SCOPE
sundar
parents: 32786
diff changeset
  1287
        return initGlobal(global, null);
25422
199a23bee487 8049524: Global object initialization via javax.script API should be minimal
sundar
parents: 25243
diff changeset
  1288
    }
199a23bee487 8049524: Global object initialization via javax.script API should be minimal
sundar
parents: 25243
diff changeset
  1289
199a23bee487 8049524: Global object initialization via javax.script API should be minimal
sundar
parents: 25243
diff changeset
  1290
    /**
16188
d6390b0ea32a 8006678: Avoid too many Context.getGlobal() calls
sundar
parents: 16185
diff changeset
  1291
     * Return the current global's context
d6390b0ea32a 8006678: Avoid too many Context.getGlobal() calls
sundar
parents: 16185
diff changeset
  1292
     * @return current global's context
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
  1293
     */
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
  1294
    static Context getContextTrusted() {
27369
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1295
        return getContext(getGlobal());
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
  1296
    }
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
  1297
24769
attila
parents: 24759 24282
diff changeset
  1298
    static Context getContextTrustedOrNull() {
attila
parents: 24759 24282
diff changeset
  1299
        final Global global = Context.getGlobal();
27369
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1300
        return global == null ? null : getContext(global);
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1301
    }
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1302
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1303
    private static Context getContext(final Global global) {
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1304
        // 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
  1305
        // 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
  1306
        // virtual invocation do its thing.
5a251d0063d1 8062308: Incorrect constant linkage with multiple Globals in a Context
attila
parents: 27366
diff changeset
  1307
        return ((ScriptObject)global).getContext();
24769
attila
parents: 24759 24282
diff changeset
  1308
    }
attila
parents: 24759 24282
diff changeset
  1309
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16155
diff changeset
  1310
    /**
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1311
     * Try to infer Context instance from the Class. If we cannot,
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1312
     * then get it from the thread local variable.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1313
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1314
     * @param clazz the class
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1315
     * @return context
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1316
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1317
    static Context fromClass(final Class<?> clazz) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1318
        final ClassLoader loader = clazz.getClassLoader();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1319
19895
965b12eb322e 8024619: JDBC java.sql.DriverManager is not usable from JS script
sundar
parents: 19884
diff changeset
  1320
        if (loader instanceof ScriptLoader) {
965b12eb322e 8024619: JDBC java.sql.DriverManager is not usable from JS script
sundar
parents: 19884
diff changeset
  1321
            return ((ScriptLoader)loader).getContext();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1322
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1323
19895
965b12eb322e 8024619: JDBC java.sql.DriverManager is not usable from JS script
sundar
parents: 19884
diff changeset
  1324
        return Context.getContextTrusted();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1325
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1326
20928
3ff39d5c8c08 8026137: Fix Issues with Binary Evaluation Order
lagergren
parents: 20567
diff changeset
  1327
    private URL getResourceURL(final String resName) {
33684
1bfe8ffd9baf 8141541: Simplify Nashorn's Context class loader handling
attila
parents: 33538
diff changeset
  1328
        if (appLoader != null) {
20564
f353da961684 8025629: load function should support a way to load scripts from classpath
sundar
parents: 19895
diff changeset
  1329
            return appLoader.getResource(resName);
f353da961684 8025629: load function should support a way to load scripts from classpath
sundar
parents: 19895
diff changeset
  1330
        }
33684
1bfe8ffd9baf 8141541: Simplify Nashorn's Context class loader handling
attila
parents: 33538
diff changeset
  1331
        return ClassLoader.getSystemResource(resName);
20564
f353da961684 8025629: load function should support a way to load scripts from classpath
sundar
parents: 19895
diff changeset
  1332
    }
f353da961684 8025629: load function should support a way to load scripts from classpath
sundar
parents: 19895
diff changeset
  1333
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1334
    private Object evaluateSource(final Source source, final ScriptObject scope, final ScriptObject thiz) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1335
        ScriptFunction script = null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1336
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1337
        try {
16230
c38c724d82e7 8008103: Source object should maintain URL of the script source as a private field
sundar
parents: 16226
diff changeset
  1338
            script = compileScript(source, scope, new Context.ThrowErrorManager());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1339
        } catch (final ParserException e) {
16188
d6390b0ea32a 8006678: Avoid too many Context.getGlobal() calls
sundar
parents: 16185
diff changeset
  1340
            e.throwAsEcmaException();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1341
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1342
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1343
        return ScriptRuntime.apply(script, thiz);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1344
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1345
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 23076
diff changeset
  1346
    private static ScriptFunction getProgramFunction(final Class<?> script, final ScriptObject scope) {
24879
d316854e4249 8046215: Running uncompilable scripts throws NullPointerException
hannesw
parents: 24783
diff changeset
  1347
        if (script == null) {
d316854e4249 8046215: Running uncompilable scripts throws NullPointerException
hannesw
parents: 24783
diff changeset
  1348
            return null;
d316854e4249 8046215: Running uncompilable scripts throws NullPointerException
hannesw
parents: 24783
diff changeset
  1349
        }
24783
b5c31bfe1496 8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents: 24779
diff changeset
  1350
        return invokeCreateProgramFunctionHandle(getCreateProgramFunctionHandle(script), scope);
b5c31bfe1496 8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents: 24779
diff changeset
  1351
    }
24282
2e3bd98c5664 8041697: CompiledScript slower when eval with binding
sundar
parents: 24206
diff changeset
  1352
24783
b5c31bfe1496 8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents: 24779
diff changeset
  1353
    private static MethodHandle getCreateProgramFunctionHandle(final Class<?> script) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1354
        try {
24783
b5c31bfe1496 8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents: 24779
diff changeset
  1355
            return LOOKUP.findStatic(script, CREATE_PROGRAM_FUNCTION.symbolName(), CREATE_PROGRAM_FUNCTION_TYPE);
b5c31bfe1496 8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents: 24779
diff changeset
  1356
        } catch (NoSuchMethodException | IllegalAccessException e) {
b5c31bfe1496 8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents: 24779
diff changeset
  1357
            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
  1358
        }
b5c31bfe1496 8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents: 24779
diff changeset
  1359
    }
b5c31bfe1496 8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents: 24779
diff changeset
  1360
b5c31bfe1496 8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents: 24779
diff changeset
  1361
    private static ScriptFunction invokeCreateProgramFunctionHandle(final MethodHandle createProgramFunctionHandle, final ScriptObject scope) {
b5c31bfe1496 8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents: 24779
diff changeset
  1362
        try {
b5c31bfe1496 8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents: 24779
diff changeset
  1363
            return (ScriptFunction)createProgramFunctionHandle.invokeExact(scope);
b5c31bfe1496 8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents: 24779
diff changeset
  1364
        } catch (final RuntimeException|Error e) {
b5c31bfe1496 8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents: 24779
diff changeset
  1365
            throw e;
b5c31bfe1496 8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents: 24779
diff changeset
  1366
        } catch (final Throwable t) {
b5c31bfe1496 8046014: MultiGlobalCompiledScript should cache :createProgramFunction handle
attila
parents: 24779
diff changeset
  1367
            throw new AssertionError("Failed to create a program function", t);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1368
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1369
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1370
16230
c38c724d82e7 8008103: Source object should maintain URL of the script source as a private field
sundar
parents: 16226
diff changeset
  1371
    private ScriptFunction compileScript(final Source source, final ScriptObject scope, final ErrorManager errMan) {
32895
5a09b2d3d73a 8138882: Performance regression due to anonymous classloading
hannesw
parents: 32893
diff changeset
  1372
        return getProgramFunction(compile(source, errMan, this._strict, false), scope);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1373
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1374
32895
5a09b2d3d73a 8138882: Performance regression due to anonymous classloading
hannesw
parents: 32893
diff changeset
  1375
    private synchronized Class<?> compile(final Source source, final ErrorManager errMan, final boolean strict, final boolean isEval) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1376
        // start with no errors, no warnings.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1377
        errMan.reset();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1378
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1379
        Class<?> script = findCachedClass(source);
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1380
        if (script != null) {
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1381
            final DebugLogger log = getLogger(Compiler.class);
24744
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24742
diff changeset
  1382
            if (log.isEnabled()) {
5290da85fc3d 8038426: Move all loggers from process wide scope into Global scope
lagergren
parents: 24742
diff changeset
  1383
                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
  1384
            }
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1385
            return script;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1386
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1387
26055
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25422
diff changeset
  1388
        StoredScript storedScript = null;
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
  1389
        FunctionNode functionNode = null;
30389
35e1a33f3d12 8078612: Persistent code cache should support more configurations
hannesw
parents: 30056
diff changeset
  1390
        // 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
  1391
        // 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
  1392
        // 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
  1393
        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
  1394
        final String cacheKey = useCodeStore ? CodeStore.getCacheKey("script", null) : null;
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
  1395
26055
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25422
diff changeset
  1396
        if (useCodeStore) {
26764
c777787a937d 8046202: Make persistent code store more flexible
hannesw
parents: 26508
diff changeset
  1397
            storedScript = codeStore.load(source, cacheKey);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1398
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1399
26055
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25422
diff changeset
  1400
        if (storedScript == null) {
30513
14cefab8350f 8080090: -d option should dump script source as well
sundar
parents: 30389
diff changeset
  1401
            if (env._dest_dir != null) {
14cefab8350f 8080090: -d option should dump script source as well
sundar
parents: 30389
diff changeset
  1402
                source.dump(env._dest_dir);
14cefab8350f 8080090: -d option should dump script source as well
sundar
parents: 30389
diff changeset
  1403
            }
14cefab8350f 8080090: -d option should dump script source as well
sundar
parents: 30389
diff changeset
  1404
24769
attila
parents: 24759 24282
diff changeset
  1405
            functionNode = new Parser(env, source, errMan, strict, getLogger(Parser.class)).parse();
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
  1406
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26248
diff changeset
  1407
            if (errMan.hasErrors()) {
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
  1408
                return null;
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
  1409
            }
16240
e1468b33e201 8008239: Unpublicized parts of the code generator package that were only package internal.
lagergren
parents: 16233
diff changeset
  1410
26065
d15adb218527 8055107: Extension directives to turn on callsite profiling, tracing, AST print and other debug features locally
sundar
parents: 26055
diff changeset
  1411
            if (env._print_ast || functionNode.getFlag(FunctionNode.IS_PRINT_AST)) {
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
  1412
                getErr().println(new ASTWriter(functionNode));
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
  1413
            }
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
  1414
26065
d15adb218527 8055107: Extension directives to turn on callsite profiling, tracing, AST print and other debug features locally
sundar
parents: 26055
diff changeset
  1415
            if (env._print_parse || functionNode.getFlag(FunctionNode.IS_PRINT_PARSE)) {
24769
attila
parents: 24759 24282
diff changeset
  1416
                getErr().println(new PrintVisitor(functionNode, true, false));
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
  1417
            }
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16230
diff changeset
  1418
        }
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16230
diff changeset
  1419
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 17231
diff changeset
  1420
        if (env._parse_only) {
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 17231
diff changeset
  1421
            return null;
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 17231
diff changeset
  1422
        }
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 17231
diff changeset
  1423
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16230
diff changeset
  1424
        final URL          url    = source.getURL();
23076
8660ebaaa2f2 8033924: Default permissions are not given for eval code
sundar
parents: 22669
diff changeset
  1425
        final CodeSource   cs     = new CodeSource(url, (CodeSigner[])null);
32696
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
  1426
        final CodeInstaller installer;
32895
5a09b2d3d73a 8138882: Performance regression due to anonymous classloading
hannesw
parents: 32893
diff changeset
  1427
        if (!env.useAnonymousClasses(isEval) || env._persistent_cache || !env._lazy_compilation) {
32696
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
  1428
            // 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
  1429
            final ScriptLoader loader = env._loader_per_compile ? createNewLoader() : scriptLoader;
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
  1430
            installer = new NamedContextCodeInstaller(this, cs, loader);
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
  1431
        } else {
32786
dedf2b6ea495 8136700: Make sure Context.anonymousHostClasses doesn't grow unbounded
attila
parents: 32781
diff changeset
  1432
            installer = new AnonymousContextCodeInstaller(this, cs, getAnonymousHostClass(cs));
32696
05c6d9c5eb07 8135251: Use Unsafe.defineAnonymousClass for loading Nashorn script code
attila
parents: 32534
diff changeset
  1433
        }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1434
26055
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25422
diff changeset
  1435
        if (storedScript == null) {
24769
attila
parents: 24759 24282
diff changeset
  1436
            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
  1437
32530
20aa15248117 8135262: Sanitize CodeInstaller API
attila
parents: 31199
diff changeset
  1438
            final Compiler compiler = Compiler.forInitialCompilation(
24769
attila
parents: 24759 24282
diff changeset
  1439
                    installer,
attila
parents: 24759 24282
diff changeset
  1440
                    source,
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26248
diff changeset
  1441
                    errMan,
24769
attila
parents: 24759 24282
diff changeset
  1442
                    strict | functionNode.isStrict());
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16230
diff changeset
  1443
26055
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25422
diff changeset
  1444
            final FunctionNode compiledFunction = compiler.compile(functionNode, phases);
26377
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26248
diff changeset
  1445
            if (errMan.hasErrors()) {
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26248
diff changeset
  1446
                return null;
028dad61662f 8051889: Implement block scoping in symbol assignment and scope computation
hannesw
parents: 26248
diff changeset
  1447
            }
26055
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25422
diff changeset
  1448
            script = compiledFunction.getRootClass();
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25422
diff changeset
  1449
            compiler.persistClassInfo(cacheKey, compiledFunction);
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
  1450
        } else {
26055
fe8be844ba50 8043956: Make code caching work with optimistic typing and lazy compilation
hannesw
parents: 25422
diff changeset
  1451
            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
  1452
            script = storedScript.installScript(source, installer);
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
  1453
        }
16233
95d3e01c04c3 8008199: Lazy compilation and trampoline implementation
lagergren
parents: 16230
diff changeset
  1454
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1455
        cacheClass(source, script);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1456
        return script;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1457
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1458
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1459
    private ScriptLoader createNewLoader() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1460
        return AccessController.doPrivileged(
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1461
             new PrivilegedAction<ScriptLoader>() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1462
                @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1463
                public ScriptLoader run() {
19895
965b12eb322e 8024619: JDBC java.sql.DriverManager is not usable from JS script
sundar
parents: 19884
diff changeset
  1464
                    return new ScriptLoader(appLoader, Context.this);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1465
                }
19459
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19098
diff changeset
  1466
             }, CREATE_LOADER_ACC_CTXT);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1467
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1468
18864
c701b823ed9e 8020276: interface checks in Invocable.getInterface implementation
sundar
parents: 18862
diff changeset
  1469
    private long getUniqueScriptId() {
c701b823ed9e 8020276: interface checks in Invocable.getInterface implementation
sundar
parents: 18862
diff changeset
  1470
        return uniqueScriptId.getAndIncrement();
18862
8b6a01b38cb8 8020224: LinkageError: attempted duplicate class definition when --loader-per-compiler=false
sundar
parents: 18860
diff changeset
  1471
    }
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1472
23767
7c0614b75e23 8038638: Persistent store for compiled scripts
hannesw
parents: 23375
diff changeset
  1473
    /**
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1474
     * Cache for compiled script classes.
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1475
     */
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1476
    @SuppressWarnings("serial")
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26982
diff changeset
  1477
    @Logger(name="classcache")
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26982
diff changeset
  1478
    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
  1479
        private final int size;
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1480
        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
  1481
        private final DebugLogger log;
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1482
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26982
diff changeset
  1483
        ClassCache(final Context context, final int size) {
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1484
            super(size, 0.75f, true);
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1485
            this.size = size;
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1486
            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
  1487
            this.log   = initLogger(context);
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1488
        }
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1489
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1490
        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
  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("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
  1493
            }
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1494
            put(source, new ClassReference(clazz, queue, source));
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1495
        }
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1496
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1497
        @Override
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1498
        protected boolean removeEldestEntry(final Map.Entry<Source, ClassReference> eldest) {
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1499
            return size() > size;
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1500
        }
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1501
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1502
        @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
  1503
        public ClassReference get(final Object key) {
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1504
            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
  1505
                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
  1506
                if (log.isEnabled()) {
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26982
diff changeset
  1507
                    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
  1508
                }
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26982
diff changeset
  1509
                remove(source);
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26982
diff changeset
  1510
            }
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26982
diff changeset
  1511
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26982
diff changeset
  1512
            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
  1513
            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
  1514
                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
  1515
            }
27102
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26982
diff changeset
  1516
            return ref;
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26982
diff changeset
  1517
        }
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26982
diff changeset
  1518
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26982
diff changeset
  1519
        @Override
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26982
diff changeset
  1520
        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
  1521
            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
  1522
        }
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26982
diff changeset
  1523
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26982
diff changeset
  1524
        @Override
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26982
diff changeset
  1525
        public DebugLogger getLogger() {
c64b3468d51d 8012518: Reengineer Parser.java to make it play well with the copy-on-write IR.
lagergren
parents: 26982
diff changeset
  1526
            return log;
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1527
        }
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1528
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 static class ClassReference extends SoftReference<Class<?>> {
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1532
        private final Source source;
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1533
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1534
        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
  1535
            super(clazz, queue);
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1536
            this.source = source;
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1537
        }
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1538
    }
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1539
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1540
    // Class cache management
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1541
    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
  1542
        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
  1543
        return ref != null ? ref.get() : null;
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1544
    }
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1545
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1546
    private void cacheClass(final Source source, final Class<?> clazz) {
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1547
        if (classCache != null) {
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1548
            classCache.cache(source, clazz);
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1549
        }
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1550
    }
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1551
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1552
    // logging
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1553
    private final Map<String, DebugLogger> loggers = new HashMap<>();
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1554
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1555
    private void initLoggers() {
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1556
        ((Loggable)MethodHandleFactory.getFunctionality()).initLogger(this);
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1557
    }
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1558
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1559
    /**
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1560
     * Get a logger, given a loggable class
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1561
     * @param clazz a Loggable class
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1562
     * @return debuglogger associated with that class
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1563
     */
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1564
    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
  1565
        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
  1566
    }
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
  1567
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
    /**
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
     * 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
  1570
     * @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
  1571
     * @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
  1572
     * @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
  1573
     */
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
  1574
    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
  1575
        final String name = getLoggerName(clazz);
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1576
        DebugLogger logger = loggers.get(name);
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1577
        if (logger == null) {
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1578
            if (!env.hasLogger(name)) {
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1579
                return DebugLogger.DISABLED_LOGGER;
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1580
            }
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1581
            final LoggerInfo info = env._loggers.get(name);
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1582
            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
  1583
            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
  1584
                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
  1585
            }
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1586
            loggers.put(name, logger);
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1587
        }
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1588
        return logger;
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
    /**
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1592
     * 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
  1593
     * Level.INFO is used
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1594
     *
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1595
     * @param clazz loggable
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1596
     * @param mh    method handle
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1597
     * @param text  debug printout to add
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1598
     *
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1599
     * @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
  1600
     */
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1601
    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
  1602
        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
  1603
    }
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1604
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1605
    /**
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1606
     * 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
  1607
     *
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1608
     * @param clazz            loggable
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1609
     * @param level            log level
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1610
     * @param mh               method handle
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1611
     * @param paramStart       first parameter to print
32534
b3ec7f3b3c2a 8136349: Typos patch for nashorn sources submitted on Sep 10, 2015
sundar
parents: 32530
diff changeset
  1612
     * @param printReturnValue should we print the return value?
24745
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1613
     * @param text             debug printout to add
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1614
     *
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1615
     * @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
  1616
     */
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1617
    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
  1618
        final DebugLogger log = getLogger(clazz);
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1619
        if (log.isEnabled()) {
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1620
            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
  1621
        }
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1622
        return mh;
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1623
    }
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1624
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1625
    private static String getLoggerName(final Class<?> clazz) {
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1626
        Class<?> current = clazz;
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1627
        while (current != null) {
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1628
            final Logger log = current.getAnnotation(Logger.class);
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1629
            if (log != null) {
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1630
                assert !"".equals(log.name());
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1631
                return log.name();
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1632
            }
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1633
            current = current.getSuperclass();
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1634
        }
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1635
        assert false;
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1636
        return null;
3a6e1477362b 8041434: Add synchronization to the common global constants structure
lagergren
parents: 24744
diff changeset
  1637
    }
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23076
diff changeset
  1638
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
  1639
    /**
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
  1640
     * 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
  1641
     * 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
  1642
     * 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
  1643
     */
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
  1644
    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
  1645
        //empty
26768
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
  1646
    }
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
  1647
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
  1648
    /**
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
  1649
     * 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
  1650
     * @param name key name
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
  1651
     * @return new builtin switchpoint
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
    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
  1654
        assert builtinSwitchPoints.get(name) == null;
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
  1655
        final SwitchPoint sp = new BuiltinSwitchPoint();
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
  1656
        builtinSwitchPoints.put(name, sp);
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
  1657
        return sp;
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
  1658
    }
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
  1659
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
  1660
    /**
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
  1661
     * 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
  1662
     * @param name key name
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
  1663
     * @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
  1664
     */
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
  1665
    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
  1666
        return builtinSwitchPoints.get(name);
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
  1667
    }
751b0f427090 8025435: Optimistic builtins support, implemented initial optimistic versions of push, pop, and charCodeAt
lagergren
parents: 26764
diff changeset
  1668
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
  1669
}