mirror of
https://github.com/janet-lang/janet
synced 2025-05-07 01:44:15 +00:00
Merge branch 'master' into ev
This commit is contained in:
commit
a4de83b3a3
@ -17,7 +17,7 @@ tasks:
|
|||||||
meson configure -Dpeg=false
|
meson configure -Dpeg=false
|
||||||
meson configure -Dassembler=false
|
meson configure -Dassembler=false
|
||||||
meson configure -Dint_types=false
|
meson configure -Dint_types=false
|
||||||
meson configure -Dtyped_arrays=false
|
meson configure -Dtyped_array=false
|
||||||
meson configure -Dreduced_os=true
|
meson configure -Dreduced_os=true
|
||||||
meson configure -Dprf=false
|
meson configure -Dprf=false
|
||||||
ninja # will not pass tests but should build
|
ninja # will not pass tests but should build
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
## Unreleased - ???
|
## Unreleased - ???
|
||||||
|
- Add `math/int-min`, `math/int-max`, `math/int32-min`, and `math/int32-max` for getting integer limits.
|
||||||
- The gc interval is now autotuned, to prevent very bad gc behavior.
|
- The gc interval is now autotuned, to prevent very bad gc behavior.
|
||||||
- Improvements to the bytecode compiler, Janet will now generate more efficient bytecode.
|
- Improvements to the bytecode compiler, Janet will now generate more efficient bytecode.
|
||||||
- Add `peg/find`, `peg/find-all`, `peg/replace`, and `peg/replace-all`
|
- Add `peg/find`, `peg/find-all`, `peg/replace`, and `peg/replace-all`
|
||||||
|
@ -720,6 +720,9 @@ static JanetAssembleResult janet_asm1(JanetAssembler *parent, Janet source, int
|
|||||||
janet_asm_error(&a, "invalid assembly");
|
janet_asm_error(&a, "invalid assembly");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add final flags */
|
||||||
|
janet_def_addflags(def);
|
||||||
|
|
||||||
/* Finish everything and return funcdef */
|
/* Finish everything and return funcdef */
|
||||||
janet_asm_deinit(&a);
|
janet_asm_deinit(&a);
|
||||||
result.error = NULL;
|
result.error = NULL;
|
||||||
|
@ -27,12 +27,26 @@
|
|||||||
#include "fiber.h"
|
#include "fiber.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef JANET_SINGLE_THREADED
|
||||||
|
#ifndef JANET_WINDOWS
|
||||||
|
#include <pthread.h>
|
||||||
|
#else
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
JANET_NO_RETURN static void janet_top_level_signal(const char *msg) {
|
JANET_NO_RETURN static void janet_top_level_signal(const char *msg) {
|
||||||
#ifdef JANET_TOP_LEVEL_SIGNAL
|
#ifdef JANET_TOP_LEVEL_SIGNAL
|
||||||
JANET_TOP_LEVEL_SIGNAL(msg);
|
JANET_TOP_LEVEL_SIGNAL(msg);
|
||||||
#else
|
#else
|
||||||
fputs(msg, stdout);
|
fputs(msg, stdout);
|
||||||
exit(1);
|
# ifdef JANET_SINGLE_THREADED
|
||||||
|
exit(-1);
|
||||||
|
# elif defined(JANET_WINDOWS)
|
||||||
|
ExitThread(-1);
|
||||||
|
# else
|
||||||
|
pthread_exit(NULL);
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -698,7 +698,32 @@ JanetSlot janetc_value(JanetFopts opts, Janet x) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add function flags to janet functions */
|
||||||
|
void janet_def_addflags(JanetFuncDef *def) {
|
||||||
|
int32_t set_flags = 0;
|
||||||
|
int32_t unset_flags = 0;
|
||||||
|
/* pos checks */
|
||||||
|
if (def->name) set_flags |= JANET_FUNCDEF_FLAG_HASNAME;
|
||||||
|
if (def->source) set_flags |= JANET_FUNCDEF_FLAG_HASSOURCE;
|
||||||
|
if (def->defs) set_flags |= JANET_FUNCDEF_FLAG_HASDEFS;
|
||||||
|
if (def->environments) set_flags |= JANET_FUNCDEF_FLAG_HASENVS;
|
||||||
|
if (def->sourcemap) set_flags |= JANET_FUNCDEF_FLAG_HASSOURCEMAP;
|
||||||
|
if (def->closure_bitset) set_flags |= JANET_FUNCDEF_FLAG_HASCLOBITSET;
|
||||||
|
/* negative checks */
|
||||||
|
if (!def->name) unset_flags |= JANET_FUNCDEF_FLAG_HASNAME;
|
||||||
|
if (!def->source) unset_flags |= JANET_FUNCDEF_FLAG_HASSOURCE;
|
||||||
|
if (!def->defs) unset_flags |= JANET_FUNCDEF_FLAG_HASDEFS;
|
||||||
|
if (!def->environments) unset_flags |= JANET_FUNCDEF_FLAG_HASENVS;
|
||||||
|
if (!def->sourcemap) unset_flags |= JANET_FUNCDEF_FLAG_HASSOURCEMAP;
|
||||||
|
if (!def->closure_bitset) unset_flags |= JANET_FUNCDEF_FLAG_HASCLOBITSET;
|
||||||
|
/* Update flags */
|
||||||
|
def->flags |= set_flags;
|
||||||
|
def->flags &= ~unset_flags;
|
||||||
|
}
|
||||||
|
|
||||||
/* Compile a funcdef */
|
/* Compile a funcdef */
|
||||||
|
/* Once the various other settings of the FuncDef have been tweaked,
|
||||||
|
* call janet_def_addflags to set the proper flags for the funcdef */
|
||||||
JanetFuncDef *janetc_pop_funcdef(JanetCompiler *c) {
|
JanetFuncDef *janetc_pop_funcdef(JanetCompiler *c) {
|
||||||
JanetScope *scope = c->scope;
|
JanetScope *scope = c->scope;
|
||||||
JanetFuncDef *def = janet_funcdef_alloc();
|
JanetFuncDef *def = janet_funcdef_alloc();
|
||||||
@ -761,7 +786,6 @@ JanetFuncDef *janetc_pop_funcdef(JanetCompiler *c) {
|
|||||||
/* Register allocator preallocates some registers [240-255, high 16 bits of chunk index 7], we can ignore those. */
|
/* Register allocator preallocates some registers [240-255, high 16 bits of chunk index 7], we can ignore those. */
|
||||||
if (scope->ua.count > 7) chunks[7] &= 0xFFFFU;
|
if (scope->ua.count > 7) chunks[7] &= 0xFFFFU;
|
||||||
def->closure_bitset = chunks;
|
def->closure_bitset = chunks;
|
||||||
def->flags |= JANET_FUNCDEF_FLAG_HASCLOBITSET;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Pop the scope */
|
/* Pop the scope */
|
||||||
@ -818,6 +842,7 @@ JanetCompileResult janet_compile(Janet source, JanetTable *env, const uint8_t *w
|
|||||||
if (c.result.status == JANET_COMPILE_OK) {
|
if (c.result.status == JANET_COMPILE_OK) {
|
||||||
JanetFuncDef *def = janetc_pop_funcdef(&c);
|
JanetFuncDef *def = janetc_pop_funcdef(&c);
|
||||||
def->name = janet_cstring("_thunk");
|
def->name = janet_cstring("_thunk");
|
||||||
|
janet_def_addflags(def);
|
||||||
c.result.funcdef = def;
|
c.result.funcdef = def;
|
||||||
} else {
|
} else {
|
||||||
c.result.error_mapping = c.current_mapping;
|
c.result.error_mapping = c.current_mapping;
|
||||||
|
@ -741,6 +741,7 @@ static void janet_quick_asm(
|
|||||||
JANET_OUT_OF_MEMORY;
|
JANET_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
memcpy(def->bytecode, bytecode, bytecode_size);
|
memcpy(def->bytecode, bytecode, bytecode_size);
|
||||||
|
janet_def_addflags(def);
|
||||||
janet_def(env, name, janet_wrap_function(janet_thunk(def)), doc);
|
janet_def(env, name, janet_wrap_function(janet_thunk(def)), doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,18 +20,18 @@
|
|||||||
* IN THE SOFTWARE.
|
* IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <limits.h>
|
|
||||||
#include <inttypes.h>
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
#ifndef JANET_AMALG
|
#ifndef JANET_AMALG
|
||||||
#include "features.h"
|
#include "features.h"
|
||||||
#include <janet.h>
|
#include <janet.h>
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
/* Conditional compilation */
|
/* Conditional compilation */
|
||||||
#ifdef JANET_INT_TYPES
|
#ifdef JANET_INT_TYPES
|
||||||
|
|
||||||
|
@ -37,18 +37,23 @@
|
|||||||
|
|
||||||
static int cfun_io_gc(void *p, size_t len);
|
static int cfun_io_gc(void *p, size_t len);
|
||||||
static int io_file_get(void *p, Janet key, Janet *out);
|
static int io_file_get(void *p, Janet key, Janet *out);
|
||||||
|
static void io_file_marshal(void *p, JanetMarshalContext *ctx);
|
||||||
|
static void *io_file_unmarshal(JanetMarshalContext *ctx);
|
||||||
|
|
||||||
const JanetAbstractType janet_file_type = {
|
const JanetAbstractType janet_file_type = {
|
||||||
"core/file",
|
"core/file",
|
||||||
cfun_io_gc,
|
cfun_io_gc,
|
||||||
NULL,
|
NULL,
|
||||||
io_file_get,
|
io_file_get,
|
||||||
JANET_ATEND_GET
|
NULL,
|
||||||
|
io_file_marshal,
|
||||||
|
io_file_unmarshal,
|
||||||
|
JANET_ATEND_UNMARSHAL
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Check arguments to fopen */
|
/* Check arguments to fopen */
|
||||||
static int checkflags(const uint8_t *str) {
|
static int32_t checkflags(const uint8_t *str) {
|
||||||
int flags = 0;
|
int32_t flags = 0;
|
||||||
int32_t i;
|
int32_t i;
|
||||||
int32_t len = janet_string_length(str);
|
int32_t len = janet_string_length(str);
|
||||||
if (!len || len > 3)
|
if (!len || len > 3)
|
||||||
@ -85,7 +90,7 @@ static int checkflags(const uint8_t *str) {
|
|||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Janet makef(FILE *f, int flags) {
|
static void *makef(FILE *f, int32_t flags) {
|
||||||
JanetFile *iof = (JanetFile *) janet_abstract(&janet_file_type, sizeof(JanetFile));
|
JanetFile *iof = (JanetFile *) janet_abstract(&janet_file_type, sizeof(JanetFile));
|
||||||
iof->file = f;
|
iof->file = f;
|
||||||
iof->flags = flags;
|
iof->flags = flags;
|
||||||
@ -95,7 +100,7 @@ static Janet makef(FILE *f, int flags) {
|
|||||||
if (!(flags & JANET_FILE_NOT_CLOSEABLE))
|
if (!(flags & JANET_FILE_NOT_CLOSEABLE))
|
||||||
fcntl(fileno(f), F_SETFD, FD_CLOEXEC);
|
fcntl(fileno(f), F_SETFD, FD_CLOEXEC);
|
||||||
#endif
|
#endif
|
||||||
return janet_wrap_abstract(iof);
|
return iof;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Open a process */
|
/* Open a process */
|
||||||
@ -104,7 +109,7 @@ static Janet cfun_io_popen(int32_t argc, Janet *argv) {
|
|||||||
janet_arity(argc, 1, 2);
|
janet_arity(argc, 1, 2);
|
||||||
const uint8_t *fname = janet_getstring(argv, 0);
|
const uint8_t *fname = janet_getstring(argv, 0);
|
||||||
const uint8_t *fmode = NULL;
|
const uint8_t *fmode = NULL;
|
||||||
int flags;
|
int32_t flags;
|
||||||
if (argc == 2) {
|
if (argc == 2) {
|
||||||
fmode = janet_getkeyword(argv, 1);
|
fmode = janet_getkeyword(argv, 1);
|
||||||
if (janet_string_length(fmode) != 1 ||
|
if (janet_string_length(fmode) != 1 ||
|
||||||
@ -123,7 +128,7 @@ static Janet cfun_io_popen(int32_t argc, Janet *argv) {
|
|||||||
if (!f) {
|
if (!f) {
|
||||||
return janet_wrap_nil();
|
return janet_wrap_nil();
|
||||||
}
|
}
|
||||||
return makef(f, flags);
|
return janet_makefile(f, flags);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -141,7 +146,7 @@ static Janet cfun_io_fopen(int32_t argc, Janet *argv) {
|
|||||||
janet_arity(argc, 1, 2);
|
janet_arity(argc, 1, 2);
|
||||||
const uint8_t *fname = janet_getstring(argv, 0);
|
const uint8_t *fname = janet_getstring(argv, 0);
|
||||||
const uint8_t *fmode;
|
const uint8_t *fmode;
|
||||||
int flags;
|
int32_t flags;
|
||||||
if (argc == 2) {
|
if (argc == 2) {
|
||||||
fmode = janet_getkeyword(argv, 1);
|
fmode = janet_getkeyword(argv, 1);
|
||||||
flags = checkflags(fmode);
|
flags = checkflags(fmode);
|
||||||
@ -150,7 +155,7 @@ static Janet cfun_io_fopen(int32_t argc, Janet *argv) {
|
|||||||
flags = JANET_FILE_READ;
|
flags = JANET_FILE_READ;
|
||||||
}
|
}
|
||||||
FILE *f = fopen((const char *)fname, (const char *)fmode);
|
FILE *f = fopen((const char *)fname, (const char *)fmode);
|
||||||
return f ? makef(f, flags) : janet_wrap_nil();
|
return f ? janet_makefile(f, flags) : janet_wrap_nil();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read up to n bytes into buffer. */
|
/* Read up to n bytes into buffer. */
|
||||||
@ -331,6 +336,49 @@ static int io_file_get(void *p, Janet key, Janet *out) {
|
|||||||
return janet_getmethod(janet_unwrap_keyword(key), io_file_methods, out);
|
return janet_getmethod(janet_unwrap_keyword(key), io_file_methods, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void io_file_marshal(void *p, JanetMarshalContext *ctx) {
|
||||||
|
JanetFile *iof = (JanetFile *)p;
|
||||||
|
if (ctx->flags & JANET_MARSHAL_UNSAFE) {
|
||||||
|
#ifdef JANET_WINDOWS
|
||||||
|
janet_marshal_int(ctx, _fileno(iof->file));
|
||||||
|
#else
|
||||||
|
janet_marshal_int(ctx, fileno(iof->file));
|
||||||
|
#endif
|
||||||
|
janet_marshal_int(ctx, iof->flags);
|
||||||
|
} else {
|
||||||
|
janet_panic("cannot marshal file in safe mode");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *io_file_unmarshal(JanetMarshalContext *ctx) {
|
||||||
|
if (ctx->flags & JANET_MARSHAL_UNSAFE) {
|
||||||
|
JanetFile *iof = janet_unmarshal_abstract(ctx, sizeof(JanetFile));
|
||||||
|
int32_t fd = janet_unmarshal_int(ctx);
|
||||||
|
int32_t flags = janet_unmarshal_int(ctx);
|
||||||
|
char fmt[4] = {0};
|
||||||
|
int index = 0;
|
||||||
|
if (flags & JANET_FILE_READ) fmt[index++] = 'r';
|
||||||
|
if (flags & JANET_FILE_APPEND) {
|
||||||
|
fmt[index++] = 'a';
|
||||||
|
} else if (flags & JANET_FILE_WRITE) {
|
||||||
|
fmt[index++] = 'w';
|
||||||
|
}
|
||||||
|
#ifdef JANET_WINDOWS
|
||||||
|
iof->file = _fdopen(fd, fmt);
|
||||||
|
#else
|
||||||
|
iof->file = fdopen(fd, fmt);
|
||||||
|
#endif
|
||||||
|
if (iof->file == NULL) {
|
||||||
|
iof->flags = JANET_FILE_CLOSED;
|
||||||
|
} else {
|
||||||
|
iof->flags = flags;
|
||||||
|
}
|
||||||
|
return iof;
|
||||||
|
} else {
|
||||||
|
janet_panic("cannot unmarshal file in safe mode");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FILE *janet_dynfile(const char *name, FILE *def) {
|
FILE *janet_dynfile(const char *name, FILE *def) {
|
||||||
Janet x = janet_dyn(name);
|
Janet x = janet_dyn(name);
|
||||||
if (!janet_checktype(x, JANET_ABSTRACT)) return def;
|
if (!janet_checktype(x, JANET_ABSTRACT)) return def;
|
||||||
@ -677,7 +725,7 @@ FILE *janet_getfile(const Janet *argv, int32_t n, int *flags) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Janet janet_makefile(FILE *f, int flags) {
|
Janet janet_makefile(FILE *f, int flags) {
|
||||||
return makef(f, flags);
|
return janet_wrap_abstract(makef(f, flags));
|
||||||
}
|
}
|
||||||
|
|
||||||
JanetAbstract janet_checkfile(Janet j) {
|
JanetAbstract janet_checkfile(Janet j) {
|
||||||
@ -693,18 +741,18 @@ FILE *janet_unwrapfile(Janet j, int *flags) {
|
|||||||
/* Module entry point */
|
/* Module entry point */
|
||||||
void janet_lib_io(JanetTable *env) {
|
void janet_lib_io(JanetTable *env) {
|
||||||
janet_core_cfuns(env, NULL, io_cfuns);
|
janet_core_cfuns(env, NULL, io_cfuns);
|
||||||
|
janet_register_abstract_type(&janet_file_type);
|
||||||
/* stdout */
|
/* stdout */
|
||||||
janet_core_def(env, "stdout",
|
janet_core_def(env, "stdout",
|
||||||
makef(stdout, JANET_FILE_APPEND | JANET_FILE_NOT_CLOSEABLE | JANET_FILE_SERIALIZABLE),
|
janet_makefile(stdout, JANET_FILE_APPEND | JANET_FILE_NOT_CLOSEABLE | JANET_FILE_SERIALIZABLE),
|
||||||
JDOC("The standard output file."));
|
JDOC("The standard output file."));
|
||||||
/* stderr */
|
/* stderr */
|
||||||
janet_core_def(env, "stderr",
|
janet_core_def(env, "stderr",
|
||||||
makef(stderr, JANET_FILE_APPEND | JANET_FILE_NOT_CLOSEABLE | JANET_FILE_SERIALIZABLE),
|
janet_makefile(stderr, JANET_FILE_APPEND | JANET_FILE_NOT_CLOSEABLE | JANET_FILE_SERIALIZABLE),
|
||||||
JDOC("The standard error file."));
|
JDOC("The standard error file."));
|
||||||
/* stdin */
|
/* stdin */
|
||||||
janet_core_def(env, "stdin",
|
janet_core_def(env, "stdin",
|
||||||
makef(stdin, JANET_FILE_READ | JANET_FILE_NOT_CLOSEABLE | JANET_FILE_SERIALIZABLE),
|
janet_makefile(stdin, JANET_FILE_READ | JANET_FILE_NOT_CLOSEABLE | JANET_FILE_SERIALIZABLE),
|
||||||
JDOC("The standard input file."));
|
JDOC("The standard input file."));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -214,15 +214,6 @@ static void marshal_one_env(MarshalState *st, JanetFuncEnv *env, int flags) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add function flags to janet functions */
|
|
||||||
static void janet_func_addflags(JanetFuncDef *def) {
|
|
||||||
if (def->name) def->flags |= JANET_FUNCDEF_FLAG_HASNAME;
|
|
||||||
if (def->source) def->flags |= JANET_FUNCDEF_FLAG_HASSOURCE;
|
|
||||||
if (def->defs) def->flags |= JANET_FUNCDEF_FLAG_HASDEFS;
|
|
||||||
if (def->environments) def->flags |= JANET_FUNCDEF_FLAG_HASENVS;
|
|
||||||
if (def->sourcemap) def->flags |= JANET_FUNCDEF_FLAG_HASSOURCEMAP;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Marshal a sequence of u32s */
|
/* Marshal a sequence of u32s */
|
||||||
static void janet_marshal_u32s(MarshalState *st, const uint32_t *u32s, int32_t n) {
|
static void janet_marshal_u32s(MarshalState *st, const uint32_t *u32s, int32_t n) {
|
||||||
for (int32_t i = 0; i < n; i++) {
|
for (int32_t i = 0; i < n; i++) {
|
||||||
@ -243,7 +234,6 @@ static void marshal_one_def(MarshalState *st, JanetFuncDef *def, int flags) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
janet_func_addflags(def);
|
|
||||||
/* Add to lookup */
|
/* Add to lookup */
|
||||||
janet_v_push(st->seen_defs, def);
|
janet_v_push(st->seen_defs, def);
|
||||||
pushint(st, def->flags);
|
pushint(st, def->flags);
|
||||||
@ -900,7 +890,7 @@ static const uint8_t *unmarshal_one_def(
|
|||||||
for (int32_t i = 0; i < bytecode_length; i++) {
|
for (int32_t i = 0; i < bytecode_length; i++) {
|
||||||
current += readint(st, &data);
|
current += readint(st, &data);
|
||||||
def->sourcemap[i].line = current;
|
def->sourcemap[i].line = current;
|
||||||
def->sourcemap[i].column = readnat(st, &data);
|
def->sourcemap[i].column = readint(st, &data);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
def->sourcemap = NULL;
|
def->sourcemap = NULL;
|
||||||
@ -908,11 +898,12 @@ static const uint8_t *unmarshal_one_def(
|
|||||||
|
|
||||||
/* Unmarshal closure bitset if needed */
|
/* Unmarshal closure bitset if needed */
|
||||||
if (def->flags & JANET_FUNCDEF_FLAG_HASCLOBITSET) {
|
if (def->flags & JANET_FUNCDEF_FLAG_HASCLOBITSET) {
|
||||||
def->closure_bitset = malloc(sizeof(uint32_t) * def->slotcount);
|
int32_t n = (def->slotcount + 31) >> 5;
|
||||||
|
def->closure_bitset = malloc(sizeof(uint32_t) * (size_t) n);
|
||||||
if (NULL == def->closure_bitset) {
|
if (NULL == def->closure_bitset) {
|
||||||
JANET_OUT_OF_MEMORY;
|
JANET_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
data = janet_unmarshal_u32s(st, data, def->closure_bitset, (def->slotcount + 31) >> 5);
|
data = janet_unmarshal_u32s(st, data, def->closure_bitset, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Validate */
|
/* Validate */
|
||||||
|
@ -499,6 +499,14 @@ void janet_lib_math(JanetTable *env) {
|
|||||||
JDOC("The number representing positive infinity"));
|
JDOC("The number representing positive infinity"));
|
||||||
janet_def(env, "math/-inf", janet_wrap_number(-INFINITY),
|
janet_def(env, "math/-inf", janet_wrap_number(-INFINITY),
|
||||||
JDOC("The number representing negative infinity"));
|
JDOC("The number representing negative infinity"));
|
||||||
|
janet_def(env, "math/int32-min", janet_wrap_number(INT32_MIN),
|
||||||
|
JDOC("The maximum contiguous integer representable by a 32 bit signed integer"));
|
||||||
|
janet_def(env, "math/int32-max", janet_wrap_number(INT32_MAX),
|
||||||
|
JDOC("The minimum contiguous integer represtenable by a 32 bit signed integer"));
|
||||||
|
janet_def(env, "math/int-min", janet_wrap_number(JANET_INTMIN_DOUBLE),
|
||||||
|
JDOC("The maximum contiguous integer representable by a double (2^53)"));
|
||||||
|
janet_def(env, "math/int-max", janet_wrap_number(JANET_INTMAX_DOUBLE),
|
||||||
|
JDOC("The minimum contiguous integer represtenable by a double (-(2^53))"));
|
||||||
#ifdef NAN
|
#ifdef NAN
|
||||||
janet_def(env, "math/nan", janet_wrap_number(NAN),
|
janet_def(env, "math/nan", janet_wrap_number(NAN),
|
||||||
#else
|
#else
|
||||||
|
@ -39,11 +39,9 @@
|
|||||||
|
|
||||||
static void number_to_string_b(JanetBuffer *buffer, double x) {
|
static void number_to_string_b(JanetBuffer *buffer, double x) {
|
||||||
janet_buffer_ensure(buffer, buffer->count + BUFSIZE, 2);
|
janet_buffer_ensure(buffer, buffer->count + BUFSIZE, 2);
|
||||||
/* Use int32_t range for valid integers because that is the
|
|
||||||
* range most integer-expecting functions in the C api use. */
|
|
||||||
const char *fmt = (x == floor(x) &&
|
const char *fmt = (x == floor(x) &&
|
||||||
x <= ((double) INT32_MAX) &&
|
x <= JANET_INTMAX_DOUBLE &&
|
||||||
x >= ((double) INT32_MIN)) ? "%.0f" : "%g";
|
x >= JANET_INTMIN_DOUBLE) ? "%.0f" : "%g";
|
||||||
int count = snprintf((char *) buffer->data + buffer->count, BUFSIZE, fmt, x);
|
int count = snprintf((char *) buffer->data + buffer->count, BUFSIZE, fmt, x);
|
||||||
buffer->count += count;
|
buffer->count += count;
|
||||||
}
|
}
|
||||||
|
@ -649,6 +649,7 @@ static JanetSlot janetc_while(JanetFopts opts, int32_t argn, const Janet *argv)
|
|||||||
/* Compile function */
|
/* Compile function */
|
||||||
JanetFuncDef *def = janetc_pop_funcdef(c);
|
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);
|
int32_t defindex = janetc_addfuncdef(c, def);
|
||||||
/* And then load the closure and call it. */
|
/* And then load the closure and call it. */
|
||||||
int32_t cloreg = janetc_regalloc_temp(&c->scope->ra, JANETC_REGTEMP_0);
|
int32_t cloreg = janetc_regalloc_temp(&c->scope->ra, JANETC_REGTEMP_0);
|
||||||
@ -823,6 +824,7 @@ static JanetSlot janetc_fn(JanetFopts opts, int32_t argn, const Janet *argv) {
|
|||||||
if (structarg) def->flags |= JANET_FUNCDEF_FLAG_STRUCTARG;
|
if (structarg) def->flags |= JANET_FUNCDEF_FLAG_STRUCTARG;
|
||||||
|
|
||||||
if (selfref) def->name = janet_unwrap_symbol(head);
|
if (selfref) def->name = janet_unwrap_symbol(head);
|
||||||
|
janet_def_addflags(def);
|
||||||
defindex = janetc_addfuncdef(c, def);
|
defindex = janetc_addfuncdef(c, def);
|
||||||
|
|
||||||
/* Ensure enough slots for vararg function. */
|
/* Ensure enough slots for vararg function. */
|
||||||
|
@ -375,8 +375,12 @@ int janet_thread_receive(Janet *msg_out, double timeout) {
|
|||||||
|
|
||||||
/* Handle errors */
|
/* Handle errors */
|
||||||
if (setjmp(buf)) {
|
if (setjmp(buf)) {
|
||||||
/* Cleanup jmp_buf, keep lock */
|
/* Cleanup jmp_buf, return error.
|
||||||
|
* Do not ignore bad messages as before. */
|
||||||
janet_vm_jmp_buf = old_buf;
|
janet_vm_jmp_buf = old_buf;
|
||||||
|
*msg_out = *janet_vm_return_reg;
|
||||||
|
janet_mailbox_unlock(mailbox);
|
||||||
|
return 2;
|
||||||
} else {
|
} else {
|
||||||
JanetBuffer *msgbuf = mailbox->messages + mailbox->messageFirst;
|
JanetBuffer *msgbuf = mailbox->messages + mailbox->messageFirst;
|
||||||
mailbox->messageCount--;
|
mailbox->messageCount--;
|
||||||
@ -411,7 +415,6 @@ int janet_thread_receive(Janet *msg_out, double timeout) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int janet_thread_getter(void *p, Janet key, Janet *out);
|
static int janet_thread_getter(void *p, Janet key, Janet *out);
|
||||||
@ -499,6 +502,10 @@ static int thread_worker(JanetMailboxPair *pair) {
|
|||||||
/* Call function */
|
/* Call function */
|
||||||
Janet argv[1] = { parentv };
|
Janet argv[1] = { parentv };
|
||||||
fiber = janet_fiber(func, 64, 1, argv);
|
fiber = janet_fiber(func, 64, 1, argv);
|
||||||
|
if (pair->flags & JANET_THREAD_HEAVYWEIGHT) {
|
||||||
|
fiber->env = janet_table(0);
|
||||||
|
fiber->env->proto = janet_core_env(NULL);
|
||||||
|
}
|
||||||
JanetSignal sig = janet_continue(fiber, janet_wrap_nil(), &out);
|
JanetSignal sig = janet_continue(fiber, janet_wrap_nil(), &out);
|
||||||
if (sig != JANET_SIGNAL_OK && sig < JANET_SIGNAL_USER0) {
|
if (sig != JANET_SIGNAL_OK && sig < JANET_SIGNAL_USER0) {
|
||||||
janet_eprintf("in thread %v: ", janet_wrap_abstract(janet_make_thread(pair->newbox, encode)));
|
janet_eprintf("in thread %v: ", janet_wrap_abstract(janet_make_thread(pair->newbox, encode)));
|
||||||
@ -660,6 +667,8 @@ static Janet cfun_thread_receive(int32_t argc, Janet *argv) {
|
|||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
janet_panicf("timeout after %f seconds", wait);
|
janet_panicf("timeout after %f seconds", wait);
|
||||||
|
case 2:
|
||||||
|
janet_panicf("failed to receive message: %v", out);
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
@ -671,6 +680,18 @@ static Janet cfun_thread_close(int32_t argc, Janet *argv) {
|
|||||||
return janet_wrap_nil();
|
return janet_wrap_nil();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Janet cfun_thread_exit(int32_t argc, Janet *argv) {
|
||||||
|
(void) argv;
|
||||||
|
janet_arity(argc, 0, 1);
|
||||||
|
#if defined(JANET_WINDOWS)
|
||||||
|
int32_t flag = janet_optinteger(argv, argc, 0, 0);
|
||||||
|
ExitThread(flag);
|
||||||
|
#else
|
||||||
|
pthread_exit(NULL);
|
||||||
|
#endif
|
||||||
|
return janet_wrap_nil();
|
||||||
|
}
|
||||||
|
|
||||||
static const JanetMethod janet_thread_methods[] = {
|
static const JanetMethod janet_thread_methods[] = {
|
||||||
{"send", cfun_thread_send},
|
{"send", cfun_thread_send},
|
||||||
{"close", cfun_thread_close},
|
{"close", cfun_thread_close},
|
||||||
@ -719,6 +740,12 @@ static const JanetReg threadlib_cfuns[] = {
|
|||||||
"Close a thread, unblocking it and ending communication with it. Note that closing "
|
"Close a thread, unblocking it and ending communication with it. Note that closing "
|
||||||
"a thread is idempotent and does not cancel the thread's operation. Returns nil.")
|
"a thread is idempotent and does not cancel the thread's operation. Returns nil.")
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"thread/exit", cfun_thread_exit,
|
||||||
|
JDOC("(thread/exit &opt code)\n\n"
|
||||||
|
"Exit from the current thread. If no more threads are running, ends the process, but otherwise does "
|
||||||
|
"not end the current process.")
|
||||||
|
},
|
||||||
{NULL, NULL, NULL}
|
{NULL, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -596,6 +596,11 @@ JanetTable *janet_get_core_table(const char *name) {
|
|||||||
|
|
||||||
/* Clock shims for various platforms */
|
/* Clock shims for various platforms */
|
||||||
#ifdef JANET_GETTIME
|
#ifdef JANET_GETTIME
|
||||||
|
/* For macos */
|
||||||
|
#ifdef __MACH__
|
||||||
|
#include <mach/clock.h>
|
||||||
|
#include <mach/mach.h>
|
||||||
|
#endif
|
||||||
#ifdef JANET_WINDOWS
|
#ifdef JANET_WINDOWS
|
||||||
int janet_gettime(struct timespec *spec) {
|
int janet_gettime(struct timespec *spec) {
|
||||||
FILETIME ftime;
|
FILETIME ftime;
|
||||||
@ -621,7 +626,7 @@ int janet_gettime(struct timespec *spec) {
|
|||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
int janet_gettime(struct timespec *spec) {
|
int janet_gettime(struct timespec *spec) {
|
||||||
return clock_gettime(CLOCK_MONOTONIC, spec);
|
return clock_gettime(CLOCK_REALTIME, spec);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
@ -31,6 +31,11 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
#if !defined(JANET_REDUCED_OS) || !defined(JANET_SINGLE_THREADED)
|
||||||
|
#include <time.h>
|
||||||
|
#define JANET_GETTIME
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Handle runtime errors */
|
/* Handle runtime errors */
|
||||||
#ifndef JANET_EXIT
|
#ifndef JANET_EXIT
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -75,6 +80,7 @@ Janet janet_dict_get(const JanetKV *buckets, int32_t cap, Janet key);
|
|||||||
void janet_memempty(JanetKV *mem, int32_t count);
|
void janet_memempty(JanetKV *mem, int32_t count);
|
||||||
void *janet_memalloc_empty(int32_t count);
|
void *janet_memalloc_empty(int32_t count);
|
||||||
JanetTable *janet_get_core_table(const char *name);
|
JanetTable *janet_get_core_table(const char *name);
|
||||||
|
void janet_def_addflags(JanetFuncDef *def);
|
||||||
const void *janet_strbinsearch(
|
const void *janet_strbinsearch(
|
||||||
const void *tab,
|
const void *tab,
|
||||||
size_t tabcount,
|
size_t tabcount,
|
||||||
@ -98,12 +104,7 @@ void janet_core_cfuns(JanetTable *env, const char *regprefix, const JanetReg *cf
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Clock gettime */
|
/* Clock gettime */
|
||||||
#if !defined(JANET_REDUCED_OS) || !defined(JANET_SINGLE_THREADED)
|
#ifdef JANET_GETTIME
|
||||||
#include <time.h>
|
|
||||||
#ifndef JANET_WINDOWS
|
|
||||||
#include <sys/time.h>
|
|
||||||
#endif
|
|
||||||
#define JANET_GETTIME
|
|
||||||
int janet_gettime(struct timespec *spec);
|
int janet_gettime(struct timespec *spec);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -128,10 +128,10 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Limits for converting doubles to 64 bit integers */
|
/* Limits for converting doubles to 64 bit integers */
|
||||||
#define JANET_INTMAX_DOUBLE 9007199254740991.0
|
#define JANET_INTMAX_DOUBLE 9007199254740992.0
|
||||||
#define JANET_INTMIN_DOUBLE (-9007199254740991.0)
|
#define JANET_INTMIN_DOUBLE (-9007199254740992.0)
|
||||||
#define JANET_INTMAX_INT64 9007199254740991
|
#define JANET_INTMAX_INT64 9007199254740992
|
||||||
#define JANET_INTMIN_INT64 (-9007199254740991)
|
#define JANET_INTMIN_INT64 (-9007199254740992)
|
||||||
|
|
||||||
/* Check emscripten */
|
/* Check emscripten */
|
||||||
#ifdef __EMSCRIPTEN__
|
#ifdef __EMSCRIPTEN__
|
||||||
@ -1065,7 +1065,7 @@ struct JanetRNG {
|
|||||||
typedef struct JanetFile JanetFile;
|
typedef struct JanetFile JanetFile;
|
||||||
struct JanetFile {
|
struct JanetFile {
|
||||||
FILE *file;
|
FILE *file;
|
||||||
int flags;
|
int32_t flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Thread types */
|
/* Thread types */
|
||||||
@ -1613,11 +1613,11 @@ extern JANET_API const JanetAbstractType janet_file_type;
|
|||||||
#define JANET_FILE_SERIALIZABLE 128
|
#define JANET_FILE_SERIALIZABLE 128
|
||||||
#define JANET_FILE_PIPED 256
|
#define JANET_FILE_PIPED 256
|
||||||
|
|
||||||
JANET_API Janet janet_makefile(FILE *f, int flags);
|
JANET_API Janet janet_makefile(FILE *f, int32_t flags);
|
||||||
JANET_API FILE *janet_getfile(const Janet *argv, int32_t n, int *flags);
|
JANET_API FILE *janet_getfile(const Janet *argv, int32_t n, int32_t *flags);
|
||||||
JANET_API FILE *janet_dynfile(const char *name, FILE *def);
|
JANET_API FILE *janet_dynfile(const char *name, FILE *def);
|
||||||
JANET_API JanetAbstract janet_checkfile(Janet j);
|
JANET_API JanetAbstract janet_checkfile(Janet j);
|
||||||
JANET_API FILE *janet_unwrapfile(Janet j, int *flags);
|
JANET_API FILE *janet_unwrapfile(Janet j, int32_t *flags);
|
||||||
|
|
||||||
/* Marshal API */
|
/* Marshal API */
|
||||||
JANET_API void janet_marshal_size(JanetMarshalContext *ctx, size_t value);
|
JANET_API void janet_marshal_size(JanetMarshalContext *ctx, size_t value);
|
||||||
|
@ -126,21 +126,28 @@ https://github.com/antirez/linenoise/blob/master/linenoise.c
|
|||||||
#define JANET_LINE_MAX 1024
|
#define JANET_LINE_MAX 1024
|
||||||
#define JANET_MATCH_MAX 256
|
#define JANET_MATCH_MAX 256
|
||||||
#define JANET_HISTORY_MAX 100
|
#define JANET_HISTORY_MAX 100
|
||||||
static JANET_THREAD_LOCAL int gbl_israwmode = 0;
|
static int gbl_israwmode = 0;
|
||||||
static JANET_THREAD_LOCAL const char *gbl_prompt = "> ";
|
static const char *gbl_prompt = "> ";
|
||||||
static JANET_THREAD_LOCAL int gbl_plen = 2;
|
static int gbl_plen = 2;
|
||||||
static JANET_THREAD_LOCAL char gbl_buf[JANET_LINE_MAX];
|
static char gbl_buf[JANET_LINE_MAX];
|
||||||
static JANET_THREAD_LOCAL int gbl_len = 0;
|
static int gbl_len = 0;
|
||||||
static JANET_THREAD_LOCAL int gbl_pos = 0;
|
static int gbl_pos = 0;
|
||||||
static JANET_THREAD_LOCAL int gbl_cols = 80;
|
static int gbl_cols = 80;
|
||||||
static JANET_THREAD_LOCAL char *gbl_history[JANET_HISTORY_MAX];
|
static char *gbl_history[JANET_HISTORY_MAX];
|
||||||
static JANET_THREAD_LOCAL int gbl_history_count = 0;
|
static int gbl_history_count = 0;
|
||||||
static JANET_THREAD_LOCAL int gbl_historyi = 0;
|
static int gbl_historyi = 0;
|
||||||
static JANET_THREAD_LOCAL int gbl_sigint_flag = 0;
|
static int gbl_sigint_flag = 0;
|
||||||
static JANET_THREAD_LOCAL struct termios gbl_termios_start;
|
static struct termios gbl_termios_start;
|
||||||
static JANET_THREAD_LOCAL JanetByteView gbl_matches[JANET_MATCH_MAX];
|
static JanetByteView gbl_matches[JANET_MATCH_MAX];
|
||||||
static JANET_THREAD_LOCAL int gbl_match_count = 0;
|
static int gbl_match_count = 0;
|
||||||
static JANET_THREAD_LOCAL int gbl_lines_below = 0;
|
static int gbl_lines_below = 0;
|
||||||
|
|
||||||
|
/* Put a lock around this global state so we don't screw up
|
||||||
|
* the terminal in a multithreaded situation */
|
||||||
|
#ifndef JANET_SINGLE_THREADED
|
||||||
|
#include <pthread.h>
|
||||||
|
static pthread_mutex_t gbl_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Unsupported terminal list from linenoise */
|
/* Unsupported terminal list from linenoise */
|
||||||
static const char *badterms[] = {
|
static const char *badterms[] = {
|
||||||
@ -162,6 +169,9 @@ static char *sdup(const char *s) {
|
|||||||
/* Ansi terminal raw mode */
|
/* Ansi terminal raw mode */
|
||||||
static int rawmode(void) {
|
static int rawmode(void) {
|
||||||
struct termios t;
|
struct termios t;
|
||||||
|
#ifndef JANET_SINGLE_THREADED
|
||||||
|
pthread_mutex_lock(&gbl_lock);
|
||||||
|
#endif
|
||||||
if (!isatty(STDIN_FILENO)) goto fatal;
|
if (!isatty(STDIN_FILENO)) goto fatal;
|
||||||
if (tcgetattr(STDIN_FILENO, &gbl_termios_start) == -1) goto fatal;
|
if (tcgetattr(STDIN_FILENO, &gbl_termios_start) == -1) goto fatal;
|
||||||
t = gbl_termios_start;
|
t = gbl_termios_start;
|
||||||
@ -175,6 +185,9 @@ static int rawmode(void) {
|
|||||||
return 0;
|
return 0;
|
||||||
fatal:
|
fatal:
|
||||||
errno = ENOTTY;
|
errno = ENOTTY;
|
||||||
|
#ifndef JANET_SINGLE_THREADED
|
||||||
|
pthread_mutex_unlock(&gbl_lock);
|
||||||
|
#endif
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,6 +195,9 @@ fatal:
|
|||||||
static void norawmode(void) {
|
static void norawmode(void) {
|
||||||
if (gbl_israwmode && tcsetattr(STDIN_FILENO, TCSAFLUSH, &gbl_termios_start) != -1)
|
if (gbl_israwmode && tcsetattr(STDIN_FILENO, TCSAFLUSH, &gbl_termios_start) != -1)
|
||||||
gbl_israwmode = 0;
|
gbl_israwmode = 0;
|
||||||
|
#ifndef JANET_SINGLE_THREADED
|
||||||
|
pthread_mutex_unlock(&gbl_lock);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int curpos(void) {
|
static int curpos(void) {
|
||||||
@ -996,6 +1012,11 @@ int main(int argc, char **argv) {
|
|||||||
SetConsoleOutputCP(65001);
|
SetConsoleOutputCP(65001);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined(JANET_WINDOWS) && !defined(JANET_SIMPLE_GETLINE)
|
||||||
|
/* Try and not leave the terminal in a bad state */
|
||||||
|
atexit(norawmode);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Set up VM */
|
/* Set up VM */
|
||||||
janet_init();
|
janet_init();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user