Skip to content

Commit 9727a86

Browse files
committed
[GR-37175] ClassCastException in JavaScriptNode.getScope.
PullRequest: js/2354
2 parents c7c10cd + b5b2ee9 commit 9727a86

File tree

3 files changed

+112
-4
lines changed

3 files changed

+112
-4
lines changed

graal-js/src/com.oracle.truffle.js.test/src/com/oracle/truffle/js/test/TestHelper.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -250,13 +250,17 @@ public ParsedFunction(JSFunctionData functionData) {
250250
}
251251

252252
public Object call(Object[] args) {
253-
DynamicObject funObj = JSFunction.create(getRealm(), functionData);
253+
DynamicObject funObj = createFunctionObject();
254254
return JSFunction.call(funObj, Null.instance, args);
255255
}
256256

257257
public RootNode getRootNode() {
258258
return ((RootCallTarget) functionData.getCallTarget()).getRootNode();
259259
}
260+
261+
public DynamicObject createFunctionObject() {
262+
return JSFunction.create(getRealm(), functionData);
263+
}
260264
}
261265

262266
public ParsedFunction parseFirstFunction(String source) {
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/*
2+
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* The Universal Permissive License (UPL), Version 1.0
6+
*
7+
* Subject to the condition set forth below, permission is hereby granted to any
8+
* person obtaining a copy of this software, associated documentation and/or
9+
* data (collectively the "Software"), free of charge and under any and all
10+
* copyright rights in the Software, and any and all patent rights owned or
11+
* freely licensable by each licensor hereunder covering either (i) the
12+
* unmodified Software as contributed to or provided by such licensor, or (ii)
13+
* the Larger Works (as defined below), to deal in both
14+
*
15+
* (a) the Software, and
16+
*
17+
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
18+
* one is included with the Software each a "Larger Work" to which the Software
19+
* is contributed by such licensors),
20+
*
21+
* without restriction, including without limitation the rights to copy, create
22+
* derivative works of, display, perform, and distribute the Software and make,
23+
* use, sell, offer for sale, import, export, have made, and have sold the
24+
* Software and the Larger Work(s), and to sublicense the foregoing rights on
25+
* either these or other terms.
26+
*
27+
* This license is subject to the following condition:
28+
*
29+
* The above copyright notice and either this complete permission notice or at a
30+
* minimum a reference to the UPL must be included in all copies or substantial
31+
* portions of the Software.
32+
*
33+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
39+
* SOFTWARE.
40+
*/
41+
package com.oracle.truffle.js.test.runtime;
42+
43+
import org.junit.Assert;
44+
import org.junit.Test;
45+
46+
import com.oracle.truffle.api.Truffle;
47+
import com.oracle.truffle.api.frame.FrameDescriptor;
48+
import com.oracle.truffle.api.frame.FrameSlot;
49+
import com.oracle.truffle.api.frame.MaterializedFrame;
50+
import com.oracle.truffle.api.interop.InteropLibrary;
51+
import com.oracle.truffle.api.interop.NodeLibrary;
52+
import com.oracle.truffle.api.nodes.NodeUtil;
53+
import com.oracle.truffle.api.nodes.RootNode;
54+
import com.oracle.truffle.js.nodes.function.BlockScopeNode;
55+
import com.oracle.truffle.js.runtime.JSArguments;
56+
import com.oracle.truffle.js.runtime.objects.Undefined;
57+
import com.oracle.truffle.js.test.JSTest;
58+
import com.oracle.truffle.js.test.TestHelper.ParsedFunction;
59+
60+
public class NodeLibraryTest extends JSTest {
61+
@Test
62+
public void testBlockScopeEnter() throws Exception {
63+
String src = "function testBlock(p) {\n" +
64+
" for (let i = 8; i <= 10; i++) {\n" +
65+
" let f = fac(i);\n" +
66+
" console.log(`fac(${i}) = ${f}`);\n" +
67+
" }\n" +
68+
"}\n" +
69+
"function fac(n) {\n" +
70+
" if (n <= 1) {\n" +
71+
" return 1;\n" +
72+
" } else {\n" +
73+
" return n * fac(n - 1);\n" +
74+
" }\n" +
75+
"}" +
76+
"\n" +
77+
"testBlock(42);\n";
78+
79+
testHelper.enterContext();
80+
try {
81+
ParsedFunction parsedFunction = testHelper.parseFirstFunction(src);
82+
RootNode rootNode = parsedFunction.getRootNode();
83+
BlockScopeNode blockScopeNode = NodeUtil.findFirstNodeInstance(rootNode, BlockScopeNode.class);
84+
Object[] args = JSArguments.createZeroArg(Undefined.instance, parsedFunction.createFunctionObject());
85+
FrameDescriptor frameDesc = rootNode.getFrameDescriptor();
86+
MaterializedFrame frame = Truffle.getRuntime().createMaterializedFrame(args, frameDesc);
87+
FrameSlot pSlot = frameDesc.findFrameSlot("p");
88+
frame.setInt(pSlot, 42);
89+
Object scope = NodeLibrary.getUncached().getScope(blockScopeNode, frame, true);
90+
InteropLibrary interop = InteropLibrary.getUncached();
91+
Assert.assertTrue(interop.isMemberReadable(scope, "p"));
92+
Object pValue = interop.readMember(scope, "p");
93+
Assert.assertTrue(String.valueOf(pValue), interop.fitsInInt(pValue));
94+
Assert.assertEquals(42, interop.asInt(pValue));
95+
} finally {
96+
testHelper.leaveContext();
97+
}
98+
}
99+
}

graal-js/src/com.oracle.truffle.js/src/com/oracle/truffle/js/nodes/JavaScriptNode.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -418,7 +418,12 @@ final Object getScope(Frame frame, boolean nodeEnter,
418418
functionFrame = frame.materialize();
419419
}
420420
if (block instanceof BlockScopeNode) {
421-
scopeFrame = (Frame) ((BlockScopeNode) block).getBlockScope((VirtualFrame) functionFrame);
421+
Object maybeScopeFrame = ((BlockScopeNode) block).getBlockScope((VirtualFrame) functionFrame);
422+
if (maybeScopeFrame instanceof Frame) {
423+
scopeFrame = (Frame) maybeScopeFrame;
424+
} else {
425+
scopeFrame = functionFrame;
426+
}
422427
} else {
423428
scopeFrame = functionFrame;
424429
}

0 commit comments

Comments
 (0)