mirror of
https://github.com/janet-lang/janet
synced 2026-04-03 21:41:25 +00:00
Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0fea20c821 | ||
|
|
91cc499e77 | ||
|
|
68850a0a05 | ||
|
|
d3d7c675a8 | ||
|
|
b2c9fc123c | ||
|
|
fa0c039cd3 | ||
|
|
78ef9d1733 | ||
|
|
b6676f350c | ||
|
|
0299620a2d | ||
|
|
739d9d9fe3 | ||
|
|
1557f9da78 | ||
|
|
529d8c9e4a | ||
|
|
2df16e5a48 | ||
|
|
b0db2b22d6 |
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -17,7 +17,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ ubuntu-latest, macos-13 ]
|
||||
os: [ ubuntu-latest ]
|
||||
steps:
|
||||
- name: Checkout the repository
|
||||
uses: actions/checkout@master
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
# Changelog
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## 1.41.2 - 2026-02-18
|
||||
- Fix regressions in `put` for arrays and buffers.
|
||||
- Add `module/add-file-extension`
|
||||
- Add `module/add-syspath`
|
||||
- Fix issue with possible stack corrpution with abstract types that modify the current fiber.
|
||||
- Allow use of the interpreter and garbage collection inside module entry for native modules.
|
||||
|
||||
## 1.41.1 - 2026-02-15
|
||||
- Revert to blocking behaior of `net/connect` on windows to fix spurious errors.
|
||||
- Allow overriding the loader when doing imports with the `:loader` argument.
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
project('janet', 'c',
|
||||
default_options : ['c_std=c99', 'build.c_std=c99', 'b_lundef=false', 'default_library=both'],
|
||||
version : '1.41.1')
|
||||
version : '1.41.2')
|
||||
|
||||
# Global settings
|
||||
janet_path = join_paths(get_option('prefix'), get_option('libdir'), 'janet')
|
||||
|
||||
@@ -2910,7 +2910,9 @@
|
||||
the generated paths behave like other module types, including
|
||||
relative imports and syspath imports. `ext` is the file extension
|
||||
to associate with this module type, including the dot. `loader` is the
|
||||
keyword name of a loader in `module/loaders`. Returns the modified `module/paths`.
|
||||
keyword name of a loader in `module/loaders`. The parameter `match-exact-path`
|
||||
will allow users to import files with this extension directly with a relative
|
||||
or absolute path. Returns the modified `module/paths`.
|
||||
```
|
||||
[ext loader]
|
||||
(def mp (dyn *module-paths* module/paths))
|
||||
@@ -2925,11 +2927,23 @@
|
||||
(array/insert mp sys-index [(string ":sys:/:all:" ext) loader check-is-dep])
|
||||
(def curall-index (find-prefix ":cur:/:all:"))
|
||||
(array/insert mp curall-index [(string ":cur:/:all:" ext) loader check-relative])
|
||||
mp)
|
||||
|
||||
(defn module/add-file-extension
|
||||
```
|
||||
Add paths to `module/paths` for a given file extension such that
|
||||
the programmer can import a module by relative or absolute path from
|
||||
the current working directory.
|
||||
Returns the modified `module/paths`.
|
||||
```
|
||||
[ext loader]
|
||||
(assert (string/has-prefix? "." ext) "file extension must have . prefix")
|
||||
(def mp (dyn *module-paths* module/paths))
|
||||
(array/insert mp 0 [":all:" loader (fn :check-ext [x] (string/has-suffix? ext x))])
|
||||
mp)
|
||||
|
||||
# Don't expose this externally yet - could break if custom module/paths is setup.
|
||||
(defn- module/add-syspath
|
||||
(defn module/add-syspath
|
||||
```
|
||||
Add a custom syspath to `module/paths` by duplicating all entries that being with `:sys:` and
|
||||
adding duplicates with a specific path prefix instead.
|
||||
@@ -2950,6 +2964,12 @@
|
||||
(module/add-paths "/init.janet" :source)
|
||||
(module/add-paths ".janet" :source)
|
||||
(module/add-paths ".jimage" :image)
|
||||
(module/add-file-extension ".janet" :source)
|
||||
(module/add-file-extension ".jimage" :source)
|
||||
# These obviously won't work on all platforms, but if a user explicitly
|
||||
# tries to import them, we may as well try.
|
||||
(module/add-file-extension ".so" :native)
|
||||
(module/add-file-extension ".dll" :native)
|
||||
(array/insert module/paths 0
|
||||
[(fn is-cached [path] (if (in (dyn *module-cache* module/cache) path) path))
|
||||
:preload
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
|
||||
#define JANET_VERSION_MAJOR 1
|
||||
#define JANET_VERSION_MINOR 41
|
||||
#define JANET_VERSION_PATCH 1
|
||||
#define JANET_VERSION_PATCH 2
|
||||
#define JANET_VERSION_EXTRA ""
|
||||
#define JANET_VERSION "1.41.1"
|
||||
#define JANET_VERSION "1.41.2"
|
||||
|
||||
/* #define JANET_BUILD "local" */
|
||||
|
||||
|
||||
@@ -201,14 +201,29 @@ static JanetSlot do_cmp(JanetFopts opts, JanetSlot *args) {
|
||||
return opreduce(opts, args, JOP_COMPARE, 0, janet_wrap_nil(), janet_wrap_nil());
|
||||
}
|
||||
static JanetSlot do_put(JanetFopts opts, JanetSlot *args) {
|
||||
if (opts.flags & JANET_FOPTS_DROP) {
|
||||
janetc_emit_sss(opts.compiler, JOP_PUT, args[0], args[1], args[2], 0);
|
||||
return janetc_cslot(janet_wrap_nil());
|
||||
int8_t inline_index = 0;
|
||||
if (can_slot_be_imm(args[1], &inline_index)) {
|
||||
/* Use JOP_PUT_INDEX */
|
||||
if (opts.flags & JANET_FOPTS_DROP) {
|
||||
janetc_emit_ssi(opts.compiler, JOP_PUT_INDEX, args[0], args[2], inline_index, 0);
|
||||
return janetc_cslot(janet_wrap_nil());
|
||||
} else {
|
||||
JanetSlot t = janetc_gettarget(opts);
|
||||
janetc_copy(opts.compiler, t, args[0]);
|
||||
janetc_emit_ssi(opts.compiler, JOP_PUT_INDEX, t, args[2], inline_index, 0);
|
||||
return t;
|
||||
}
|
||||
} else {
|
||||
JanetSlot t = janetc_gettarget(opts);
|
||||
janetc_copy(opts.compiler, t, args[0]);
|
||||
janetc_emit_sss(opts.compiler, JOP_PUT, t, args[1], args[2], 0);
|
||||
return t;
|
||||
/* Use JOP_PUT */
|
||||
if (opts.flags & JANET_FOPTS_DROP) {
|
||||
janetc_emit_sss(opts.compiler, JOP_PUT, args[0], args[1], args[2], 0);
|
||||
return janetc_cslot(janet_wrap_nil());
|
||||
} else {
|
||||
JanetSlot t = janetc_gettarget(opts);
|
||||
janetc_copy(opts.compiler, t, args[0]);
|
||||
janetc_emit_sss(opts.compiler, JOP_PUT, t, args[1], args[2], 0);
|
||||
return t;
|
||||
}
|
||||
}
|
||||
}
|
||||
static JanetSlot do_length(JanetFopts opts, JanetSlot *args) {
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "compile.h"
|
||||
#include "state.h"
|
||||
#include "util.h"
|
||||
#include "fiber.h"
|
||||
#endif
|
||||
|
||||
/* Generated bytes */
|
||||
@@ -294,6 +295,7 @@ JANET_CORE_FN(janet_core_native,
|
||||
"from the native module.") {
|
||||
JanetModule init;
|
||||
janet_arity(argc, 1, 2);
|
||||
Janet argv0 = argv[0];
|
||||
const uint8_t *path = janet_getstring(argv, 0);
|
||||
const uint8_t *error = NULL;
|
||||
JanetTable *env;
|
||||
@@ -306,8 +308,10 @@ JANET_CORE_FN(janet_core_native,
|
||||
if (!init) {
|
||||
janet_panicf("could not load native %S: %S", path, error);
|
||||
}
|
||||
/* GC root incase garbage collection called inside module entry */
|
||||
janet_fiber_push(janet_vm.fiber, janet_wrap_table(env));
|
||||
init(env);
|
||||
janet_table_put(env, janet_ckeywordv("native"), argv[0]);
|
||||
janet_table_put(env, janet_ckeywordv("native"), argv0);
|
||||
return janet_wrap_table(env);
|
||||
}
|
||||
|
||||
|
||||
@@ -2948,10 +2948,11 @@ int janet_make_pipe(JanetHandle handles[2], int mode) {
|
||||
if (!CreatePipe(handles, handles + 1, &saAttr, 0)) return -1;
|
||||
return 0;
|
||||
}
|
||||
sprintf(PipeNameBuffer,
|
||||
"\\\\.\\Pipe\\JanetPipeFile.%08x.%08x",
|
||||
(unsigned int) GetCurrentProcessId(),
|
||||
(unsigned int) InterlockedIncrement(&PipeSerialNumber));
|
||||
snprintf(PipeNameBuffer,
|
||||
sizeof(PipeNameBuffer),
|
||||
"\\\\.\\Pipe\\JanetPipeFile.%08x.%08x",
|
||||
(unsigned int) GetCurrentProcessId(),
|
||||
(unsigned int) InterlockedIncrement(&PipeSerialNumber));
|
||||
|
||||
/* server handle goes to subprocess */
|
||||
shandle = CreateNamedPipeA(
|
||||
|
||||
@@ -2579,7 +2579,7 @@ JANET_CORE_FN(os_dir,
|
||||
char pattern[MAX_PATH + 1];
|
||||
if (strlen(dir) > (sizeof(pattern) - 3))
|
||||
janet_panicf("path too long: %s", dir);
|
||||
sprintf(pattern, "%s/*", dir);
|
||||
snprintf(pattern, sizeof(pattern), "%s/*", dir);
|
||||
intptr_t res = _findfirst(pattern, &afile);
|
||||
if (-1 == res) janet_panicv(janet_cstringv(janet_strerror(errno)));
|
||||
do {
|
||||
|
||||
@@ -909,7 +909,7 @@ static JanetSlot janetc_while(JanetFopts opts, int32_t argn, const Janet *argv)
|
||||
janetc_regalloc_freetemp(&c->scope->ra, tempself, JANETC_REGTEMP_0);
|
||||
/* Compile function */
|
||||
JanetFuncDef *def = janetc_pop_funcdef(c);
|
||||
def->name = janet_cstring("_while");
|
||||
def->name = janet_cstring("while");
|
||||
janet_def_addflags(def);
|
||||
int32_t defindex = janetc_addfuncdef(c, def);
|
||||
/* And then load the closure and call it. */
|
||||
|
||||
@@ -495,7 +495,7 @@ Janet janet_in(Janet ds, Janet key) {
|
||||
if (!(type->get)(janet_unwrap_abstract(ds), key, &value))
|
||||
janet_panicf("key %v not found in %v ", key, ds);
|
||||
} else {
|
||||
janet_panicf("no getter for %v ", ds);
|
||||
janet_panicf("no getter for %v", ds);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -622,7 +622,7 @@ Janet janet_getindex(Janet ds, int32_t index) {
|
||||
if (!(type->get)(janet_unwrap_abstract(ds), janet_wrap_integer(index), &value))
|
||||
value = janet_wrap_nil();
|
||||
} else {
|
||||
janet_panicf("no getter for %v ", ds);
|
||||
janet_panicf("no getter for %v", ds);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -724,6 +724,9 @@ void janet_putindex(Janet ds, int32_t index, Janet value) {
|
||||
JanetArray *array = janet_unwrap_array(ds);
|
||||
if (index >= array->count) {
|
||||
janet_array_ensure(array, index + 1, 2);
|
||||
for (int32_t i = array->count; i < index + 1; i++) {
|
||||
array->data[i] = janet_wrap_nil();
|
||||
}
|
||||
array->count = index + 1;
|
||||
}
|
||||
array->data[index] = value;
|
||||
@@ -735,6 +738,7 @@ void janet_putindex(Janet ds, int32_t index, Janet value) {
|
||||
janet_panicf("can only put integers in buffers, got %v", value);
|
||||
if (index >= buffer->count) {
|
||||
janet_buffer_ensure(buffer, index + 1, 2);
|
||||
memset(buffer->data + buffer->count, 0, index + 1 - buffer->count);
|
||||
buffer->count = index + 1;
|
||||
}
|
||||
buffer->data[index] = (uint8_t)(janet_unwrap_integer(value) & 0xFF);
|
||||
@@ -768,6 +772,9 @@ void janet_put(Janet ds, Janet key, Janet value) {
|
||||
int32_t index = getter_checkint(type, key, INT32_MAX - 1);
|
||||
if (index >= array->count) {
|
||||
janet_array_ensure(array, index + 1, 2);
|
||||
for (int32_t i = array->count; i < index + 1; i++) {
|
||||
array->data[i] = janet_wrap_nil();
|
||||
}
|
||||
array->count = index + 1;
|
||||
}
|
||||
array->data[index] = value;
|
||||
@@ -780,6 +787,7 @@ void janet_put(Janet ds, Janet key, Janet value) {
|
||||
janet_panicf("can only put integers in buffers, got %v", value);
|
||||
if (index >= buffer->count) {
|
||||
janet_buffer_ensure(buffer, index + 1, 2);
|
||||
memset(buffer->data + buffer->count, 0, index + 1 - buffer->count);
|
||||
buffer->count = index + 1;
|
||||
}
|
||||
buffer->data[index] = (uint8_t)(janet_unwrap_integer(value) & 0xFF);
|
||||
|
||||
@@ -129,7 +129,9 @@
|
||||
if (!janet_checktype(op1, JANET_NUMBER)) {\
|
||||
vm_commit();\
|
||||
Janet _argv[2] = { op1, janet_wrap_number(CS) };\
|
||||
stack[A] = janet_mcall(#op, 2, _argv);\
|
||||
Janet a = janet_mcall(#op, 2, _argv);\
|
||||
stack = fiber->data + fiber->frame;\
|
||||
stack[A] = a;\
|
||||
vm_checkgc_pcnext();\
|
||||
} else {\
|
||||
double x1 = janet_unwrap_number(op1);\
|
||||
@@ -143,7 +145,9 @@
|
||||
if (!janet_checktype(op1, JANET_NUMBER)) {\
|
||||
vm_commit();\
|
||||
Janet _argv[2] = { op1, janet_wrap_number(CS) };\
|
||||
stack[A] = janet_mcall(#op, 2, _argv);\
|
||||
Janet a = janet_mcall(#op, 2, _argv);\
|
||||
stack = fiber->data + fiber->frame;\
|
||||
stack[A] = a;\
|
||||
vm_checkgc_pcnext();\
|
||||
} else {\
|
||||
double y1 = janet_unwrap_number(op1);\
|
||||
@@ -166,7 +170,9 @@
|
||||
vm_pcnext();\
|
||||
} else {\
|
||||
vm_commit();\
|
||||
stack[A] = janet_binop_call(#op, "r" #op, op1, op2);\
|
||||
Janet a = janet_binop_call(#op, "r" #op, op1, op2);\
|
||||
stack = fiber->data + fiber->frame;\
|
||||
stack[A] = a;\
|
||||
vm_checkgc_pcnext();\
|
||||
}\
|
||||
}
|
||||
@@ -186,7 +192,9 @@
|
||||
vm_pcnext();\
|
||||
} else {\
|
||||
vm_commit();\
|
||||
stack[A] = janet_binop_call(#op, "r" #op, op1, op2);\
|
||||
Janet a = janet_binop_call(#op, "r" #op, op1, op2);\
|
||||
stack = fiber->data + fiber->frame;\
|
||||
stack[A] = a;\
|
||||
vm_checkgc_pcnext();\
|
||||
}\
|
||||
}
|
||||
@@ -203,7 +211,9 @@
|
||||
vm_pcnext();\
|
||||
} else {\
|
||||
vm_commit();\
|
||||
stack[A] = janet_wrap_boolean(janet_compare(op1, op2) op 0);\
|
||||
Janet a = janet_wrap_boolean(janet_compare(op1, op2) op 0);\
|
||||
stack = fiber->data + fiber->frame;\
|
||||
stack[A] = a;\
|
||||
vm_checkgc_pcnext();\
|
||||
}\
|
||||
}
|
||||
@@ -217,7 +227,9 @@
|
||||
vm_pcnext();\
|
||||
} else {\
|
||||
vm_commit();\
|
||||
stack[A] = janet_wrap_boolean(janet_compare(op1, janet_wrap_integer(CS)) op 0);\
|
||||
Janet a = janet_wrap_boolean(janet_compare(op1, janet_wrap_integer(CS)) op 0);\
|
||||
stack = fiber->data + fiber->frame;\
|
||||
stack[A] = a;\
|
||||
vm_checkgc_pcnext();\
|
||||
}\
|
||||
}
|
||||
@@ -710,7 +722,9 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in) {
|
||||
vm_pcnext();
|
||||
} else {
|
||||
vm_commit();
|
||||
stack[A] = janet_binop_call("div", "rdiv", op1, op2);
|
||||
Janet a = janet_binop_call("div", "rdiv", op1, op2);
|
||||
stack = fiber->data + fiber->frame;
|
||||
stack[A] = a;
|
||||
vm_checkgc_pcnext();
|
||||
}
|
||||
}
|
||||
@@ -730,7 +744,9 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in) {
|
||||
vm_pcnext();
|
||||
} else {
|
||||
vm_commit();
|
||||
stack[A] = janet_binop_call("mod", "rmod", op1, op2);
|
||||
Janet a = janet_binop_call("mod", "rmod", op1, op2);
|
||||
stack = fiber->data + fiber->frame;
|
||||
stack[A] = a;
|
||||
vm_checkgc_pcnext();
|
||||
}
|
||||
}
|
||||
@@ -745,7 +761,9 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in) {
|
||||
vm_pcnext();
|
||||
} else {
|
||||
vm_commit();
|
||||
stack[A] = janet_binop_call("%", "r%", op1, op2);
|
||||
Janet a = janet_binop_call("%", "r%", op1, op2);
|
||||
stack = fiber->data + fiber->frame;
|
||||
stack[A] = a;
|
||||
vm_checkgc_pcnext();
|
||||
}
|
||||
}
|
||||
@@ -766,7 +784,9 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in) {
|
||||
vm_pcnext();
|
||||
} else {
|
||||
vm_commit();
|
||||
stack[A] = janet_unary_call("~", op);
|
||||
Janet a = janet_unary_call("~", op);
|
||||
stack = fiber->data + fiber->frame;
|
||||
stack[A] = a;
|
||||
vm_checkgc_pcnext();
|
||||
}
|
||||
}
|
||||
@@ -872,8 +892,11 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in) {
|
||||
stack[A] = janet_wrap_boolean(!janet_checktype(stack[B], JANET_NUMBER) || (janet_unwrap_number(stack[B]) != (double) CS));
|
||||
vm_pcnext();
|
||||
|
||||
VM_OP(JOP_COMPARE)
|
||||
stack[A] = janet_wrap_integer(janet_compare(stack[B], stack[C]));
|
||||
VM_OP(JOP_COMPARE) {
|
||||
Janet a = janet_wrap_integer(janet_compare(stack[B], stack[C]));
|
||||
stack = fiber->data + fiber->frame;
|
||||
stack[A] = a;
|
||||
}
|
||||
vm_pcnext();
|
||||
|
||||
VM_OP(JOP_NEXT)
|
||||
@@ -1157,6 +1180,7 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in) {
|
||||
vm_commit();
|
||||
fiber->flags |= JANET_FIBER_RESUME_NO_USEVAL;
|
||||
janet_put(stack[A], stack[B], stack[C]);
|
||||
stack = fiber->data + fiber->frame;
|
||||
fiber->flags &= ~JANET_FIBER_RESUME_NO_USEVAL;
|
||||
vm_checkgc_pcnext();
|
||||
|
||||
@@ -1164,27 +1188,44 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in) {
|
||||
vm_commit();
|
||||
fiber->flags |= JANET_FIBER_RESUME_NO_USEVAL;
|
||||
janet_putindex(stack[A], C, stack[B]);
|
||||
stack = fiber->data + fiber->frame;
|
||||
fiber->flags &= ~JANET_FIBER_RESUME_NO_USEVAL;
|
||||
vm_checkgc_pcnext();
|
||||
|
||||
VM_OP(JOP_IN)
|
||||
vm_commit();
|
||||
stack[A] = janet_in(stack[B], stack[C]);
|
||||
{
|
||||
Janet a = janet_in(stack[B], stack[C]);
|
||||
stack = fiber->data + fiber->frame;
|
||||
stack[A] = a;
|
||||
}
|
||||
vm_pcnext();
|
||||
|
||||
VM_OP(JOP_GET)
|
||||
vm_commit();
|
||||
stack[A] = janet_get(stack[B], stack[C]);
|
||||
{
|
||||
Janet a = janet_get(stack[B], stack[C]);
|
||||
stack = fiber->data + fiber->frame;
|
||||
stack[A] = a;
|
||||
}
|
||||
vm_pcnext();
|
||||
|
||||
VM_OP(JOP_GET_INDEX)
|
||||
vm_commit();
|
||||
stack[A] = janet_getindex(stack[B], C);
|
||||
{
|
||||
Janet a = janet_getindex(stack[B], C);
|
||||
stack = fiber->data + fiber->frame;
|
||||
stack[A] = a;
|
||||
}
|
||||
vm_pcnext();
|
||||
|
||||
VM_OP(JOP_LENGTH)
|
||||
vm_commit();
|
||||
stack[A] = janet_lengthv(stack[E]);
|
||||
{
|
||||
Janet a = janet_lengthv(stack[E]);
|
||||
stack = fiber->data + fiber->frame;
|
||||
stack[A] = a;
|
||||
}
|
||||
vm_pcnext();
|
||||
|
||||
VM_OP(JOP_MAKE_ARRAY) {
|
||||
|
||||
@@ -86,5 +86,10 @@
|
||||
(assert-error "array/join error 4" (array/join @[] "abc123"))
|
||||
(assert-error "array/join error 5" (array/join @[] "abc123"))
|
||||
|
||||
# Regression 1714
|
||||
(repeat 10
|
||||
(assert (deep= (put @[] 100 10) (put (seq [_ :range [0 101]] nil) 100 10)) "regression 1714")
|
||||
(assert (deep= (put @[] 200 10) (put (seq [_ :range [0 201]] nil) 200 10)) "regression 1714"))
|
||||
|
||||
(end-suite)
|
||||
|
||||
|
||||
@@ -179,5 +179,10 @@
|
||||
(assert (= (string buf) "xxxxxx") "buffer/format-at negative index")
|
||||
(assert-error "expected index at to be in range [0, 0), got 1" (buffer/format-at @"" 1 "abc"))
|
||||
|
||||
# Regression 1714
|
||||
(repeat 10
|
||||
(assert (deep= (put @"" 100 10) (put (buffer (string/repeat "\0" 101)) 100 10)) "regression 1714")
|
||||
(assert (deep= (put @"" 200 10) (put (buffer (string/repeat "\0" 201)) 200 10)) "regression 1714"))
|
||||
|
||||
(end-suite)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user