Skip to content

Commit 0750f95

Browse files
committed
GR-26077: Added PConstructAndRaiseNode - utility node to construct and raise exceptions
- remove custom PRaiseOSErrorNode and PRaiseImportErrorNode
1 parent 52b0a87 commit 0750f95

File tree

6 files changed

+234
-251
lines changed

6 files changed

+234
-251
lines changed
Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
/*
2+
* Copyright (c) 2020, 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.graal.python.nodes;
42+
43+
import com.oracle.graal.python.PythonLanguage;
44+
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
45+
import com.oracle.graal.python.builtins.objects.PNone;
46+
import com.oracle.graal.python.builtins.objects.exception.OSErrorEnum;
47+
import com.oracle.graal.python.builtins.objects.exception.PBaseException;
48+
import com.oracle.graal.python.builtins.objects.function.PKeyword;
49+
import com.oracle.graal.python.builtins.objects.object.PythonObjectLibrary;
50+
import com.oracle.graal.python.nodes.call.special.CallVarargsMethodNode;
51+
import com.oracle.graal.python.runtime.PythonContext;
52+
import com.oracle.graal.python.runtime.PythonCore;
53+
import com.oracle.graal.python.runtime.PythonOptions;
54+
import com.oracle.graal.python.runtime.exception.PException;
55+
import com.oracle.graal.python.runtime.formatting.ErrorMessageFormatter;
56+
import com.oracle.truffle.api.CompilerDirectives;
57+
import com.oracle.truffle.api.dsl.Cached;
58+
import com.oracle.truffle.api.dsl.CachedContext;
59+
import com.oracle.truffle.api.dsl.CachedLanguage;
60+
import com.oracle.truffle.api.dsl.GenerateUncached;
61+
import com.oracle.truffle.api.dsl.ImportStatic;
62+
import com.oracle.truffle.api.dsl.Specialization;
63+
import com.oracle.truffle.api.frame.Frame;
64+
import com.oracle.truffle.api.frame.VirtualFrame;
65+
import com.oracle.truffle.api.library.CachedLibrary;
66+
import com.oracle.truffle.api.nodes.Node;
67+
68+
@GenerateUncached
69+
@ImportStatic(PGuards.class)
70+
public abstract class PConstructAndRaiseNode extends Node {
71+
private static final ErrorMessageFormatter FORMATTER = new ErrorMessageFormatter();
72+
73+
public final PException executeWithArgsOnly(Frame frame, PythonBuiltinClassType type, Object[] arguments) {
74+
return execute(frame, type, null, null, arguments, PKeyword.EMPTY_KEYWORDS);
75+
}
76+
77+
public final PException executeWithArgsAndKwargs(Frame frame, PythonBuiltinClassType type, Object[] arguments, PKeyword[] keywords) {
78+
return execute(frame, type, null, null, arguments, keywords);
79+
}
80+
81+
public final PException executeWithFmtMessageAndKwargs(Frame frame, PythonBuiltinClassType type, String format, Object[] formatArgs, PKeyword[] keywords) {
82+
return execute(frame, type, format, formatArgs, null, keywords);
83+
}
84+
85+
public final PException executeWithFmtMessageAndArgs(Frame frame, PythonBuiltinClassType type, String format, Object[] formatArgs, Object[] arguments) {
86+
return execute(frame, type, format, formatArgs, arguments, PKeyword.EMPTY_KEYWORDS);
87+
}
88+
89+
public abstract PException execute(Frame frame, PythonBuiltinClassType type, String format, Object[] formatArgs, Object[] arguments, PKeyword[] keywords);
90+
91+
@CompilerDirectives.TruffleBoundary
92+
private static String getFormattedMessage(PythonObjectLibrary pol, String format, Object[] formatArgs) {
93+
return FORMATTER.format(pol, format, formatArgs);
94+
}
95+
96+
private PException raiseInternal(VirtualFrame frame, PythonBuiltinClassType type, Object[] arguments, PKeyword[] keywords,
97+
CallVarargsMethodNode callNode, PythonLanguage language, PythonCore core) {
98+
PBaseException error = (PBaseException) callNode.execute(frame, core.lookupType(type), arguments, keywords);
99+
return PRaiseNode.raise(this, error, PythonOptions.isPExceptionWithJavaStacktrace(language));
100+
}
101+
102+
@Specialization(guards = {"format == null", "formatArgs == null"})
103+
PException constructAndRaiseNoFormatString(VirtualFrame frame, PythonBuiltinClassType type, @SuppressWarnings("unused") String format, @SuppressWarnings("unused") Object[] formatArgs,
104+
Object[] arguments, PKeyword[] keywords,
105+
@Cached.Shared("callNode") @Cached CallVarargsMethodNode callNode,
106+
@CachedLanguage PythonLanguage language,
107+
@CachedContext(PythonLanguage.class) PythonContext context) {
108+
PythonCore core = context.getCore();
109+
return raiseInternal(frame, type, arguments, keywords, callNode, language, core);
110+
}
111+
112+
@Specialization(guards = {"arguments == null"})
113+
PException constructAndRaiseNoArgs(VirtualFrame frame, PythonBuiltinClassType type, String format, Object[] formatArgs,
114+
@SuppressWarnings("unused") Object[] arguments, PKeyword[] keywords,
115+
@Cached.Shared("callNode") @Cached CallVarargsMethodNode callNode,
116+
@Cached.Shared("pol") @CachedLibrary(limit = "3") PythonObjectLibrary pol,
117+
@CachedLanguage PythonLanguage language,
118+
@CachedContext(PythonLanguage.class) PythonContext context) {
119+
PythonCore core = context.getCore();
120+
Object[] args = new Object[]{getFormattedMessage(pol, format, formatArgs)};
121+
return raiseInternal(frame, type, args, keywords, callNode, language, core);
122+
}
123+
124+
@Specialization(guards = {"arguments != null"})
125+
PException constructAndRaise(VirtualFrame frame, PythonBuiltinClassType type, String format, Object[] formatArgs,
126+
Object[] arguments, PKeyword[] keywords,
127+
@Cached.Shared("callNode") @Cached CallVarargsMethodNode callNode,
128+
@Cached.Shared("pol") @CachedLibrary(limit = "3") PythonObjectLibrary pol,
129+
@CachedLanguage PythonLanguage language,
130+
@CachedContext(PythonLanguage.class) PythonContext context) {
131+
PythonCore core = context.getCore();
132+
Object[] args = new Object[arguments.length + 1];
133+
args[0] = formatArgs != null ? getFormattedMessage(pol, format, formatArgs) : format;
134+
System.arraycopy(arguments, 0, args, 1, arguments.length);
135+
return raiseInternal(frame, type, args, keywords, callNode, language, core);
136+
}
137+
138+
// ImportError helpers
139+
private PException raiseImportErrorInternal(Frame frame, String format, Object[] formatArgs, PKeyword[] keywords) {
140+
return executeWithFmtMessageAndKwargs(frame, PythonBuiltinClassType.ImportError, format, formatArgs, keywords);
141+
}
142+
143+
public final PException raiseImportError(Frame frame, Object name, Object path, String format, Object... formatArgs) {
144+
return raiseImportErrorInternal(frame, format, formatArgs, new PKeyword[]{new PKeyword("name", name), new PKeyword("path", path)});
145+
}
146+
147+
public final PException raiseImportError(Frame frame, String format, Object... formatArgs) {
148+
return raiseImportErrorInternal(frame, format, formatArgs, PKeyword.EMPTY_KEYWORDS);
149+
}
150+
151+
// OSError helpers
152+
@CompilerDirectives.TruffleBoundary
153+
private static String getMessage(Exception exception) {
154+
return exception.getMessage();
155+
}
156+
157+
private Object[] createOsErrorArgs(OSErrorEnum osErrorEnum, String filename1, String filename2) {
158+
return new Object[]{osErrorEnum.getNumber(), osErrorEnum.getMessage(),
159+
(filename1 != null) ? filename1 : PNone.NONE,
160+
PNone.NONE,
161+
(filename2 != null) ? filename2 : PNone.NONE};
162+
}
163+
164+
private Object[] createOsErrorArgs(Exception exception, String filename1, String filename2) {
165+
OSErrorEnum.ErrorAndMessagePair errorAndMessage = OSErrorEnum.fromException(exception);
166+
return new Object[]{errorAndMessage.oserror.getNumber(), errorAndMessage.message,
167+
(filename1 != null) ? filename1 : PNone.NONE,
168+
PNone.NONE,
169+
(filename2 != null) ? filename2 : PNone.NONE};
170+
}
171+
172+
private PException raiseOSErrorInternal(Frame frame, Object[] arguments) {
173+
return executeWithArgsOnly(frame, PythonBuiltinClassType.OSError, arguments);
174+
}
175+
176+
public final PException raiseOSError(Frame frame, OSErrorEnum osErrorEnum) {
177+
return raiseOSErrorInternal(frame, createOsErrorArgs(osErrorEnum, null, null));
178+
}
179+
180+
public final PException raiseOSError(Frame frame, OSErrorEnum osErrorEnum, String filename) {
181+
return raiseOSErrorInternal(frame, createOsErrorArgs(osErrorEnum, filename, null));
182+
}
183+
184+
public final PException raiseOSError(Frame frame, OSErrorEnum osErrorEnum, String filename, String filename2) {
185+
return raiseOSErrorInternal(frame, createOsErrorArgs(osErrorEnum, filename, filename2));
186+
}
187+
188+
public final PException raiseOSError(Frame frame, Exception exception) {
189+
return raiseOSErrorInternal(frame, createOsErrorArgs(exception, null, null));
190+
}
191+
192+
public final PException raiseOSError(Frame frame, Exception exception, String filename) {
193+
return raiseOSErrorInternal(frame, createOsErrorArgs(exception, filename, null));
194+
}
195+
196+
public final PException raiseOSError(Frame frame, Exception exception, String filename, String filename2) {
197+
return raiseOSErrorInternal(frame, createOsErrorArgs(exception, filename, filename2));
198+
}
199+
200+
public final PException raiseOSError(Frame frame, OSErrorEnum osErrorEnum, Exception exception) {
201+
return raiseOSError(frame, osErrorEnum, getMessage(exception));
202+
}
203+
204+
public static PConstructAndRaiseNode create() {
205+
return PConstructAndRaiseNodeGen.create();
206+
}
207+
208+
public static PConstructAndRaiseNode getUncached() {
209+
return PConstructAndRaiseNodeGen.getUncached();
210+
}
211+
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/PRaiseImportErrorNode.java

Lines changed: 0 additions & 103 deletions
This file was deleted.

0 commit comments

Comments
 (0)