Skip to content

Commit 65e4d64

Browse files
committed
clean up and casting to Java int in socket module
1 parent 77ec2a8 commit 65e4d64

File tree

3 files changed

+212
-28
lines changed

3 files changed

+212
-28
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SocketModuleBuiltins.java

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
6161
import com.oracle.graal.python.builtins.PythonBuiltins;
6262
import com.oracle.graal.python.builtins.objects.PNone;
63+
import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes;
6364
import com.oracle.graal.python.builtins.objects.exception.OSErrorEnum;
6465
import com.oracle.graal.python.builtins.objects.ints.PInt;
6566
import com.oracle.graal.python.builtins.objects.list.PList;
@@ -69,7 +70,8 @@
6970
import com.oracle.graal.python.builtins.objects.type.LazyPythonClass;
7071
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
7172
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
72-
import com.oracle.graal.python.nodes.util.CastToIndexNode;
73+
import com.oracle.graal.python.nodes.util.CastToJavaIntNode;
74+
import com.oracle.graal.python.nodes.util.CastToStringNode;
7375
import com.oracle.graal.python.runtime.exception.PythonErrorType;
7476
import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage;
7577
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
@@ -209,31 +211,31 @@ Object socket(LazyPythonClass cls, @SuppressWarnings("unused") PNone family, @Su
209211

210212
@Specialization(guards = {"isNoValue(family)", "isNoValue(type)", "isNoValue(proto)", "!isNoValue(fileno)"})
211213
Object socket(VirtualFrame frame, LazyPythonClass cls, @SuppressWarnings("unused") PNone family, @SuppressWarnings("unused") PNone type, @SuppressWarnings("unused") PNone proto, Object fileno,
212-
@Cached CastToIndexNode cast) {
214+
@Cached CastToJavaIntNode cast) {
213215
return createSocketInternal(frame, cls, -1, -1, -1, cast.execute(fileno));
214216
}
215217

216218
@Specialization(guards = {"!isNoValue(family)", "isNoValue(type)", "isNoValue(proto)", "isNoValue(fileno)"})
217219
Object socket(LazyPythonClass cls, Object family, @SuppressWarnings("unused") PNone type, @SuppressWarnings("unused") PNone proto, @SuppressWarnings("unused") PNone fileno,
218-
@Cached CastToIndexNode cast) {
220+
@Cached CastToJavaIntNode cast) {
219221
return createSocketInternal(cls, cast.execute(family), PSocket.SOCK_STREAM, 0);
220222
}
221223

222224
@Specialization(guards = {"!isNoValue(family)", "!isNoValue(type)", "isNoValue(proto)", "isNoValue(fileno)"})
223225
Object socket(LazyPythonClass cls, Object family, Object type, @SuppressWarnings("unused") PNone proto, @SuppressWarnings("unused") PNone fileno,
224-
@Cached CastToIndexNode cast) {
226+
@Cached CastToJavaIntNode cast) {
225227
return createSocketInternal(cls, cast.execute(family), cast.execute(type), 0);
226228
}
227229

228230
@Specialization(guards = {"!isNoValue(family)", "!isNoValue(type)", "!isNoValue(proto)", "isNoValue(fileno)"})
229231
Object socket(LazyPythonClass cls, Object family, Object type, Object proto, @SuppressWarnings("unused") PNone fileno,
230-
@Cached CastToIndexNode cast) {
232+
@Cached CastToJavaIntNode cast) {
231233
return createSocketInternal(cls, cast.execute(family), cast.execute(type), cast.execute(proto));
232234
}
233235

234236
@Specialization(guards = {"!isNoValue(family)", "!isNoValue(type)", "!isNoValue(proto)", "!isNoValue(fileno)"})
235237
Object socket(VirtualFrame frame, LazyPythonClass cls, Object family, Object type, Object proto, Object fileno,
236-
@Cached CastToIndexNode cast) {
238+
@Cached CastToJavaIntNode cast) {
237239
return createSocketInternal(frame, cls, cast.execute(family), cast.execute(type), cast.execute(proto), cast.execute(fileno));
238240
}
239241

@@ -415,24 +417,24 @@ Object getServByPort(int port, String protocolName) {
415417
@GenerateNodeFactory
416418
public abstract static class GetNameInfoNode extends PythonBuiltinNode {
417419
@Specialization
418-
Object getNameInfo(PTuple sockaddr, PInt flags) {
419-
return getNameInfo(sockaddr, flags.intValue());
420-
}
421-
422-
@Specialization
423-
@TruffleBoundary
424-
Object getNameInfo(PTuple sockaddr, int flags) {
420+
Object getNameInfo(VirtualFrame frame, PTuple sockaddr, Object flagArg,
421+
@Cached CastToJavaIntNode castFlags,
422+
@Cached SequenceStorageNodes.LenNode lenNode,
423+
@Cached SequenceStorageNodes.GetItemNode getItem,
424+
@Cached CastToStringNode castAddress,
425+
@Cached CastToJavaIntNode castPort) {
426+
int flags = castFlags.execute(flagArg);
425427
SequenceStorage addr = sockaddr.getSequenceStorage();
426-
if (addr.length() != 2 && addr.length() != 4) {
428+
int addLen = lenNode.execute(addr);
429+
if (addLen != 2 && addLen != 4) {
427430
throw raise(PythonBuiltinClassType.OSError);
428431
}
429-
String address = (String) addr.getItemNormalized(0);
430-
int port = (int) addr.getItemNormalized(1);
432+
String address = castAddress.execute(frame, getItem.execute(addr, 0));
433+
int port = castPort.execute(getItem.execute(addr, 1));
431434

432435
if ((flags & PSocket.NI_NUMERICHOST) != PSocket.NI_NUMERICHOST) {
433436
try {
434-
InetAddress inetAddress = InetAddress.getByName(address);
435-
address = inetAddress.getHostName();
437+
address = getHostName(address);
436438
} catch (UnknownHostException e) {
437439
throw raise(PythonBuiltinClassType.OSError);
438440
}
@@ -448,6 +450,13 @@ Object getNameInfo(PTuple sockaddr, int flags) {
448450

449451
return factory().createTuple(new Object[]{address, portServ});
450452
}
453+
454+
@TruffleBoundary
455+
private String getHostName(String address) throws UnknownHostException {
456+
InetAddress inetAddress = InetAddress.getByName(address);
457+
address = inetAddress.getHostName();
458+
return address;
459+
}
451460
}
452461

453462
@Builtin(name = "getaddrinfo", parameterNames = {"host", "port", "family", "type", "proto", "flags"})
@@ -459,19 +468,19 @@ public abstract static class GetAddrInfoNode extends PythonBuiltinNode {
459468

460469
@Specialization
461470
Object getAddrInfoPString(PString host, Object port, Object family, Object type, Object proto, Object flags,
462-
@Cached CastToIndexNode cast) {
471+
@Cached CastToJavaIntNode cast) {
463472
return getAddrInfoString(host.getValue(), port, family, type, proto, flags, cast);
464473
}
465474

466475
@Specialization
467476
Object getAddrInfoNone(@SuppressWarnings("unused") PNone host, Object port, Object family, Object type, Object proto, Object flags,
468-
@Cached CastToIndexNode cast) {
477+
@Cached CastToJavaIntNode cast) {
469478
return getAddrInfoString("localhost", port, family, type, proto, flags, cast);
470479
}
471480

472481
@Specialization
473482
Object getAddrInfoString(String host, Object port, Object family, Object type, Object proto, Object flags,
474-
@Cached CastToIndexNode cast) {
483+
@Cached CastToJavaIntNode cast) {
475484
String stringPort = null;
476485
if (port instanceof PString) {
477486
stringPort = ((PString) port).getValue();

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/socket/SocketBuiltins.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -358,11 +358,15 @@ Object recvFrom(PSocket socket, int bufsize, PNone flags) {
358358
@Builtin(name = "recv_into", minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 3)
359359
@GenerateNodeFactory
360360
abstract static class RecvIntoNode extends PythonTernaryBuiltinNode {
361+
protected static SequenceStorageNodes.SetItemNode createSetItem() {
362+
return SequenceStorageNodes.SetItemNode.create("cannot happen: non-byte store in socket.recv_into");
363+
}
364+
361365
@Specialization
362366
Object recvInto(VirtualFrame frame, PSocket socket, PByteArray buffer, Object flags,
363-
@Cached ConditionProfile byteStorage,
367+
@Cached("createBinaryProfile()") ConditionProfile byteStorage,
364368
@Cached SequenceStorageNodes.LenNode lenNode,
365-
@Cached SequenceStorageNodes.SetItemNode setItem) {
369+
@Cached("createSetItem()") SequenceStorageNodes.SetItemNode setItem) {
366370
SequenceStorage storage = buffer.getSequenceStorage();
367371
int bufferLen = lenNode.execute(storage);
368372
if (byteStorage.profile(storage instanceof ByteSequenceStorage)) {
@@ -385,12 +389,9 @@ Object recvInto(VirtualFrame frame, PSocket socket, PByteArray buffer, Object fl
385389
} catch (IOException e) {
386390
throw raiseOSError(frame, OSErrorEnum.EBADF, e);
387391
}
388-
SequenceStorage newStorage = storage;
389392
for (int i = 0; i < length; i++) {
390-
newStorage = setItem.execute(newStorage, i, targetBuffer[i]);
391-
}
392-
if (newStorage != storage) {
393-
buffer.setSequenceStorage(newStorage);
393+
// we don't allow generalization
394+
setItem.execute(storage, i, targetBuffer[i]);
394395
}
395396
return length;
396397
}
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
/*
2+
* Copyright (c) 2019, 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.util;
42+
43+
import static com.oracle.graal.python.nodes.SpecialMethodNames.__INT__;
44+
import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError;
45+
46+
import com.oracle.graal.python.builtins.modules.MathGuards;
47+
import com.oracle.graal.python.builtins.objects.PNone;
48+
import com.oracle.graal.python.builtins.objects.ints.PInt;
49+
import com.oracle.graal.python.nodes.PNodeWithContext;
50+
import com.oracle.graal.python.nodes.PRaiseNode;
51+
import com.oracle.graal.python.nodes.call.special.LookupAndCallUnaryNode.LookupAndCallUnaryDynamicNode;
52+
import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes;
53+
import com.oracle.graal.python.nodes.util.CastToJavaIntNodeGen.CastToJavaIntExactNodeGen;
54+
import com.oracle.graal.python.nodes.util.CastToJavaIntNodeGen.CastToJavaIntLossyNodeGen;
55+
import com.oracle.truffle.api.CompilerDirectives;
56+
import com.oracle.truffle.api.dsl.Cached;
57+
import com.oracle.truffle.api.dsl.GenerateUncached;
58+
import com.oracle.truffle.api.dsl.ImportStatic;
59+
import com.oracle.truffle.api.dsl.Specialization;
60+
import com.oracle.truffle.api.dsl.TypeSystemReference;
61+
import com.oracle.truffle.api.profiles.BranchProfile;
62+
63+
@TypeSystemReference(PythonArithmeticTypes.class)
64+
@ImportStatic(MathGuards.class)
65+
public abstract class CastToJavaIntNode extends PNodeWithContext {
66+
67+
public abstract int execute(int x);
68+
69+
public abstract int execute(long x);
70+
71+
public abstract int execute(Object x);
72+
73+
protected int toIntInternal(@SuppressWarnings("unused") long x) {
74+
throw new IllegalStateException("should not be reached");
75+
}
76+
77+
protected int toIntInternal(@SuppressWarnings("unused") PInt x) {
78+
throw new IllegalStateException("should not be reached");
79+
}
80+
81+
public static CastToJavaIntNode create() {
82+
return CastToJavaIntExactNodeGen.create();
83+
}
84+
85+
public static CastToJavaIntNode createLossy() {
86+
return CastToJavaIntLossyNodeGen.create();
87+
}
88+
89+
public static CastToJavaIntNode getUncached() {
90+
return CastToJavaIntExactNodeGen.getUncached();
91+
}
92+
93+
public static CastToJavaIntNode createLossyUncached() {
94+
return CastToJavaIntLossyNodeGen.getUncached();
95+
}
96+
97+
@Specialization
98+
public int toInt(int x) {
99+
return x;
100+
}
101+
102+
@Specialization
103+
public int toInt(long x) {
104+
return toIntInternal(x);
105+
}
106+
107+
@Specialization
108+
public int toInt(PInt x) {
109+
return toIntInternal(x);
110+
}
111+
112+
@Specialization(guards = "!isNumber(x)")
113+
public int toInt(Object x,
114+
@Cached BranchProfile noValueProfile,
115+
@Cached BranchProfile integerProfile,
116+
@Cached BranchProfile longProfile,
117+
@Cached BranchProfile pIntProfile,
118+
@Cached BranchProfile errorProfile,
119+
@Cached PRaiseNode raise,
120+
@Cached LookupAndCallUnaryDynamicNode callIntNode) {
121+
Object result = callIntNode.executeObject(x, __INT__);
122+
if (result instanceof PNone) {
123+
noValueProfile.enter();
124+
throw raise.raise(TypeError, "must be numeric, not %p", x);
125+
} else if (result instanceof Integer) {
126+
integerProfile.enter();
127+
return ((Integer) result).intValue();
128+
} else if (result instanceof Long) {
129+
longProfile.enter();
130+
return toIntInternal((long) result);
131+
} else if (result instanceof PInt) {
132+
pIntProfile.enter();
133+
return toIntInternal((PInt) result);
134+
}
135+
errorProfile.enter();
136+
throw raise.raise(TypeError, "%p.__int__ returned a non int (type %p)", x, result);
137+
}
138+
139+
@GenerateUncached
140+
abstract static class CastToJavaIntLossyNode extends CastToJavaIntNode {
141+
@Override
142+
protected int toIntInternal(long x) {
143+
return (int) x;
144+
}
145+
146+
@Override
147+
protected int toIntInternal(PInt x) {
148+
return x.intValue();
149+
}
150+
}
151+
152+
@GenerateUncached
153+
abstract static class CastToJavaIntExactNode extends CastToJavaIntNode {
154+
@Override
155+
protected int toIntInternal(long x) {
156+
try {
157+
return PInt.intValueExact(x);
158+
} catch (ArithmeticException e) {
159+
CompilerDirectives.transferToInterpreter();
160+
throw PRaiseNode.getUncached().raise(TypeError, "value too large to find into index-sized integer");
161+
}
162+
}
163+
164+
@Override
165+
protected int toIntInternal(PInt x) {
166+
try {
167+
return x.intValueExact();
168+
} catch (ArithmeticException e) {
169+
CompilerDirectives.transferToInterpreter();
170+
throw PRaiseNode.getUncached().raise(TypeError, "%s cannot be interpreted as int (type %p)", x);
171+
}
172+
}
173+
}
174+
}

0 commit comments

Comments
 (0)