Skip to content

Commit 2fb24ed

Browse files
committed
Fix bytes hashing in source_hash
1 parent 7e2aa1f commit 2fb24ed

File tree

3 files changed

+56
-39
lines changed

3 files changed

+56
-39
lines changed

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

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -49,15 +49,16 @@
4949
import org.graalvm.nativeimage.ImageInfo;
5050

5151
import com.oracle.graal.python.PythonLanguage;
52+
import com.oracle.graal.python.annotations.ArgumentClinic;
5253
import com.oracle.graal.python.builtins.Builtin;
5354
import com.oracle.graal.python.builtins.CoreFunctions;
5455
import com.oracle.graal.python.builtins.Python3Core;
5556
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
5657
import com.oracle.graal.python.builtins.PythonBuiltins;
5758
import com.oracle.graal.python.builtins.objects.PNone;
5859
import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary;
60+
import com.oracle.graal.python.builtins.objects.bytes.BytesNodes;
5961
import com.oracle.graal.python.builtins.objects.bytes.PBytes;
60-
import com.oracle.graal.python.builtins.objects.bytes.PBytesLike;
6162
import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.ExecModuleNode;
6263
import com.oracle.graal.python.builtins.objects.cext.capi.DynamicObjectNativeWrapper;
6364
import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionNodesFactory.DefaultCheckFunctionResultNodeGen;
@@ -72,7 +73,6 @@
7273
import com.oracle.graal.python.builtins.objects.code.PCode;
7374
import com.oracle.graal.python.builtins.objects.common.HashingStorageLibrary;
7475
import com.oracle.graal.python.builtins.objects.ints.IntBuiltins;
75-
import com.oracle.graal.python.builtins.objects.ints.PInt;
7676
import com.oracle.graal.python.builtins.objects.module.PythonModule;
7777
import com.oracle.graal.python.builtins.objects.object.PythonObject;
7878
import com.oracle.graal.python.builtins.objects.str.PString;
@@ -82,6 +82,8 @@
8282
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
8383
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
8484
import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
85+
import com.oracle.graal.python.nodes.function.builtins.PythonBinaryClinicBuiltinNode;
86+
import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider;
8587
import com.oracle.graal.python.nodes.util.CastToJavaStringNode;
8688
import com.oracle.graal.python.parser.sst.SerializationUtils;
8789
import com.oracle.graal.python.runtime.ExecutionContext.IndirectCallContext;
@@ -378,30 +380,25 @@ private static void doPostInit(Python3Core core, PythonBuiltins builtins) {
378380
}
379381
}
380382

381-
@Builtin(name = "source_hash", minNumOfPositionalArgs = 2)
383+
@Builtin(name = "source_hash", minNumOfPositionalArgs = 2, parameterNames = {"key", "source"})
384+
@ArgumentClinic(name = "key", conversion = ArgumentClinic.ClinicConversion.Long)
385+
@ArgumentClinic(name = "source", conversion = ArgumentClinic.ClinicConversion.ReadableBuffer)
382386
@GenerateNodeFactory
383-
public abstract static class SourceHashNode extends PythonBinaryBuiltinNode {
387+
public abstract static class SourceHashNode extends PythonBinaryClinicBuiltinNode {
384388
@Specialization
385-
@TruffleBoundary
386-
PBytes run(long magicNumber, PBytesLike source) {
389+
PBytes run(long magicNumber, Object sourceBuffer,
390+
@Cached BytesNodes.HashBufferNode hashBufferNode) {
387391
byte[] hash = new byte[Long.BYTES];
388-
long hashCode = magicNumber ^ source.hashCode();
392+
long hashCode = magicNumber ^ hashBufferNode.execute(sourceBuffer);
389393
for (int i = 0; i < hash.length; i++) {
390394
hash[i] = (byte) (hashCode << (8 * i));
391395
}
392396
return factory().createBytes(hash);
393397
}
394398

395-
@Specialization
396-
@TruffleBoundary
397-
PBytes run(PInt magicNumber, PBytesLike source) {
398-
return run(magicNumber.longValue(), source);
399-
}
400-
401-
@Specialization
402-
@TruffleBoundary
403-
PBytes run(int magicNumber, PBytesLike source) {
404-
return run((long) magicNumber, source);
399+
@Override
400+
protected ArgumentClinicProvider getArgumentClinic() {
401+
return ImpModuleBuiltinsClinicProviders.SourceHashNodeClinicProviderGen.INSTANCE;
405402
}
406403
}
407404

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/BytesBuiltins.java

Lines changed: 4 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -443,28 +443,10 @@ public Object mul(@SuppressWarnings("unused") Object self, Object other) {
443443
@Builtin(name = __HASH__, minNumOfPositionalArgs = 1)
444444
@GenerateNodeFactory
445445
abstract static class HashNode extends PythonUnaryBuiltinNode {
446-
@Specialization(guards = "isByteStorage(self)")
447-
@TruffleBoundary
448-
static long hash(PBytes self) {
449-
ByteSequenceStorage storage = (ByteSequenceStorage) self.getSequenceStorage();
450-
byte[] array = storage.getInternalByteArray();
451-
int len = storage.length();
452-
int result = 1;
453-
for (int i = 0; i < len; i++) {
454-
result = 31 * result + array[i];
455-
}
456-
return result;
457-
}
458-
459-
@Specialization(guards = "!isByteStorage(self)", limit = "1")
460-
static long hashNative(PBytes self,
461-
@CachedLibrary("self") PythonBufferAccessLibrary bufferLib) {
462-
int result = 1;
463-
int len = bufferLib.getBufferLength(self);
464-
for (int i = 0; i < len; i++) {
465-
result = 31 * result + bufferLib.readByte(self, i);
466-
}
467-
return result;
446+
@Specialization
447+
long hash(PBytes bytes,
448+
@Cached BytesNodes.HashBufferNode hashBufferNode) {
449+
return hashBufferNode.execute(bytes);
468450
}
469451
}
470452

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/BytesNodes.java

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -858,4 +858,42 @@ private static String encodeFSDefault(byte[] path) {
858858
return createUTF8String(path);
859859
}
860860
}
861+
862+
@GenerateUncached
863+
public abstract static class HashBufferNode extends PNodeWithContext {
864+
public abstract long execute(Object buffer);
865+
866+
@Specialization(guards = "bufferLib.hasInternalByteArray(buffer)", limit = "2")
867+
static long hashDirect(Object buffer,
868+
@CachedLibrary("buffer") PythonBufferAccessLibrary bufferLib) {
869+
PythonBufferAccessLibrary.assertIsBuffer(buffer);
870+
int len = bufferLib.getBufferLength(buffer);
871+
byte[] array = bufferLib.getInternalByteArray(buffer);
872+
int result = 1;
873+
for (int i = 0; i < len; i++) {
874+
result = 31 * result + array[i];
875+
}
876+
return result;
877+
}
878+
879+
@Specialization(guards = "!bufferLib.hasInternalByteArray(buffer)", limit = "2")
880+
static long hashIndirect(Object buffer,
881+
@CachedLibrary("buffer") PythonBufferAccessLibrary bufferLib) {
882+
PythonBufferAccessLibrary.assertIsBuffer(buffer);
883+
int len = bufferLib.getBufferLength(buffer);
884+
int result = 1;
885+
for (int i = 0; i < len; i++) {
886+
result = 31 * result + bufferLib.readByte(buffer, i);
887+
}
888+
return result;
889+
}
890+
891+
public static HashBufferNode create() {
892+
return BytesNodesFactory.HashBufferNodeGen.create();
893+
}
894+
895+
public static HashBufferNode getUncached() {
896+
return BytesNodesFactory.HashBufferNodeGen.getUncached();
897+
}
898+
}
861899
}

0 commit comments

Comments
 (0)