diff --git a/src/compiler/library.jl b/src/compiler/library.jl index db6b29446..5258ae2e1 100644 --- a/src/compiler/library.jl +++ b/src/compiler/library.jl @@ -337,9 +337,44 @@ tag_value_io["SARC"] = ( id = String(readuntil(io, UInt8(0))) compressed = read(io, nb - sizeof(id) - 1) - # unpad and decompress the archive - i = findlast(!iszero, compressed) - archive = transcode(Bzip2Decompressor, compressed[1:i]) + # Bzip2Decompressor doesn't support padding (JuliaIO/CodecBzip2.jl#31), + # so find the end marker and truncate the archive (in a naive way, + # but these source code archives are expected to be small) + compressed[1:2] == [0x42, 0x5a] || error("Not a BZip2 archive") + trailing_bytes = 10 # end marker + checksum + end_marker = 0x177245385090 + i = 1 + while i < length(compressed) - trailing_bytes + # aligned match + current_value = UInt64(compressed[i]) << 40 | + UInt64(compressed[i+1]) << 32 | + UInt64(compressed[i+2]) << 24 | + UInt64(compressed[i+3]) << 16 | + UInt64(compressed[i+4]) << 8 | + UInt64(compressed[i+5]) + if current_value == end_marker + break + end + + # misaligned match + current_value = UInt64(current_value) << 8 | compressed[i+6] + if end_marker in ((current_value >> 1) & 0xffffffffffff, + (current_value >> 2) & 0xffffffffffff, + (current_value >> 3) & 0xffffffffffff, + (current_value >> 4) & 0xffffffffffff, + (current_value >> 5) & 0xffffffffffff, + (current_value >> 6) & 0xffffffffffff, + (current_value >> 7) & 0xffffffffffff) + i += 1 + break + end + + i += 1 + end + compressed = compressed[1:i+trailing_bytes-1] + + # decompress the archive + archive = transcode(Bzip2Decompressor, compressed) (; id, archive) end, diff --git a/test/metallib/Makefile b/test/metallib/Makefile index 6bf7a1af2..6660f1ff9 100644 --- a/test/metallib/Makefile +++ b/test/metallib/Makefile @@ -1,5 +1,5 @@ METAL := xcrun -sdk macosx metal -MACOSX_VERSIONS := 11 12 13 14 +MACOSX_VERSIONS := 11 12 13 14 15 SOURCES := $(wildcard *.metal) METALLIBS := $(foreach ver,$(MACOSX_VERSIONS),$(SOURCES:.metal=.$(ver).metallib)) diff --git a/test/metallib/constants.15.metallib b/test/metallib/constants.15.metallib new file mode 100644 index 000000000..363e8372f Binary files /dev/null and b/test/metallib/constants.15.metallib differ diff --git a/test/metallib/debuginfo.15.metallib b/test/metallib/debuginfo.15.metallib new file mode 100644 index 000000000..1dadaa7c0 Binary files /dev/null and b/test/metallib/debuginfo.15.metallib differ diff --git a/test/metallib/kernel.15.metallib b/test/metallib/kernel.15.metallib new file mode 100644 index 000000000..9d8e470c3 Binary files /dev/null and b/test/metallib/kernel.15.metallib differ diff --git a/test/metallib/kernels.15.metallib b/test/metallib/kernels.15.metallib new file mode 100644 index 000000000..21f5b9587 Binary files /dev/null and b/test/metallib/kernels.15.metallib differ diff --git a/test/metallib/sources.15.metallib b/test/metallib/sources.15.metallib new file mode 100644 index 000000000..b684b2376 Binary files /dev/null and b/test/metallib/sources.15.metallib differ