nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java
author attila
Fri, 21 Mar 2014 17:52:03 +0100
changeset 24727 611ba7e2101f
parent 24719 f726e9d67629
parent 23375 a1110f2cbe75
child 24731 ab0c8fc915ae
permissions -rw-r--r--
Merge
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.api.scripting;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    27
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    28
import static jdk.nashorn.internal.runtime.ECMAErrors.referenceError;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    29
import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    30
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    31
import java.io.IOException;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    32
import java.io.InputStream;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    33
import java.io.InputStreamReader;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    34
import java.io.Reader;
22669
75563515567f 8032681: Issues with Nashorn
attila
parents: 22379
diff changeset
    35
import java.lang.invoke.MethodHandles;
16528
8d20ffabe47e 8010199: javax.script.Invocable implementation for nashorn does not return null when matching functions are missing
sundar
parents: 16527
diff changeset
    36
import java.lang.reflect.Method;
18864
c701b823ed9e 8020276: interface checks in Invocable.getInterface implementation
sundar
parents: 18615
diff changeset
    37
import java.lang.reflect.Modifier;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    38
import java.net.URL;
18337
effcb00fcf58 8008915: URLReader constructor should allow specifying encoding
sundar
parents: 18335
diff changeset
    39
import java.nio.charset.Charset;
19459
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19101
diff changeset
    40
import java.security.AccessControlContext;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    41
import java.security.AccessController;
19459
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19101
diff changeset
    42
import java.security.Permissions;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    43
import java.security.PrivilegedAction;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    44
import java.security.PrivilegedActionException;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    45
import java.security.PrivilegedExceptionAction;
19459
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19101
diff changeset
    46
import java.security.ProtectionDomain;
19101
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
    47
import java.text.MessageFormat;
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
    48
import java.util.Locale;
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
    49
import java.util.ResourceBundle;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    50
import javax.script.AbstractScriptEngine;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    51
import javax.script.Bindings;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    52
import javax.script.Compilable;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    53
import javax.script.CompiledScript;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    54
import javax.script.Invocable;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    55
import javax.script.ScriptContext;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    56
import javax.script.ScriptEngine;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    57
import javax.script.ScriptEngineFactory;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    58
import javax.script.ScriptException;
19623
53207b2e3a7d 8023560: Arbitrary javax.script.Bindings objects as ENGINE_SCOPE objects are not handled as expected.
sundar
parents: 19620
diff changeset
    59
import javax.script.SimpleBindings;
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 22669
diff changeset
    60
import jdk.nashorn.internal.objects.Global;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    61
import jdk.nashorn.internal.runtime.Context;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    62
import jdk.nashorn.internal.runtime.ErrorManager;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    63
import jdk.nashorn.internal.runtime.Property;
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
    64
import jdk.nashorn.internal.runtime.ScriptEnvironment;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    65
import jdk.nashorn.internal.runtime.ScriptFunction;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    66
import jdk.nashorn.internal.runtime.ScriptObject;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    67
import jdk.nashorn.internal.runtime.ScriptRuntime;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    68
import jdk.nashorn.internal.runtime.Source;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    69
import jdk.nashorn.internal.runtime.linker.JavaAdapterFactory;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    70
import jdk.nashorn.internal.runtime.options.Options;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    71
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    72
/**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    73
 * JSR-223 compliant script engine for Nashorn. Instances are not created directly, but rather returned through
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    74
 * {@link NashornScriptEngineFactory#getScriptEngine()}. Note that this engine implements the {@link Compilable} and
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    75
 * {@link Invocable} interfaces, allowing for efficient precompilation and repeated execution of scripts.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    76
 * @see NashornScriptEngineFactory
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    77
 */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    78
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    79
public final class NashornScriptEngine extends AbstractScriptEngine implements Compilable, Invocable {
19623
53207b2e3a7d 8023560: Arbitrary javax.script.Bindings objects as ENGINE_SCOPE objects are not handled as expected.
sundar
parents: 19620
diff changeset
    80
    /**
53207b2e3a7d 8023560: Arbitrary javax.script.Bindings objects as ENGINE_SCOPE objects are not handled as expected.
sundar
parents: 19620
diff changeset
    81
     * Key used to associate Nashorn global object mirror with arbitrary Bindings instance.
53207b2e3a7d 8023560: Arbitrary javax.script.Bindings objects as ENGINE_SCOPE objects are not handled as expected.
sundar
parents: 19620
diff changeset
    82
     */
53207b2e3a7d 8023560: Arbitrary javax.script.Bindings objects as ENGINE_SCOPE objects are not handled as expected.
sundar
parents: 19620
diff changeset
    83
    public static final String NASHORN_GLOBAL = "nashorn.global";
53207b2e3a7d 8023560: Arbitrary javax.script.Bindings objects as ENGINE_SCOPE objects are not handled as expected.
sundar
parents: 19620
diff changeset
    84
19624
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
    85
    // commonly used access control context objects
19459
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19101
diff changeset
    86
    private static AccessControlContext createPermAccCtxt(final String permName) {
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19101
diff changeset
    87
        final Permissions perms = new Permissions();
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19101
diff changeset
    88
        perms.add(new RuntimePermission(permName));
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19101
diff changeset
    89
        return new AccessControlContext(new ProtectionDomain[] { new ProtectionDomain(null, perms) });
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19101
diff changeset
    90
    }
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19101
diff changeset
    91
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19101
diff changeset
    92
    private static final AccessControlContext CREATE_CONTEXT_ACC_CTXT = createPermAccCtxt(Context.NASHORN_CREATE_CONTEXT);
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19101
diff changeset
    93
    private static final AccessControlContext CREATE_GLOBAL_ACC_CTXT  = createPermAccCtxt(Context.NASHORN_CREATE_GLOBAL);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    94
19624
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
    95
    // the factory that created this engine
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    96
    private final ScriptEngineFactory factory;
19624
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
    97
    // underlying nashorn Context - 1:1 with engine instance
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    98
    private final Context             nashornContext;
19623
53207b2e3a7d 8023560: Arbitrary javax.script.Bindings objects as ENGINE_SCOPE objects are not handled as expected.
sundar
parents: 19620
diff changeset
    99
    // do we want to share single Nashorn global instance across ENGINE_SCOPEs?
53207b2e3a7d 8023560: Arbitrary javax.script.Bindings objects as ENGINE_SCOPE objects are not handled as expected.
sundar
parents: 19620
diff changeset
   100
    private final boolean             _global_per_engine;
19624
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   101
    // This is the initial default Nashorn global object.
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   102
    // This is used as "shared" global if above option is true.
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 22669
diff changeset
   103
    private final Global              global;
19624
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   104
    // initialized bit late to be made 'final'.
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   105
    // Property object for "context" property of global object.
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   106
    private volatile Property         contextProperty;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   107
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   108
    // default options passed to Nashorn Options object
22669
75563515567f 8032681: Issues with Nashorn
attila
parents: 22379
diff changeset
   109
    private static final String[] DEFAULT_OPTIONS = new String[] { "-doe" };
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   110
19624
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   111
    // Nashorn script engine error message management
19101
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   112
    private static final String MESSAGES_RESOURCE = "jdk.nashorn.api.scripting.resources.Messages";
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   113
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   114
    private static final ResourceBundle MESSAGES_BUNDLE;
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   115
    static {
19459
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19101
diff changeset
   116
        MESSAGES_BUNDLE = ResourceBundle.getBundle(MESSAGES_RESOURCE, Locale.getDefault());
19101
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   117
    }
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   118
19624
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   119
    // helper to get Nashorn script engine error message
19101
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   120
    private static String getMessage(final String msgId, final String... args) {
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   121
        try {
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   122
            return new MessageFormat(MESSAGES_BUNDLE.getString(msgId)).format(args);
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   123
        } catch (final java.util.MissingResourceException e) {
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   124
            throw new RuntimeException("no message resource found for message id: "+ msgId);
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   125
        }
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   126
    }
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   127
19624
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   128
    // load engine.js and return content as a char[]
19630
99f53f31008e 8023550: -d option was broken for any dir but '.'. Fixed Java warnings.
lagergren
parents: 19624
diff changeset
   129
    @SuppressWarnings("resource")
19624
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   130
    private static char[] loadEngineJSSource() {
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   131
        final String script = "resources/engine.js";
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   132
        try {
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   133
            final InputStream is = AccessController.doPrivileged(
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   134
                    new PrivilegedExceptionAction<InputStream>() {
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   135
                        @Override
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   136
                        public InputStream run() throws Exception {
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   137
                            final URL url = NashornScriptEngine.class.getResource(script);
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   138
                            return url.openStream();
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   139
                        }
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   140
                    });
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   141
            return Source.readFully(new InputStreamReader(is));
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   142
        } catch (final PrivilegedActionException | IOException e) {
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   143
            if (Context.DEBUG) {
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   144
                e.printStackTrace();
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   145
            }
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   146
            throw new RuntimeException(e);
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   147
        }
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   148
    }
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   149
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   150
    // Source object for engine.js
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   151
    private static final Source ENGINE_SCRIPT_SRC = new Source(NashornException.ENGINE_SCRIPT_SOURCE_NAME, loadEngineJSSource());
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   152
16197
1a5414cce91a 8007004: nashorn script engine should not use thread context class loader as script 'application loader'
sundar
parents: 16189
diff changeset
   153
    NashornScriptEngine(final NashornScriptEngineFactory factory, final ClassLoader appLoader) {
1a5414cce91a 8007004: nashorn script engine should not use thread context class loader as script 'application loader'
sundar
parents: 16189
diff changeset
   154
        this(factory, DEFAULT_OPTIONS, appLoader);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   155
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   156
16197
1a5414cce91a 8007004: nashorn script engine should not use thread context class loader as script 'application loader'
sundar
parents: 16189
diff changeset
   157
    NashornScriptEngine(final NashornScriptEngineFactory factory, final String[] args, final ClassLoader appLoader) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   158
        this.factory = factory;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   159
        final Options options = new Options("nashorn");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   160
        options.process(args);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   161
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   162
        // throw ParseException on first error from script
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16182
diff changeset
   163
        final ErrorManager errMgr = new Context.ThrowErrorManager();
16180
374e36bd1357 8006527: nashorn jsr223 engine does not work in sandbox
sundar
parents: 16172
diff changeset
   164
        // create new Nashorn Context
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   165
        this.nashornContext = AccessController.doPrivileged(new PrivilegedAction<Context>() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   166
            @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   167
            public Context run() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   168
                try {
16185
893aabe8c800 8006635: Reduce access levels as much as possible
sundar
parents: 16182
diff changeset
   169
                    return new Context(options, errMgr, appLoader);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   170
                } catch (final RuntimeException e) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   171
                    if (Context.DEBUG) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   172
                        e.printStackTrace();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   173
                    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   174
                    throw e;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   175
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   176
            }
19459
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19101
diff changeset
   177
        }, CREATE_CONTEXT_ACC_CTXT);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   178
19623
53207b2e3a7d 8023560: Arbitrary javax.script.Bindings objects as ENGINE_SCOPE objects are not handled as expected.
sundar
parents: 19620
diff changeset
   179
        // cache this option that is used often
53207b2e3a7d 8023560: Arbitrary javax.script.Bindings objects as ENGINE_SCOPE objects are not handled as expected.
sundar
parents: 19620
diff changeset
   180
        this._global_per_engine = nashornContext.getEnv()._global_per_engine;
53207b2e3a7d 8023560: Arbitrary javax.script.Bindings objects as ENGINE_SCOPE objects are not handled as expected.
sundar
parents: 19620
diff changeset
   181
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   182
        // create new global object
19624
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   183
        this.global = createNashornGlobal(context);
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   184
        // set the default ENGINE_SCOPE object for the default context
16189
38eaf01bf6d6 8006736: nashorn script engine should support the usage multiple global objects with same engine instance
sundar
parents: 16188
diff changeset
   185
        context.setBindings(new ScriptObjectMirror(global, global), ScriptContext.ENGINE_SCOPE);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   186
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   187
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   188
    @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   189
    public Object eval(final Reader reader, final ScriptContext ctxt) throws ScriptException {
20210
80d652da38ac 8024973: Using a different ScriptContext with a CompiledScript results in ScriptException
sundar
parents: 19889
diff changeset
   190
        return evalImpl(makeSource(reader, ctxt), ctxt);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   191
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   192
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   193
    @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   194
    public Object eval(final String script, final ScriptContext ctxt) throws ScriptException {
20210
80d652da38ac 8024973: Using a different ScriptContext with a CompiledScript results in ScriptException
sundar
parents: 19889
diff changeset
   195
        return evalImpl(makeSource(script, ctxt), ctxt);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   196
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   197
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   198
    @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   199
    public ScriptEngineFactory getFactory() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   200
        return factory;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   201
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   202
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   203
    @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   204
    public Bindings createBindings() {
19623
53207b2e3a7d 8023560: Arbitrary javax.script.Bindings objects as ENGINE_SCOPE objects are not handled as expected.
sundar
parents: 19620
diff changeset
   205
        if (_global_per_engine) {
53207b2e3a7d 8023560: Arbitrary javax.script.Bindings objects as ENGINE_SCOPE objects are not handled as expected.
sundar
parents: 19620
diff changeset
   206
            // just create normal SimpleBindings.
53207b2e3a7d 8023560: Arbitrary javax.script.Bindings objects as ENGINE_SCOPE objects are not handled as expected.
sundar
parents: 19620
diff changeset
   207
            // We use same 'global' for all Bindings.
53207b2e3a7d 8023560: Arbitrary javax.script.Bindings objects as ENGINE_SCOPE objects are not handled as expected.
sundar
parents: 19620
diff changeset
   208
            return new SimpleBindings();
53207b2e3a7d 8023560: Arbitrary javax.script.Bindings objects as ENGINE_SCOPE objects are not handled as expected.
sundar
parents: 19620
diff changeset
   209
        }
19630
99f53f31008e 8023550: -d option was broken for any dir but '.'. Fixed Java warnings.
lagergren
parents: 19624
diff changeset
   210
        return createGlobalMirror(null);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   211
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   212
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   213
    // Compilable methods
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   214
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   215
    @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   216
    public CompiledScript compile(final Reader reader) throws ScriptException {
20210
80d652da38ac 8024973: Using a different ScriptContext with a CompiledScript results in ScriptException
sundar
parents: 19889
diff changeset
   217
        return asCompiledScript(makeSource(reader, context));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   218
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   219
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   220
    @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   221
    public CompiledScript compile(final String str) throws ScriptException {
20210
80d652da38ac 8024973: Using a different ScriptContext with a CompiledScript results in ScriptException
sundar
parents: 19889
diff changeset
   222
        return asCompiledScript(makeSource(str, context));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   223
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   224
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   225
    // Invocable methods
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   226
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   227
    @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   228
    public Object invokeFunction(final String name, final Object... args)
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   229
            throws ScriptException, NoSuchMethodException {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   230
        return invokeImpl(null, name, args);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   231
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   232
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   233
    @Override
19101
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   234
    public Object invokeMethod(final Object thiz, final String name, final Object... args)
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   235
            throws ScriptException, NoSuchMethodException {
19101
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   236
        if (thiz == null) {
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   237
            throw new IllegalArgumentException(getMessage("thiz.cannot.be.null"));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   238
        }
19101
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   239
        return invokeImpl(thiz, name, args);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   240
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   241
19624
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   242
    @Override
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   243
    public <T> T getInterface(final Class<T> clazz) {
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   244
        return getInterfaceInner(null, clazz);
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   245
    }
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   246
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   247
    @Override
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   248
    public <T> T getInterface(final Object thiz, final Class<T> clazz) {
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   249
        if (thiz == null) {
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   250
            throw new IllegalArgumentException(getMessage("thiz.cannot.be.null"));
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   251
        }
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   252
        return getInterfaceInner(thiz, clazz);
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   253
    }
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   254
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   255
    // These are called from the "engine.js" script
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   256
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   257
    /**
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   258
     * This hook is used to search js global variables exposed from Java code.
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   259
     *
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   260
     * @param self 'this' passed from the script
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   261
     * @param ctxt current ScriptContext in which name is searched
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   262
     * @param name name of the variable searched
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   263
     * @return the value of the named variable
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   264
     */
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   265
    public Object __noSuchProperty__(final Object self, final ScriptContext ctxt, final String name) {
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   266
        if (ctxt != null) {
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   267
            final int scope = ctxt.getAttributesScope(name);
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 22669
diff changeset
   268
            final Global ctxtGlobal = getNashornGlobalFrom(ctxt);
19624
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   269
            if (scope != -1) {
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   270
                return ScriptObjectMirror.unwrap(ctxt.getAttribute(name, scope), ctxtGlobal);
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   271
            }
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   272
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   273
            if (self == UNDEFINED) {
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   274
                // scope access and so throw ReferenceError
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   275
                throw referenceError(ctxtGlobal, "not.defined", name);
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   276
            }
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   277
        }
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   278
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   279
        return UNDEFINED;
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   280
    }
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   281
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   282
    // Implementation only below this point
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   283
20210
80d652da38ac 8024973: Using a different ScriptContext with a CompiledScript results in ScriptException
sundar
parents: 19889
diff changeset
   284
    private static Source makeSource(final Reader reader, final ScriptContext ctxt) throws ScriptException {
80d652da38ac 8024973: Using a different ScriptContext with a CompiledScript results in ScriptException
sundar
parents: 19889
diff changeset
   285
        try {
80d652da38ac 8024973: Using a different ScriptContext with a CompiledScript results in ScriptException
sundar
parents: 19889
diff changeset
   286
            if (reader instanceof URLReader) {
80d652da38ac 8024973: Using a different ScriptContext with a CompiledScript results in ScriptException
sundar
parents: 19889
diff changeset
   287
                final URL url = ((URLReader)reader).getURL();
80d652da38ac 8024973: Using a different ScriptContext with a CompiledScript results in ScriptException
sundar
parents: 19889
diff changeset
   288
                final Charset cs = ((URLReader)reader).getCharset();
80d652da38ac 8024973: Using a different ScriptContext with a CompiledScript results in ScriptException
sundar
parents: 19889
diff changeset
   289
                return new Source(url.toString(), url, cs);
80d652da38ac 8024973: Using a different ScriptContext with a CompiledScript results in ScriptException
sundar
parents: 19889
diff changeset
   290
            }
20933
89748612fd1d 8026250: Logging nullpointer bugfix and javadoc warnings
lagergren
parents: 20567
diff changeset
   291
            return new Source(getScriptName(ctxt), Source.readFully(reader));
89748612fd1d 8026250: Logging nullpointer bugfix and javadoc warnings
lagergren
parents: 20567
diff changeset
   292
        } catch (final IOException e) {
89748612fd1d 8026250: Logging nullpointer bugfix and javadoc warnings
lagergren
parents: 20567
diff changeset
   293
            throw new ScriptException(e);
20210
80d652da38ac 8024973: Using a different ScriptContext with a CompiledScript results in ScriptException
sundar
parents: 19889
diff changeset
   294
        }
80d652da38ac 8024973: Using a different ScriptContext with a CompiledScript results in ScriptException
sundar
parents: 19889
diff changeset
   295
    }
80d652da38ac 8024973: Using a different ScriptContext with a CompiledScript results in ScriptException
sundar
parents: 19889
diff changeset
   296
80d652da38ac 8024973: Using a different ScriptContext with a CompiledScript results in ScriptException
sundar
parents: 19889
diff changeset
   297
    private static Source makeSource(final String src, final ScriptContext ctxt) {
80d652da38ac 8024973: Using a different ScriptContext with a CompiledScript results in ScriptException
sundar
parents: 19889
diff changeset
   298
        return new Source(getScriptName(ctxt), src);
80d652da38ac 8024973: Using a different ScriptContext with a CompiledScript results in ScriptException
sundar
parents: 19889
diff changeset
   299
    }
80d652da38ac 8024973: Using a different ScriptContext with a CompiledScript results in ScriptException
sundar
parents: 19889
diff changeset
   300
80d652da38ac 8024973: Using a different ScriptContext with a CompiledScript results in ScriptException
sundar
parents: 19889
diff changeset
   301
    private static String getScriptName(final ScriptContext ctxt) {
80d652da38ac 8024973: Using a different ScriptContext with a CompiledScript results in ScriptException
sundar
parents: 19889
diff changeset
   302
        final Object val = ctxt.getAttribute(ScriptEngine.FILENAME);
80d652da38ac 8024973: Using a different ScriptContext with a CompiledScript results in ScriptException
sundar
parents: 19889
diff changeset
   303
        return (val != null) ? val.toString() : "<eval>";
80d652da38ac 8024973: Using a different ScriptContext with a CompiledScript results in ScriptException
sundar
parents: 19889
diff changeset
   304
    }
80d652da38ac 8024973: Using a different ScriptContext with a CompiledScript results in ScriptException
sundar
parents: 19889
diff changeset
   305
19101
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   306
    private <T> T getInterfaceInner(final Object thiz, final Class<T> clazz) {
18864
c701b823ed9e 8020276: interface checks in Invocable.getInterface implementation
sundar
parents: 18615
diff changeset
   307
        if (clazz == null || !clazz.isInterface()) {
19101
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   308
            throw new IllegalArgumentException(getMessage("interface.class.expected"));
18864
c701b823ed9e 8020276: interface checks in Invocable.getInterface implementation
sundar
parents: 18615
diff changeset
   309
        }
c701b823ed9e 8020276: interface checks in Invocable.getInterface implementation
sundar
parents: 18615
diff changeset
   310
c701b823ed9e 8020276: interface checks in Invocable.getInterface implementation
sundar
parents: 18615
diff changeset
   311
        // perform security access check as early as possible
c701b823ed9e 8020276: interface checks in Invocable.getInterface implementation
sundar
parents: 18615
diff changeset
   312
        final SecurityManager sm = System.getSecurityManager();
c701b823ed9e 8020276: interface checks in Invocable.getInterface implementation
sundar
parents: 18615
diff changeset
   313
        if (sm != null) {
c701b823ed9e 8020276: interface checks in Invocable.getInterface implementation
sundar
parents: 18615
diff changeset
   314
            if (! Modifier.isPublic(clazz.getModifiers())) {
19101
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   315
                throw new SecurityException(getMessage("implementing.non.public.interface", clazz.getName()));
18864
c701b823ed9e 8020276: interface checks in Invocable.getInterface implementation
sundar
parents: 18615
diff changeset
   316
            }
20567
5621fc356049 8025771: Enhance Nashorn Contexts
sundar
parents: 20210
diff changeset
   317
            Context.checkPackageAccess(clazz);
18864
c701b823ed9e 8020276: interface checks in Invocable.getInterface implementation
sundar
parents: 18615
diff changeset
   318
        }
c701b823ed9e 8020276: interface checks in Invocable.getInterface implementation
sundar
parents: 18615
diff changeset
   319
19101
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   320
        ScriptObject realSelf = null;
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 22669
diff changeset
   321
        Global realGlobal = null;
19101
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   322
        if(thiz == null) {
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   323
            // making interface out of global functions
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   324
            realSelf = realGlobal = getNashornGlobalFrom(context);
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   325
        } else if (thiz instanceof ScriptObjectMirror) {
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   326
            final ScriptObjectMirror mirror = (ScriptObjectMirror)thiz;
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   327
            realSelf = mirror.getScriptObject();
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   328
            realGlobal = mirror.getHomeGlobal();
19884
1bacbaa1bfc7 8024180: Incorrect handling of expression and parent scope in 'with' statements
sundar
parents: 19630
diff changeset
   329
            if (! isOfContext(realGlobal, nashornContext)) {
19101
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   330
                throw new IllegalArgumentException(getMessage("script.object.from.another.engine"));
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   331
            }
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   332
        } else if (thiz instanceof ScriptObject) {
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   333
            // called from script code.
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   334
            realSelf = (ScriptObject)thiz;
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   335
            realGlobal = Context.getGlobal();
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   336
            if (realGlobal == null) {
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   337
                throw new IllegalArgumentException(getMessage("no.current.nashorn.global"));
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   338
            }
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   339
19884
1bacbaa1bfc7 8024180: Incorrect handling of expression and parent scope in 'with' statements
sundar
parents: 19630
diff changeset
   340
            if (! isOfContext(realGlobal, nashornContext)) {
19101
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   341
                throw new IllegalArgumentException(getMessage("script.object.from.another.engine"));
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   342
            }
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   343
        }
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   344
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   345
        if (realSelf == null) {
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   346
            throw new IllegalArgumentException(getMessage("interface.on.non.script.object"));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   347
        }
18864
c701b823ed9e 8020276: interface checks in Invocable.getInterface implementation
sundar
parents: 18615
diff changeset
   348
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   349
        try {
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 22669
diff changeset
   350
            final Global oldGlobal = Context.getGlobal();
19101
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   351
            final boolean globalChanged = (oldGlobal != realGlobal);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   352
            try {
19101
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   353
                if (globalChanged) {
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   354
                    Context.setGlobal(realGlobal);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   355
                }
16528
8d20ffabe47e 8010199: javax.script.Invocable implementation for nashorn does not return null when matching functions are missing
sundar
parents: 16527
diff changeset
   356
8d20ffabe47e 8010199: javax.script.Invocable implementation for nashorn does not return null when matching functions are missing
sundar
parents: 16527
diff changeset
   357
                if (! isInterfaceImplemented(clazz, realSelf)) {
8d20ffabe47e 8010199: javax.script.Invocable implementation for nashorn does not return null when matching functions are missing
sundar
parents: 16527
diff changeset
   358
                    return null;
8d20ffabe47e 8010199: javax.script.Invocable implementation for nashorn does not return null when matching functions are missing
sundar
parents: 16527
diff changeset
   359
                }
22669
75563515567f 8032681: Issues with Nashorn
attila
parents: 22379
diff changeset
   360
                return clazz.cast(JavaAdapterFactory.getConstructor(realSelf.getClass(), clazz,
75563515567f 8032681: Issues with Nashorn
attila
parents: 22379
diff changeset
   361
                        MethodHandles.publicLookup()).invoke(realSelf));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   362
            } finally {
19101
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   363
                if (globalChanged) {
19085
066c9e5afd79 8020731: Revisit checkPermission calls in Context class
sundar
parents: 18865
diff changeset
   364
                    Context.setGlobal(oldGlobal);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   365
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   366
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   367
        } catch(final RuntimeException|Error e) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   368
            throw e;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   369
        } catch(final Throwable t) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   370
            throw new RuntimeException(t);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   371
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   372
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   373
19624
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   374
    // Retrieve nashorn Global object for a given ScriptContext object
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 22669
diff changeset
   375
    private Global getNashornGlobalFrom(final ScriptContext ctxt) {
19623
53207b2e3a7d 8023560: Arbitrary javax.script.Bindings objects as ENGINE_SCOPE objects are not handled as expected.
sundar
parents: 19620
diff changeset
   376
        if (_global_per_engine) {
19624
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   377
            // shared single global object for all ENGINE_SCOPE Bindings
19623
53207b2e3a7d 8023560: Arbitrary javax.script.Bindings objects as ENGINE_SCOPE objects are not handled as expected.
sundar
parents: 19620
diff changeset
   378
            return global;
53207b2e3a7d 8023560: Arbitrary javax.script.Bindings objects as ENGINE_SCOPE objects are not handled as expected.
sundar
parents: 19620
diff changeset
   379
        }
53207b2e3a7d 8023560: Arbitrary javax.script.Bindings objects as ENGINE_SCOPE objects are not handled as expected.
sundar
parents: 19620
diff changeset
   380
16189
38eaf01bf6d6 8006736: nashorn script engine should support the usage multiple global objects with same engine instance
sundar
parents: 16188
diff changeset
   381
        final Bindings bindings = ctxt.getBindings(ScriptContext.ENGINE_SCOPE);
19623
53207b2e3a7d 8023560: Arbitrary javax.script.Bindings objects as ENGINE_SCOPE objects are not handled as expected.
sundar
parents: 19620
diff changeset
   382
        // is this Nashorn's own Bindings implementation?
16189
38eaf01bf6d6 8006736: nashorn script engine should support the usage multiple global objects with same engine instance
sundar
parents: 16188
diff changeset
   383
        if (bindings instanceof ScriptObjectMirror) {
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 22669
diff changeset
   384
            final Global glob = globalFromMirror((ScriptObjectMirror)bindings);
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 22669
diff changeset
   385
            if (glob != null) {
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 22669
diff changeset
   386
                return glob;
19620
3f0c79b63846 8023551: Mirror functions can not be invoked using invokeMethod, invokeFunction
sundar
parents: 19459
diff changeset
   387
            }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   388
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   389
19623
53207b2e3a7d 8023560: Arbitrary javax.script.Bindings objects as ENGINE_SCOPE objects are not handled as expected.
sundar
parents: 19620
diff changeset
   390
        // Arbitrary user Bindings implementation. Look for NASHORN_GLOBAL in it!
53207b2e3a7d 8023560: Arbitrary javax.script.Bindings objects as ENGINE_SCOPE objects are not handled as expected.
sundar
parents: 19620
diff changeset
   391
        Object scope = bindings.get(NASHORN_GLOBAL);
53207b2e3a7d 8023560: Arbitrary javax.script.Bindings objects as ENGINE_SCOPE objects are not handled as expected.
sundar
parents: 19620
diff changeset
   392
        if (scope instanceof ScriptObjectMirror) {
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 22669
diff changeset
   393
            final Global glob = globalFromMirror((ScriptObjectMirror)scope);
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 22669
diff changeset
   394
            if (glob != null) {
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 22669
diff changeset
   395
                return glob;
19623
53207b2e3a7d 8023560: Arbitrary javax.script.Bindings objects as ENGINE_SCOPE objects are not handled as expected.
sundar
parents: 19620
diff changeset
   396
            }
53207b2e3a7d 8023560: Arbitrary javax.script.Bindings objects as ENGINE_SCOPE objects are not handled as expected.
sundar
parents: 19620
diff changeset
   397
        }
53207b2e3a7d 8023560: Arbitrary javax.script.Bindings objects as ENGINE_SCOPE objects are not handled as expected.
sundar
parents: 19620
diff changeset
   398
53207b2e3a7d 8023560: Arbitrary javax.script.Bindings objects as ENGINE_SCOPE objects are not handled as expected.
sundar
parents: 19620
diff changeset
   399
        // We didn't find associated nashorn global mirror in the Bindings given!
53207b2e3a7d 8023560: Arbitrary javax.script.Bindings objects as ENGINE_SCOPE objects are not handled as expected.
sundar
parents: 19620
diff changeset
   400
        // Create new global instance mirror and associate with the Bindings.
19624
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   401
        final ScriptObjectMirror mirror = createGlobalMirror(ctxt);
19623
53207b2e3a7d 8023560: Arbitrary javax.script.Bindings objects as ENGINE_SCOPE objects are not handled as expected.
sundar
parents: 19620
diff changeset
   402
        bindings.put(NASHORN_GLOBAL, mirror);
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 22669
diff changeset
   403
        return mirror.getHomeGlobal();
19623
53207b2e3a7d 8023560: Arbitrary javax.script.Bindings objects as ENGINE_SCOPE objects are not handled as expected.
sundar
parents: 19620
diff changeset
   404
    }
53207b2e3a7d 8023560: Arbitrary javax.script.Bindings objects as ENGINE_SCOPE objects are not handled as expected.
sundar
parents: 19620
diff changeset
   405
19624
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   406
    // Retrieve nashorn Global object from a given ScriptObjectMirror
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 22669
diff changeset
   407
    private Global globalFromMirror(final ScriptObjectMirror mirror) {
19623
53207b2e3a7d 8023560: Arbitrary javax.script.Bindings objects as ENGINE_SCOPE objects are not handled as expected.
sundar
parents: 19620
diff changeset
   408
        ScriptObject sobj = mirror.getScriptObject();
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 22669
diff changeset
   409
        if (sobj instanceof Global && isOfContext((Global)sobj, nashornContext)) {
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 22669
diff changeset
   410
            return (Global)sobj;
19623
53207b2e3a7d 8023560: Arbitrary javax.script.Bindings objects as ENGINE_SCOPE objects are not handled as expected.
sundar
parents: 19620
diff changeset
   411
        }
53207b2e3a7d 8023560: Arbitrary javax.script.Bindings objects as ENGINE_SCOPE objects are not handled as expected.
sundar
parents: 19620
diff changeset
   412
53207b2e3a7d 8023560: Arbitrary javax.script.Bindings objects as ENGINE_SCOPE objects are not handled as expected.
sundar
parents: 19620
diff changeset
   413
        return null;
16189
38eaf01bf6d6 8006736: nashorn script engine should support the usage multiple global objects with same engine instance
sundar
parents: 16188
diff changeset
   414
    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   415
19624
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   416
    // Create a new ScriptObjectMirror wrapping a newly created Nashorn Global object
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   417
    private ScriptObjectMirror createGlobalMirror(final ScriptContext ctxt) {
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 22669
diff changeset
   418
        final Global newGlobal = createNashornGlobal(ctxt);
19624
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   419
        return new ScriptObjectMirror(newGlobal, newGlobal);
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   420
    }
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   421
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   422
    // Create a new Nashorn Global object
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 22669
diff changeset
   423
    private Global createNashornGlobal(final ScriptContext ctxt) {
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 22669
diff changeset
   424
        final Global newGlobal = AccessController.doPrivileged(new PrivilegedAction<Global>() {
16189
38eaf01bf6d6 8006736: nashorn script engine should support the usage multiple global objects with same engine instance
sundar
parents: 16188
diff changeset
   425
            @Override
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 22669
diff changeset
   426
            public Global run() {
16189
38eaf01bf6d6 8006736: nashorn script engine should support the usage multiple global objects with same engine instance
sundar
parents: 16188
diff changeset
   427
                try {
16211
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16210
diff changeset
   428
                    return nashornContext.newGlobal();
16189
38eaf01bf6d6 8006736: nashorn script engine should support the usage multiple global objects with same engine instance
sundar
parents: 16188
diff changeset
   429
                } catch (final RuntimeException e) {
38eaf01bf6d6 8006736: nashorn script engine should support the usage multiple global objects with same engine instance
sundar
parents: 16188
diff changeset
   430
                    if (Context.DEBUG) {
38eaf01bf6d6 8006736: nashorn script engine should support the usage multiple global objects with same engine instance
sundar
parents: 16188
diff changeset
   431
                        e.printStackTrace();
38eaf01bf6d6 8006736: nashorn script engine should support the usage multiple global objects with same engine instance
sundar
parents: 16188
diff changeset
   432
                    }
38eaf01bf6d6 8006736: nashorn script engine should support the usage multiple global objects with same engine instance
sundar
parents: 16188
diff changeset
   433
                    throw e;
38eaf01bf6d6 8006736: nashorn script engine should support the usage multiple global objects with same engine instance
sundar
parents: 16188
diff changeset
   434
                }
38eaf01bf6d6 8006736: nashorn script engine should support the usage multiple global objects with same engine instance
sundar
parents: 16188
diff changeset
   435
            }
19459
79e75274df99 8022707: Revisit all doPrivileged blocks
sundar
parents: 19101
diff changeset
   436
        }, CREATE_GLOBAL_ACC_CTXT);
16189
38eaf01bf6d6 8006736: nashorn script engine should support the usage multiple global objects with same engine instance
sundar
parents: 16188
diff changeset
   437
16211
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16210
diff changeset
   438
        nashornContext.initGlobal(newGlobal);
41e031a45186 8006191: `cmd` -> exec("cmd") in script mode
jlaskey
parents: 16210
diff changeset
   439
18615
3f6e6adcbc1a 8015969: Needs to enforce and document that global "context" and "engine" can't be modified when running via jsr223
sundar
parents: 18337
diff changeset
   440
        final int NON_ENUMERABLE_CONSTANT = Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE | Property.NOT_WRITABLE;
16189
38eaf01bf6d6 8006736: nashorn script engine should support the usage multiple global objects with same engine instance
sundar
parents: 16188
diff changeset
   441
        // current ScriptContext exposed as "context"
18615
3f6e6adcbc1a 8015969: Needs to enforce and document that global "context" and "engine" can't be modified when running via jsr223
sundar
parents: 18337
diff changeset
   442
        // "context" is non-writable from script - but script engine still
3f6e6adcbc1a 8015969: Needs to enforce and document that global "context" and "engine" can't be modified when running via jsr223
sundar
parents: 18337
diff changeset
   443
        // needs to set it and so save the context Property object
20210
80d652da38ac 8024973: Using a different ScriptContext with a CompiledScript results in ScriptException
sundar
parents: 19889
diff changeset
   444
        contextProperty = newGlobal.addOwnProperty("context", NON_ENUMERABLE_CONSTANT, ctxt);
16189
38eaf01bf6d6 8006736: nashorn script engine should support the usage multiple global objects with same engine instance
sundar
parents: 16188
diff changeset
   445
        // current ScriptEngine instance exposed as "engine". We added @SuppressWarnings("LeakingThisInConstructor") as
38eaf01bf6d6 8006736: nashorn script engine should support the usage multiple global objects with same engine instance
sundar
parents: 16188
diff changeset
   446
        // NetBeans identifies this assignment as such a leak - this is a false positive as we're setting this property
38eaf01bf6d6 8006736: nashorn script engine should support the usage multiple global objects with same engine instance
sundar
parents: 16188
diff changeset
   447
        // in the Global of a Context we just created - both the Context and the Global were just created and can not be
38eaf01bf6d6 8006736: nashorn script engine should support the usage multiple global objects with same engine instance
sundar
parents: 16188
diff changeset
   448
        // seen from another thread outside of this constructor.
18615
3f6e6adcbc1a 8015969: Needs to enforce and document that global "context" and "engine" can't be modified when running via jsr223
sundar
parents: 18337
diff changeset
   449
        newGlobal.addOwnProperty("engine", NON_ENUMERABLE_CONSTANT, this);
16189
38eaf01bf6d6 8006736: nashorn script engine should support the usage multiple global objects with same engine instance
sundar
parents: 16188
diff changeset
   450
        // global script arguments with undefined value
38eaf01bf6d6 8006736: nashorn script engine should support the usage multiple global objects with same engine instance
sundar
parents: 16188
diff changeset
   451
        newGlobal.addOwnProperty("arguments", Property.NOT_ENUMERABLE, UNDEFINED);
38eaf01bf6d6 8006736: nashorn script engine should support the usage multiple global objects with same engine instance
sundar
parents: 16188
diff changeset
   452
        // file name default is null
38eaf01bf6d6 8006736: nashorn script engine should support the usage multiple global objects with same engine instance
sundar
parents: 16188
diff changeset
   453
        newGlobal.addOwnProperty(ScriptEngine.FILENAME, Property.NOT_ENUMERABLE, null);
19624
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   454
        // evaluate engine.js initialization script this new global object
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   455
        try {
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   456
            evalImpl(compileImpl(ENGINE_SCRIPT_SRC, newGlobal), ctxt, newGlobal);
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   457
        } catch (final ScriptException exp) {
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   458
            throw new RuntimeException(exp);
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   459
        }
16189
38eaf01bf6d6 8006736: nashorn script engine should support the usage multiple global objects with same engine instance
sundar
parents: 16188
diff changeset
   460
        return newGlobal;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   461
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   462
19624
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   463
    // scripts should see "context" and "engine" as variables in the given global object
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 22669
diff changeset
   464
    private void setContextVariables(final Global ctxtGlobal, final ScriptContext ctxt) {
18615
3f6e6adcbc1a 8015969: Needs to enforce and document that global "context" and "engine" can't be modified when running via jsr223
sundar
parents: 18337
diff changeset
   465
        // set "context" global variable via contextProperty - because this
3f6e6adcbc1a 8015969: Needs to enforce and document that global "context" and "engine" can't be modified when running via jsr223
sundar
parents: 18337
diff changeset
   466
        // property is non-writable
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   467
        contextProperty.setValue(ctxtGlobal, ctxtGlobal, ctxt, false);
16189
38eaf01bf6d6 8006736: nashorn script engine should support the usage multiple global objects with same engine instance
sundar
parents: 16188
diff changeset
   468
        Object args = ScriptObjectMirror.unwrap(ctxt.getAttribute("arguments"), ctxtGlobal);
16182
06e8c712f6a3 8006584: improve variable handling in NashornScriptEngine
sundar
parents: 16180
diff changeset
   469
        if (args == null || args == UNDEFINED) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   470
            args = ScriptRuntime.EMPTY_ARRAY;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   471
        }
16182
06e8c712f6a3 8006584: improve variable handling in NashornScriptEngine
sundar
parents: 16180
diff changeset
   472
        // if no arguments passed, expose it
19620
3f0c79b63846 8023551: Mirror functions can not be invoked using invokeMethod, invokeFunction
sundar
parents: 19459
diff changeset
   473
        if (! (args instanceof ScriptObject)) {
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 22669
diff changeset
   474
            args = ctxtGlobal.wrapAsObject(args);
19620
3f0c79b63846 8023551: Mirror functions can not be invoked using invokeMethod, invokeFunction
sundar
parents: 19459
diff changeset
   475
            ctxtGlobal.set("arguments", args, false);
3f0c79b63846 8023551: Mirror functions can not be invoked using invokeMethod, invokeFunction
sundar
parents: 19459
diff changeset
   476
        }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   477
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   478
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   479
    private Object invokeImpl(final Object selfObject, final String name, final Object... args) throws ScriptException, NoSuchMethodException {
19099
30230d3febb8 8021252: invokeMethod throws NoSuchMethodException when script object is from different script context
sundar
parents: 19085
diff changeset
   480
        name.getClass(); // null check
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   481
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 22669
diff changeset
   482
        Global invokeGlobal = null;
19099
30230d3febb8 8021252: invokeMethod throws NoSuchMethodException when script object is from different script context
sundar
parents: 19085
diff changeset
   483
        ScriptObjectMirror selfMirror = null;
30230d3febb8 8021252: invokeMethod throws NoSuchMethodException when script object is from different script context
sundar
parents: 19085
diff changeset
   484
        if (selfObject instanceof ScriptObjectMirror) {
30230d3febb8 8021252: invokeMethod throws NoSuchMethodException when script object is from different script context
sundar
parents: 19085
diff changeset
   485
            selfMirror = (ScriptObjectMirror)selfObject;
19884
1bacbaa1bfc7 8024180: Incorrect handling of expression and parent scope in 'with' statements
sundar
parents: 19630
diff changeset
   486
            if (! isOfContext(selfMirror.getHomeGlobal(), nashornContext)) {
19101
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   487
                throw new IllegalArgumentException(getMessage("script.object.from.another.engine"));
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   488
            }
22370
c150d042ffff 8029364: NashornException to expose thrown object
sundar
parents: 20933
diff changeset
   489
            invokeGlobal = selfMirror.getHomeGlobal();
19099
30230d3febb8 8021252: invokeMethod throws NoSuchMethodException when script object is from different script context
sundar
parents: 19085
diff changeset
   490
        } else if (selfObject instanceof ScriptObject) {
30230d3febb8 8021252: invokeMethod throws NoSuchMethodException when script object is from different script context
sundar
parents: 19085
diff changeset
   491
            // invokeMethod called from script code - in which case we may get 'naked' ScriptObject
30230d3febb8 8021252: invokeMethod throws NoSuchMethodException when script object is from different script context
sundar
parents: 19085
diff changeset
   492
            // Wrap it with oldGlobal to make a ScriptObjectMirror for the same.
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 22669
diff changeset
   493
            final Global oldGlobal = Context.getGlobal();
22370
c150d042ffff 8029364: NashornException to expose thrown object
sundar
parents: 20933
diff changeset
   494
            invokeGlobal = oldGlobal;
19101
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   495
            if (oldGlobal == null) {
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   496
                throw new IllegalArgumentException(getMessage("no.current.nashorn.global"));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   497
            }
19101
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   498
19884
1bacbaa1bfc7 8024180: Incorrect handling of expression and parent scope in 'with' statements
sundar
parents: 19630
diff changeset
   499
            if (! isOfContext(oldGlobal, nashornContext)) {
19101
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   500
                throw new IllegalArgumentException(getMessage("script.object.from.another.engine"));
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   501
            }
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   502
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   503
            selfMirror = (ScriptObjectMirror)ScriptObjectMirror.wrap(selfObject, oldGlobal);
19099
30230d3febb8 8021252: invokeMethod throws NoSuchMethodException when script object is from different script context
sundar
parents: 19085
diff changeset
   504
        } else if (selfObject == null) {
30230d3febb8 8021252: invokeMethod throws NoSuchMethodException when script object is from different script context
sundar
parents: 19085
diff changeset
   505
            // selfObject is null => global function call
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 22669
diff changeset
   506
            final Global ctxtGlobal = getNashornGlobalFrom(context);
22370
c150d042ffff 8029364: NashornException to expose thrown object
sundar
parents: 20933
diff changeset
   507
            invokeGlobal = ctxtGlobal;
19099
30230d3febb8 8021252: invokeMethod throws NoSuchMethodException when script object is from different script context
sundar
parents: 19085
diff changeset
   508
            selfMirror = (ScriptObjectMirror)ScriptObjectMirror.wrap(ctxtGlobal, ctxtGlobal);
30230d3febb8 8021252: invokeMethod throws NoSuchMethodException when script object is from different script context
sundar
parents: 19085
diff changeset
   509
        }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   510
19099
30230d3febb8 8021252: invokeMethod throws NoSuchMethodException when script object is from different script context
sundar
parents: 19085
diff changeset
   511
        if (selfMirror != null) {
30230d3febb8 8021252: invokeMethod throws NoSuchMethodException when script object is from different script context
sundar
parents: 19085
diff changeset
   512
            try {
19889
63af9358d0dc 8024615: Refactor ScriptObjectMirror and JSObject to support external JSObject implementations
sundar
parents: 19884
diff changeset
   513
                return ScriptObjectMirror.translateUndefined(selfMirror.callMember(name, args));
19099
30230d3febb8 8021252: invokeMethod throws NoSuchMethodException when script object is from different script context
sundar
parents: 19085
diff changeset
   514
            } catch (final Exception e) {
30230d3febb8 8021252: invokeMethod throws NoSuchMethodException when script object is from different script context
sundar
parents: 19085
diff changeset
   515
                final Throwable cause = e.getCause();
30230d3febb8 8021252: invokeMethod throws NoSuchMethodException when script object is from different script context
sundar
parents: 19085
diff changeset
   516
                if (cause instanceof NoSuchMethodException) {
30230d3febb8 8021252: invokeMethod throws NoSuchMethodException when script object is from different script context
sundar
parents: 19085
diff changeset
   517
                    throw (NoSuchMethodException)cause;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   518
                }
22370
c150d042ffff 8029364: NashornException to expose thrown object
sundar
parents: 20933
diff changeset
   519
                throwAsScriptException(e, invokeGlobal);
19099
30230d3febb8 8021252: invokeMethod throws NoSuchMethodException when script object is from different script context
sundar
parents: 19085
diff changeset
   520
                throw new AssertionError("should not reach here");
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   521
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   522
        }
19099
30230d3febb8 8021252: invokeMethod throws NoSuchMethodException when script object is from different script context
sundar
parents: 19085
diff changeset
   523
30230d3febb8 8021252: invokeMethod throws NoSuchMethodException when script object is from different script context
sundar
parents: 19085
diff changeset
   524
        // Non-script object passed as selfObject
19101
3e6fe94f02a8 8021361: ClassCastException:.ScriptObjectMirror -> ScriptObject when getInterface called on object from different ScriptContext
sundar
parents: 19099
diff changeset
   525
        throw new IllegalArgumentException(getMessage("interface.on.non.script.object"));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   526
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   527
20210
80d652da38ac 8024973: Using a different ScriptContext with a CompiledScript results in ScriptException
sundar
parents: 19889
diff changeset
   528
    private Object evalImpl(final Source src, final ScriptContext ctxt) throws ScriptException {
80d652da38ac 8024973: Using a different ScriptContext with a CompiledScript results in ScriptException
sundar
parents: 19889
diff changeset
   529
        return evalImpl(compileImpl(src, ctxt), ctxt);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   530
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   531
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   532
    private Object evalImpl(final ScriptFunction script, final ScriptContext ctxt) throws ScriptException {
19624
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   533
        return evalImpl(script, ctxt, getNashornGlobalFrom(ctxt));
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   534
    }
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   535
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 22669
diff changeset
   536
    private Object evalImpl(final ScriptFunction script, final ScriptContext ctxt, final Global ctxtGlobal) throws ScriptException {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   537
        if (script == null) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   538
            return null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   539
        }
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 22669
diff changeset
   540
        final Global oldGlobal = Context.getGlobal();
16189
38eaf01bf6d6 8006736: nashorn script engine should support the usage multiple global objects with same engine instance
sundar
parents: 16188
diff changeset
   541
        final boolean globalChanged = (oldGlobal != ctxtGlobal);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   542
        try {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   543
            if (globalChanged) {
19085
066c9e5afd79 8020731: Revisit checkPermission calls in Context class
sundar
parents: 18865
diff changeset
   544
                Context.setGlobal(ctxtGlobal);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   545
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   546
19624
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   547
            // set ScriptContext variables if ctxt is non-null
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   548
            if (ctxt != null) {
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   549
                setContextVariables(ctxtGlobal, ctxt);
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   550
            }
17233
72ccf78a8216 8010701: Immutable nodes - final iteration
lagergren
parents: 16528
diff changeset
   551
            return ScriptObjectMirror.translateUndefined(ScriptObjectMirror.wrap(ScriptRuntime.apply(script, ctxtGlobal), ctxtGlobal));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   552
        } catch (final Exception e) {
22370
c150d042ffff 8029364: NashornException to expose thrown object
sundar
parents: 20933
diff changeset
   553
            throwAsScriptException(e, ctxtGlobal);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   554
            throw new AssertionError("should not reach here");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   555
        } finally {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   556
            if (globalChanged) {
19085
066c9e5afd79 8020731: Revisit checkPermission calls in Context class
sundar
parents: 18865
diff changeset
   557
                Context.setGlobal(oldGlobal);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   558
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   559
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   560
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   561
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 22669
diff changeset
   562
    private static void throwAsScriptException(final Exception e, final Global global) throws ScriptException {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   563
        if (e instanceof ScriptException) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   564
            throw (ScriptException)e;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   565
        } else if (e instanceof NashornException) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   566
            final NashornException ne = (NashornException)e;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   567
            final ScriptException se = new ScriptException(
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   568
                ne.getMessage(), ne.getFileName(),
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   569
                ne.getLineNumber(), ne.getColumnNumber());
22370
c150d042ffff 8029364: NashornException to expose thrown object
sundar
parents: 20933
diff changeset
   570
            ne.initEcmaError(global);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   571
            se.initCause(e);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   572
            throw se;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   573
        } else if (e instanceof RuntimeException) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   574
            throw (RuntimeException)e;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   575
        } else {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   576
            // wrap any other exception as ScriptException
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   577
            throw new ScriptException(e);
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   578
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   579
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   580
20210
80d652da38ac 8024973: Using a different ScriptContext with a CompiledScript results in ScriptException
sundar
parents: 19889
diff changeset
   581
    private CompiledScript asCompiledScript(final Source source) throws ScriptException {
80d652da38ac 8024973: Using a different ScriptContext with a CompiledScript results in ScriptException
sundar
parents: 19889
diff changeset
   582
        final ScriptFunction func = compileImpl(source, context);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   583
        return new CompiledScript() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   584
            @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   585
            public Object eval(final ScriptContext ctxt) throws ScriptException {
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 22669
diff changeset
   586
                final Global globalObject = getNashornGlobalFrom(ctxt);
20210
80d652da38ac 8024973: Using a different ScriptContext with a CompiledScript results in ScriptException
sundar
parents: 19889
diff changeset
   587
                // Are we running the script in the correct global?
20933
89748612fd1d 8026250: Logging nullpointer bugfix and javadoc warnings
lagergren
parents: 20567
diff changeset
   588
                if (func.getScope() == globalObject) {
89748612fd1d 8026250: Logging nullpointer bugfix and javadoc warnings
lagergren
parents: 20567
diff changeset
   589
                    return evalImpl(func, ctxt, globalObject);
20210
80d652da38ac 8024973: Using a different ScriptContext with a CompiledScript results in ScriptException
sundar
parents: 19889
diff changeset
   590
                }
20933
89748612fd1d 8026250: Logging nullpointer bugfix and javadoc warnings
lagergren
parents: 20567
diff changeset
   591
                // ScriptContext with a different global. Compile again!
89748612fd1d 8026250: Logging nullpointer bugfix and javadoc warnings
lagergren
parents: 20567
diff changeset
   592
                // Note that we may still hit per-global compilation cache.
89748612fd1d 8026250: Logging nullpointer bugfix and javadoc warnings
lagergren
parents: 20567
diff changeset
   593
                return evalImpl(compileImpl(source, ctxt), ctxt, globalObject);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   594
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   595
            @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   596
            public ScriptEngine getEngine() {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   597
                return NashornScriptEngine.this;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   598
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   599
        };
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   600
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   601
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   602
    /**
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   603
     * Check if the global script environment tells us to do optimistic
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   604
     * compilation
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   605
     * @return true if optimistic compilation enabled
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   606
     */
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   607
    public static boolean isOptimistic() {
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   608
        return ScriptEnvironment.globalOptimistic();
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   609
    }
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 22669
diff changeset
   610
16243
f5fdf89e1583 8008305: ScriptEngine.eval should offer the ability to provide a codebase
sundar
parents: 16232
diff changeset
   611
    private ScriptFunction compileImpl(final Source source, final ScriptContext ctxt) throws ScriptException {
19624
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   612
        return compileImpl(source, getNashornGlobalFrom(ctxt));
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   613
    }
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   614
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 22669
diff changeset
   615
    private ScriptFunction compileImpl(final Source source, final Global newGlobal) throws ScriptException {
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 22669
diff changeset
   616
        final Global oldGlobal = Context.getGlobal();
19624
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   617
        final boolean globalChanged = (oldGlobal != newGlobal);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   618
        try {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   619
            if (globalChanged) {
19624
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   620
                Context.setGlobal(newGlobal);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   621
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   622
19624
976b3bfbd657 8023631: engine.js init script should be loaded into every global instance created by engines
sundar
parents: 19623
diff changeset
   623
            return nashornContext.compileScript(source, newGlobal);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   624
        } catch (final Exception e) {
22370
c150d042ffff 8029364: NashornException to expose thrown object
sundar
parents: 20933
diff changeset
   625
            throwAsScriptException(e, newGlobal);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   626
            throw new AssertionError("should not reach here");
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   627
        } finally {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   628
            if (globalChanged) {
19085
066c9e5afd79 8020731: Revisit checkPermission calls in Context class
sundar
parents: 18865
diff changeset
   629
                Context.setGlobal(oldGlobal);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   630
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   631
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   632
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   633
16528
8d20ffabe47e 8010199: javax.script.Invocable implementation for nashorn does not return null when matching functions are missing
sundar
parents: 16527
diff changeset
   634
    private static boolean isInterfaceImplemented(final Class<?> iface, final ScriptObject sobj) {
8d20ffabe47e 8010199: javax.script.Invocable implementation for nashorn does not return null when matching functions are missing
sundar
parents: 16527
diff changeset
   635
        for (final Method method : iface.getMethods()) {
8d20ffabe47e 8010199: javax.script.Invocable implementation for nashorn does not return null when matching functions are missing
sundar
parents: 16527
diff changeset
   636
            // ignore methods of java.lang.Object class
8d20ffabe47e 8010199: javax.script.Invocable implementation for nashorn does not return null when matching functions are missing
sundar
parents: 16527
diff changeset
   637
            if (method.getDeclaringClass() == Object.class) {
8d20ffabe47e 8010199: javax.script.Invocable implementation for nashorn does not return null when matching functions are missing
sundar
parents: 16527
diff changeset
   638
                continue;
8d20ffabe47e 8010199: javax.script.Invocable implementation for nashorn does not return null when matching functions are missing
sundar
parents: 16527
diff changeset
   639
            }
8d20ffabe47e 8010199: javax.script.Invocable implementation for nashorn does not return null when matching functions are missing
sundar
parents: 16527
diff changeset
   640
22379
5181d08e3440 8031359: Invocable.getInterface() works incorrectly if interface has default methods
sundar
parents: 22370
diff changeset
   641
            // skip check for default methods - non-abstract, interface methods
5181d08e3440 8031359: Invocable.getInterface() works incorrectly if interface has default methods
sundar
parents: 22370
diff changeset
   642
            if (! Modifier.isAbstract(method.getModifiers())) {
5181d08e3440 8031359: Invocable.getInterface() works incorrectly if interface has default methods
sundar
parents: 22370
diff changeset
   643
                continue;
5181d08e3440 8031359: Invocable.getInterface() works incorrectly if interface has default methods
sundar
parents: 22370
diff changeset
   644
            }
5181d08e3440 8031359: Invocable.getInterface() works incorrectly if interface has default methods
sundar
parents: 22370
diff changeset
   645
16528
8d20ffabe47e 8010199: javax.script.Invocable implementation for nashorn does not return null when matching functions are missing
sundar
parents: 16527
diff changeset
   646
            Object obj = sobj.get(method.getName());
8d20ffabe47e 8010199: javax.script.Invocable implementation for nashorn does not return null when matching functions are missing
sundar
parents: 16527
diff changeset
   647
            if (! (obj instanceof ScriptFunction)) {
8d20ffabe47e 8010199: javax.script.Invocable implementation for nashorn does not return null when matching functions are missing
sundar
parents: 16527
diff changeset
   648
                return false;
8d20ffabe47e 8010199: javax.script.Invocable implementation for nashorn does not return null when matching functions are missing
sundar
parents: 16527
diff changeset
   649
            }
8d20ffabe47e 8010199: javax.script.Invocable implementation for nashorn does not return null when matching functions are missing
sundar
parents: 16527
diff changeset
   650
        }
8d20ffabe47e 8010199: javax.script.Invocable implementation for nashorn does not return null when matching functions are missing
sundar
parents: 16527
diff changeset
   651
        return true;
8d20ffabe47e 8010199: javax.script.Invocable implementation for nashorn does not return null when matching functions are missing
sundar
parents: 16527
diff changeset
   652
    }
19884
1bacbaa1bfc7 8024180: Incorrect handling of expression and parent scope in 'with' statements
sundar
parents: 19630
diff changeset
   653
23375
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 22669
diff changeset
   654
    private static boolean isOfContext(final Global global, final Context context) {
a1110f2cbe75 8037400: Remove getInitialMap getters and GlobalObject interface
sundar
parents: 22669
diff changeset
   655
        return global.isOfContext(context);
19884
1bacbaa1bfc7 8024180: Incorrect handling of expression and parent scope in 'with' statements
sundar
parents: 19630
diff changeset
   656
    }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   657
}