mirror of
https://github.com/janet-lang/janet
synced 2024-11-28 11:09:54 +00:00
Add API version checking for modules.
Checking now actively implemented for dynamic modules in a fully backwards compatible way.
This commit is contained in:
parent
c8c6419013
commit
bcbe42ab23
@ -1,6 +1,10 @@
|
||||
# Changelog
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## Unreleased
|
||||
- Add API compatibility checking for modules. This will let native modules not load
|
||||
when the host program is not of a compatible version or configuration.
|
||||
|
||||
## 0.6.0 - 2019-05-29
|
||||
- `file/close` returns exit code when closing file opened with `file/popen`.
|
||||
- Add `os/rename`
|
||||
|
@ -26,14 +26,15 @@
|
||||
#include "fiber.h"
|
||||
#endif
|
||||
|
||||
static JanetBuildConfig *api_build_config = &(JanetBuildConfig) {
|
||||
.api_version = JANET_API_VERSION,
|
||||
.single_threaded = JANET_SINGLE_THREADED_BIT,
|
||||
.nanbox = JANET_NANBOX_BIT
|
||||
static const JanetBuildConfig api_build_config = (JanetBuildConfig) {
|
||||
JANET_VERSION_MAJOR,
|
||||
JANET_VERSION_MINOR,
|
||||
JANET_VERSION_PATCH,
|
||||
JANET_CURRENT_CONFIG_BITS
|
||||
};
|
||||
|
||||
const JanetBuildConfig *janet_build_config() {
|
||||
return api_build_config;
|
||||
const JanetBuildConfig *janet_config_host(void) {
|
||||
return &api_build_config;
|
||||
}
|
||||
|
||||
void janet_panicv(Janet message) {
|
||||
|
@ -63,7 +63,30 @@ JanetModule janet_native(const char *name, const uint8_t **error) {
|
||||
}
|
||||
init = (JanetModule) symbol_clib(lib, "_janet_init");
|
||||
if (!init) {
|
||||
*error = janet_cstring("could not find _janet_init symbol");
|
||||
*error = janet_cstring("could not find the _janet_init symbol");
|
||||
return NULL;
|
||||
}
|
||||
JanetBuildConfig(*modconf_getter)(void) = symbol_clib(lib, "_janet_mod_config");
|
||||
if (!modconf_getter) {
|
||||
*error = janet_cstring("could not find the _janet_mod_config symbol");
|
||||
return NULL;
|
||||
}
|
||||
JanetBuildConfig modconf = modconf_getter();
|
||||
JanetBuildConfig host = janet_config_current();
|
||||
if (host.major != modconf.major ||
|
||||
host.minor < modconf.minor ||
|
||||
host.bits != modconf.bits) {
|
||||
char errbuf[128];
|
||||
sprintf(errbuf, "config mismatch - host %d.%.d.%d(%.4x) vs. module %d.%d.%d(%.4x)",
|
||||
host.major,
|
||||
host.minor,
|
||||
host.patch,
|
||||
host.bits,
|
||||
modconf.major,
|
||||
modconf.minor,
|
||||
modconf.patch,
|
||||
modconf.bits);
|
||||
*error = janet_cstring(errbuf);
|
||||
return NULL;
|
||||
}
|
||||
return init;
|
||||
@ -830,6 +853,9 @@ JanetTable *janet_core_env(JanetTable *replacements) {
|
||||
JDOC("The version number of the running janet program."));
|
||||
janet_def(env, "janet/build", janet_cstringv(JANET_BUILD),
|
||||
JDOC("The build identifier of the running janet program."));
|
||||
janet_def(env, "janet/config-bits", janet_wrap_integer(JANET_CURRENT_CONFIG_BITS),
|
||||
JDOC("The flag set of config options from janetconf.h which is used to check "
|
||||
"if native modules are compatible with the host program."));
|
||||
|
||||
/* Allow references to the environment */
|
||||
janet_def(env, "_env", janet_wrap_table(env), JDOC("The environment table for the current scope."));
|
||||
|
@ -31,8 +31,6 @@ extern "C" {
|
||||
|
||||
#include "janetconf.h"
|
||||
|
||||
#define JANET_API_VERSION 1
|
||||
|
||||
#ifndef JANET_VERSION
|
||||
#define JANET_VERSION "latest"
|
||||
#endif
|
||||
@ -186,26 +184,38 @@ extern "C" {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* Runtime config constants */
|
||||
#ifdef JANET_NO_NANBOX
|
||||
#define JANET_NANBOX_BIT 0
|
||||
#else
|
||||
#define JANET_NANBOX_BIT 1
|
||||
#define JANET_NANBOX_BIT 0x1
|
||||
#endif
|
||||
|
||||
#ifdef JANET_SINGLE_THREADED
|
||||
#define JANET_SINGLE_THREADED_BIT 1
|
||||
#define JANET_SINGLE_THREADED_BIT 0x2
|
||||
#else
|
||||
#define JANET_SINGLE_THREADED_BIT 0
|
||||
#endif
|
||||
|
||||
#define JANET_CURRENT_CONFIG_BITS \
|
||||
(JANET_SINGLE_THREADED_BIT | \
|
||||
JANET_NANBOX_BIT)
|
||||
|
||||
/* Represents the settings used to compile Janet, as well as the version */
|
||||
typedef struct {
|
||||
int api_version;
|
||||
int single_threaded : 1;
|
||||
int nanbox : 1;
|
||||
unsigned major;
|
||||
unsigned minor;
|
||||
unsigned patch;
|
||||
unsigned bits;
|
||||
} JanetBuildConfig;
|
||||
|
||||
/* Get config of current compilation unit. */
|
||||
#define janet_config_current() ((JanetBuildConfig){ \
|
||||
JANET_VERSION_MAJOR, \
|
||||
JANET_VERSION_MINOR, \
|
||||
JANET_VERSION_PATCH, \
|
||||
JANET_CURRENT_CONFIG_BITS })
|
||||
|
||||
/***** END SECTION CONFIG *****/
|
||||
|
||||
/***** START SECTION TYPES *****/
|
||||
@ -1276,15 +1286,11 @@ JANET_API void janet_register(const char *name, JanetCFunction cfun);
|
||||
|
||||
/* New C API */
|
||||
|
||||
#define JANET_MODULE_ENTRY JANET_API void _janet_init
|
||||
|
||||
JANET_API int janet_api_version();
|
||||
JANET_API const JanetBuildConfig *janet_build_config();
|
||||
|
||||
#define janet_api_compatible() \
|
||||
((janet_api_build_config()->api_version == JANET_API_VERSION) \
|
||||
&& (janet_api_build_config()->nanbox == JANET_NANBOX_BIT) \
|
||||
&& (janet_api_build_config()->single_threaded == JANET_SINGLE_THREADED_BIT))
|
||||
#define JANET_MODULE_ENTRY \
|
||||
JANET_API JanetBuildConfig _janet_mod_config(void) { \
|
||||
return janet_config_current(); \
|
||||
} \
|
||||
JANET_API void _janet_init
|
||||
|
||||
JANET_API void janet_panicv(Janet message);
|
||||
JANET_API void janet_panic(const char *message);
|
||||
|
@ -25,7 +25,11 @@
|
||||
#ifndef JANETCONF_H
|
||||
#define JANETCONF_H
|
||||
|
||||
#define JANET_VERSION "0.6.0"
|
||||
#define JANET_VERSION_MAJOR 0
|
||||
#define JANET_VERSION_MINOR 6
|
||||
#define JANET_VERSION_PATCH 0
|
||||
#define JANET_VERSION_EXTRA "-dev"
|
||||
#define JANET_VERSION "0.6.0-dev"
|
||||
|
||||
/* #define JANET_BUILD "local" */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user