Skip to content

Commit

Permalink
8261926: Attempt to access property/element of a Java method results …
Browse files Browse the repository at this point in the history
…in AssertionError: unknown call type (#15)

* test

* 8261926: Attempt to access property/element of a Java method results in AssertionError: unknown call type
  • Loading branch information
szegedi committed Jun 29, 2021
1 parent b78652e commit d577a18
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@ private static MethodHandle unboxReturnType(final MethodHandle target, final Met
}

private static MethodHandle createMissingMemberHandler(
final LinkRequest linkRequest, final LinkerServices linkerServices) throws Exception {
final LinkRequest linkRequest, final LinkerServices linkerServices) {
if (BrowserJSObjectLinker.canLinkTypeStatic(linkRequest.getReceiver().getClass())) {
// Don't create missing member handlers for the browser JS objects as they
// have their own logic.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,12 @@ public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest, fin
}

// None of the objects that can be linked by NashornLinker should ever reach here. Basically, anything below
// this point is a generic Java bean. Therefore, reaching here with a ScriptObject is a Nashorn bug.
// this point is a generic Java bean or a DynamicMethod with an operation that couldn't be linked with BeansLinker.
// Therefore, reaching here with a ScriptObject is a Nashorn bug.
assert isExpectedObject(self) : "Couldn't link " + linkRequest.getCallSiteDescriptor() + " for " + self.getClass().getName();

return linkBean(linkRequest);
// Provide some JavaScript semantics for otherwise unlinkable operations on generic beans or dynamic methods.
return linkBean(linkRequest, linkerServices);
}

private static final MethodHandle EMPTY_PROP_GETTER =
Expand All @@ -89,16 +91,18 @@ public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest, fin
private static final MethodHandle THROW_STRICT_PROPERTY_REMOVER;
private static final MethodHandle THROW_OPTIMISTIC_UNDEFINED;
private static final MethodHandle MISSING_PROPERTY_REMOVER;
private static final MethodHandle IS_DYNAMIC_METHOD;

static {
final Lookup lookup = new Lookup(MethodHandles.lookup());
THROW_STRICT_PROPERTY_SETTER = lookup.findOwnStatic("throwStrictPropertySetter", void.class, Object.class, Object.class);
THROW_STRICT_PROPERTY_REMOVER = lookup.findOwnStatic("throwStrictPropertyRemover", boolean.class, Object.class, Object.class);
THROW_OPTIMISTIC_UNDEFINED = lookup.findOwnStatic("throwOptimisticUndefined", Object.class, int.class);
MISSING_PROPERTY_REMOVER = lookup.findOwnStatic("missingPropertyRemover", boolean.class, Object.class, Object.class);
IS_DYNAMIC_METHOD = lookup.findStatic(BeansLinker.class, "isDynamicMethod", MethodType.methodType(boolean.class, Object.class));
}

private static GuardedInvocation linkBean(final LinkRequest linkRequest) {
private static GuardedInvocation linkBean(final LinkRequest linkRequest, final LinkerServices linkerServices) {
final CallSiteDescriptor desc = linkRequest.getCallSiteDescriptor();
final Object self = linkRequest.getReceiver();
switch (NashornCallSiteDescriptor.getStandardOperation(desc)) {
Expand All @@ -119,6 +123,11 @@ private static GuardedInvocation linkBean(final LinkRequest linkRequest) {
}
throw typeError("not.a.function", NashornCallSiteDescriptor.getFunctionErrorMessage(desc, self));
default:
// Property accessors on dynamic methods
if (BeansLinker.isDynamicMethod(self)) {
return new GuardedInvocation(
linkMissingBeanMember(linkRequest, linkerServices), IS_DYNAMIC_METHOD);
}
// Everything else is supposed to have been already handled by Bootstrap.beansLinker
// delegating to linkNoSuchBeanMember
throw new AssertionError("unknown call type " + desc);
Expand Down
63 changes: 63 additions & 0 deletions test/nashorn/script/basic/JDK-8261926.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

/**
* JDK-8261926: Attempt to access property/element of a Java method results in AssertionError: unknown call type
*
* @test
* @run
*/

var v = java.lang.String.valueOf

isVCallUndefined()
v.call = 1
isVCallUndefined()

function isVCallUndefined() {
Assert.assertEquals(typeof(v.call), "undefined")
}

function mustFailWithTypeError(f){
try {
f()
Assert.fail("Did not fail with TypeError")
} catch (e) {
if (!(e instanceof TypeError)) {
Assert.fail("Should have failed with TypeError, it was instead " + e)
}
}
}

(function() {
"use strict";
Assert.assertEquals(typeof(v.call), "undefined")
mustFailWithTypeError(function() {
v.call = 1
})
isVCallUndefined()
Assert.assertTrue(delete v.call)
})()

Assert.assertTrue(delete v.call)
isVCallUndefined()

0 comments on commit d577a18

Please sign in to comment.