commit: 81698ccb285eea2cb5516b68349b217320cd87fc
parent 8823d6461ed16d8e353a9b84d707ff79f53dc802
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date: Wed, 23 Nov 2022 03:44:16 +0100
Add support for Racket bytecode
Diffstat:
8 files changed, 47 insertions(+), 13 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -6,3 +6,4 @@
/test/fixtures/hello.a
/test/fixtures/hello.o
/test/check_dir-fixtures/
+/test/fixtures/compiled/*.dep
diff --git a/.reuse/dep5 b/.reuse/dep5
@@ -3,6 +3,6 @@ Upstream-Name: deblob
Upstream-Contact: deblob Authors <https://hacktivis.me/projects/deblob>
Source: https://hacktivis.me/projects/deblob
-Files: test/fixtures/pyc/*.pyc test/fixtures/pickle/*.pickle test/fixtures/hello.luac* test/fixtures/hello.class test/fixtures/hello.nqp.moarvm test/fixtures/hello.pir.pbc test/fixtures/perl_storage.pst test/fixtures/hello.beam test/fixtures/empty.dtb test/fixtures/hello-chez.so test/fixtures/hello.n test/fixtures/hello-ocaml.*
+Files: test/fixtures/pyc/*.pyc test/fixtures/pickle/*.pickle test/fixtures/hello.luac* test/fixtures/hello.class test/fixtures/hello.nqp.moarvm test/fixtures/hello.pir.pbc test/fixtures/perl_storage.pst test/fixtures/hello.beam test/fixtures/empty.dtb test/fixtures/hello-chez.so test/fixtures/hello.n test/fixtures/hello-ocaml.* test/fixtures/compiled/hello-racket_rkt.zo
Copyright: 2019-2022 deblob Authors <https://hacktivis.me/projects/deblob>
License: BSD-3-Clause
diff --git a/deblob.1 b/deblob.1
@@ -77,6 +77,8 @@ Chez Scheme bytecode
NekoVM bytecode
.It
OCaml bytecode and native binaries
+.It
+Racket bytecode
.El
.Sh EXAMPLES
The following code block shows how it can be used in Gentoo's
diff --git a/main.ha b/main.ha
@@ -51,6 +51,7 @@ const magic: [_][]u8 = [
];
const dos_magic: []u8 = ['M', 'Z'];
const pe_magic: []u8 = ['P', 'E', 0x00, 0x00];
+const racket: []u8 = ['r', 'a', 'c', 'k', 'e', 't'];
fn is_blob(filename: str) (bool | fs::error | io::error) = {
static let buffer: [512]u8 = [0...];
@@ -79,6 +80,26 @@ fn is_blob(filename: str) (bool | fs::error | io::error) = {
};
};
+ // Special check to detect racket bytecode
+ if (bytes::hasprefix(buffer, ['#', '~'])) {
+ // From src/expander/compile/write-linklet.rkt in racket:
+ // - #~
+ // - length-prefixed version string (ie. "\x038.5")
+ // - length-prefixed virtual machine string (ie. "\x06racket")
+ // - 'D' / 'B'
+ // Here it verifies that the virtual machine string is racket, assuming none other is supported in the wild.
+ // Racket itself only matches against '#~' which is small & only printable-ASCII, so too prone to false positives
+ const version_len = buffer[2];
+ const version_end = 2+version_len;
+
+ const racket_len = buffer[version_end+1];
+ const racket_start = version_end+2;
+
+ if(bytes::equal(racket, buffer[racket_start..racket_start+racket_len])) {
+ return true;
+ };
+ };
+
return false;
};
@@ -86,6 +107,8 @@ fn is_blob(filename: str) (bool | fs::error | io::error) = {
const tests = [
(false, "test/fixtures/empty"),
(false, "test/fixtures/empty.dts"),
+ (false, "test/fixtures/hello-ocaml.ml"),
+ (false, "test/fixtures/hello-racket.rkt"),
(false, "test/fixtures/hello.1"),
(false, "test/fixtures/hello.c"),
(false, "test/fixtures/hello.cs"),
@@ -97,10 +120,17 @@ fn is_blob(filename: str) (bool | fs::error | io::error) = {
(false, "test/fixtures/hello.pir"),
(false, "test/fixtures/hello.py"),
(false, "test/fixtures/hello.wat"),
- (false, "test/fixtures/hello-ocaml.ml"),
(false, "test/fixtures/perl_storage.pm"),
+ (true, "test/fixtures/compiled/hello-racket_rkt.zo"),
(true, "test/fixtures/empty.dtb"),
(true, "test/fixtures/hello"),
+ (true, "test/fixtures/hello-ocaml.a"),
+ (true, "test/fixtures/hello-ocaml.cma"),
+ (true, "test/fixtures/hello-ocaml.cmi"),
+ (true, "test/fixtures/hello-ocaml.cmo"),
+ (true, "test/fixtures/hello-ocaml.cmx"),
+ (true, "test/fixtures/hello-ocaml.cmxa"),
+ (true, "test/fixtures/hello-ocaml.o"),
(true, "test/fixtures/hello.a"),
(true, "test/fixtures/hello.beam"),
(true, "test/fixtures/hello.class"),
@@ -113,18 +143,11 @@ fn is_blob(filename: str) (bool | fs::error | io::error) = {
(true, "test/fixtures/hello.pir.pbc"),
(true, "test/fixtures/hello.wasm"),
(true, "test/fixtures/monodx.dll"),
- (true, "test/fixtures/hello-ocaml.a"),
- (true, "test/fixtures/hello-ocaml.cma"),
- (true, "test/fixtures/hello-ocaml.cmi"),
- (true, "test/fixtures/hello-ocaml.cmo"),
- (true, "test/fixtures/hello-ocaml.cmx"),
- (true, "test/fixtures/hello-ocaml.cmxa"),
- (true, "test/fixtures/hello-ocaml.o"),
- //(true, "test/fixtures/option.rom"),
(true, "test/fixtures/perl_storage.pst"),
(true, "test/fixtures/pickle/hello.4.pickle"),
(true, "test/fixtures/pickle/hello.5.pickle"),
(true, "test/fixtures/qemu_vga.ndrv"),
+ //(true, "test/fixtures/option.rom"),
];
for (let i = 0z; i < len(tests); i += 1) {
@@ -225,7 +248,7 @@ fn check_dir(dirname: str) (void | errors::invalid) = {
case let e: fs::error =>
fmt::fatalf("os::readdir({}): {}", dirname, fs::strerror(e));
};
- assert(len(files_before) == 50);
+ assert(len(files_before) == 52);
const ret = check_dir(dirname);
assert(ret is void);
@@ -236,7 +259,7 @@ fn check_dir(dirname: str) (void | errors::invalid) = {
case let e: fs::error =>
fmt::fatalf("os::readdir({}): {}", dirname, fs::strerror(e));
};
- assert(len(files_after) == 26);
+ assert(len(files_after) == 28);
};
export fn main() void = {
diff --git a/test/fixtures/Makefile b/test/fixtures/Makefile
@@ -16,7 +16,7 @@ OCAMLC ?= ocamlc
OCAMLOPT ?= ocamlopt
NONBUNDLED_BLOBS = hello hello.a hello.o
-TEST_BLOBS = $(NONBUNDLED_BLOBS) hello.exe hello.luac53 hello.luac54 hello.wasm hello.class hello.nqp.moarvm hello.pir.pbc perl_storage.pst hello.beam empty.dtb hello-chez.so hello.n hello-ocaml.cmo hello-ocaml.cma hello-ocaml.cmx hello-ocaml.cmxa
+TEST_BLOBS = $(NONBUNDLED_BLOBS) hello.exe hello.luac53 hello.luac54 hello.wasm hello.class hello.nqp.moarvm hello.pir.pbc perl_storage.pst hello.beam empty.dtb hello-chez.so hello.n hello-ocaml.cmo hello-ocaml.cma hello-ocaml.cmx hello-ocaml.cmxa compiled/hello-racket_rkt.zo
base: $(NONBUNDLED_BLOBS)
@@ -86,3 +86,6 @@ hello-ocaml.cmx: hello-ocaml.ml
hello-ocaml.cmxa: hello-ocaml.cmx
$(OCAMLOPT) -a -o hello-ocaml.cmxa hello-ocaml.cmx
+
+compiled/hello-racket_rkt.zo: hello-racket.rkt
+ racket -e '(require compiler/cm)(managed-compile-zo "hello-racket.rkt")'
diff --git a/test/fixtures/README.md b/test/fixtures/README.md
@@ -14,6 +14,7 @@ Dependencies:
- Device Tree Compiler, default one is [dtc](https://git.kernel.org/cgit/utils/dtc/dtc.git/)
- [NekoVM Compiler](https://nekovm.org/)
- OCaml bytecode(ocamlc) and native(ocamlopt) compilers
+- Racket
Rebuilding:
```
diff --git a/test/fixtures/compiled/hello-racket_rkt.zo b/test/fixtures/compiled/hello-racket_rkt.zo
Binary files differ.
diff --git a/test/fixtures/hello-racket.rkt b/test/fixtures/hello-racket.rkt
@@ -0,0 +1,4 @@
+; SPDX-FileCopyrightText: 2019-2022 deblob Authors <https://hacktivis.me/projects/deblob>
+; SPDX-License-Identifier: BSD-3-Clause
+#lang racket
+(displayln "Hello, World!")