summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--buf.c14
-rw-r--r--buf.h2
-rw-r--r--itypes.c2
-rw-r--r--parser.c9
-rw-r--r--share/txr/stdlib/compiler.tl6
5 files changed, 30 insertions, 3 deletions
diff --git a/buf.c b/buf.c
index efd2e4a6..40e81607 100644
--- a/buf.c
+++ b/buf.c
@@ -914,6 +914,20 @@ val get_buf_from_stream(val stream)
return s->buf;
}
+void buf_swap32(val buf)
+{
+ val self = lit("buf-swap32");
+ struct buf *b = buf_handle(buf, self);
+ mem_t *data = b->data, *end = data + c_num(b->len);
+
+ for (; data + 3 < end; data += 4) {
+ u32_t sw32 = *coerce(u32_t *, data);
+ sw32 = ((sw32 & 0xFF00FF00U) >> 8) | ((sw32 & 0x00FF00FFU) << 8);
+ sw32 = ((sw32 & 0xFFFF0000U) >> 16) | ((sw32 & 0x0000FFFFU) << 16);
+ *coerce(u32_t *, data) = sw32;
+ }
+}
+
void buf_init(void)
{
reg_fun(intern(lit("make-buf"), user_package), func_n3o(make_buf, 1));
diff --git a/buf.h b/buf.h
index 107d7608..cf394ff0 100644
--- a/buf.h
+++ b/buf.h
@@ -106,4 +106,6 @@ val buf_pprint(val buf, val stream);
val make_buf_stream(val buf_opt);
val get_buf_from_stream(val stream);
+void buf_swap32(val buf);
+
void buf_init(void);
diff --git a/itypes.c b/itypes.c
index a963e330..4e973d5f 100644
--- a/itypes.c
+++ b/itypes.c
@@ -228,5 +228,5 @@ void itypes_init()
volatile unsigned char uc[sizeof (unsigned)];
} u = { 0xff };
- itypes_little_endian = (u.uc[0] = 0xff);
+ itypes_little_endian = (u.uc[0] == 0xff);
}
diff --git a/parser.c b/parser.c
index 5d310b5b..93d9703c 100644
--- a/parser.c
+++ b/parser.c
@@ -55,6 +55,8 @@
#include "cadr.h"
#include "struct.h"
#include "parser.h"
+#include "itypes.h"
+#include "buf.h"
#include "vm.h"
#include "txr.h"
#if HAVE_TERMIOS
@@ -611,6 +613,7 @@ static val read_file_common(val stream, val error_stream, val compiled)
val error_val = gensym(nil);
val name = stream_get_prop(stream, name_k);
val first = t;
+ val big_endian = nil;
for (;;) {
val form = lisp_parse(stream, error_stream, error_val, name, colon_k);
@@ -625,11 +628,12 @@ static val read_file_common(val stream, val error_stream, val compiled)
}
if (compiled && first) {
- val major = pop(&form);
+ val major = car(form);
if (gt(major, zero))
uw_throwf(error_s,
lit("cannot load ~s; it was compiled by a newer implementation"),
stream, nao);
+ big_endian = caddr(form);
first = nil;
} else if (compiled) {
for (; form; form = cdr(form)) {
@@ -640,6 +644,9 @@ static val read_file_common(val stream, val error_stream, val compiled)
val datavec = pop(&item);
val funvec = car(item);
val desc = vm_make_desc(nlevels, nregs, bytecode, datavec, funvec);
+ if ((big_endian && itypes_little_endian) ||
+ (!big_endian && !itypes_little_endian))
+ buf_swap32(bytecode);
(void) vm_execute_toplevel(desc);
gc_hint(desc);
}
diff --git a/share/txr/stdlib/compiler.tl b/share/txr/stdlib/compiler.tl
index 6a8bc59c..a10f4f14 100644
--- a/share/txr/stdlib/compiler.tl
+++ b/share/txr/stdlib/compiler.tl
@@ -1313,6 +1313,10 @@
(defvar *eval*)
+(defvarl %big-endian% (equal (ffi-put 1 (ffi uint32)) #b'00000001'))
+
+(defvarl %tlo-ver% ^(0 0 ,%big-endian%))
+
(defun open-compile-streams (in-path out-path)
(let* ((rsuff (r$ %file-suff-rx% in-path))
(suff (if rsuff [in-path rsuff]))
@@ -1386,7 +1390,7 @@
(sys:vm-execute-toplevel vm-desc))
(when *emit*
out.(add flat-vd)))))))))
- (prinl '(0 0) out-stream)
+ (prinl %tlo-ver% out-stream)
(unwind-protect
(whilet ((obj (read in-stream *stderr* err-ret))
((neq obj err-ret)))