src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/WithObject.java
author hannesw
Mon, 23 Oct 2017 13:03:01 +0200
changeset 47437 54a2f246edd8
parent 47216 71c04702a3d5
permissions -rw-r--r--
8165198: Inconsistent values with JavaImporter after accessing undefined variable Reviewed-by: sundar, hannesw Contributed-by: priya.lakshmi.muthuswamy@oracle.com
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     1
/*
16151
97c1e756ae1e 8005663: Update copyright year to 2013
jlaskey
parents: 16147
diff changeset
     2
 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     4
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    10
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    15
 * accompanied this code).
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    16
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    20
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    23
 * questions.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    24
 */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    25
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    26
package jdk.nashorn.internal.runtime;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    27
16277
fd698c5ee684 8009559: clean up method handle lookup code.
sundar
parents: 16264
diff changeset
    28
import static jdk.nashorn.internal.lookup.Lookup.MH;
32694
da2f35ab2ea6 8136544: Call site switching to megamorphic causes incorrect property read
sundar
parents: 32527
diff changeset
    29
import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    30
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    31
import java.lang.invoke.MethodHandle;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    32
import java.lang.invoke.MethodHandles;
16780
f23743ec1a93 8011555: Invalid class name in with block with JavaImporter causes MH type mismatch
attila
parents: 16277
diff changeset
    33
import java.lang.invoke.MethodType;
19884
1bacbaa1bfc7 8024180: Incorrect handling of expression and parent scope in 'with' statements
sundar
parents: 19621
diff changeset
    34
import java.lang.invoke.SwitchPoint;
34447
ec4c069f9436 8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents: 33690
diff changeset
    35
import jdk.dynalink.CallSiteDescriptor;
ec4c069f9436 8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents: 33690
diff changeset
    36
import jdk.dynalink.NamedOperation;
ec4c069f9436 8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents: 33690
diff changeset
    37
import jdk.dynalink.Operation;
ec4c069f9436 8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents: 33690
diff changeset
    38
import jdk.dynalink.StandardOperation;
ec4c069f9436 8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents: 33690
diff changeset
    39
import jdk.dynalink.linker.GuardedInvocation;
ec4c069f9436 8141338: Move jdk.internal.dynalink package to jdk.dynalink
attila
parents: 33690
diff changeset
    40
import jdk.dynalink.linker.LinkRequest;
25821
fbb51e67d2a7 8048869: Reduce compile time by about 5% by removing the Class.casts from the AST nodes
lagergren
parents: 25247
diff changeset
    41
import jdk.nashorn.api.scripting.AbstractJSObject;
fbb51e67d2a7 8048869: Reduce compile time by about 5% by removing the Class.casts from the AST nodes
lagergren
parents: 25247
diff changeset
    42
import jdk.nashorn.api.scripting.ScriptObjectMirror;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    43
import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
23084
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 20933
diff changeset
    44
import jdk.nashorn.internal.runtime.linker.NashornGuards;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    45
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    46
/**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    47
 * This class supports the handling of scope in a with body.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    48
 *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    49
 */
31199
17932ffc49b5 8098808: Convert Scope from interface to class
hannesw
parents: 31194
diff changeset
    50
public final class WithObject extends Scope {
32695
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32694
diff changeset
    51
    private static final MethodHandle WITHEXPRESSIONGUARD    = findOwnMH("withExpressionGuard",  boolean.class, Object.class, PropertyMap.class, SwitchPoint[].class);
16780
f23743ec1a93 8011555: Invalid class name in with block with JavaImporter causes MH type mismatch
attila
parents: 16277
diff changeset
    52
    private static final MethodHandle WITHEXPRESSIONFILTER   = findOwnMH("withFilterExpression", Object.class, Object.class);
f23743ec1a93 8011555: Invalid class name in with block with JavaImporter causes MH type mismatch
attila
parents: 16277
diff changeset
    53
    private static final MethodHandle WITHSCOPEFILTER        = findOwnMH("withFilterScope",      Object.class, Object.class);
f23743ec1a93 8011555: Invalid class name in with block with JavaImporter causes MH type mismatch
attila
parents: 16277
diff changeset
    54
    private static final MethodHandle BIND_TO_EXPRESSION_OBJ = findOwnMH("bindToExpression",     Object.class, Object.class, Object.class);
f23743ec1a93 8011555: Invalid class name in with block with JavaImporter causes MH type mismatch
attila
parents: 16277
diff changeset
    55
    private static final MethodHandle BIND_TO_EXPRESSION_FN  = findOwnMH("bindToExpression",     Object.class, ScriptFunction.class, Object.class);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    56
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    57
    /** With expression object. */
19884
1bacbaa1bfc7 8024180: Incorrect handling of expression and parent scope in 'with' statements
sundar
parents: 19621
diff changeset
    58
    private final ScriptObject expression;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    59
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    60
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    61
     * Constructor
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    62
     *
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    63
     * @param scope scope object
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    64
     * @param expression with expression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    65
     */
19884
1bacbaa1bfc7 8024180: Incorrect handling of expression and parent scope in 'with' statements
sundar
parents: 19621
diff changeset
    66
    WithObject(final ScriptObject scope, final ScriptObject expression) {
19085
066c9e5afd79 8020731: Revisit checkPermission calls in Context class
sundar
parents: 17236
diff changeset
    67
        super(scope, null);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    68
        this.expression = expression;
39900
a9ad93ab3f6d 8160034: The `this` value in the `with` is broken by the repetition of a function call
hannesw
parents: 39164
diff changeset
    69
        setIsInternal();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    70
    }
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
     * Delete a property based on a key.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    74
     * @param key Any valid JavaScript value.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    75
     * @param strict strict mode execution.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    76
     * @return True if deleted.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    77
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    78
    @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    79
    public boolean delete(final Object key, final boolean strict) {
19884
1bacbaa1bfc7 8024180: Incorrect handling of expression and parent scope in 'with' statements
sundar
parents: 19621
diff changeset
    80
        final ScriptObject self = expression;
1bacbaa1bfc7 8024180: Incorrect handling of expression and parent scope in 'with' statements
sundar
parents: 19621
diff changeset
    81
        final String propName = JSType.toString(key);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    82
19884
1bacbaa1bfc7 8024180: Incorrect handling of expression and parent scope in 'with' statements
sundar
parents: 19621
diff changeset
    83
        final FindProperty find = self.findProperty(propName, true);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    84
19884
1bacbaa1bfc7 8024180: Incorrect handling of expression and parent scope in 'with' statements
sundar
parents: 19621
diff changeset
    85
        if (find != null) {
1bacbaa1bfc7 8024180: Incorrect handling of expression and parent scope in 'with' statements
sundar
parents: 19621
diff changeset
    86
            return self.delete(propName, strict);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    87
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    88
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    89
        return false;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    90
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    91
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    92
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
    93
    @Override
16195
3f6c0ab2597a 8006766: Array-like access to characters of a string is slow
hannesw
parents: 16173
diff changeset
    94
    public GuardedInvocation lookup(final CallSiteDescriptor desc, final LinkRequest request) {
23372
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23084
diff changeset
    95
        if (request.isCallSiteUnstable()) {
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23084
diff changeset
    96
            // Fall back to megamorphic invocation which performs a complete lookup each time without further relinking.
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23084
diff changeset
    97
            return super.lookup(desc, request);
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23084
diff changeset
    98
        }
09707b3e5fb0 8021350: Share script classes between threads/globals within context
hannesw
parents: 23084
diff changeset
    99
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   100
        GuardedInvocation link = null;
33343
23abd10384a5 8139931: Introduce Operation objects in Dynalink instead of string encoding
attila
parents: 33330
diff changeset
   101
        final Operation op = desc.getOperation();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   102
39900
a9ad93ab3f6d 8160034: The `this` value in the `with` is broken by the repetition of a function call
hannesw
parents: 39164
diff changeset
   103
        assert op instanceof NamedOperation; // WithObject is a scope object, access is always named
a9ad93ab3f6d 8160034: The `this` value in the `with` is broken by the repetition of a function call
hannesw
parents: 39164
diff changeset
   104
        final String name = ((NamedOperation)op).getName().toString();
a9ad93ab3f6d 8160034: The `this` value in the `with` is broken by the repetition of a function call
hannesw
parents: 39164
diff changeset
   105
a9ad93ab3f6d 8160034: The `this` value in the `with` is broken by the repetition of a function call
hannesw
parents: 39164
diff changeset
   106
        FindProperty find = expression.findProperty(name, true);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   107
19884
1bacbaa1bfc7 8024180: Incorrect handling of expression and parent scope in 'with' statements
sundar
parents: 19621
diff changeset
   108
        if (find != null) {
39900
a9ad93ab3f6d 8160034: The `this` value in the `with` is broken by the repetition of a function call
hannesw
parents: 39164
diff changeset
   109
            link = expression.lookup(desc, request);
19884
1bacbaa1bfc7 8024180: Incorrect handling of expression and parent scope in 'with' statements
sundar
parents: 19621
diff changeset
   110
            if (link != null) {
41842
50202a344d28 8168005: Introduce namespaces for GET, SET Dynalink operations
attila
parents: 41422
diff changeset
   111
                return fixExpressionCallSite(desc, link);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   112
            }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   113
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   114
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   115
        final ScriptObject scope = getProto();
39900
a9ad93ab3f6d 8160034: The `this` value in the `with` is broken by the repetition of a function call
hannesw
parents: 39164
diff changeset
   116
        find = scope.findProperty(name, true);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   117
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   118
        if (find != null) {
23084
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 20933
diff changeset
   119
            return fixScopeCallSite(scope.lookup(desc, request), name, find.getOwner());
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   120
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   121
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   122
        // the property is not found - now check for
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   123
        // __noSuchProperty__ and __noSuchMethod__ in expression
39900
a9ad93ab3f6d 8160034: The `this` value in the `with` is broken by the repetition of a function call
hannesw
parents: 39164
diff changeset
   124
        final String fallBack;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   125
41842
50202a344d28 8168005: Introduce namespaces for GET, SET Dynalink operations
attila
parents: 41422
diff changeset
   126
        final Operation firstOp = NashornCallSiteDescriptor.getBaseOperation(desc);
50202a344d28 8168005: Introduce namespaces for GET, SET Dynalink operations
attila
parents: 41422
diff changeset
   127
        if (firstOp == StandardOperation.GET) {
50202a344d28 8168005: Introduce namespaces for GET, SET Dynalink operations
attila
parents: 41422
diff changeset
   128
            if (NashornCallSiteDescriptor.isMethodFirstOperation(desc)) {
50202a344d28 8168005: Introduce namespaces for GET, SET Dynalink operations
attila
parents: 41422
diff changeset
   129
                fallBack = NO_SUCH_METHOD_NAME;
50202a344d28 8168005: Introduce namespaces for GET, SET Dynalink operations
attila
parents: 41422
diff changeset
   130
            } else {
50202a344d28 8168005: Introduce namespaces for GET, SET Dynalink operations
attila
parents: 41422
diff changeset
   131
                fallBack = NO_SUCH_PROPERTY_NAME;
50202a344d28 8168005: Introduce namespaces for GET, SET Dynalink operations
attila
parents: 41422
diff changeset
   132
            }
50202a344d28 8168005: Introduce namespaces for GET, SET Dynalink operations
attila
parents: 41422
diff changeset
   133
        } else {
39900
a9ad93ab3f6d 8160034: The `this` value in the `with` is broken by the repetition of a function call
hannesw
parents: 39164
diff changeset
   134
            fallBack = null;
a9ad93ab3f6d 8160034: The `this` value in the `with` is broken by the repetition of a function call
hannesw
parents: 39164
diff changeset
   135
        }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   136
39900
a9ad93ab3f6d 8160034: The `this` value in the `with` is broken by the repetition of a function call
hannesw
parents: 39164
diff changeset
   137
        if (fallBack != null) {
a9ad93ab3f6d 8160034: The `this` value in the `with` is broken by the repetition of a function call
hannesw
parents: 39164
diff changeset
   138
            find = expression.findProperty(fallBack, true);
a9ad93ab3f6d 8160034: The `this` value in the `with` is broken by the repetition of a function call
hannesw
parents: 39164
diff changeset
   139
            if (find != null) {
41842
50202a344d28 8168005: Introduce namespaces for GET, SET Dynalink operations
attila
parents: 41422
diff changeset
   140
                if (NO_SUCH_METHOD_NAME.equals(fallBack)) {
47437
54a2f246edd8 8165198: Inconsistent values with JavaImporter after accessing undefined variable
hannesw
parents: 47216
diff changeset
   141
                    link = expression.noSuchMethod(desc, request).addSwitchPoint(getProtoSwitchPoint(name));
41842
50202a344d28 8168005: Introduce namespaces for GET, SET Dynalink operations
attila
parents: 41422
diff changeset
   142
                } else if (NO_SUCH_PROPERTY_NAME.equals(fallBack)) {
47437
54a2f246edd8 8165198: Inconsistent values with JavaImporter after accessing undefined variable
hannesw
parents: 47216
diff changeset
   143
                    link = expression.noSuchProperty(desc, request).addSwitchPoint(getProtoSwitchPoint(name));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   144
                }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   145
            }
39900
a9ad93ab3f6d 8160034: The `this` value in the `with` is broken by the repetition of a function call
hannesw
parents: 39164
diff changeset
   146
        }
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   147
39900
a9ad93ab3f6d 8160034: The `this` value in the `with` is broken by the repetition of a function call
hannesw
parents: 39164
diff changeset
   148
        if (link != null) {
41842
50202a344d28 8168005: Introduce namespaces for GET, SET Dynalink operations
attila
parents: 41422
diff changeset
   149
            return fixExpressionCallSite(desc, link);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   150
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   151
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   152
        // still not found, may be scope can handle with it's own
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   153
        // __noSuchProperty__, __noSuchMethod__ etc.
16195
3f6c0ab2597a 8006766: Array-like access to characters of a string is slow
hannesw
parents: 16173
diff changeset
   154
        link = scope.lookup(desc, request);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   155
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   156
        if (link != null) {
23084
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 20933
diff changeset
   157
            return fixScopeCallSite(link, name, null);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   158
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   159
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   160
        return null;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   161
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   162
16264
e0c3c97cd93e 8006984: Introducing local into a function inside with statement confuses its scope
attila
parents: 16234
diff changeset
   163
    /**
e0c3c97cd93e 8006984: Introducing local into a function inside with statement confuses its scope
attila
parents: 16234
diff changeset
   164
     * Overridden to try to find the property first in the expression object (and its prototypes), and only then in this
e0c3c97cd93e 8006984: Introducing local into a function inside with statement confuses its scope
attila
parents: 16234
diff changeset
   165
     * object (and its prototypes).
e0c3c97cd93e 8006984: Introducing local into a function inside with statement confuses its scope
attila
parents: 16234
diff changeset
   166
     *
e0c3c97cd93e 8006984: Introducing local into a function inside with statement confuses its scope
attila
parents: 16234
diff changeset
   167
     * @param key  Property key.
e0c3c97cd93e 8006984: Introducing local into a function inside with statement confuses its scope
attila
parents: 16234
diff changeset
   168
     * @param deep Whether the search should look up proto chain.
39164
d40cf0f38270 8159977: typeof operator does not see lexical bindings declared in other scripts
hannesw
parents: 34447
diff changeset
   169
     * @param isScope true if is this a scope access
16264
e0c3c97cd93e 8006984: Introducing local into a function inside with statement confuses its scope
attila
parents: 16234
diff changeset
   170
     * @param start the object on which the lookup was originally initiated
e0c3c97cd93e 8006984: Introducing local into a function inside with statement confuses its scope
attila
parents: 16234
diff changeset
   171
     * @return FindPropertyData or null if not found.
e0c3c97cd93e 8006984: Introducing local into a function inside with statement confuses its scope
attila
parents: 16234
diff changeset
   172
     */
e0c3c97cd93e 8006984: Introducing local into a function inside with statement confuses its scope
attila
parents: 16234
diff changeset
   173
    @Override
41422
97eda72f53b6 8167117: insert missing final keywords
attila
parents: 39900
diff changeset
   174
    protected FindProperty findProperty(final Object key, final boolean deep, final boolean isScope, final ScriptObject start) {
26765
97501edd2979 8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents: 26068
diff changeset
   175
        // We call findProperty on 'expression' with 'expression' itself as start parameter.
97501edd2979 8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents: 26068
diff changeset
   176
        // This way in ScriptObject.setObject we can tell the property is from a 'with' expression
97501edd2979 8047764: Indexed or polymorphic set on global affects Object.prototype
hannesw
parents: 26068
diff changeset
   177
        // (as opposed from another non-scope object in the proto chain such as Object.prototype).
39164
d40cf0f38270 8159977: typeof operator does not see lexical bindings declared in other scripts
hannesw
parents: 34447
diff changeset
   178
        final FindProperty exprProperty = expression.findProperty(key, true, false, expression);
19884
1bacbaa1bfc7 8024180: Incorrect handling of expression and parent scope in 'with' statements
sundar
parents: 19621
diff changeset
   179
        if (exprProperty != null) {
39900
a9ad93ab3f6d 8160034: The `this` value in the `with` is broken by the repetition of a function call
hannesw
parents: 39164
diff changeset
   180
            return exprProperty;
16264
e0c3c97cd93e 8006984: Introducing local into a function inside with statement confuses its scope
attila
parents: 16234
diff changeset
   181
        }
39164
d40cf0f38270 8159977: typeof operator does not see lexical bindings declared in other scripts
hannesw
parents: 34447
diff changeset
   182
        return super.findProperty(key, deep, isScope, start);
16264
e0c3c97cd93e 8006984: Introducing local into a function inside with statement confuses its scope
attila
parents: 16234
diff changeset
   183
    }
e0c3c97cd93e 8006984: Introducing local into a function inside with statement confuses its scope
attila
parents: 16234
diff changeset
   184
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   185
    @Override
33690
46a1bc24cf2c 8141702: Add support for Symbol property keys
hannesw
parents: 33343
diff changeset
   186
    protected Object invokeNoSuchProperty(final Object key, final boolean isScope, final int programPoint) {
33330
35531ae624ef 8139304: Remove elaborate call site descriptor class hierarchy and factory for them. Remove AutoDiscovery, DefaultPrelinkFilter, and BottomGuardingDynamicLinker as they can be inlined into DynamicLinkerFactory. Remove CallerSensitiveDetector as it can be inlined into AbstractJavaLinker. Make ClassMap non-public.
attila
parents: 32695
diff changeset
   187
        final FindProperty find = expression.findProperty(NO_SUCH_PROPERTY_NAME, true);
27097
423a434620b4 8060101: AssertionError: __noSuchProperty__ placeholder called from NativeJavaImporter
sundar
parents: 26765
diff changeset
   188
        if (find != null) {
423a434620b4 8060101: AssertionError: __noSuchProperty__ placeholder called from NativeJavaImporter
sundar
parents: 26765
diff changeset
   189
            final Object func = find.getObjectValue();
423a434620b4 8060101: AssertionError: __noSuchProperty__ placeholder called from NativeJavaImporter
sundar
parents: 26765
diff changeset
   190
            if (func instanceof ScriptFunction) {
32694
da2f35ab2ea6 8136544: Call site switching to megamorphic causes incorrect property read
sundar
parents: 32527
diff changeset
   191
                final ScriptFunction sfunc = (ScriptFunction)func;
da2f35ab2ea6 8136544: Call site switching to megamorphic causes incorrect property read
sundar
parents: 32527
diff changeset
   192
                final Object self = isScope && sfunc.isStrict()? UNDEFINED : expression;
33690
46a1bc24cf2c 8141702: Add support for Symbol property keys
hannesw
parents: 33343
diff changeset
   193
                return ScriptRuntime.apply(sfunc, self, key);
27097
423a434620b4 8060101: AssertionError: __noSuchProperty__ placeholder called from NativeJavaImporter
sundar
parents: 26765
diff changeset
   194
            }
423a434620b4 8060101: AssertionError: __noSuchProperty__ placeholder called from NativeJavaImporter
sundar
parents: 26765
diff changeset
   195
        }
423a434620b4 8060101: AssertionError: __noSuchProperty__ placeholder called from NativeJavaImporter
sundar
parents: 26765
diff changeset
   196
33690
46a1bc24cf2c 8141702: Add support for Symbol property keys
hannesw
parents: 33343
diff changeset
   197
        return getProto().invokeNoSuchProperty(key, isScope, programPoint);
27097
423a434620b4 8060101: AssertionError: __noSuchProperty__ placeholder called from NativeJavaImporter
sundar
parents: 26765
diff changeset
   198
    }
423a434620b4 8060101: AssertionError: __noSuchProperty__ placeholder called from NativeJavaImporter
sundar
parents: 26765
diff changeset
   199
423a434620b4 8060101: AssertionError: __noSuchProperty__ placeholder called from NativeJavaImporter
sundar
parents: 26765
diff changeset
   200
    @Override
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   201
    public void setSplitState(final int state) {
31194
f00cb8259826 8098546: eval within a 'with' leaks definitions into global scope
hannesw
parents: 29756
diff changeset
   202
        ((Scope) getNonWithParent()).setSplitState(state);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   203
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   204
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   205
    @Override
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   206
    public int getSplitState() {
31194
f00cb8259826 8098546: eval within a 'with' leaks definitions into global scope
hannesw
parents: 29756
diff changeset
   207
        return ((Scope) getNonWithParent()).getSplitState();
f00cb8259826 8098546: eval within a 'with' leaks definitions into global scope
hannesw
parents: 29756
diff changeset
   208
    }
f00cb8259826 8098546: eval within a 'with' leaks definitions into global scope
hannesw
parents: 29756
diff changeset
   209
f00cb8259826 8098546: eval within a 'with' leaks definitions into global scope
hannesw
parents: 29756
diff changeset
   210
    @Override
f00cb8259826 8098546: eval within a 'with' leaks definitions into global scope
hannesw
parents: 29756
diff changeset
   211
    public void addBoundProperties(final ScriptObject source, final Property[] properties) {
f00cb8259826 8098546: eval within a 'with' leaks definitions into global scope
hannesw
parents: 29756
diff changeset
   212
        // Declared variables in nested eval go to first normal (non-with) parent scope.
f00cb8259826 8098546: eval within a 'with' leaks definitions into global scope
hannesw
parents: 29756
diff changeset
   213
        getNonWithParent().addBoundProperties(source, properties);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   214
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   215
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   216
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   217
     * Get first parent scope that is not an instance of WithObject.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   218
     */
31194
f00cb8259826 8098546: eval within a 'with' leaks definitions into global scope
hannesw
parents: 29756
diff changeset
   219
    private ScriptObject getNonWithParent() {
f00cb8259826 8098546: eval within a 'with' leaks definitions into global scope
hannesw
parents: 29756
diff changeset
   220
        ScriptObject proto = getProto();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   221
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   222
        while (proto != null && proto instanceof WithObject) {
31194
f00cb8259826 8098546: eval within a 'with' leaks definitions into global scope
hannesw
parents: 29756
diff changeset
   223
            proto = proto.getProto();
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   224
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   225
31194
f00cb8259826 8098546: eval within a 'with' leaks definitions into global scope
hannesw
parents: 29756
diff changeset
   226
        return proto;
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   227
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   228
17236
75779a53c6a9 8012919: findMegaMorphicSetMethod should not cast result type
jlaskey
parents: 17234
diff changeset
   229
    private static GuardedInvocation fixReceiverType(final GuardedInvocation link, final MethodHandle filter) {
75779a53c6a9 8012919: findMegaMorphicSetMethod should not cast result type
jlaskey
parents: 17234
diff changeset
   230
        // The receiver may be an Object or a ScriptObject.
75779a53c6a9 8012919: findMegaMorphicSetMethod should not cast result type
jlaskey
parents: 17234
diff changeset
   231
        final MethodType invType = link.getInvocation().type();
75779a53c6a9 8012919: findMegaMorphicSetMethod should not cast result type
jlaskey
parents: 17234
diff changeset
   232
        final MethodType newInvType = invType.changeParameterType(0, filter.type().returnType());
75779a53c6a9 8012919: findMegaMorphicSetMethod should not cast result type
jlaskey
parents: 17234
diff changeset
   233
        return link.asType(newInvType);
75779a53c6a9 8012919: findMegaMorphicSetMethod should not cast result type
jlaskey
parents: 17234
diff changeset
   234
    }
75779a53c6a9 8012919: findMegaMorphicSetMethod should not cast result type
jlaskey
parents: 17234
diff changeset
   235
41842
50202a344d28 8168005: Introduce namespaces for GET, SET Dynalink operations
attila
parents: 41422
diff changeset
   236
    private static GuardedInvocation fixExpressionCallSite(final CallSiteDescriptor desc, final GuardedInvocation link) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   237
        // If it's not a getMethod, just add an expression filter that converts WithObject in "this" position to its
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   238
        // expression.
41842
50202a344d28 8168005: Introduce namespaces for GET, SET Dynalink operations
attila
parents: 41422
diff changeset
   239
        if (NashornCallSiteDescriptor.getBaseOperation(desc) != StandardOperation.GET || !NashornCallSiteDescriptor.isMethodFirstOperation(desc)) {
17236
75779a53c6a9 8012919: findMegaMorphicSetMethod should not cast result type
jlaskey
parents: 17234
diff changeset
   240
            return fixReceiverType(link, WITHEXPRESSIONFILTER).filterArguments(0, WITHEXPRESSIONFILTER);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   241
        }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   242
24720
75f8388b79df 8035836: Array performance improvements
lagergren
parents: 24719
diff changeset
   243
        final MethodHandle linkInvocation      = link.getInvocation();
75f8388b79df 8035836: Array performance improvements
lagergren
parents: 24719
diff changeset
   244
        final MethodType   linkType            = linkInvocation.type();
75f8388b79df 8035836: Array performance improvements
lagergren
parents: 24719
diff changeset
   245
        final boolean      linkReturnsFunction = ScriptFunction.class.isAssignableFrom(linkType.returnType());
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20933
diff changeset
   246
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   247
        return link.replaceMethods(
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   248
                // Make sure getMethod will bind the script functions it receives to WithObject.expression
24720
75f8388b79df 8035836: Array performance improvements
lagergren
parents: 24719
diff changeset
   249
                MH.foldArguments(
75f8388b79df 8035836: Array performance improvements
lagergren
parents: 24719
diff changeset
   250
                        linkReturnsFunction ?
75f8388b79df 8035836: Array performance improvements
lagergren
parents: 24719
diff changeset
   251
                                BIND_TO_EXPRESSION_FN :
75f8388b79df 8035836: Array performance improvements
lagergren
parents: 24719
diff changeset
   252
                                BIND_TO_EXPRESSION_OBJ,
75f8388b79df 8035836: Array performance improvements
lagergren
parents: 24719
diff changeset
   253
                        filterReceiver(
75f8388b79df 8035836: Array performance improvements
lagergren
parents: 24719
diff changeset
   254
                                linkInvocation.asType(
75f8388b79df 8035836: Array performance improvements
lagergren
parents: 24719
diff changeset
   255
                                        linkType.changeReturnType(
75f8388b79df 8035836: Array performance improvements
lagergren
parents: 24719
diff changeset
   256
                                                linkReturnsFunction ?
75f8388b79df 8035836: Array performance improvements
lagergren
parents: 24719
diff changeset
   257
                                                        ScriptFunction.class :
75f8388b79df 8035836: Array performance improvements
lagergren
parents: 24719
diff changeset
   258
                                                        Object.class).
75f8388b79df 8035836: Array performance improvements
lagergren
parents: 24719
diff changeset
   259
                                                            changeParameterType(
75f8388b79df 8035836: Array performance improvements
lagergren
parents: 24719
diff changeset
   260
                                                                    0,
24727
attila
parents: 24720 23372
diff changeset
   261
                                                                    Object.class)),
24720
75f8388b79df 8035836: Array performance improvements
lagergren
parents: 24719
diff changeset
   262
                                        WITHEXPRESSIONFILTER)),
75f8388b79df 8035836: Array performance improvements
lagergren
parents: 24719
diff changeset
   263
                         filterGuardReceiver(link, WITHEXPRESSIONFILTER));
75f8388b79df 8035836: Array performance improvements
lagergren
parents: 24719
diff changeset
   264
     // No clever things for the guard -- it is still identically filtered.
75f8388b79df 8035836: Array performance improvements
lagergren
parents: 24719
diff changeset
   265
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   266
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   267
23084
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 20933
diff changeset
   268
    private GuardedInvocation fixScopeCallSite(final GuardedInvocation link, final String name, final ScriptObject owner) {
24733
1e825be55fd1 8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents: 24727
diff changeset
   269
        final GuardedInvocation newLink             = fixReceiverType(link, WITHSCOPEFILTER);
1e825be55fd1 8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents: 24727
diff changeset
   270
        final MethodHandle      expressionGuard     = expressionGuard(name, owner);
39900
a9ad93ab3f6d 8160034: The `this` value in the `with` is broken by the repetition of a function call
hannesw
parents: 39164
diff changeset
   271
        final MethodHandle      filteredGuard       = filterGuardReceiver(newLink, WITHSCOPEFILTER);
24733
1e825be55fd1 8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents: 24727
diff changeset
   272
        return link.replaceMethods(
1e825be55fd1 8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents: 24727
diff changeset
   273
                filterReceiver(
1e825be55fd1 8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents: 24727
diff changeset
   274
                        newLink.getInvocation(),
1e825be55fd1 8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents: 24727
diff changeset
   275
                        WITHSCOPEFILTER),
1e825be55fd1 8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents: 24727
diff changeset
   276
                NashornGuards.combineGuards(
1e825be55fd1 8027043: Turn global accesses into MethodHandle.constant, with one chance of reassignment, e.g. x = value occuring once in the global scope is ok, twice is not.
lagergren
parents: 24727
diff changeset
   277
                        expressionGuard,
39900
a9ad93ab3f6d 8160034: The `this` value in the `with` is broken by the repetition of a function call
hannesw
parents: 39164
diff changeset
   278
                        filteredGuard));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   279
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   280
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20933
diff changeset
   281
    private static MethodHandle filterGuardReceiver(final GuardedInvocation link, final MethodHandle receiverFilter) {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   282
        final MethodHandle test = link.getGuard();
24720
75f8388b79df 8035836: Array performance improvements
lagergren
parents: 24719
diff changeset
   283
        if (test == null) {
75f8388b79df 8035836: Array performance improvements
lagergren
parents: 24719
diff changeset
   284
            return null;
75f8388b79df 8035836: Array performance improvements
lagergren
parents: 24719
diff changeset
   285
        }
75f8388b79df 8035836: Array performance improvements
lagergren
parents: 24719
diff changeset
   286
75f8388b79df 8035836: Array performance improvements
lagergren
parents: 24719
diff changeset
   287
        final Class<?> receiverType = test.type().parameterType(0);
75f8388b79df 8035836: Array performance improvements
lagergren
parents: 24719
diff changeset
   288
        final MethodHandle filter = MH.asType(receiverFilter,
75f8388b79df 8035836: Array performance improvements
lagergren
parents: 24719
diff changeset
   289
                receiverFilter.type().changeParameterType(0, receiverType).
75f8388b79df 8035836: Array performance improvements
lagergren
parents: 24719
diff changeset
   290
                changeReturnType(receiverType));
75f8388b79df 8035836: Array performance improvements
lagergren
parents: 24719
diff changeset
   291
75f8388b79df 8035836: Array performance improvements
lagergren
parents: 24719
diff changeset
   292
        return filterReceiver(test, filter);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   293
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   294
24719
f726e9d67629 8035820: Optimistic recompilation
attila
parents: 20933
diff changeset
   295
    private static MethodHandle filterReceiver(final MethodHandle mh, final MethodHandle receiverFilter) {
24720
75f8388b79df 8035836: Array performance improvements
lagergren
parents: 24719
diff changeset
   296
        //With expression filter == receiverFilter, i.e. receiver is cast to withobject and its expression returned
24727
attila
parents: 24720 23372
diff changeset
   297
        return MH.filterArguments(mh, 0, receiverFilter.asType(receiverFilter.type().changeReturnType(mh.type().parameterType(0))));
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   298
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   299
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   300
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   301
     * Drops the WithObject wrapper from the expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   302
     * @param receiver WithObject wrapper.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   303
     * @return The with expression.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   304
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   305
    public static Object withFilterExpression(final Object receiver) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   306
        return ((WithObject)receiver).expression;
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   307
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   308
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   309
    @SuppressWarnings("unused")
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   310
    private static Object bindToExpression(final Object fn, final Object receiver) {
25247
c0f911459863 8046013: TypeError: Cannot apply "with" to non script object
sundar
parents: 24733
diff changeset
   311
        if (fn instanceof ScriptFunction) {
c0f911459863 8046013: TypeError: Cannot apply "with" to non script object
sundar
parents: 24733
diff changeset
   312
            return bindToExpression((ScriptFunction) fn, receiver);
c0f911459863 8046013: TypeError: Cannot apply "with" to non script object
sundar
parents: 24733
diff changeset
   313
        } else if (fn instanceof ScriptObjectMirror) {
c0f911459863 8046013: TypeError: Cannot apply "with" to non script object
sundar
parents: 24733
diff changeset
   314
            final ScriptObjectMirror mirror = (ScriptObjectMirror)fn;
c0f911459863 8046013: TypeError: Cannot apply "with" to non script object
sundar
parents: 24733
diff changeset
   315
            if (mirror.isFunction()) {
c0f911459863 8046013: TypeError: Cannot apply "with" to non script object
sundar
parents: 24733
diff changeset
   316
                // We need to make sure correct 'this' is used for calls with Ident call
c0f911459863 8046013: TypeError: Cannot apply "with" to non script object
sundar
parents: 24733
diff changeset
   317
                // expressions. We do so here using an AbstractJSObject instance.
c0f911459863 8046013: TypeError: Cannot apply "with" to non script object
sundar
parents: 24733
diff changeset
   318
                return new AbstractJSObject() {
25821
fbb51e67d2a7 8048869: Reduce compile time by about 5% by removing the Class.casts from the AST nodes
lagergren
parents: 25247
diff changeset
   319
                    @Override
25247
c0f911459863 8046013: TypeError: Cannot apply "with" to non script object
sundar
parents: 24733
diff changeset
   320
                    public Object call(final Object thiz, final Object... args) {
c0f911459863 8046013: TypeError: Cannot apply "with" to non script object
sundar
parents: 24733
diff changeset
   321
                        return mirror.call(withFilterExpression(receiver), args);
c0f911459863 8046013: TypeError: Cannot apply "with" to non script object
sundar
parents: 24733
diff changeset
   322
                    }
c0f911459863 8046013: TypeError: Cannot apply "with" to non script object
sundar
parents: 24733
diff changeset
   323
                };
c0f911459863 8046013: TypeError: Cannot apply "with" to non script object
sundar
parents: 24733
diff changeset
   324
            }
c0f911459863 8046013: TypeError: Cannot apply "with" to non script object
sundar
parents: 24733
diff changeset
   325
        }
c0f911459863 8046013: TypeError: Cannot apply "with" to non script object
sundar
parents: 24733
diff changeset
   326
c0f911459863 8046013: TypeError: Cannot apply "with" to non script object
sundar
parents: 24733
diff changeset
   327
        return fn;
16780
f23743ec1a93 8011555: Invalid class name in with block with JavaImporter causes MH type mismatch
attila
parents: 16277
diff changeset
   328
    }
f23743ec1a93 8011555: Invalid class name in with block with JavaImporter causes MH type mismatch
attila
parents: 16277
diff changeset
   329
f23743ec1a93 8011555: Invalid class name in with block with JavaImporter causes MH type mismatch
attila
parents: 16277
diff changeset
   330
    private static Object bindToExpression(final ScriptFunction fn, final Object receiver) {
32527
b105632002c5 8027137: Merge ScriptFunction and ScriptFunctionImpl
sundar
parents: 31199
diff changeset
   331
        return fn.createBound(withFilterExpression(receiver), ScriptRuntime.EMPTY_ARRAY);
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   332
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   333
23084
6c5c02d1023a 8035948: Redesign property listeners for shared classes
hannesw
parents: 20933
diff changeset
   334
    private MethodHandle expressionGuard(final String name, final ScriptObject owner) {
19884
1bacbaa1bfc7 8024180: Incorrect handling of expression and parent scope in 'with' statements
sundar
parents: 19621
diff changeset
   335
        final PropertyMap map = expression.getMap();
32695
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32694
diff changeset
   336
        final SwitchPoint[] sp = expression.getProtoSwitchPoints(name, owner);
19884
1bacbaa1bfc7 8024180: Incorrect handling of expression and parent scope in 'with' statements
sundar
parents: 19621
diff changeset
   337
        return MH.insertArguments(WITHEXPRESSIONGUARD, 1, map, sp);
1bacbaa1bfc7 8024180: Incorrect handling of expression and parent scope in 'with' statements
sundar
parents: 19621
diff changeset
   338
    }
1bacbaa1bfc7 8024180: Incorrect handling of expression and parent scope in 'with' statements
sundar
parents: 19621
diff changeset
   339
1bacbaa1bfc7 8024180: Incorrect handling of expression and parent scope in 'with' statements
sundar
parents: 19621
diff changeset
   340
    @SuppressWarnings("unused")
32695
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32694
diff changeset
   341
    private static boolean withExpressionGuard(final Object receiver, final PropertyMap map, final SwitchPoint[] sp) {
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32694
diff changeset
   342
        return ((WithObject)receiver).expression.getMap() == map && !hasBeenInvalidated(sp);
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32694
diff changeset
   343
    }
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32694
diff changeset
   344
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32694
diff changeset
   345
    private static boolean hasBeenInvalidated(final SwitchPoint[] switchPoints) {
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32694
diff changeset
   346
        if (switchPoints != null) {
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32694
diff changeset
   347
            for (final SwitchPoint switchPoint : switchPoints) {
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32694
diff changeset
   348
                if (switchPoint.hasBeenInvalidated()) {
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32694
diff changeset
   349
                    return true;
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32694
diff changeset
   350
                }
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32694
diff changeset
   351
            }
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32694
diff changeset
   352
        }
9b708b92c695 8134609: Allow constructors with same prototoype map to share the allocator map
hannesw
parents: 32694
diff changeset
   353
        return false;
19884
1bacbaa1bfc7 8024180: Incorrect handling of expression and parent scope in 'with' statements
sundar
parents: 19621
diff changeset
   354
    }
1bacbaa1bfc7 8024180: Incorrect handling of expression and parent scope in 'with' statements
sundar
parents: 19621
diff changeset
   355
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   356
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   357
     * Drops the WithObject wrapper from the scope.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   358
     * @param receiver WithObject wrapper.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   359
     * @return The with scope.
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   360
     */
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   361
    public static Object withFilterScope(final Object receiver) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   362
        return ((WithObject)receiver).getProto();
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   363
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   364
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   365
    /**
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   366
     * Get the with expression for this {@code WithObject}
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   367
     * @return the with expression
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   368
     */
19884
1bacbaa1bfc7 8024180: Incorrect handling of expression and parent scope in 'with' statements
sundar
parents: 19621
diff changeset
   369
    public ScriptObject getExpression() {
16147
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   370
        return expression;
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
    private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   374
        return MH.findStatic(MethodHandles.lookup(), WithObject.class, name, MH.type(rtype, types));
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   375
    }
e63b63819133 8005403: Open-source Nashorn
jlaskey
parents:
diff changeset
   376
}