diff --git a/eval.c b/eval.c index 56cfebb7..20f82d6e 100644 --- a/eval.c +++ b/eval.c @@ -1170,6 +1170,7 @@ static sexp sexp_load_dl (sexp ctx, sexp file, sexp env) { #ifdef __MINGW32__ #include static sexp sexp_load_dl (sexp ctx, sexp file, sexp env) { + sexp res; sexp_init_proc init; HINSTANCE handle = LoadLibraryA(sexp_string_data(file)); if(!handle) @@ -1179,7 +1180,9 @@ static sexp sexp_load_dl (sexp ctx, sexp file, sexp env) { FreeLibrary(handle); return sexp_compile_error(ctx, "dynamic library has no sexp_init_library", file); } - return init(ctx, NULL, 3, env, sexp_version, SEXP_ABI_IDENTIFIER); + res = init(ctx, NULL, 3, env, sexp_version, SEXP_ABI_IDENTIFIER); + if (res == SEXP_ABI_ERROR) res = sexp_global(ctx, SEXP_G_ABI_ERROR); + return res; } #else static sexp sexp_make_dl (sexp ctx, sexp file, void* handle) { @@ -1203,6 +1206,10 @@ static sexp sexp_load_dl (sexp ctx, sexp file, sexp env) { old_dl = sexp_context_dl(ctx); sexp_context_dl(ctx) = sexp_make_dl(ctx, file, handle); res = init(ctx, NULL, 3, env, sexp_version, SEXP_ABI_IDENTIFIER); + /* If the ABI is incompatible the library may not even be able to + properly reference a global, so it returns a special immediate + which we need to translate. */ + if (res == SEXP_ABI_ERROR) res = sexp_global(ctx, SEXP_G_ABI_ERROR); sexp_context_dl(ctx) = old_dl; sexp_gc_release2(ctx); return res; diff --git a/include/chibi/sexp.h b/include/chibi/sexp.h index 14852c24..4df3de3d 100755 --- a/include/chibi/sexp.h +++ b/include/chibi/sexp.h @@ -454,8 +454,9 @@ struct sexp_struct { #define SEXP_RAWDOT SEXP_MAKE_IMMEDIATE(7) /* internal use */ #define SEXP_STRING_OPORT SEXP_MAKE_IMMEDIATE(8) /* internal use */ #define SEXP_TRAMPOLINE SEXP_MAKE_IMMEDIATE(9) /* internal use */ +#define SEXP_ABI_ERROR SEXP_MAKE_IMMEDIATE(10) /* internal use */ #if SEXP_USE_OBJECT_BRACE_LITERALS -#define SEXP_CLOSE_BRACE SEXP_MAKE_IMMEDIATE(10) /* internal use */ +#define SEXP_CLOSE_BRACE SEXP_MAKE_IMMEDIATE(11) /* internal use */ #endif #if SEXP_USE_LIMITED_MALLOC diff --git a/lib/chibi/ast.c b/lib/chibi/ast.c index 37aedeec..2d3698b0 100644 --- a/lib/chibi/ast.c +++ b/lib/chibi/ast.c @@ -375,7 +375,7 @@ static sexp sexp_update_free_vars (sexp ctx, sexp self, sexp_sint_t n, sexp x) { sexp sexp_init_library (sexp ctx, sexp self, sexp_sint_t n, sexp env, const char* version, sexp_abi_identifier_t abi) { if (!(sexp_version_compatible(ctx, version, sexp_version) && sexp_abi_compatible(ctx, abi, SEXP_ABI_IDENTIFIER))) - return sexp_global(ctx, SEXP_G_ABI_ERROR); + return SEXP_ABI_ERROR; sexp_define_type(ctx, "Object", SEXP_OBJECT); sexp_define_type(ctx, "Number", SEXP_NUMBER); sexp_define_type(ctx, "Bignum", SEXP_BIGNUM); diff --git a/lib/chibi/disasm.c b/lib/chibi/disasm.c index 34610c30..4b1ca738 100644 --- a/lib/chibi/disasm.c +++ b/lib/chibi/disasm.c @@ -234,7 +234,7 @@ static sexp sexp_disasm (sexp ctx, sexp self, sexp_sint_t n, sexp bc, sexp out) sexp sexp_init_library (sexp ctx, sexp self, sexp_sint_t n, sexp env, const char* version, sexp_abi_identifier_t abi) { if (!(sexp_version_compatible(ctx, version, sexp_version) && sexp_abi_compatible(ctx, abi, SEXP_ABI_IDENTIFIER))) - return sexp_global(ctx, SEXP_G_ABI_ERROR); + return SEXP_ABI_ERROR; sexp_define_foreign_param(ctx, env, "disasm", 2, (sexp_proc1)sexp_disasm, "current-output-port"); return SEXP_VOID; } diff --git a/lib/chibi/heap-stats.c b/lib/chibi/heap-stats.c index af873ce2..0f4438c5 100644 --- a/lib/chibi/heap-stats.c +++ b/lib/chibi/heap-stats.c @@ -130,7 +130,7 @@ static sexp sexp_heap_dump (sexp ctx, sexp self, sexp_sint_t n, sexp depth) { sexp sexp_init_library (sexp ctx, sexp self, sexp_sint_t n, sexp env, const char* version, sexp_abi_identifier_t abi) { if (!(sexp_version_compatible(ctx, version, sexp_version) && sexp_abi_compatible(ctx, abi, SEXP_ABI_IDENTIFIER))) - return sexp_global(ctx, SEXP_G_ABI_ERROR); + return SEXP_ABI_ERROR; sexp_define_foreign(ctx, env, "heap-stats", 0, sexp_heap_stats); sexp_define_foreign_opt(ctx, env, "heap-dump", 1, sexp_heap_dump, SEXP_ONE); return SEXP_VOID; diff --git a/lib/chibi/optimize/profile.c b/lib/chibi/optimize/profile.c index 8759fedf..5fc4bb60 100644 --- a/lib/chibi/optimize/profile.c +++ b/lib/chibi/optimize/profile.c @@ -13,7 +13,7 @@ static sexp sexp_increment_cdr (sexp ctx, sexp self, sexp_sint_t n, sexp pair) { sexp sexp_init_library (sexp ctx, sexp self, sexp_sint_t n, sexp env, const char* version, sexp_abi_identifier_t abi) { if (!(sexp_version_compatible(ctx, version, sexp_version) && sexp_abi_compatible(ctx, abi, SEXP_ABI_IDENTIFIER))) - return sexp_global(ctx, SEXP_G_ABI_ERROR); + return SEXP_ABI_ERROR; sexp_define_foreign(ctx, env, "increment-cdr!", 1, sexp_increment_cdr); return SEXP_VOID; } diff --git a/lib/chibi/optimize/rest.c b/lib/chibi/optimize/rest.c index 3fb2f8d5..fbdcd417 100644 --- a/lib/chibi/optimize/rest.c +++ b/lib/chibi/optimize/rest.c @@ -23,7 +23,7 @@ sexp sexp_init_library (sexp ctx, sexp self, sexp_sint_t n, sexp env, const char sexp_gc_var2(name, op); if (!(sexp_version_compatible(ctx, version, sexp_version) && sexp_abi_compatible(ctx, abi, SEXP_ABI_IDENTIFIER))) - return sexp_global(ctx, SEXP_G_ABI_ERROR); + return SEXP_ABI_ERROR; sexp_gc_preserve2(ctx, name, op); sexp_define_foreign(ctx, env, "num-parameters", 0, sexp_num_parameters); op = copy_opcode(ctx, &local_ref_op); diff --git a/lib/chibi/weak.c b/lib/chibi/weak.c index d2ed8a5a..7b5701f3 100644 --- a/lib/chibi/weak.c +++ b/lib/chibi/weak.c @@ -62,7 +62,7 @@ sexp sexp_init_library (sexp ctx, sexp self, sexp_sint_t n, sexp env, const char sexp_gc_var3(name, t, op); if (!(sexp_version_compatible(ctx, version, sexp_version) && sexp_abi_compatible(ctx, abi, SEXP_ABI_IDENTIFIER))) - return sexp_global(ctx, SEXP_G_ABI_ERROR); + return SEXP_ABI_ERROR; sexp_gc_preserve3(ctx, name, t, op); name = sexp_c_string(ctx, "Ephemeron", -1); diff --git a/lib/srfi/18/threads.c b/lib/srfi/18/threads.c index b2aa23ce..3c65032f 100644 --- a/lib/srfi/18/threads.c +++ b/lib/srfi/18/threads.c @@ -622,7 +622,7 @@ sexp sexp_init_library (sexp ctx, sexp self, sexp_sint_t n, sexp env, const char sexp_gc_var1(name); if (!(sexp_version_compatible(ctx, version, sexp_version) && sexp_abi_compatible(ctx, abi, SEXP_ABI_IDENTIFIER))) - return sexp_global(ctx, SEXP_G_ABI_ERROR); + return SEXP_ABI_ERROR; sexp_gc_preserve1(ctx, name); sexp_global(ctx, SEXP_G_THREADS_MUTEX_ID) = sexp_lookup_named_type(ctx, env, "Mutex"); diff --git a/lib/srfi/27/rand.c b/lib/srfi/27/rand.c index a2beb3b5..26a50c71 100644 --- a/lib/srfi/27/rand.c +++ b/lib/srfi/27/rand.c @@ -171,7 +171,7 @@ sexp sexp_init_library (sexp ctx, sexp self, sexp_sint_t n, sexp env, const char sexp_gc_var2(name, op); if (!(sexp_version_compatible(ctx, version, sexp_version) && sexp_abi_compatible(ctx, abi, SEXP_ABI_IDENTIFIER))) - return sexp_global(ctx, SEXP_G_ABI_ERROR); + return SEXP_ABI_ERROR; sexp_gc_preserve2(ctx, name, op); name = sexp_c_string(ctx, "random-source", -1); diff --git a/lib/srfi/33/bit.c b/lib/srfi/33/bit.c index 078808eb..a9806a18 100644 --- a/lib/srfi/33/bit.c +++ b/lib/srfi/33/bit.c @@ -298,7 +298,7 @@ static sexp sexp_bit_set_p (sexp ctx, sexp self, sexp_sint_t n, sexp i, sexp x) sexp sexp_init_library (sexp ctx, sexp self, sexp_sint_t n, sexp env, const char* version, sexp_abi_identifier_t abi) { if (!(sexp_version_compatible(ctx, version, sexp_version) && sexp_abi_compatible(ctx, abi, SEXP_ABI_IDENTIFIER))) - return sexp_global(ctx, SEXP_G_ABI_ERROR); + return SEXP_ABI_ERROR; sexp_define_foreign(ctx, env, "bit-and", 2, sexp_bit_and); sexp_define_foreign(ctx, env, "bit-ior", 2, sexp_bit_ior); sexp_define_foreign(ctx, env, "bit-xor", 2, sexp_bit_xor); diff --git a/lib/srfi/39/param.c b/lib/srfi/39/param.c index 02da69bc..5cd1c90c 100644 --- a/lib/srfi/39/param.c +++ b/lib/srfi/39/param.c @@ -29,7 +29,7 @@ static sexp sexp_parameter_converter (sexp ctx, sexp self, sexp_sint_t n, sexp p sexp sexp_init_library (sexp ctx, sexp self, sexp_sint_t n, sexp env, const char* version, sexp_abi_identifier_t abi) { if (!(sexp_version_compatible(ctx, version, sexp_version) && sexp_abi_compatible(ctx, abi, SEXP_ABI_IDENTIFIER))) - return sexp_global(ctx, SEXP_G_ABI_ERROR); + return SEXP_ABI_ERROR; sexp_define_foreign(ctx, env, "%make-parameter", 2, sexp_make_parameter); sexp_define_foreign(ctx, env, "parameter-converter", 1, sexp_parameter_converter); diff --git a/lib/srfi/69/hash.c b/lib/srfi/69/hash.c index d0646843..30816072 100644 --- a/lib/srfi/69/hash.c +++ b/lib/srfi/69/hash.c @@ -239,7 +239,7 @@ static sexp sexp_hash_table_delete (sexp ctx, sexp self, sexp_sint_t n, sexp ht, sexp sexp_init_library (sexp ctx, sexp self, sexp_sint_t n, sexp env, const char* version, sexp_abi_identifier_t abi) { if (!(sexp_version_compatible(ctx, version, sexp_version) && sexp_abi_compatible(ctx, abi, SEXP_ABI_IDENTIFIER))) - return sexp_global(ctx, SEXP_G_ABI_ERROR); + return SEXP_ABI_ERROR; sexp_define_foreign_opt(ctx, env, "string-hash", 2, sexp_string_hash, HASH_BOUND); sexp_define_foreign_opt(ctx, env, "string-ci-hash", 2, sexp_string_ci_hash, HASH_BOUND); diff --git a/lib/srfi/95/qsort.c b/lib/srfi/95/qsort.c index acbc3e92..477ad614 100644 --- a/lib/srfi/95/qsort.c +++ b/lib/srfi/95/qsort.c @@ -245,7 +245,7 @@ static sexp sexp_sort_x (sexp ctx, sexp self, sexp_sint_t n, sexp seq, sexp sexp_init_library (sexp ctx, sexp self, sexp_sint_t n, sexp env, const char* version, sexp_abi_identifier_t abi) { if (!(sexp_version_compatible(ctx, version, sexp_version) && sexp_abi_compatible(ctx, abi, SEXP_ABI_IDENTIFIER))) - return sexp_global(ctx, SEXP_G_ABI_ERROR); + return SEXP_ABI_ERROR; sexp_define_foreign(ctx, env, "object-cmp", 2, sexp_object_compare_op); sexp_define_foreign_opt(ctx, env, "sort!", 3, sexp_sort_x, SEXP_FALSE); return SEXP_VOID; diff --git a/lib/srfi/98/env.c b/lib/srfi/98/env.c index 29cfba25..486d5fe8 100644 --- a/lib/srfi/98/env.c +++ b/lib/srfi/98/env.c @@ -47,7 +47,7 @@ sexp sexp_get_environment_variables (sexp ctx, sexp self, sexp_sint_t n) { sexp sexp_init_library (sexp ctx, sexp self, sexp_sint_t n, sexp env, const char* version, sexp_abi_identifier_t abi) { if (!(sexp_version_compatible(ctx, version, sexp_version) && sexp_abi_compatible(ctx, abi, SEXP_ABI_IDENTIFIER))) - return sexp_global(ctx, SEXP_G_ABI_ERROR); + return SEXP_ABI_ERROR; sexp_define_foreign(ctx, env, "get-environment-variable", 1, sexp_get_environment_variable); sexp_define_foreign(ctx, env, "get-environment-variables", 0, sexp_get_environment_variables); return SEXP_VOID; diff --git a/tools/chibi-ffi b/tools/chibi-ffi index d7705a82..30fb758f 100755 --- a/tools/chibi-ffi +++ b/tools/chibi-ffi @@ -1679,7 +1679,7 @@ " sexp_gc_var3(name, tmp, op);\n" " if (!(sexp_version_compatible(ctx, version, sexp_version)\n" " && sexp_abi_compatible(ctx, abi, SEXP_ABI_IDENTIFIER)))\n" - " return sexp_global(ctx, SEXP_G_ABI_ERROR);\n" + " return SEXP_ABI_ERROR;\n" " sexp_gc_preserve3(ctx, name, tmp, op);\n") (for-each write-const *consts*) (for-each write-type *types*)