mirror of
https://github.com/janet-lang/janet
synced 2025-10-28 14:17:42 +00:00
Weak containers did not preserve their weakness when marshalled. This fixes that for tables and arrays, as well as adds some tests for this. Also exposes functions for creating weak tables in janet.h
2247 lines
84 KiB
C
2247 lines
84 KiB
C
/*
|
|
* Copyright (c) 2023 Calvin Rose
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to
|
|
* deal in the Software without restriction, including without limitation the
|
|
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
* sell copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in
|
|
* all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
* IN THE SOFTWARE.
|
|
*/
|
|
|
|
#include "janetconf.h"
|
|
|
|
#ifndef JANET_H_defined
|
|
#define JANET_H_defined
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/* Variable length arrays are ok */
|
|
#ifdef _MSC_VER
|
|
#pragma warning( push )
|
|
#pragma warning( disable : 4200 )
|
|
#endif
|
|
|
|
/***** START SECTION CONFIG *****/
|
|
|
|
#ifndef JANET_VERSION
|
|
#define JANET_VERSION "latest"
|
|
#endif
|
|
|
|
#ifndef JANET_BUILD
|
|
#define JANET_BUILD "local"
|
|
#endif
|
|
|
|
/*
|
|
* Detect OS and endianness.
|
|
* From webkit source. There is likely some extreneous
|
|
* detection for unsupported platforms
|
|
*/
|
|
|
|
/* Check for any flavor of BSD (except apple) */
|
|
#if defined(__FreeBSD__) || defined(__DragonFly__) || \
|
|
defined(__NetBSD__) || defined(__OpenBSD__)
|
|
#define JANET_BSD 1
|
|
#endif
|
|
|
|
/* Check for macOS or OS X */
|
|
#if defined(__APPLE__) && defined(__MACH__)
|
|
#define JANET_APPLE 1
|
|
#endif
|
|
|
|
/* Check for Linux */
|
|
#ifdef __linux__
|
|
#define JANET_LINUX 1
|
|
#endif
|
|
|
|
/* Check for Cygwin */
|
|
#if defined(__CYGWIN__)
|
|
#define JANET_CYGWIN 1
|
|
#endif
|
|
|
|
/* Check Unix */
|
|
#if defined(_AIX) \
|
|
|| defined(__APPLE__) /* Darwin */ \
|
|
|| defined(__FreeBSD__) || defined(__DragonFly__) \
|
|
|| defined(__FreeBSD_kernel__) \
|
|
|| defined(__GNU__) /* GNU/Hurd */ \
|
|
|| defined(__HAIKU__) \
|
|
|| defined(__linux__) \
|
|
|| defined(__NetBSD__) \
|
|
|| defined(__OpenBSD__) \
|
|
|| defined(__QNXNTO__) \
|
|
|| defined(sun) || defined(__sun) /* Solaris */ \
|
|
|| defined(unix) || defined(__unix) || defined(__unix__)
|
|
#define JANET_POSIX 1
|
|
#elif defined(__EMSCRIPTEN__)
|
|
#define JANET_WEB 1
|
|
#elif defined(WIN32) || defined(_WIN32)
|
|
#define JANET_WINDOWS 1
|
|
#endif
|
|
|
|
/* Check if compiling with MSVC - else assume a GCC-like compiler by default */
|
|
#ifdef _MSC_VER
|
|
#define JANET_MSVC
|
|
#endif
|
|
|
|
/* Check Mingw 32-bit and 64-bit */
|
|
#ifdef __MINGW32__
|
|
#define JANET_MINGW
|
|
#endif
|
|
|
|
/* Check 64-bit vs 32-bit */
|
|
#if ((defined(__x86_64__) || defined(_M_X64)) \
|
|
&& (defined(JANET_POSIX) || defined(JANET_WINDOWS))) \
|
|
|| (defined(_WIN64)) /* Windows 64 bit */ \
|
|
|| (defined(__ia64__) && defined(__LP64__)) /* Itanium in LP64 mode */ \
|
|
|| defined(__alpha__) /* DEC Alpha */ \
|
|
|| (defined(__sparc__) && defined(__arch64__) || defined (__sparcv9)) /* BE */ \
|
|
|| defined(__s390x__) /* S390 64-bit (BE) */ \
|
|
|| (defined(__ppc64__) || defined(__PPC64__)) \
|
|
|| defined(__aarch64__) /* ARM 64-bit */ \
|
|
|| (defined(__riscv) && (__riscv_xlen == 64)) /* RISC-V 64-bit */ \
|
|
|| defined(__loongarch64) /* LoongArch64 64-bit */
|
|
#define JANET_64 1
|
|
#else
|
|
#define JANET_32 1
|
|
#endif
|
|
|
|
/* Check big endian */
|
|
#if defined(__LITTLE_ENDIAN__) || \
|
|
(defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
|
|
/* If we know the target is LE, always use that - e.g. ppc64 little endian
|
|
* defines the __LITTLE_ENDIAN__ macro in the ABI spec, so we can rely
|
|
* on that and if that's not defined, fall back to big endian assumption
|
|
*/
|
|
#define JANET_LITTLE_ENDIAN 1
|
|
#elif defined(__MIPSEB__) /* MIPS 32-bit */ \
|
|
|| defined(__ppc__) || defined(__PPC__) /* CPU(PPC) - PowerPC 32-bit */ \
|
|
|| defined(__powerpc__) || defined(__powerpc) || defined(__POWERPC__) \
|
|
|| defined(_M_PPC) || defined(__PPC) \
|
|
|| defined(__ppc64__) || defined(__PPC64__) /* PowerPC 64-bit */ \
|
|
|| defined(__sparc) /* Sparc 32bit */ \
|
|
|| defined(__sparc__) /* Sparc 64-bit */ \
|
|
|| defined(__s390x__) /* S390 64-bit */ \
|
|
|| defined(__s390__) /* S390 32-bit */ \
|
|
|| defined(__ARMEB__) /* ARM big endian */ \
|
|
|| ((defined(__CC_ARM) || defined(__ARMCC__)) /* ARM RealView compiler */ \
|
|
&& defined(__BIG_ENDIAN))
|
|
#define JANET_BIG_ENDIAN 1
|
|
#else
|
|
#define JANET_LITTLE_ENDIAN 1
|
|
#endif
|
|
|
|
/* Limits for converting doubles to 64 bit integers */
|
|
#define JANET_INTMAX_DOUBLE 9007199254740992.0
|
|
#define JANET_INTMIN_DOUBLE (-9007199254740992.0)
|
|
#define JANET_INTMAX_INT64 9007199254740992
|
|
#define JANET_INTMIN_INT64 (-9007199254740992)
|
|
|
|
/* Check emscripten */
|
|
#ifdef __EMSCRIPTEN__
|
|
#define JANET_NO_DYNAMIC_MODULES
|
|
#define JANET_NO_PROCESSES
|
|
#endif
|
|
|
|
/* Check sun */
|
|
#ifdef __sun
|
|
#define JANET_NO_UTC_MKTIME
|
|
#endif
|
|
|
|
/* Define how global janet state is declared */
|
|
/* Also enable the thread library only if not single-threaded */
|
|
#ifdef JANET_SINGLE_THREADED
|
|
#define JANET_THREAD_LOCAL
|
|
#undef JANET_THREADS
|
|
#elif defined(__GNUC__)
|
|
#define JANET_THREAD_LOCAL __thread
|
|
#elif defined(_MSC_BUILD)
|
|
#define JANET_THREAD_LOCAL __declspec(thread)
|
|
#else
|
|
#define JANET_THREAD_LOCAL
|
|
#undef JANET_THREADS
|
|
#endif
|
|
|
|
/* Enable or disable dynamic module loading. Enabled by default. */
|
|
#ifndef JANET_NO_DYNAMIC_MODULES
|
|
#define JANET_DYNAMIC_MODULES
|
|
#endif
|
|
|
|
/* Enable or disable the FFI library. Currently, FFI only enabled on
|
|
* x86-64 operating systems. */
|
|
#ifndef JANET_NO_FFI
|
|
#if !defined(__EMSCRIPTEN__)
|
|
#define JANET_FFI
|
|
#endif
|
|
#endif
|
|
|
|
/* If FFI is enabled and FFI-JIT is not disabled... */
|
|
#ifdef JANET_FFI
|
|
#ifndef JANET_NO_FFI_JIT
|
|
#define JANET_FFI_JIT
|
|
#endif
|
|
#endif
|
|
|
|
/* Enable or disable the assembler. Enabled by default. */
|
|
#ifndef JANET_NO_ASSEMBLER
|
|
#define JANET_ASSEMBLER
|
|
#endif
|
|
|
|
/* Enable or disable the peg module */
|
|
#ifndef JANET_NO_PEG
|
|
#define JANET_PEG
|
|
#endif
|
|
|
|
/* Enable or disable event loop */
|
|
#if !defined(JANET_NO_EV) && !defined(__EMSCRIPTEN__)
|
|
#define JANET_EV
|
|
#endif
|
|
|
|
/* Enable or disable the filewatch/ module */
|
|
#if !defined(JANET_NO_FILEWATCH)
|
|
#define JANET_FILEWATCH
|
|
#endif
|
|
|
|
/* Enable or disable networking */
|
|
#if defined(JANET_EV) && !defined(JANET_NO_NET) && !defined(__EMSCRIPTEN__)
|
|
#define JANET_NET
|
|
#endif
|
|
|
|
/* Enable or disable large int types (for now 64 bit, maybe 128 / 256 bit integer types) */
|
|
#ifndef JANET_NO_INT_TYPES
|
|
#define JANET_INT_TYPES
|
|
#endif
|
|
|
|
/* Enable or disable epoll on Linux */
|
|
#if defined(JANET_LINUX) && !defined(JANET_EV_NO_EPOLL)
|
|
#define JANET_EV_EPOLL
|
|
#endif
|
|
|
|
/* Enable or disable kqueue on BSD */
|
|
#if defined(JANET_BSD) && !defined(JANET_EV_NO_KQUEUE)
|
|
#define JANET_EV_KQUEUE
|
|
#endif
|
|
|
|
/* Enable or disable kqueue on Apple */
|
|
#if defined(JANET_APPLE) && !defined(JANET_EV_NO_KQUEUE)
|
|
#define JANET_EV_KQUEUE
|
|
#endif
|
|
|
|
/* Use poll as last resort */
|
|
#if !defined(JANET_WINDOWS) && !defined(JANET_EV_EPOLL) && !defined(JANET_EV_KQUEUE)
|
|
#define JANET_EV_POLL
|
|
#endif
|
|
|
|
/* How to export symbols */
|
|
#ifndef JANET_EXPORT
|
|
#ifdef JANET_WINDOWS
|
|
#define JANET_EXPORT __declspec(dllexport)
|
|
#else
|
|
#define JANET_EXPORT __attribute__((visibility ("default")))
|
|
#endif
|
|
#endif
|
|
|
|
/* How declare API functions */
|
|
#ifndef JANET_API
|
|
#ifdef JANET_WINDOWS
|
|
#ifdef JANET_DLL_IMPORT
|
|
#define JANET_API __declspec(dllimport)
|
|
#else
|
|
#define JANET_API __declspec(dllexport)
|
|
#endif
|
|
#else
|
|
#define JANET_API __attribute__((visibility ("default")))
|
|
#endif
|
|
#endif
|
|
|
|
/* Tell compiler some functions don't return */
|
|
#ifndef JANET_NO_RETURN
|
|
#ifdef JANET_WINDOWS
|
|
#define JANET_NO_RETURN __declspec(noreturn)
|
|
#else
|
|
#define JANET_NO_RETURN __attribute__((noreturn))
|
|
#endif
|
|
#endif
|
|
|
|
/* Prevent some recursive functions from recursing too deeply
|
|
* and crashing (the parser). Instead, error out. */
|
|
#define JANET_RECURSION_GUARD 1024
|
|
|
|
/* Maximum depth to follow table prototypes before giving up and returning nil. */
|
|
#define JANET_MAX_PROTO_DEPTH 200
|
|
|
|
/* Prevent macros to expand too deeply and error out. */
|
|
#define JANET_MAX_MACRO_EXPAND 200
|
|
|
|
/* Define default max stack size for stacks before raising a stack overflow error.
|
|
* This can also be set on a per fiber basis. */
|
|
#ifndef JANET_STACK_MAX
|
|
#define JANET_STACK_MAX 0x7fffffff
|
|
#endif
|
|
|
|
/* Use nanboxed values - uses 8 bytes per value instead of 12 or 16.
|
|
* To turn of nanboxing, for debugging purposes or for certain
|
|
* architectures (Nanboxing only tested on x86 and x64), comment out
|
|
* the JANET_NANBOX define.*/
|
|
|
|
#if defined(_M_ARM64) || defined(_M_ARM) || defined(__aarch64__)
|
|
#define JANET_NO_NANBOX
|
|
#endif
|
|
|
|
#ifndef JANET_NO_NANBOX
|
|
#ifdef JANET_32
|
|
#define JANET_NANBOX_32
|
|
#elif defined(__x86_64__) || defined(_WIN64) || defined(__riscv)
|
|
/* We will only enable nanboxing by default on 64 bit systems
|
|
* for x64 and risc-v. This is mainly because the approach is tied to the
|
|
* implicit 47 bit address space. Many arches allow/require this, but not all,
|
|
* and it requires cooperation from the OS. ARM should also work in many configurations. */
|
|
#define JANET_NANBOX_64
|
|
#endif
|
|
#endif
|
|
|
|
/* Runtime config constants */
|
|
#ifdef JANET_NO_NANBOX
|
|
#define JANET_NANBOX_BIT 0
|
|
#else
|
|
#define JANET_NANBOX_BIT 0x1
|
|
#endif
|
|
|
|
#ifdef JANET_SINGLE_THREADED
|
|
#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 {
|
|
unsigned major;
|
|
unsigned minor;
|
|
unsigned patch;
|
|
unsigned bits;
|
|
} JanetBuildConfig;
|
|
|
|
/* Get config of current compilation unit. */
|
|
#ifdef __cplusplus
|
|
/* C++11 syntax */
|
|
#define janet_config_current() (JanetBuildConfig { \
|
|
JANET_VERSION_MAJOR, \
|
|
JANET_VERSION_MINOR, \
|
|
JANET_VERSION_PATCH, \
|
|
JANET_CURRENT_CONFIG_BITS })
|
|
#else
|
|
/* C99 syntax */
|
|
#define janet_config_current() ((JanetBuildConfig){ \
|
|
JANET_VERSION_MAJOR, \
|
|
JANET_VERSION_MINOR, \
|
|
JANET_VERSION_PATCH, \
|
|
JANET_CURRENT_CONFIG_BITS })
|
|
#endif
|
|
|
|
/* Some extra includes if EV is enabled */
|
|
#ifdef JANET_EV
|
|
typedef struct JanetOSMutex JanetOSMutex;
|
|
typedef struct JanetOSRWLock JanetOSRWLock;
|
|
typedef struct JanetChannel JanetChannel;
|
|
#endif
|
|
|
|
/***** END SECTION CONFIG *****/
|
|
|
|
/***** START SECTION TYPES *****/
|
|
|
|
#ifdef JANET_WINDOWS
|
|
/* Must be defined before including stdlib.h */
|
|
#define _CRT_RAND_S
|
|
#endif
|
|
|
|
#include <stdlib.h>
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
#include <stdarg.h>
|
|
#include <setjmp.h>
|
|
#include <stddef.h>
|
|
#include <stdio.h>
|
|
|
|
/* What to do when out of memory */
|
|
#ifndef JANET_OUT_OF_MEMORY
|
|
#define JANET_OUT_OF_MEMORY do { fprintf(stderr, "%s:%d - janet out of memory\n", __FILE__, __LINE__); exit(1); } while (0)
|
|
#endif
|
|
|
|
#ifdef JANET_BSD
|
|
int _setjmp(jmp_buf);
|
|
JANET_NO_RETURN void _longjmp(jmp_buf, int);
|
|
#endif
|
|
|
|
/* Names of all of the types */
|
|
JANET_API extern const char *const janet_type_names[16];
|
|
JANET_API extern const char *const janet_signal_names[14];
|
|
JANET_API extern const char *const janet_status_names[16];
|
|
|
|
/* For various IO routines, we want to use an int on posix and HANDLE on windows */
|
|
#ifdef JANET_WINDOWS
|
|
typedef void *JanetHandle;
|
|
#define JANET_HANDLE_NONE NULL
|
|
#else
|
|
typedef int JanetHandle;
|
|
#define JANET_HANDLE_NONE (-1)
|
|
#endif
|
|
|
|
/* Fiber signals */
|
|
typedef enum {
|
|
JANET_SIGNAL_OK,
|
|
JANET_SIGNAL_ERROR,
|
|
JANET_SIGNAL_DEBUG,
|
|
JANET_SIGNAL_YIELD,
|
|
JANET_SIGNAL_USER0,
|
|
JANET_SIGNAL_USER1,
|
|
JANET_SIGNAL_USER2,
|
|
JANET_SIGNAL_USER3,
|
|
JANET_SIGNAL_USER4,
|
|
JANET_SIGNAL_USER5,
|
|
JANET_SIGNAL_USER6,
|
|
JANET_SIGNAL_USER7,
|
|
JANET_SIGNAL_USER8,
|
|
JANET_SIGNAL_USER9,
|
|
JANET_SIGNAL_INTERRUPT = JANET_SIGNAL_USER8,
|
|
JANET_SIGNAL_EVENT = JANET_SIGNAL_USER9,
|
|
} JanetSignal;
|
|
|
|
/* Fiber statuses - mostly corresponds to signals. */
|
|
typedef enum {
|
|
JANET_STATUS_DEAD,
|
|
JANET_STATUS_ERROR,
|
|
JANET_STATUS_DEBUG,
|
|
JANET_STATUS_PENDING,
|
|
JANET_STATUS_USER0,
|
|
JANET_STATUS_USER1,
|
|
JANET_STATUS_USER2,
|
|
JANET_STATUS_USER3,
|
|
JANET_STATUS_USER4,
|
|
JANET_STATUS_USER5,
|
|
JANET_STATUS_USER6,
|
|
JANET_STATUS_USER7,
|
|
JANET_STATUS_USER8,
|
|
JANET_STATUS_USER9,
|
|
JANET_STATUS_NEW,
|
|
JANET_STATUS_ALIVE
|
|
} JanetFiberStatus;
|
|
|
|
/* For encapsulating all thread-local Janet state (except natives) */
|
|
typedef struct JanetVM JanetVM;
|
|
|
|
/* Use type punning for GC objects */
|
|
typedef struct JanetGCObject JanetGCObject;
|
|
|
|
/* All of the primary Janet GCed types */
|
|
typedef struct JanetFunction JanetFunction;
|
|
typedef struct JanetArray JanetArray;
|
|
typedef struct JanetBuffer JanetBuffer;
|
|
typedef struct JanetTable JanetTable;
|
|
typedef struct JanetFiber JanetFiber;
|
|
|
|
/* Prefixed Janet types */
|
|
typedef struct JanetTupleHead JanetTupleHead;
|
|
typedef struct JanetStructHead JanetStructHead;
|
|
typedef struct JanetStringHead JanetStringHead;
|
|
typedef struct JanetAbstractHead JanetAbstractHead;
|
|
|
|
/* Other structs */
|
|
typedef struct JanetFuncDef JanetFuncDef;
|
|
typedef struct JanetFuncEnv JanetFuncEnv;
|
|
typedef struct JanetKV JanetKV;
|
|
typedef struct JanetStackFrame JanetStackFrame;
|
|
typedef struct JanetAbstractType JanetAbstractType;
|
|
typedef struct JanetReg JanetReg;
|
|
typedef struct JanetRegExt JanetRegExt;
|
|
typedef struct JanetMethod JanetMethod;
|
|
typedef struct JanetSourceMapping JanetSourceMapping;
|
|
typedef struct JanetSymbolMap JanetSymbolMap;
|
|
typedef struct JanetView JanetView;
|
|
typedef struct JanetByteView JanetByteView;
|
|
typedef struct JanetDictView JanetDictView;
|
|
typedef struct JanetRange JanetRange;
|
|
typedef struct JanetRNG JanetRNG;
|
|
|
|
/* Basic types for all Janet Values */
|
|
typedef enum JanetType {
|
|
JANET_NUMBER,
|
|
JANET_NIL,
|
|
JANET_BOOLEAN,
|
|
JANET_FIBER,
|
|
JANET_STRING,
|
|
JANET_SYMBOL,
|
|
JANET_KEYWORD,
|
|
JANET_ARRAY,
|
|
JANET_TUPLE,
|
|
JANET_TABLE,
|
|
JANET_STRUCT,
|
|
JANET_BUFFER,
|
|
JANET_FUNCTION,
|
|
JANET_CFUNCTION,
|
|
JANET_ABSTRACT,
|
|
JANET_POINTER
|
|
} JanetType;
|
|
|
|
/* Recursive type (Janet) */
|
|
#ifdef JANET_NANBOX_64
|
|
typedef union Janet Janet;
|
|
union Janet {
|
|
uint64_t u64;
|
|
int64_t i64;
|
|
double number;
|
|
void *pointer;
|
|
};
|
|
#elif defined(JANET_NANBOX_32)
|
|
typedef union Janet Janet;
|
|
union Janet {
|
|
struct {
|
|
#ifdef JANET_BIG_ENDIAN
|
|
uint32_t type;
|
|
union {
|
|
int32_t integer;
|
|
void *pointer;
|
|
} payload;
|
|
#else
|
|
union {
|
|
int32_t integer;
|
|
void *pointer;
|
|
} payload;
|
|
uint32_t type;
|
|
#endif
|
|
} tagged;
|
|
double number;
|
|
uint64_t u64;
|
|
};
|
|
#else
|
|
typedef struct Janet Janet;
|
|
struct Janet {
|
|
union {
|
|
uint64_t u64;
|
|
double number;
|
|
int32_t integer;
|
|
void *pointer;
|
|
const void *cpointer;
|
|
} as;
|
|
JanetType type;
|
|
};
|
|
#endif
|
|
|
|
/* C functions */
|
|
typedef Janet(*JanetCFunction)(int32_t argc, Janet *argv);
|
|
|
|
/* String and other aliased pointer types */
|
|
typedef const uint8_t *JanetString;
|
|
typedef const uint8_t *JanetSymbol;
|
|
typedef const uint8_t *JanetKeyword;
|
|
typedef const Janet *JanetTuple;
|
|
typedef const JanetKV *JanetStruct;
|
|
typedef void *JanetAbstract;
|
|
|
|
#define JANET_COUNT_TYPES (JANET_POINTER + 1)
|
|
|
|
/* Type flags */
|
|
#define JANET_TFLAG_NIL (1 << JANET_NIL)
|
|
#define JANET_TFLAG_BOOLEAN (1 << JANET_BOOLEAN)
|
|
#define JANET_TFLAG_FIBER (1 << JANET_FIBER)
|
|
#define JANET_TFLAG_NUMBER (1 << JANET_NUMBER)
|
|
#define JANET_TFLAG_STRING (1 << JANET_STRING)
|
|
#define JANET_TFLAG_SYMBOL (1 << JANET_SYMBOL)
|
|
#define JANET_TFLAG_KEYWORD (1 << JANET_KEYWORD)
|
|
#define JANET_TFLAG_ARRAY (1 << JANET_ARRAY)
|
|
#define JANET_TFLAG_TUPLE (1 << JANET_TUPLE)
|
|
#define JANET_TFLAG_TABLE (1 << JANET_TABLE)
|
|
#define JANET_TFLAG_STRUCT (1 << JANET_STRUCT)
|
|
#define JANET_TFLAG_BUFFER (1 << JANET_BUFFER)
|
|
#define JANET_TFLAG_FUNCTION (1 << JANET_FUNCTION)
|
|
#define JANET_TFLAG_CFUNCTION (1 << JANET_CFUNCTION)
|
|
#define JANET_TFLAG_ABSTRACT (1 << JANET_ABSTRACT)
|
|
#define JANET_TFLAG_POINTER (1 << JANET_POINTER)
|
|
|
|
#define JANET_TFLAG_BYTES (JANET_TFLAG_STRING | JANET_TFLAG_SYMBOL | JANET_TFLAG_BUFFER | JANET_TFLAG_KEYWORD)
|
|
#define JANET_TFLAG_INDEXED (JANET_TFLAG_ARRAY | JANET_TFLAG_TUPLE)
|
|
#define JANET_TFLAG_DICTIONARY (JANET_TFLAG_TABLE | JANET_TFLAG_STRUCT)
|
|
#define JANET_TFLAG_LENGTHABLE (JANET_TFLAG_BYTES | JANET_TFLAG_INDEXED | JANET_TFLAG_DICTIONARY)
|
|
#define JANET_TFLAG_CALLABLE (JANET_TFLAG_FUNCTION | JANET_TFLAG_CFUNCTION | \
|
|
JANET_TFLAG_LENGTHABLE | JANET_TFLAG_ABSTRACT)
|
|
|
|
/* Event Loop Types */
|
|
#ifdef JANET_EV
|
|
|
|
#define JANET_STREAM_CLOSED 0x1
|
|
#define JANET_STREAM_SOCKET 0x2
|
|
#define JANET_STREAM_UNREGISTERED 0x4
|
|
#define JANET_STREAM_READABLE 0x200
|
|
#define JANET_STREAM_WRITABLE 0x400
|
|
#define JANET_STREAM_ACCEPTABLE 0x800
|
|
#define JANET_STREAM_UDPSERVER 0x1000
|
|
#define JANET_STREAM_TOCLOSE 0x10000
|
|
|
|
typedef enum {
|
|
JANET_ASYNC_EVENT_INIT = 0,
|
|
JANET_ASYNC_EVENT_MARK = 1,
|
|
JANET_ASYNC_EVENT_DEINIT = 2,
|
|
JANET_ASYNC_EVENT_CLOSE = 3,
|
|
JANET_ASYNC_EVENT_ERR = 4,
|
|
JANET_ASYNC_EVENT_HUP = 5,
|
|
JANET_ASYNC_EVENT_READ = 6,
|
|
JANET_ASYNC_EVENT_WRITE = 7,
|
|
JANET_ASYNC_EVENT_COMPLETE = 8, /* Used on windows for IOCP */
|
|
JANET_ASYNC_EVENT_FAILED = 9 /* Used on windows for IOCP */
|
|
} JanetAsyncEvent;
|
|
|
|
typedef enum {
|
|
JANET_ASYNC_LISTEN_READ = 1,
|
|
JANET_ASYNC_LISTEN_WRITE,
|
|
JANET_ASYNC_LISTEN_BOTH
|
|
} JanetAsyncMode;
|
|
|
|
typedef struct JanetStream JanetStream;
|
|
|
|
/* Wrapper around file descriptors and HANDLEs that can be polled. */
|
|
struct JanetStream {
|
|
JanetHandle handle;
|
|
uint32_t flags;
|
|
uint32_t index;
|
|
JanetFiber *read_fiber;
|
|
JanetFiber *write_fiber;
|
|
const void *methods; /* Methods for this stream */
|
|
};
|
|
|
|
typedef void (*JanetEVCallback)(JanetFiber *fiber, JanetAsyncEvent event);
|
|
|
|
/* Start listening for events from a stream on the current root fiber. After
|
|
* calling this, users should call janet_await() before returning from the
|
|
* current C Function. This also will call janet_await.
|
|
* mode is which events to listen for, and callback is the function pointer to
|
|
* call when ever an event is sent from the event loop. state is an optional (can be NULL)
|
|
* pointer to data allocated with janet_malloc. This pointer will be passed to callback as
|
|
* fiber->ev_state. It will also be freed for you by the runtime when the event loop determines
|
|
* it can no longer be referenced. On windows, the contents of state MUST contained an OVERLAPPED struct at the 0 offset. */
|
|
|
|
JANET_API void janet_async_start_fiber(JanetFiber *fiber, JanetStream *stream, JanetAsyncMode mode, JanetEVCallback callback, void *state);
|
|
JANET_API JANET_NO_RETURN void janet_async_start(JanetStream *stream, JanetAsyncMode mode, JanetEVCallback callback, void *state);
|
|
|
|
/* Do not send any more events to the given callback. Call this after scheduling fiber to be resume
|
|
* or canceled. */
|
|
JANET_API void janet_async_end(JanetFiber *fiber);
|
|
|
|
/* Needed for windows to mark a fiber as waiting for an IOCP completion event. Noop on other platforms. */
|
|
JANET_API void janet_async_in_flight(JanetFiber *fiber);
|
|
|
|
/* On some platforms, it is important to be able to control if a stream is edge-trigger or level triggered.
|
|
* For example, a server that is accepting connections might want to be level triggered or edge-triggered
|
|
* depending on expected service. */
|
|
JANET_API void janet_stream_edge_triggered(JanetStream *stream);
|
|
JANET_API void janet_stream_level_triggered(JanetStream *stream);
|
|
|
|
#endif
|
|
|
|
/* Janet uses atomic integers in several places for synchronization between threads and
|
|
* signals. Define them here */
|
|
#ifdef JANET_WINDOWS
|
|
typedef long JanetAtomicInt;
|
|
#else
|
|
typedef int32_t JanetAtomicInt;
|
|
#endif
|
|
JANET_API JanetAtomicInt janet_atomic_inc(JanetAtomicInt volatile *x);
|
|
JANET_API JanetAtomicInt janet_atomic_dec(JanetAtomicInt volatile *x);
|
|
JANET_API JanetAtomicInt janet_atomic_load(JanetAtomicInt volatile *x);
|
|
|
|
/* We provide three possible implementations of Janets. The preferred
|
|
* nanboxing approach, for 32 or 64 bits, and the standard C version. Code in the rest of the
|
|
* application must interact through exposed interface. */
|
|
|
|
/* Required interface for Janet */
|
|
/* wrap and unwrap for all types */
|
|
/* Get type quickly */
|
|
/* Check against type quickly */
|
|
/* Small footprint */
|
|
/* 32 bit integer support */
|
|
|
|
/* janet_type(x)
|
|
* janet_checktype(x, t)
|
|
* janet_wrap_##TYPE(x)
|
|
* janet_unwrap_##TYPE(x)
|
|
* janet_truthy(x)
|
|
* janet_memclear(p, n) - clear memory for hash tables to nils
|
|
* janet_u64(x) - get 64 bits of payload for hashing
|
|
*/
|
|
|
|
/***** START SECTION NON-C API *****/
|
|
|
|
/* Some janet types use offset tricks to make operations easier in C. For
|
|
* external bindings, we should prefer using the Head structs directly, and
|
|
* use the host language to add sugar around the manipulation of the Janet types. */
|
|
|
|
JANET_API JanetStructHead *janet_struct_head(JanetStruct st);
|
|
JANET_API JanetAbstractHead *janet_abstract_head(const void *abstract);
|
|
JANET_API JanetStringHead *janet_string_head(JanetString s);
|
|
JANET_API JanetTupleHead *janet_tuple_head(JanetTuple tuple);
|
|
|
|
/* Some language bindings won't have access to the macro versions. */
|
|
|
|
JANET_API JanetType janet_type(Janet x);
|
|
JANET_API int janet_checktype(Janet x, JanetType type);
|
|
JANET_API int janet_checktypes(Janet x, int typeflags);
|
|
JANET_API int janet_truthy(Janet x);
|
|
|
|
JANET_API JanetStruct janet_unwrap_struct(Janet x);
|
|
JANET_API JanetTuple janet_unwrap_tuple(Janet x);
|
|
JANET_API JanetFiber *janet_unwrap_fiber(Janet x);
|
|
JANET_API JanetArray *janet_unwrap_array(Janet x);
|
|
JANET_API JanetTable *janet_unwrap_table(Janet x);
|
|
JANET_API JanetBuffer *janet_unwrap_buffer(Janet x);
|
|
JANET_API JanetString janet_unwrap_string(Janet x);
|
|
JANET_API JanetSymbol janet_unwrap_symbol(Janet x);
|
|
JANET_API JanetKeyword janet_unwrap_keyword(Janet x);
|
|
JANET_API JanetAbstract janet_unwrap_abstract(Janet x);
|
|
JANET_API void *janet_unwrap_pointer(Janet x);
|
|
JANET_API JanetFunction *janet_unwrap_function(Janet x);
|
|
JANET_API JanetCFunction janet_unwrap_cfunction(Janet x);
|
|
JANET_API int janet_unwrap_boolean(Janet x);
|
|
JANET_API double janet_unwrap_number(Janet x);
|
|
JANET_API int32_t janet_unwrap_integer(Janet x);
|
|
|
|
JANET_API Janet janet_wrap_nil(void);
|
|
JANET_API Janet janet_wrap_number(double x);
|
|
JANET_API Janet janet_wrap_true(void);
|
|
JANET_API Janet janet_wrap_false(void);
|
|
JANET_API Janet janet_wrap_boolean(int x);
|
|
JANET_API Janet janet_wrap_string(JanetString x);
|
|
JANET_API Janet janet_wrap_symbol(JanetSymbol x);
|
|
JANET_API Janet janet_wrap_keyword(JanetKeyword x);
|
|
JANET_API Janet janet_wrap_array(JanetArray *x);
|
|
JANET_API Janet janet_wrap_tuple(JanetTuple x);
|
|
JANET_API Janet janet_wrap_struct(JanetStruct x);
|
|
JANET_API Janet janet_wrap_fiber(JanetFiber *x);
|
|
JANET_API Janet janet_wrap_buffer(JanetBuffer *x);
|
|
JANET_API Janet janet_wrap_function(JanetFunction *x);
|
|
JANET_API Janet janet_wrap_cfunction(JanetCFunction x);
|
|
JANET_API Janet janet_wrap_table(JanetTable *x);
|
|
JANET_API Janet janet_wrap_abstract(JanetAbstract x);
|
|
JANET_API Janet janet_wrap_pointer(void *x);
|
|
JANET_API Janet janet_wrap_integer(int32_t x);
|
|
|
|
/***** END SECTION NON-C API *****/
|
|
|
|
#ifdef JANET_NANBOX_64
|
|
|
|
#include <math.h>
|
|
|
|
#define janet_u64(x) ((x).u64)
|
|
|
|
#define JANET_NANBOX_TAGBITS 0xFFFF800000000000llu
|
|
#define JANET_NANBOX_PAYLOADBITS 0x00007FFFFFFFFFFFllu
|
|
#define janet_nanbox_lowtag(type) ((uint64_t)(type) | 0x1FFF0)
|
|
#define janet_nanbox_tag(type) (janet_nanbox_lowtag(type) << 47)
|
|
#define janet_type(x) \
|
|
(isnan((x).number) \
|
|
? (JanetType) (((x).u64 >> 47) & 0xF) \
|
|
: JANET_NUMBER)
|
|
|
|
#define janet_nanbox_checkauxtype(x, type) \
|
|
(((x).u64 & JANET_NANBOX_TAGBITS) == janet_nanbox_tag((type)))
|
|
|
|
#define janet_nanbox_isnumber(x) \
|
|
(!isnan((x).number) || ((((x).u64 >> 47) & 0xF) == JANET_NUMBER))
|
|
|
|
#define janet_checktype(x, t) \
|
|
(((t) == JANET_NUMBER) \
|
|
? janet_nanbox_isnumber(x) \
|
|
: janet_nanbox_checkauxtype((x), (t)))
|
|
|
|
/* Use JANET_API so that modules will use a local version of these functions if possible */
|
|
JANET_API void *janet_nanbox_to_pointer(Janet x);
|
|
JANET_API Janet janet_nanbox_from_pointer(void *p, uint64_t tagmask);
|
|
JANET_API Janet janet_nanbox_from_cpointer(const void *p, uint64_t tagmask);
|
|
JANET_API Janet janet_nanbox_from_double(double d);
|
|
JANET_API Janet janet_nanbox_from_bits(uint64_t bits);
|
|
|
|
#define janet_truthy(x) \
|
|
(!janet_checktype((x), JANET_NIL) && \
|
|
(!janet_checktype((x), JANET_BOOLEAN) || ((x).u64 & 0x1)))
|
|
|
|
#define janet_nanbox_from_payload(t, p) \
|
|
janet_nanbox_from_bits(janet_nanbox_tag(t) | (p))
|
|
|
|
#define janet_nanbox_wrap_(p, t) \
|
|
janet_nanbox_from_pointer((p), janet_nanbox_tag(t))
|
|
|
|
#define janet_nanbox_wrap_c(p, t) \
|
|
janet_nanbox_from_cpointer((p), janet_nanbox_tag(t))
|
|
|
|
/* Wrap the simple types */
|
|
#define janet_wrap_nil() janet_nanbox_from_payload(JANET_NIL, 1)
|
|
#define janet_wrap_true() janet_nanbox_from_payload(JANET_BOOLEAN, 1)
|
|
#define janet_wrap_false() janet_nanbox_from_payload(JANET_BOOLEAN, 0)
|
|
#define janet_wrap_boolean(b) janet_nanbox_from_payload(JANET_BOOLEAN, !!(b))
|
|
#define janet_wrap_number(r) janet_nanbox_from_double(r)
|
|
|
|
/* Unwrap the simple types */
|
|
#define janet_unwrap_boolean(x) ((x).u64 & 0x1)
|
|
#define janet_unwrap_number(x) ((x).number)
|
|
|
|
/* Wrap the pointer types */
|
|
#define janet_wrap_struct(s) janet_nanbox_wrap_c((s), JANET_STRUCT)
|
|
#define janet_wrap_tuple(s) janet_nanbox_wrap_c((s), JANET_TUPLE)
|
|
#define janet_wrap_fiber(s) janet_nanbox_wrap_((s), JANET_FIBER)
|
|
#define janet_wrap_array(s) janet_nanbox_wrap_((s), JANET_ARRAY)
|
|
#define janet_wrap_table(s) janet_nanbox_wrap_((s), JANET_TABLE)
|
|
#define janet_wrap_buffer(s) janet_nanbox_wrap_((s), JANET_BUFFER)
|
|
#define janet_wrap_string(s) janet_nanbox_wrap_c((s), JANET_STRING)
|
|
#define janet_wrap_symbol(s) janet_nanbox_wrap_c((s), JANET_SYMBOL)
|
|
#define janet_wrap_keyword(s) janet_nanbox_wrap_c((s), JANET_KEYWORD)
|
|
#define janet_wrap_abstract(s) janet_nanbox_wrap_((s), JANET_ABSTRACT)
|
|
#define janet_wrap_function(s) janet_nanbox_wrap_((s), JANET_FUNCTION)
|
|
#define janet_wrap_cfunction(s) janet_nanbox_wrap_((s), JANET_CFUNCTION)
|
|
#define janet_wrap_pointer(s) janet_nanbox_wrap_((s), JANET_POINTER)
|
|
|
|
/* Unwrap the pointer types */
|
|
#define janet_unwrap_struct(x) ((JanetStruct)janet_nanbox_to_pointer(x))
|
|
#define janet_unwrap_tuple(x) ((JanetTuple)janet_nanbox_to_pointer(x))
|
|
#define janet_unwrap_fiber(x) ((JanetFiber *)janet_nanbox_to_pointer(x))
|
|
#define janet_unwrap_array(x) ((JanetArray *)janet_nanbox_to_pointer(x))
|
|
#define janet_unwrap_table(x) ((JanetTable *)janet_nanbox_to_pointer(x))
|
|
#define janet_unwrap_buffer(x) ((JanetBuffer *)janet_nanbox_to_pointer(x))
|
|
#define janet_unwrap_string(x) ((JanetString)janet_nanbox_to_pointer(x))
|
|
#define janet_unwrap_symbol(x) ((JanetSymbol)janet_nanbox_to_pointer(x))
|
|
#define janet_unwrap_keyword(x) ((const uint8_t *)janet_nanbox_to_pointer(x))
|
|
#define janet_unwrap_abstract(x) (janet_nanbox_to_pointer(x))
|
|
#define janet_unwrap_pointer(x) (janet_nanbox_to_pointer(x))
|
|
#define janet_unwrap_function(x) ((JanetFunction *)janet_nanbox_to_pointer(x))
|
|
#define janet_unwrap_cfunction(x) ((JanetCFunction)janet_nanbox_to_pointer(x))
|
|
|
|
#elif defined(JANET_NANBOX_32)
|
|
|
|
#define JANET_DOUBLE_OFFSET 0xFFFF
|
|
|
|
#define janet_u64(x) ((x).u64)
|
|
#define janet_type(x) (((x).tagged.type < JANET_DOUBLE_OFFSET) ? (JanetType)((x).tagged.type) : JANET_NUMBER)
|
|
#define janet_checktype(x, t) ((t) == JANET_NUMBER \
|
|
? (x).tagged.type >= JANET_DOUBLE_OFFSET \
|
|
: (x).tagged.type == (t))
|
|
#define janet_truthy(x) \
|
|
((x).tagged.type != JANET_NIL && ((x).tagged.type != JANET_BOOLEAN || ((x).tagged.payload.integer & 0x1)))
|
|
|
|
JANET_API Janet janet_nanbox32_from_tagi(uint32_t tag, int32_t integer);
|
|
JANET_API Janet janet_nanbox32_from_tagp(uint32_t tag, void *pointer);
|
|
|
|
#define janet_wrap_nil() janet_nanbox32_from_tagi(JANET_NIL, 0)
|
|
#define janet_wrap_true() janet_nanbox32_from_tagi(JANET_BOOLEAN, 1)
|
|
#define janet_wrap_false() janet_nanbox32_from_tagi(JANET_BOOLEAN, 0)
|
|
#define janet_wrap_boolean(b) janet_nanbox32_from_tagi(JANET_BOOLEAN, !!(b))
|
|
|
|
/* Wrap the pointer types */
|
|
#define janet_wrap_struct(s) janet_nanbox32_from_tagp(JANET_STRUCT, (void *)(s))
|
|
#define janet_wrap_tuple(s) janet_nanbox32_from_tagp(JANET_TUPLE, (void *)(s))
|
|
#define janet_wrap_fiber(s) janet_nanbox32_from_tagp(JANET_FIBER, (void *)(s))
|
|
#define janet_wrap_array(s) janet_nanbox32_from_tagp(JANET_ARRAY, (void *)(s))
|
|
#define janet_wrap_table(s) janet_nanbox32_from_tagp(JANET_TABLE, (void *)(s))
|
|
#define janet_wrap_buffer(s) janet_nanbox32_from_tagp(JANET_BUFFER, (void *)(s))
|
|
#define janet_wrap_string(s) janet_nanbox32_from_tagp(JANET_STRING, (void *)(s))
|
|
#define janet_wrap_symbol(s) janet_nanbox32_from_tagp(JANET_SYMBOL, (void *)(s))
|
|
#define janet_wrap_keyword(s) janet_nanbox32_from_tagp(JANET_KEYWORD, (void *)(s))
|
|
#define janet_wrap_abstract(s) janet_nanbox32_from_tagp(JANET_ABSTRACT, (void *)(s))
|
|
#define janet_wrap_function(s) janet_nanbox32_from_tagp(JANET_FUNCTION, (void *)(s))
|
|
#define janet_wrap_cfunction(s) janet_nanbox32_from_tagp(JANET_CFUNCTION, (void *)(s))
|
|
#define janet_wrap_pointer(s) janet_nanbox32_from_tagp(JANET_POINTER, (void *)(s))
|
|
|
|
#define janet_unwrap_struct(x) ((JanetStruct)(x).tagged.payload.pointer)
|
|
#define janet_unwrap_tuple(x) ((JanetTuple)(x).tagged.payload.pointer)
|
|
#define janet_unwrap_fiber(x) ((JanetFiber *)(x).tagged.payload.pointer)
|
|
#define janet_unwrap_array(x) ((JanetArray *)(x).tagged.payload.pointer)
|
|
#define janet_unwrap_table(x) ((JanetTable *)(x).tagged.payload.pointer)
|
|
#define janet_unwrap_buffer(x) ((JanetBuffer *)(x).tagged.payload.pointer)
|
|
#define janet_unwrap_string(x) ((JanetString)(x).tagged.payload.pointer)
|
|
#define janet_unwrap_symbol(x) ((JanetSymbol)(x).tagged.payload.pointer)
|
|
#define janet_unwrap_keyword(x) ((JanetKeyword)(x).tagged.payload.pointer)
|
|
#define janet_unwrap_abstract(x) ((x).tagged.payload.pointer)
|
|
#define janet_unwrap_pointer(x) ((x).tagged.payload.pointer)
|
|
#define janet_unwrap_function(x) ((JanetFunction *)(x).tagged.payload.pointer)
|
|
#define janet_unwrap_cfunction(x) ((JanetCFunction)(x).tagged.payload.pointer)
|
|
#define janet_unwrap_boolean(x) ((x).tagged.payload.integer)
|
|
|
|
#else
|
|
|
|
#define janet_u64(x) ((x).as.u64)
|
|
#define janet_type(x) ((x).type)
|
|
#define janet_checktype(x, t) ((x).type == (t))
|
|
#define janet_truthy(x) \
|
|
((x).type != JANET_NIL && ((x).type != JANET_BOOLEAN || ((x).as.u64 & 0x1)))
|
|
|
|
#define janet_unwrap_struct(x) ((JanetStruct)(x).as.pointer)
|
|
#define janet_unwrap_tuple(x) ((JanetTuple)(x).as.pointer)
|
|
#define janet_unwrap_fiber(x) ((JanetFiber *)(x).as.pointer)
|
|
#define janet_unwrap_array(x) ((JanetArray *)(x).as.pointer)
|
|
#define janet_unwrap_table(x) ((JanetTable *)(x).as.pointer)
|
|
#define janet_unwrap_buffer(x) ((JanetBuffer *)(x).as.pointer)
|
|
#define janet_unwrap_string(x) ((JanetString)(x).as.pointer)
|
|
#define janet_unwrap_symbol(x) ((JanetSymbol)(x).as.pointer)
|
|
#define janet_unwrap_keyword(x) ((JanetKeyword)(x).as.pointer)
|
|
#define janet_unwrap_abstract(x) ((x).as.pointer)
|
|
#define janet_unwrap_pointer(x) ((x).as.pointer)
|
|
#define janet_unwrap_function(x) ((JanetFunction *)(x).as.pointer)
|
|
#define janet_unwrap_cfunction(x) ((JanetCFunction)(x).as.pointer)
|
|
#define janet_unwrap_boolean(x) ((x).as.u64 & 0x1)
|
|
#define janet_unwrap_number(x) ((x).as.number)
|
|
|
|
/* End of tagged union implementation */
|
|
#endif
|
|
|
|
JANET_API int janet_checkint16(Janet x);
|
|
JANET_API int janet_checkuint16(Janet x);
|
|
JANET_API int janet_checkint(Janet x);
|
|
JANET_API int janet_checkuint(Janet x);
|
|
JANET_API int janet_checkint64(Janet x);
|
|
JANET_API int janet_checkuint64(Janet x);
|
|
JANET_API int janet_checksize(Janet x);
|
|
JANET_API JanetAbstract janet_checkabstract(Janet x, const JanetAbstractType *at);
|
|
#define janet_checkint16range(x) ((x) >= INT16_MIN && (x) <= INT16_MAX && (x) == (int16_t)(x))
|
|
#define janet_checkuint16range(x) ((x) >= 0 && (x) <= UINT16_MAX && (x) == (uint16_t)(x))
|
|
#define janet_checkintrange(x) ((x) >= INT32_MIN && (x) <= INT32_MAX && (x) == (int32_t)(x))
|
|
#define janet_checkuintrange(x) ((x) >= 0 && (x) <= UINT32_MAX && (x) == (uint32_t)(x))
|
|
#define janet_checkint64range(x) ((x) >= JANET_INTMIN_DOUBLE && (x) <= JANET_INTMAX_DOUBLE && (x) == (int64_t)(x))
|
|
#define janet_checkuint64range(x) ((x) >= 0 && (x) <= JANET_INTMAX_DOUBLE && (x) == (uint64_t)(x))
|
|
#define janet_unwrap_integer(x) ((int32_t) janet_unwrap_number(x))
|
|
#define janet_wrap_integer(x) janet_wrap_number((int32_t)(x))
|
|
|
|
#define janet_checktypes(x, tps) ((1 << janet_type(x)) & (tps))
|
|
|
|
/* GC Object type pun. The lower 16 bits of flags are reserved for the garbage collector,
|
|
* but the upper 16 can be used per type for custom flags. The current collector is a linked
|
|
* list of blocks, which is naive but works. */
|
|
struct JanetGCObject {
|
|
int32_t flags;
|
|
union {
|
|
JanetGCObject *next;
|
|
volatile JanetAtomicInt refcount; /* For threaded abstract types */
|
|
} data;
|
|
};
|
|
|
|
/* A lightweight green thread in janet. Does not correspond to
|
|
* operating system threads. */
|
|
struct JanetFiber {
|
|
JanetGCObject gc; /* GC Object stuff */
|
|
int32_t flags; /* More flags */
|
|
int32_t frame; /* Index of the stack frame */
|
|
int32_t stackstart; /* Beginning of next args */
|
|
int32_t stacktop; /* Top of stack. Where values are pushed and popped from. */
|
|
int32_t capacity; /* How big is the stack memory */
|
|
int32_t maxstack; /* Arbitrary defined limit for stack overflow */
|
|
JanetTable *env; /* Dynamic bindings table (usually current environment). */
|
|
Janet *data; /* Dynamically resized stack memory */
|
|
JanetFiber *child; /* Keep linked list of fibers for restarting pending fibers */
|
|
Janet last_value; /* Last returned value from a fiber */
|
|
#ifdef JANET_EV
|
|
/* These fields are only relevant for fibers that are used as "root fibers" -
|
|
* that is, fibers that are scheduled on the event loop and behave much like threads
|
|
* in a multi-tasking system. It would be possible to move these fields to a new
|
|
* type, say "JanetTask", that as separate from fibers to save a bit of space. */
|
|
uint32_t sched_id; /* Increment everytime fiber is scheduled by event loop */
|
|
JanetEVCallback ev_callback; /* Call this before starting scheduled fibers */
|
|
JanetStream *ev_stream; /* which stream we are waiting on */
|
|
void *ev_state; /* Extra data for ev callback state. On windows, first element must be OVERLAPPED. */
|
|
void *supervisor_channel; /* Channel to push self to when complete */
|
|
#endif
|
|
};
|
|
|
|
/* Mark if a stack frame is a tail call for debugging */
|
|
#define JANET_STACKFRAME_TAILCALL 1
|
|
|
|
/* Mark if a stack frame is an entrance frame */
|
|
#define JANET_STACKFRAME_ENTRANCE 2
|
|
|
|
/* A stack frame on the fiber. Is stored along with the stack values. */
|
|
struct JanetStackFrame {
|
|
JanetFunction *func;
|
|
uint32_t *pc;
|
|
JanetFuncEnv *env;
|
|
int32_t prevframe;
|
|
int32_t flags;
|
|
};
|
|
|
|
/* Number of Janets a frame takes up in the stack
|
|
* Should be constant across architectures */
|
|
#define JANET_FRAME_SIZE 4
|
|
|
|
/* A dynamic array type. */
|
|
struct JanetArray {
|
|
JanetGCObject gc;
|
|
int32_t count;
|
|
int32_t capacity;
|
|
Janet *data;
|
|
};
|
|
|
|
/* A byte buffer type. Used as a mutable string or string builder. */
|
|
struct JanetBuffer {
|
|
JanetGCObject gc;
|
|
int32_t count;
|
|
int32_t capacity;
|
|
uint8_t *data;
|
|
};
|
|
|
|
/* A mutable associative data type. Backed by a hashtable. */
|
|
struct JanetTable {
|
|
JanetGCObject gc;
|
|
int32_t count;
|
|
int32_t capacity;
|
|
int32_t deleted;
|
|
JanetKV *data;
|
|
JanetTable *proto;
|
|
};
|
|
|
|
/* A key value pair in a struct or table */
|
|
struct JanetKV {
|
|
Janet key;
|
|
Janet value;
|
|
};
|
|
|
|
/* Prefix for a tuple */
|
|
struct JanetTupleHead {
|
|
JanetGCObject gc;
|
|
int32_t length;
|
|
int32_t hash;
|
|
int32_t sm_line;
|
|
int32_t sm_column;
|
|
const Janet data[];
|
|
};
|
|
|
|
/* Prefix for a struct */
|
|
struct JanetStructHead {
|
|
JanetGCObject gc;
|
|
int32_t length;
|
|
int32_t hash;
|
|
int32_t capacity;
|
|
const JanetKV *proto;
|
|
const JanetKV data[];
|
|
};
|
|
|
|
/* Prefix for a string */
|
|
struct JanetStringHead {
|
|
JanetGCObject gc;
|
|
int32_t length;
|
|
int32_t hash;
|
|
const uint8_t data[];
|
|
};
|
|
|
|
/* Prefix for an abstract value */
|
|
struct JanetAbstractHead {
|
|
JanetGCObject gc;
|
|
const JanetAbstractType *type;
|
|
size_t size;
|
|
long long data[]; /* Use long long to ensure most general alignment */
|
|
};
|
|
|
|
/* Some function definition flags */
|
|
#define JANET_FUNCDEF_FLAG_VARARG 0x10000
|
|
#define JANET_FUNCDEF_FLAG_NEEDSENV 0x20000
|
|
#define JANET_FUNCDEF_FLAG_HASSYMBOLMAP 0x40000
|
|
#define JANET_FUNCDEF_FLAG_HASNAME 0x80000
|
|
#define JANET_FUNCDEF_FLAG_HASSOURCE 0x100000
|
|
#define JANET_FUNCDEF_FLAG_HASDEFS 0x200000
|
|
#define JANET_FUNCDEF_FLAG_HASENVS 0x400000
|
|
#define JANET_FUNCDEF_FLAG_HASSOURCEMAP 0x800000
|
|
#define JANET_FUNCDEF_FLAG_STRUCTARG 0x1000000
|
|
#define JANET_FUNCDEF_FLAG_HASCLOBITSET 0x2000000
|
|
#define JANET_FUNCDEF_FLAG_TAG 0xFFFF
|
|
|
|
/* Source mapping structure for a bytecode instruction */
|
|
struct JanetSourceMapping {
|
|
int32_t line;
|
|
int32_t column;
|
|
};
|
|
|
|
/* Symbol to slot mapping & lifetime structure. */
|
|
struct JanetSymbolMap {
|
|
uint32_t birth_pc;
|
|
uint32_t death_pc;
|
|
uint32_t slot_index;
|
|
const uint8_t *symbol;
|
|
};
|
|
|
|
/* A function definition. Contains information needed to instantiate closures. */
|
|
struct JanetFuncDef {
|
|
JanetGCObject gc;
|
|
int32_t *environments; /* Which environments to capture from parent. */
|
|
Janet *constants;
|
|
JanetFuncDef **defs;
|
|
uint32_t *bytecode;
|
|
uint32_t *closure_bitset; /* Bit set indicating which slots can be referenced by closures. */
|
|
|
|
/* Various debug information */
|
|
JanetSourceMapping *sourcemap;
|
|
JanetString source;
|
|
JanetString name;
|
|
JanetSymbolMap *symbolmap;
|
|
|
|
int32_t flags;
|
|
int32_t slotcount; /* The amount of stack space required for the function */
|
|
int32_t arity; /* Not including varargs */
|
|
int32_t min_arity; /* Including varargs */
|
|
int32_t max_arity; /* Including varargs */
|
|
int32_t constants_length;
|
|
int32_t bytecode_length;
|
|
int32_t environments_length;
|
|
int32_t defs_length;
|
|
int32_t symbolmap_length;
|
|
};
|
|
|
|
/* A function environment */
|
|
struct JanetFuncEnv {
|
|
JanetGCObject gc;
|
|
union {
|
|
JanetFiber *fiber;
|
|
Janet *values;
|
|
} as;
|
|
int32_t length; /* Size of environment */
|
|
int32_t offset; /* Stack offset when values still on stack. If offset is <= 0, then
|
|
environment is no longer on the stack. */
|
|
};
|
|
|
|
#define JANET_FUNCFLAG_TRACE (1 << 16)
|
|
|
|
/* A function */
|
|
struct JanetFunction {
|
|
JanetGCObject gc;
|
|
JanetFuncDef *def;
|
|
JanetFuncEnv *envs[];
|
|
};
|
|
|
|
typedef struct JanetParseState JanetParseState;
|
|
typedef struct JanetParser JanetParser;
|
|
|
|
enum JanetParserStatus {
|
|
JANET_PARSE_ROOT,
|
|
JANET_PARSE_ERROR,
|
|
JANET_PARSE_PENDING,
|
|
JANET_PARSE_DEAD
|
|
};
|
|
|
|
/* A janet parser */
|
|
struct JanetParser {
|
|
Janet *args;
|
|
const char *error;
|
|
JanetParseState *states;
|
|
uint8_t *buf;
|
|
size_t argcount;
|
|
size_t argcap;
|
|
size_t statecount;
|
|
size_t statecap;
|
|
size_t bufcount;
|
|
size_t bufcap;
|
|
size_t line;
|
|
size_t column;
|
|
size_t pending;
|
|
int lookback;
|
|
int flag;
|
|
};
|
|
|
|
/* A context for marshaling and unmarshaling abstract types */
|
|
typedef struct {
|
|
void *m_state;
|
|
void *u_state;
|
|
int flags;
|
|
const uint8_t *data;
|
|
const JanetAbstractType *at;
|
|
} JanetMarshalContext;
|
|
|
|
/* Defines an abstract type */
|
|
struct JanetAbstractType {
|
|
const char *name;
|
|
int (*gc)(void *data, size_t len);
|
|
int (*gcmark)(void *data, size_t len);
|
|
int (*get)(void *data, Janet key, Janet *out);
|
|
void (*put)(void *data, Janet key, Janet value);
|
|
void (*marshal)(void *p, JanetMarshalContext *ctx);
|
|
void *(*unmarshal)(JanetMarshalContext *ctx);
|
|
void (*tostring)(void *p, JanetBuffer *buffer);
|
|
int (*compare)(void *lhs, void *rhs);
|
|
int32_t (*hash)(void *p, size_t len);
|
|
Janet(*next)(void *p, Janet key);
|
|
Janet(*call)(void *p, int32_t argc, Janet *argv);
|
|
size_t (*length)(void *p, size_t len);
|
|
JanetByteView(*bytes)(void *p, size_t len);
|
|
};
|
|
|
|
/* Some macros to let us add extra types to JanetAbstract types without
|
|
* needing to changing native modules that declare them as static const
|
|
* structures. If more fields are added, these macros are modified to include
|
|
* default values (usually NULL). This silences missing field warnings. */
|
|
#define JANET_ATEND_NAME NULL,JANET_ATEND_GC
|
|
#define JANET_ATEND_GC NULL,JANET_ATEND_GCMARK
|
|
#define JANET_ATEND_GCMARK NULL,JANET_ATEND_GET
|
|
#define JANET_ATEND_GET NULL,JANET_ATEND_PUT
|
|
#define JANET_ATEND_PUT NULL,JANET_ATEND_MARSHAL
|
|
#define JANET_ATEND_MARSHAL NULL,JANET_ATEND_UNMARSHAL
|
|
#define JANET_ATEND_UNMARSHAL NULL,JANET_ATEND_TOSTRING
|
|
#define JANET_ATEND_TOSTRING NULL,JANET_ATEND_COMPARE
|
|
#define JANET_ATEND_COMPARE NULL,JANET_ATEND_HASH
|
|
#define JANET_ATEND_HASH NULL,JANET_ATEND_NEXT
|
|
#define JANET_ATEND_NEXT NULL,JANET_ATEND_CALL
|
|
#define JANET_ATEND_CALL NULL,JANET_ATEND_LENGTH
|
|
#define JANET_ATEND_LENGTH NULL,JANET_ATEND_BYTES
|
|
#define JANET_ATEND_BYTES
|
|
|
|
struct JanetReg {
|
|
const char *name;
|
|
JanetCFunction cfun;
|
|
const char *documentation;
|
|
};
|
|
|
|
struct JanetRegExt {
|
|
const char *name;
|
|
JanetCFunction cfun;
|
|
const char *documentation;
|
|
const char *source_file;
|
|
int32_t source_line;
|
|
};
|
|
|
|
struct JanetMethod {
|
|
const char *name;
|
|
JanetCFunction cfun;
|
|
};
|
|
|
|
struct JanetView {
|
|
const Janet *items;
|
|
int32_t len;
|
|
};
|
|
|
|
struct JanetByteView {
|
|
const uint8_t *bytes;
|
|
int32_t len;
|
|
};
|
|
|
|
struct JanetDictView {
|
|
const JanetKV *kvs;
|
|
int32_t len;
|
|
int32_t cap;
|
|
};
|
|
|
|
struct JanetRange {
|
|
int32_t start;
|
|
int32_t end;
|
|
};
|
|
|
|
struct JanetRNG {
|
|
uint32_t a, b, c, d;
|
|
uint32_t counter;
|
|
};
|
|
|
|
typedef struct JanetFile JanetFile;
|
|
struct JanetFile {
|
|
FILE *file;
|
|
int32_t flags;
|
|
};
|
|
|
|
/* For janet_try and janet_restore */
|
|
typedef struct {
|
|
/* old state */
|
|
int32_t stackn;
|
|
int gc_handle;
|
|
JanetFiber *vm_fiber;
|
|
jmp_buf *vm_jmp_buf;
|
|
Janet *vm_return_reg;
|
|
/* new state */
|
|
jmp_buf buf;
|
|
Janet payload;
|
|
} JanetTryState;
|
|
|
|
/***** END SECTION TYPES *****/
|
|
|
|
/***** START SECTION OPCODES *****/
|
|
|
|
/* Bytecode op argument types */
|
|
enum JanetOpArgType {
|
|
JANET_OAT_SLOT,
|
|
JANET_OAT_ENVIRONMENT,
|
|
JANET_OAT_CONSTANT,
|
|
JANET_OAT_INTEGER,
|
|
JANET_OAT_TYPE,
|
|
JANET_OAT_SIMPLETYPE,
|
|
JANET_OAT_LABEL,
|
|
JANET_OAT_FUNCDEF
|
|
};
|
|
|
|
/* Various types of instructions */
|
|
enum JanetInstructionType {
|
|
JINT_0, /* No args */
|
|
JINT_S, /* Slot(3) */
|
|
JINT_L, /* Label(3) */
|
|
JINT_SS, /* Slot(1), Slot(2) */
|
|
JINT_SL, /* Slot(1), Label(2) */
|
|
JINT_ST, /* Slot(1), Slot(2) */
|
|
JINT_SI, /* Slot(1), Immediate(2) */
|
|
JINT_SD, /* Slot(1), Closure(2) */
|
|
JINT_SU, /* Slot(1), Unsigned Immediate(2) */
|
|
JINT_SSS, /* Slot(1), Slot(1), Slot(1) */
|
|
JINT_SSI, /* Slot(1), Slot(1), Immediate(1) */
|
|
JINT_SSU, /* Slot(1), Slot(1), Unsigned Immediate(1) */
|
|
JINT_SES, /* Slot(1), Environment(1), Far Slot(1) */
|
|
JINT_SC /* Slot(1), Constant(2) */
|
|
};
|
|
|
|
/* All opcodes for the bytecode interpreter. */
|
|
enum JanetOpCode {
|
|
JOP_NOOP,
|
|
JOP_ERROR,
|
|
JOP_TYPECHECK,
|
|
JOP_RETURN,
|
|
JOP_RETURN_NIL,
|
|
JOP_ADD_IMMEDIATE,
|
|
JOP_ADD,
|
|
JOP_SUBTRACT_IMMEDIATE,
|
|
JOP_SUBTRACT,
|
|
JOP_MULTIPLY_IMMEDIATE,
|
|
JOP_MULTIPLY,
|
|
JOP_DIVIDE_IMMEDIATE,
|
|
JOP_DIVIDE,
|
|
JOP_DIVIDE_FLOOR,
|
|
JOP_MODULO,
|
|
JOP_REMAINDER,
|
|
JOP_BAND,
|
|
JOP_BOR,
|
|
JOP_BXOR,
|
|
JOP_BNOT,
|
|
JOP_SHIFT_LEFT,
|
|
JOP_SHIFT_LEFT_IMMEDIATE,
|
|
JOP_SHIFT_RIGHT,
|
|
JOP_SHIFT_RIGHT_IMMEDIATE,
|
|
JOP_SHIFT_RIGHT_UNSIGNED,
|
|
JOP_SHIFT_RIGHT_UNSIGNED_IMMEDIATE,
|
|
JOP_MOVE_FAR,
|
|
JOP_MOVE_NEAR,
|
|
JOP_JUMP,
|
|
JOP_JUMP_IF,
|
|
JOP_JUMP_IF_NOT,
|
|
JOP_JUMP_IF_NIL,
|
|
JOP_JUMP_IF_NOT_NIL,
|
|
JOP_GREATER_THAN,
|
|
JOP_GREATER_THAN_IMMEDIATE,
|
|
JOP_LESS_THAN,
|
|
JOP_LESS_THAN_IMMEDIATE,
|
|
JOP_EQUALS,
|
|
JOP_EQUALS_IMMEDIATE,
|
|
JOP_COMPARE,
|
|
JOP_LOAD_NIL,
|
|
JOP_LOAD_TRUE,
|
|
JOP_LOAD_FALSE,
|
|
JOP_LOAD_INTEGER,
|
|
JOP_LOAD_CONSTANT,
|
|
JOP_LOAD_UPVALUE,
|
|
JOP_LOAD_SELF,
|
|
JOP_SET_UPVALUE,
|
|
JOP_CLOSURE,
|
|
JOP_PUSH,
|
|
JOP_PUSH_2,
|
|
JOP_PUSH_3,
|
|
JOP_PUSH_ARRAY,
|
|
JOP_CALL,
|
|
JOP_TAILCALL,
|
|
JOP_RESUME,
|
|
JOP_SIGNAL,
|
|
JOP_PROPAGATE,
|
|
JOP_IN,
|
|
JOP_GET,
|
|
JOP_PUT,
|
|
JOP_GET_INDEX,
|
|
JOP_PUT_INDEX,
|
|
JOP_LENGTH,
|
|
JOP_MAKE_ARRAY,
|
|
JOP_MAKE_BUFFER,
|
|
JOP_MAKE_STRING,
|
|
JOP_MAKE_STRUCT,
|
|
JOP_MAKE_TABLE,
|
|
JOP_MAKE_TUPLE,
|
|
JOP_MAKE_BRACKET_TUPLE,
|
|
JOP_GREATER_THAN_EQUAL,
|
|
JOP_LESS_THAN_EQUAL,
|
|
JOP_NEXT,
|
|
JOP_NOT_EQUALS,
|
|
JOP_NOT_EQUALS_IMMEDIATE,
|
|
JOP_CANCEL,
|
|
JOP_INSTRUCTION_COUNT
|
|
};
|
|
|
|
/* Info about all instructions */
|
|
extern enum JanetInstructionType janet_instructions[JOP_INSTRUCTION_COUNT];
|
|
|
|
/***** END SECTION OPCODES *****/
|
|
|
|
/***** START SECTION MAIN *****/
|
|
|
|
#ifdef JANET_EV
|
|
|
|
extern JANET_API const JanetAbstractType janet_stream_type;
|
|
extern JANET_API const JanetAbstractType janet_channel_type;
|
|
|
|
/* Run the event loop */
|
|
JANET_API void janet_loop(void);
|
|
|
|
/* Run the event loop, but allow for user scheduled interrupts triggered
|
|
* by janet_loop1_interrupt being called in library code, a signal handler, or
|
|
* another thread.
|
|
*
|
|
* Example:
|
|
*
|
|
* while (!janet_loop_done()) {
|
|
* // One turn of the event loop
|
|
* JanetFiber *interrupted_fiber = janet_loop1();
|
|
* // interrupted_fiber may be NULL
|
|
* // do some work here periodically...
|
|
* if (NULL != interrupted_fiber) {
|
|
* if (cancel_interrupted_fiber) {
|
|
* janet_cancel(interrupted_fiber, janet_cstringv("fiber was interrupted for [reason]"));
|
|
* } else {
|
|
* janet_schedule(interrupted_fiber, janet_wrap_nil());
|
|
* }
|
|
* }
|
|
* }
|
|
*
|
|
*/
|
|
JANET_API int janet_loop_done(void);
|
|
JANET_API JanetFiber *janet_loop1(void);
|
|
JANET_API void janet_loop1_interrupt(JanetVM *vm);
|
|
|
|
/* Wrapper around streams */
|
|
JANET_API JanetStream *janet_stream(JanetHandle handle, uint32_t flags, const JanetMethod *methods);
|
|
JANET_API JanetStream *janet_stream_ext(JanetHandle handle, uint32_t flags, const JanetMethod *methods, size_t size); /* Allow for type punning streams */
|
|
JANET_API void janet_stream_close(JanetStream *stream);
|
|
JANET_API Janet janet_cfun_stream_close(int32_t argc, Janet *argv);
|
|
JANET_API Janet janet_cfun_stream_read(int32_t argc, Janet *argv);
|
|
JANET_API Janet janet_cfun_stream_chunk(int32_t argc, Janet *argv);
|
|
JANET_API Janet janet_cfun_stream_write(int32_t argc, Janet *argv);
|
|
JANET_API void janet_stream_flags(JanetStream *stream, uint32_t flags);
|
|
|
|
/* Queue a fiber to run on the event loop */
|
|
JANET_API void janet_schedule(JanetFiber *fiber, Janet value);
|
|
JANET_API void janet_cancel(JanetFiber *fiber, Janet value);
|
|
JANET_API void janet_schedule_signal(JanetFiber *fiber, Janet value, JanetSignal sig);
|
|
JANET_API void janet_schedule_soon(JanetFiber *fiber, Janet value, JanetSignal sig);
|
|
|
|
/* Shorthand for yielding to event loop in C */
|
|
JANET_NO_RETURN JANET_API void janet_await(void);
|
|
JANET_NO_RETURN JANET_API void janet_sleep_await(double sec);
|
|
|
|
/* For use inside listeners - adds a timeout to the current fiber, such that
|
|
* it will be resumed after sec seconds if no other event schedules the current fiber. */
|
|
JANET_API void janet_addtimeout(double sec);
|
|
JANET_API void janet_ev_inc_refcount(void);
|
|
JANET_API void janet_ev_dec_refcount(void);
|
|
|
|
/* Thread aware abstract types and helpers */
|
|
JANET_API void *janet_abstract_begin_threaded(const JanetAbstractType *atype, size_t size);
|
|
JANET_API void *janet_abstract_end_threaded(void *x);
|
|
JANET_API void *janet_abstract_threaded(const JanetAbstractType *atype, size_t size);
|
|
JANET_API int32_t janet_abstract_incref(void *abst);
|
|
JANET_API int32_t janet_abstract_decref(void *abst);
|
|
|
|
/* Expose channel utilities */
|
|
JanetChannel *janet_channel_make(uint32_t limit);
|
|
JanetChannel *janet_channel_make_threaded(uint32_t limit);
|
|
JanetChannel *janet_getchannel(const Janet *argv, int32_t n);
|
|
JanetChannel *janet_optchannel(const Janet *argv, int32_t argc, int32_t n, JanetChannel *dflt);
|
|
JANET_API int janet_channel_give(JanetChannel *channel, Janet x);
|
|
JANET_API int janet_channel_take(JanetChannel *channel, Janet *out);
|
|
|
|
/* Expose some OS sync primitives */
|
|
JANET_API size_t janet_os_mutex_size(void);
|
|
JANET_API size_t janet_os_rwlock_size(void);
|
|
JANET_API void janet_os_mutex_init(JanetOSMutex *mutex);
|
|
JANET_API void janet_os_mutex_deinit(JanetOSMutex *mutex);
|
|
JANET_API void janet_os_mutex_lock(JanetOSMutex *mutex);
|
|
JANET_API void janet_os_mutex_unlock(JanetOSMutex *mutex);
|
|
JANET_API void janet_os_rwlock_init(JanetOSRWLock *rwlock);
|
|
JANET_API void janet_os_rwlock_deinit(JanetOSRWLock *rwlock);
|
|
JANET_API void janet_os_rwlock_rlock(JanetOSRWLock *rwlock);
|
|
JANET_API void janet_os_rwlock_wlock(JanetOSRWLock *rwlock);
|
|
JANET_API void janet_os_rwlock_runlock(JanetOSRWLock *rwlock);
|
|
JANET_API void janet_os_rwlock_wunlock(JanetOSRWLock *rwlock);
|
|
|
|
/* Get last error from an IO operation */
|
|
JANET_API Janet janet_ev_lasterr(void);
|
|
|
|
/* Async service for calling a function or syscall in a background thread. This is not
|
|
* as efficient in the slightest as using Streams but can be used for arbitrary blocking
|
|
* functions and syscalls. */
|
|
|
|
/* Used to pass data between the main thread and worker threads for simple tasks.
|
|
* We could just use a pointer but this prevents malloc/free in the common case
|
|
* of only a handful of arguments. */
|
|
typedef struct {
|
|
int tag;
|
|
int argi;
|
|
void *argp;
|
|
Janet argj;
|
|
JanetFiber *fiber;
|
|
} JanetEVGenericMessage;
|
|
|
|
/* How to resume or cancel after a threaded call. Not exhaustive of the possible
|
|
* ways one might want to resume after returning from a threaded call, but should
|
|
* cover most of the common cases. For something more complicated, such as resuming
|
|
* with an abstract type or a struct, one should use janet_ev_threaded_call instead
|
|
* of janet_ev_threaded_await with a custom callback. */
|
|
|
|
#define JANET_EV_TCTAG_NIL 0 /* resume with nil */
|
|
#define JANET_EV_TCTAG_INTEGER 1 /* resume with janet_wrap_integer(argi) */
|
|
#define JANET_EV_TCTAG_STRING 2 /* resume with janet_cstringv((const char *) argp) */
|
|
#define JANET_EV_TCTAG_STRINGF 3 /* resume with janet_cstringv((const char *) argp), then call free on argp. */
|
|
#define JANET_EV_TCTAG_KEYWORD 4 /* resume with janet_ckeywordv((const char *) argp) */
|
|
#define JANET_EV_TCTAG_ERR_STRING 5 /* cancel with janet_cstringv((const char *) argp) */
|
|
#define JANET_EV_TCTAG_ERR_STRINGF 6 /* cancel with janet_cstringv((const char *) argp), then call free on argp. */
|
|
#define JANET_EV_TCTAG_ERR_KEYWORD 7 /* cancel with janet_ckeywordv((const char *) argp) */
|
|
#define JANET_EV_TCTAG_BOOLEAN 8 /* resume with janet_wrap_boolean(argi) */
|
|
|
|
/* Function pointer that is run in the thread pool */
|
|
typedef JanetEVGenericMessage(*JanetThreadedSubroutine)(JanetEVGenericMessage arguments);
|
|
|
|
/* Handler for events posted to the event loop */
|
|
typedef void (*JanetCallback)(JanetEVGenericMessage return_value);
|
|
|
|
/* Handler that is run in the main thread with the result of the JanetAsyncSubroutine (same as JanetCallback) */
|
|
typedef void (*JanetThreadedCallback)(JanetEVGenericMessage return_value);
|
|
|
|
/* API calls for quickly offloading some work in C to a new thread or thread pool. */
|
|
JANET_API void janet_ev_threaded_call(JanetThreadedSubroutine fp, JanetEVGenericMessage arguments, JanetThreadedCallback cb);
|
|
JANET_NO_RETURN JANET_API void janet_ev_threaded_await(JanetThreadedSubroutine fp, int tag, int argi, void *argp);
|
|
|
|
/* Post callback + userdata to an event loop. Takes the vm parameter to allow posting from other
|
|
* threads or signal handlers. Use NULL to post to the current thread. */
|
|
JANET_API void janet_ev_post_event(JanetVM *vm, JanetCallback cb, JanetEVGenericMessage msg);
|
|
|
|
/* Callback used by janet_ev_threaded_await */
|
|
JANET_API void janet_ev_default_threaded_callback(JanetEVGenericMessage return_value);
|
|
|
|
/* Read async from a stream */
|
|
JANET_NO_RETURN JANET_API void janet_ev_read(JanetStream *stream, JanetBuffer *buf, int32_t nbytes);
|
|
JANET_NO_RETURN JANET_API void janet_ev_readchunk(JanetStream *stream, JanetBuffer *buf, int32_t nbytes);
|
|
#ifdef JANET_NET
|
|
JANET_NO_RETURN JANET_API void janet_ev_recv(JanetStream *stream, JanetBuffer *buf, int32_t nbytes, int flags);
|
|
JANET_NO_RETURN JANET_API void janet_ev_recvchunk(JanetStream *stream, JanetBuffer *buf, int32_t nbytes, int flags);
|
|
JANET_NO_RETURN JANET_API void janet_ev_recvfrom(JanetStream *stream, JanetBuffer *buf, int32_t nbytes, int flags);
|
|
#endif
|
|
|
|
/* Write async to a stream */
|
|
JANET_NO_RETURN JANET_API void janet_ev_write_buffer(JanetStream *stream, JanetBuffer *buf);
|
|
JANET_NO_RETURN JANET_API void janet_ev_write_string(JanetStream *stream, JanetString str);
|
|
#ifdef JANET_NET
|
|
JANET_NO_RETURN JANET_API void janet_ev_send_buffer(JanetStream *stream, JanetBuffer *buf, int flags);
|
|
JANET_NO_RETURN JANET_API void janet_ev_send_string(JanetStream *stream, JanetString str, int flags);
|
|
JANET_NO_RETURN JANET_API void janet_ev_sendto_buffer(JanetStream *stream, JanetBuffer *buf, void *dest, int flags);
|
|
JANET_NO_RETURN JANET_API void janet_ev_sendto_string(JanetStream *stream, JanetString str, void *dest, int flags);
|
|
#endif
|
|
|
|
#endif
|
|
|
|
/* Parsing */
|
|
extern JANET_API const JanetAbstractType janet_parser_type;
|
|
JANET_API void janet_parser_init(JanetParser *parser);
|
|
JANET_API void janet_parser_deinit(JanetParser *parser);
|
|
JANET_API void janet_parser_consume(JanetParser *parser, uint8_t c);
|
|
JANET_API enum JanetParserStatus janet_parser_status(JanetParser *parser);
|
|
JANET_API Janet janet_parser_produce(JanetParser *parser);
|
|
JANET_API Janet janet_parser_produce_wrapped(JanetParser *parser);
|
|
JANET_API const char *janet_parser_error(JanetParser *parser);
|
|
JANET_API void janet_parser_flush(JanetParser *parser);
|
|
JANET_API void janet_parser_eof(JanetParser *parser);
|
|
JANET_API int janet_parser_has_more(JanetParser *parser);
|
|
|
|
/* Assembly */
|
|
#ifdef JANET_ASSEMBLER
|
|
typedef struct JanetAssembleResult JanetAssembleResult;
|
|
enum JanetAssembleStatus {
|
|
JANET_ASSEMBLE_OK,
|
|
JANET_ASSEMBLE_ERROR
|
|
};
|
|
struct JanetAssembleResult {
|
|
JanetFuncDef *funcdef;
|
|
JanetString error;
|
|
enum JanetAssembleStatus status;
|
|
};
|
|
JANET_API JanetAssembleResult janet_asm(Janet source, int flags);
|
|
JANET_API Janet janet_disasm(JanetFuncDef *def);
|
|
JANET_API Janet janet_asm_decode_instruction(uint32_t instr);
|
|
#endif
|
|
|
|
/* Compilation */
|
|
typedef struct JanetCompileResult JanetCompileResult;
|
|
enum JanetCompileStatus {
|
|
JANET_COMPILE_OK,
|
|
JANET_COMPILE_ERROR
|
|
};
|
|
struct JanetCompileResult {
|
|
JanetFuncDef *funcdef;
|
|
JanetString error;
|
|
JanetFiber *macrofiber;
|
|
JanetSourceMapping error_mapping;
|
|
enum JanetCompileStatus status;
|
|
};
|
|
JANET_API JanetCompileResult janet_compile(Janet source, JanetTable *env, JanetString where);
|
|
JANET_API JanetCompileResult janet_compile_lint(
|
|
Janet source,
|
|
JanetTable *env,
|
|
JanetString where,
|
|
JanetArray *lints);
|
|
|
|
/* Get the default environment for janet */
|
|
JANET_API JanetTable *janet_core_env(JanetTable *replacements);
|
|
JANET_API JanetTable *janet_core_lookup_table(JanetTable *replacements);
|
|
|
|
/* Execute strings */
|
|
JANET_API int janet_dobytes(JanetTable *env, const uint8_t *bytes, int32_t len, const char *sourcePath, Janet *out);
|
|
JANET_API int janet_dostring(JanetTable *env, const char *str, const char *sourcePath, Janet *out);
|
|
|
|
/* Run the entrypoint of a wrapped program */
|
|
JANET_API int janet_loop_fiber(JanetFiber *fiber);
|
|
|
|
/* Number scanning */
|
|
JANET_API int janet_scan_number(const uint8_t *str, int32_t len, double *out);
|
|
JANET_API int janet_scan_number_base(const uint8_t *str, int32_t len, int32_t base, double *out);
|
|
JANET_API int janet_scan_int64(const uint8_t *str, int32_t len, int64_t *out);
|
|
JANET_API int janet_scan_uint64(const uint8_t *str, int32_t len, uint64_t *out);
|
|
#ifdef JANET_INT_TYPES
|
|
JANET_API int janet_scan_numeric(const uint8_t *str, int32_t len, Janet *out);
|
|
#endif
|
|
|
|
/* Debugging */
|
|
JANET_API void janet_debug_break(JanetFuncDef *def, int32_t pc);
|
|
JANET_API void janet_debug_unbreak(JanetFuncDef *def, int32_t pc);
|
|
JANET_API void janet_debug_find(
|
|
JanetFuncDef **def_out, int32_t *pc_out,
|
|
JanetString source, int32_t line, int32_t column);
|
|
|
|
/* RNG */
|
|
extern JANET_API const JanetAbstractType janet_rng_type;
|
|
JANET_API JanetRNG *janet_default_rng(void);
|
|
JANET_API void janet_rng_seed(JanetRNG *rng, uint32_t seed);
|
|
JANET_API void janet_rng_longseed(JanetRNG *rng, const uint8_t *bytes, int32_t len);
|
|
JANET_API uint32_t janet_rng_u32(JanetRNG *rng);
|
|
JANET_API double janet_rng_double(JanetRNG *rng);
|
|
|
|
/* Array functions */
|
|
JANET_API JanetArray *janet_array(int32_t capacity);
|
|
JANET_API JanetArray *janet_array_weak(int32_t capacity);
|
|
JANET_API JanetArray *janet_array_n(const Janet *elements, int32_t n);
|
|
JANET_API void janet_array_ensure(JanetArray *array, int32_t capacity, int32_t growth);
|
|
JANET_API void janet_array_setcount(JanetArray *array, int32_t count);
|
|
JANET_API void janet_array_push(JanetArray *array, Janet x);
|
|
JANET_API Janet janet_array_pop(JanetArray *array);
|
|
JANET_API Janet janet_array_peek(JanetArray *array);
|
|
|
|
/* Buffer functions */
|
|
#define JANET_BUFFER_FLAG_NO_REALLOC 0x10000
|
|
JANET_API JanetBuffer *janet_buffer(int32_t capacity);
|
|
JANET_API JanetBuffer *janet_buffer_init(JanetBuffer *buffer, int32_t capacity);
|
|
JANET_API JanetBuffer *janet_pointer_buffer_unsafe(void *memory, int32_t capacity, int32_t count);
|
|
JANET_API void janet_buffer_deinit(JanetBuffer *buffer);
|
|
JANET_API void janet_buffer_ensure(JanetBuffer *buffer, int32_t capacity, int32_t growth);
|
|
JANET_API void janet_buffer_setcount(JanetBuffer *buffer, int32_t count);
|
|
JANET_API void janet_buffer_extra(JanetBuffer *buffer, int32_t n);
|
|
JANET_API void janet_buffer_push_bytes(JanetBuffer *buffer, const uint8_t *string, int32_t len);
|
|
JANET_API void janet_buffer_push_string(JanetBuffer *buffer, JanetString string);
|
|
JANET_API void janet_buffer_push_cstring(JanetBuffer *buffer, const char *cstring);
|
|
JANET_API void janet_buffer_push_u8(JanetBuffer *buffer, uint8_t x);
|
|
JANET_API void janet_buffer_push_u16(JanetBuffer *buffer, uint16_t x);
|
|
JANET_API void janet_buffer_push_u32(JanetBuffer *buffer, uint32_t x);
|
|
JANET_API void janet_buffer_push_u64(JanetBuffer *buffer, uint64_t x);
|
|
|
|
/* Tuple */
|
|
|
|
#define JANET_TUPLE_FLAG_BRACKETCTOR 0x10000
|
|
|
|
#define janet_tuple_head(t) ((JanetTupleHead *)((char *)t - offsetof(JanetTupleHead, data)))
|
|
#define janet_tuple_from_head(gcobject) ((JanetTuple)((char *)gcobject + offsetof(JanetTupleHead, data)))
|
|
#define janet_tuple_length(t) (janet_tuple_head(t)->length)
|
|
#define janet_tuple_hash(t) (janet_tuple_head(t)->hash)
|
|
#define janet_tuple_sm_line(t) (janet_tuple_head(t)->sm_line)
|
|
#define janet_tuple_sm_column(t) (janet_tuple_head(t)->sm_column)
|
|
#define janet_tuple_flag(t) (janet_tuple_head(t)->gc.flags)
|
|
JANET_API Janet *janet_tuple_begin(int32_t length);
|
|
JANET_API JanetTuple janet_tuple_end(Janet *tuple);
|
|
JANET_API JanetTuple janet_tuple_n(const Janet *values, int32_t n);
|
|
|
|
/* String/Symbol functions */
|
|
#define janet_string_head(s) ((JanetStringHead *)((char *)s - offsetof(JanetStringHead, data)))
|
|
#define janet_string_length(s) (janet_string_head(s)->length)
|
|
#define janet_string_hash(s) (janet_string_head(s)->hash)
|
|
JANET_API uint8_t *janet_string_begin(int32_t length);
|
|
JANET_API JanetString janet_string_end(uint8_t *str);
|
|
JANET_API JanetString janet_string(const uint8_t *buf, int32_t len);
|
|
JANET_API JanetString janet_cstring(const char *cstring);
|
|
JANET_API int janet_string_compare(JanetString lhs, JanetString rhs);
|
|
JANET_API int janet_string_equal(JanetString lhs, JanetString rhs);
|
|
JANET_API int janet_string_equalconst(JanetString lhs, const uint8_t *rhs, int32_t rlen, int32_t rhash);
|
|
JANET_API JanetString janet_description(Janet x);
|
|
JANET_API JanetString janet_to_string(Janet x);
|
|
JANET_API void janet_to_string_b(JanetBuffer *buffer, Janet x);
|
|
JANET_API void janet_description_b(JanetBuffer *buffer, Janet x);
|
|
#define janet_cstringv(cstr) janet_wrap_string(janet_cstring(cstr))
|
|
#define janet_stringv(str, len) janet_wrap_string(janet_string((str), (len)))
|
|
JANET_API JanetString janet_formatc(const char *format, ...);
|
|
JANET_API JanetBuffer *janet_formatb(JanetBuffer *bufp, const char *format, ...);
|
|
JANET_API void janet_formatbv(JanetBuffer *bufp, const char *format, va_list args);
|
|
|
|
/* Symbol functions */
|
|
JANET_API JanetSymbol janet_symbol(const uint8_t *str, int32_t len);
|
|
JANET_API JanetSymbol janet_csymbol(const char *str);
|
|
JANET_API JanetSymbol janet_symbol_gen(void);
|
|
#define janet_symbolv(str, len) janet_wrap_symbol(janet_symbol((str), (len)))
|
|
#define janet_csymbolv(cstr) janet_wrap_symbol(janet_csymbol(cstr))
|
|
|
|
/* Keyword functions */
|
|
#define janet_keyword janet_symbol
|
|
#define janet_ckeyword janet_csymbol
|
|
#define janet_keywordv(str, len) janet_wrap_keyword(janet_keyword((str), (len)))
|
|
#define janet_ckeywordv(cstr) janet_wrap_keyword(janet_ckeyword(cstr))
|
|
|
|
/* Structs */
|
|
#define janet_struct_head(t) ((JanetStructHead *)((char *)t - offsetof(JanetStructHead, data)))
|
|
#define janet_struct_from_head(t) ((JanetStruct)((char *)gcobject + offsetof(JanetStructHead, data)))
|
|
#define janet_struct_length(t) (janet_struct_head(t)->length)
|
|
#define janet_struct_capacity(t) (janet_struct_head(t)->capacity)
|
|
#define janet_struct_hash(t) (janet_struct_head(t)->hash)
|
|
#define janet_struct_proto(t) (janet_struct_head(t)->proto)
|
|
JANET_API JanetKV *janet_struct_begin(int32_t count);
|
|
JANET_API void janet_struct_put(JanetKV *st, Janet key, Janet value);
|
|
JANET_API JanetStruct janet_struct_end(JanetKV *st);
|
|
JANET_API Janet janet_struct_get(JanetStruct st, Janet key);
|
|
JANET_API Janet janet_struct_rawget(JanetStruct st, Janet key);
|
|
JANET_API Janet janet_struct_get_ex(JanetStruct st, Janet key, JanetStruct *which);
|
|
JANET_API JanetTable *janet_struct_to_table(JanetStruct st);
|
|
JANET_API const JanetKV *janet_struct_find(JanetStruct st, Janet key);
|
|
|
|
/* Table functions */
|
|
JANET_API JanetTable *janet_table(int32_t capacity);
|
|
JANET_API JanetTable *janet_table_init(JanetTable *table, int32_t capacity);
|
|
JANET_API JanetTable *janet_table_init_raw(JanetTable *table, int32_t capacity);
|
|
JANET_API void janet_table_deinit(JanetTable *table);
|
|
JANET_API Janet janet_table_get(JanetTable *t, Janet key);
|
|
JANET_API Janet janet_table_get_ex(JanetTable *t, Janet key, JanetTable **which);
|
|
JANET_API Janet janet_table_rawget(JanetTable *t, Janet key);
|
|
JANET_API Janet janet_table_remove(JanetTable *t, Janet key);
|
|
JANET_API void janet_table_put(JanetTable *t, Janet key, Janet value);
|
|
JANET_API JanetStruct janet_table_to_struct(JanetTable *t);
|
|
JANET_API void janet_table_merge_table(JanetTable *table, JanetTable *other);
|
|
JANET_API void janet_table_merge_struct(JanetTable *table, JanetStruct other);
|
|
JANET_API JanetKV *janet_table_find(JanetTable *t, Janet key);
|
|
JANET_API JanetTable *janet_table_clone(JanetTable *table);
|
|
JANET_API void janet_table_clear(JanetTable *table);
|
|
JANET_API JanetTable *janet_table_weakk(int32_t capacity);
|
|
JANET_API JanetTable *janet_table_weakv(int32_t capacity);
|
|
JANET_API JanetTable *janet_table_weakkv(int32_t capacity);
|
|
|
|
/* Fiber */
|
|
JANET_API JanetFiber *janet_fiber(JanetFunction *callee, int32_t capacity, int32_t argc, const Janet *argv);
|
|
JANET_API JanetFiber *janet_fiber_reset(JanetFiber *fiber, JanetFunction *callee, int32_t argc, const Janet *argv);
|
|
JANET_API JanetFiberStatus janet_fiber_status(JanetFiber *fiber);
|
|
JANET_API int janet_fiber_can_resume(JanetFiber *fiber);
|
|
JANET_API JanetFiber *janet_current_fiber(void);
|
|
JANET_API JanetFiber *janet_root_fiber(void);
|
|
|
|
/* Treat similar types through uniform interfaces for iteration */
|
|
JANET_API int janet_indexed_view(Janet seq, const Janet **data, int32_t *len);
|
|
JANET_API int janet_bytes_view(Janet str, const uint8_t **data, int32_t *len);
|
|
JANET_API int janet_dictionary_view(Janet tab, const JanetKV **data, int32_t *len, int32_t *cap);
|
|
JANET_API Janet janet_dictionary_get(const JanetKV *data, int32_t cap, Janet key);
|
|
JANET_API const JanetKV *janet_dictionary_next(const JanetKV *kvs, int32_t cap, const JanetKV *kv);
|
|
|
|
/* Abstract */
|
|
#define janet_abstract_head(u) ((JanetAbstractHead *)((char *)u - offsetof(JanetAbstractHead, data)))
|
|
#define janet_abstract_from_head(gcobject) ((JanetAbstract)((char *)gcobject + offsetof(JanetAbstractHead, data)))
|
|
#define janet_abstract_type(u) (janet_abstract_head(u)->type)
|
|
#define janet_abstract_size(u) (janet_abstract_head(u)->size)
|
|
JANET_API void *janet_abstract_begin(const JanetAbstractType *type, size_t size);
|
|
JANET_API JanetAbstract janet_abstract_end(void *abstractTemplate);
|
|
JANET_API JanetAbstract janet_abstract(const JanetAbstractType *type, size_t size); /* begin and end in one call */
|
|
|
|
/* Native */
|
|
typedef void (*JanetModule)(JanetTable *);
|
|
typedef JanetBuildConfig(*JanetModconf)(void);
|
|
JANET_API JanetModule janet_native(const char *name, JanetString *error);
|
|
|
|
/* Marshaling */
|
|
#define JANET_MARSHAL_UNSAFE 0x20000
|
|
#define JANET_MARSHAL_NO_CYCLES 0x40000
|
|
|
|
JANET_API void janet_marshal(
|
|
JanetBuffer *buf,
|
|
Janet x,
|
|
JanetTable *rreg,
|
|
int flags);
|
|
JANET_API Janet janet_unmarshal(
|
|
const uint8_t *bytes,
|
|
size_t len,
|
|
int flags,
|
|
JanetTable *reg,
|
|
const uint8_t **next);
|
|
JANET_API JanetTable *janet_env_lookup(JanetTable *env);
|
|
JANET_API void janet_env_lookup_into(JanetTable *renv, JanetTable *env, const char *prefix, int recurse);
|
|
|
|
/* GC */
|
|
JANET_API void janet_mark(Janet x);
|
|
JANET_API void janet_sweep(void);
|
|
JANET_API void janet_collect(void);
|
|
JANET_API void janet_clear_memory(void);
|
|
JANET_API void janet_gcroot(Janet root);
|
|
JANET_API int janet_gcunroot(Janet root);
|
|
JANET_API int janet_gcunrootall(Janet root);
|
|
JANET_API int janet_gclock(void);
|
|
JANET_API void janet_gcunlock(int handle);
|
|
JANET_API void janet_gcpressure(size_t s);
|
|
|
|
/* Functions */
|
|
JANET_API JanetFuncDef *janet_funcdef_alloc(void);
|
|
JANET_API JanetFunction *janet_thunk(JanetFuncDef *def);
|
|
JANET_API JanetFunction *janet_thunk_delay(Janet x);
|
|
JANET_API int janet_verify(JanetFuncDef *def);
|
|
|
|
/* Pretty printing */
|
|
#define JANET_PRETTY_COLOR 1
|
|
#define JANET_PRETTY_ONELINE 2
|
|
#define JANET_PRETTY_NOTRUNC 4
|
|
JANET_API JanetBuffer *janet_pretty(JanetBuffer *buffer, int depth, int flags, Janet x);
|
|
|
|
/* Misc */
|
|
#ifdef JANET_PRF
|
|
#define JANET_HASH_KEY_SIZE 16
|
|
JANET_API void janet_init_hash_key(uint8_t key[JANET_HASH_KEY_SIZE]);
|
|
#endif
|
|
JANET_API void janet_try_init(JanetTryState *state);
|
|
#if defined(JANET_BSD) || defined(JANET_APPLE)
|
|
#define janet_try(state) (janet_try_init(state), (JanetSignal) _setjmp((state)->buf))
|
|
#else
|
|
#define janet_try(state) (janet_try_init(state), (JanetSignal) setjmp((state)->buf))
|
|
#endif
|
|
JANET_API void janet_restore(JanetTryState *state);
|
|
JANET_API int janet_equals(Janet x, Janet y);
|
|
JANET_API int32_t janet_hash(Janet x);
|
|
JANET_API int janet_compare(Janet x, Janet y);
|
|
JANET_API int janet_cstrcmp(JanetString str, const char *other);
|
|
JANET_API Janet janet_in(Janet ds, Janet key);
|
|
JANET_API Janet janet_get(Janet ds, Janet key);
|
|
JANET_API Janet janet_next(Janet ds, Janet key);
|
|
JANET_API Janet janet_getindex(Janet ds, int32_t index);
|
|
JANET_API int32_t janet_length(Janet x);
|
|
JANET_API Janet janet_lengthv(Janet x);
|
|
JANET_API void janet_put(Janet ds, Janet key, Janet value);
|
|
JANET_API void janet_putindex(Janet ds, int32_t index, Janet value);
|
|
#define janet_flag_at(F, I) ((F) & ((1ULL) << (I)))
|
|
JANET_API Janet janet_wrap_number_safe(double x);
|
|
JANET_API int janet_keyeq(Janet x, const char *cstring);
|
|
JANET_API int janet_streq(Janet x, const char *cstring);
|
|
JANET_API int janet_symeq(Janet x, const char *cstring);
|
|
JANET_API int32_t janet_sorted_keys(const JanetKV *dict, int32_t cap, int32_t *index_buffer);
|
|
|
|
/* VM functions */
|
|
JANET_API int janet_init(void);
|
|
JANET_API void janet_deinit(void);
|
|
JANET_API JanetVM *janet_vm_alloc(void);
|
|
JANET_API JanetVM *janet_local_vm(void);
|
|
JANET_API void janet_vm_free(JanetVM *vm);
|
|
JANET_API void janet_vm_save(JanetVM *into);
|
|
JANET_API void janet_vm_load(JanetVM *from);
|
|
JANET_API void janet_interpreter_interrupt(JanetVM *vm);
|
|
JANET_API void janet_interpreter_interrupt_handled(JanetVM *vm);
|
|
JANET_API JanetSignal janet_continue(JanetFiber *fiber, Janet in, Janet *out);
|
|
JANET_API JanetSignal janet_continue_signal(JanetFiber *fiber, Janet in, Janet *out, JanetSignal sig);
|
|
JANET_API JanetSignal janet_pcall(JanetFunction *fun, int32_t argn, const Janet *argv, Janet *out, JanetFiber **f);
|
|
JANET_API JanetSignal janet_step(JanetFiber *fiber, Janet in, Janet *out);
|
|
JANET_API Janet janet_call(JanetFunction *fun, int32_t argc, const Janet *argv);
|
|
JANET_API Janet janet_mcall(const char *name, int32_t argc, Janet *argv);
|
|
JANET_API void janet_stacktrace(JanetFiber *fiber, Janet err);
|
|
JANET_API void janet_stacktrace_ext(JanetFiber *fiber, Janet err, const char *prefix);
|
|
|
|
/* Sandboxing API */
|
|
#define JANET_SANDBOX_SANDBOX 1
|
|
#define JANET_SANDBOX_SUBPROCESS 2
|
|
#define JANET_SANDBOX_NET_CONNECT 4
|
|
#define JANET_SANDBOX_NET_LISTEN 8
|
|
#define JANET_SANDBOX_FFI_DEFINE 16
|
|
#define JANET_SANDBOX_FS_WRITE 32
|
|
#define JANET_SANDBOX_FS_READ 64
|
|
#define JANET_SANDBOX_HRTIME 128
|
|
#define JANET_SANDBOX_ENV 256
|
|
#define JANET_SANDBOX_DYNAMIC_MODULES 512
|
|
#define JANET_SANDBOX_FS_TEMP 1024
|
|
#define JANET_SANDBOX_FFI_USE 2048
|
|
#define JANET_SANDBOX_FFI_JIT 4096
|
|
#define JANET_SANDBOX_SIGNAL 8192
|
|
#define JANET_SANDBOX_FFI (JANET_SANDBOX_FFI_DEFINE | JANET_SANDBOX_FFI_USE | JANET_SANDBOX_FFI_JIT)
|
|
#define JANET_SANDBOX_FS (JANET_SANDBOX_FS_WRITE | JANET_SANDBOX_FS_READ | JANET_SANDBOX_FS_TEMP)
|
|
#define JANET_SANDBOX_NET (JANET_SANDBOX_NET_CONNECT | JANET_SANDBOX_NET_LISTEN)
|
|
#define JANET_SANDBOX_ALL (UINT32_MAX)
|
|
JANET_API void janet_sandbox(uint32_t flags);
|
|
JANET_API void janet_sandbox_assert(uint32_t forbidden_flags);
|
|
|
|
/* Scratch Memory API */
|
|
typedef void (*JanetScratchFinalizer)(void *);
|
|
|
|
JANET_API void *janet_smalloc(size_t size);
|
|
JANET_API void *janet_srealloc(void *mem, size_t size);
|
|
JANET_API void *janet_scalloc(size_t nmemb, size_t size);
|
|
JANET_API void janet_sfinalizer(void *mem, JanetScratchFinalizer finalizer);
|
|
JANET_API void janet_sfree(void *mem);
|
|
|
|
/* C Library helpers */
|
|
typedef enum {
|
|
JANET_BINDING_NONE,
|
|
JANET_BINDING_DEF,
|
|
JANET_BINDING_VAR,
|
|
JANET_BINDING_MACRO,
|
|
JANET_BINDING_DYNAMIC_DEF,
|
|
JANET_BINDING_DYNAMIC_MACRO
|
|
} JanetBindingType;
|
|
|
|
typedef struct {
|
|
JanetBindingType type;
|
|
Janet value;
|
|
enum {
|
|
JANET_BINDING_DEP_NONE,
|
|
JANET_BINDING_DEP_RELAXED,
|
|
JANET_BINDING_DEP_NORMAL,
|
|
JANET_BINDING_DEP_STRICT,
|
|
} deprecation;
|
|
} JanetBinding;
|
|
|
|
JANET_API void janet_def(JanetTable *env, const char *name, Janet val, const char *documentation);
|
|
JANET_API void janet_var(JanetTable *env, const char *name, Janet val, const char *documentation);
|
|
JANET_API void janet_cfuns(JanetTable *env, const char *regprefix, const JanetReg *cfuns);
|
|
JANET_API void janet_cfuns_prefix(JanetTable *env, const char *regprefix, const JanetReg *cfuns);
|
|
JANET_API JanetBindingType janet_resolve(JanetTable *env, JanetSymbol sym, Janet *out);
|
|
JANET_API JanetBinding janet_resolve_ext(JanetTable *env, JanetSymbol sym);
|
|
|
|
/* Get values from the core environment. */
|
|
JANET_API Janet janet_resolve_core(const char *name);
|
|
|
|
/* New C API */
|
|
|
|
/* Shorthand for janet C function declarations */
|
|
#define JANET_CFUN(name) Janet name (int32_t argc, Janet *argv)
|
|
|
|
/* Declare a C function with documentation and source mapping */
|
|
#define JANET_REG_END {NULL, NULL, NULL, NULL, 0}
|
|
|
|
/* no docstrings or sourcemaps */
|
|
#define JANET_REG_(JNAME, CNAME) {JNAME, CNAME, NULL, NULL, 0}
|
|
#define JANET_FN_(CNAME, USAGE, DOCSTRING) \
|
|
Janet CNAME (int32_t argc, Janet *argv)
|
|
#define JANET_DEF_(ENV, JNAME, VAL, DOC) \
|
|
janet_def(ENV, JNAME, VAL, NULL)
|
|
|
|
/* sourcemaps only */
|
|
#define JANET_REG_S(JNAME, CNAME) {JNAME, CNAME, NULL, __FILE__, CNAME##_sourceline_}
|
|
#define JANET_FN_S(CNAME, USAGE, DOCSTRING) \
|
|
static const int32_t CNAME##_sourceline_ = __LINE__; \
|
|
Janet CNAME (int32_t argc, Janet *argv)
|
|
#define JANET_DEF_S(ENV, JNAME, VAL, DOC) \
|
|
janet_def_sm(ENV, JNAME, VAL, NULL, __FILE__, __LINE__)
|
|
|
|
/* docstring only */
|
|
#define JANET_REG_D(JNAME, CNAME) {JNAME, CNAME, CNAME##_docstring_, NULL, 0}
|
|
#define JANET_FN_D(CNAME, USAGE, DOCSTRING) \
|
|
static const char CNAME##_docstring_[] = USAGE "\n\n" DOCSTRING; \
|
|
Janet CNAME (int32_t argc, Janet *argv)
|
|
#define JANET_DEF_D(ENV, JNAME, VAL, DOC) \
|
|
janet_def(ENV, JNAME, VAL, DOC)
|
|
|
|
/* sourcemaps and docstrings */
|
|
#define JANET_REG_SD(JNAME, CNAME) {JNAME, CNAME, CNAME##_docstring_, __FILE__, CNAME##_sourceline_}
|
|
#define JANET_FN_SD(CNAME, USAGE, DOCSTRING) \
|
|
static const int32_t CNAME##_sourceline_ = __LINE__; \
|
|
static const char CNAME##_docstring_[] = USAGE "\n\n" DOCSTRING; \
|
|
Janet CNAME (int32_t argc, Janet *argv)
|
|
#define JANET_DEF_SD(ENV, JNAME, VAL, DOC) \
|
|
janet_def_sm(ENV, JNAME, VAL, DOC, __FILE__, __LINE__)
|
|
|
|
/* Choose defaults for source mapping and docstring based on config defs */
|
|
#if defined(JANET_NO_SOURCEMAPS) && defined(JANET_NO_DOCSTRINGS)
|
|
#define JANET_REG JANET_REG_
|
|
#define JANET_FN JANET_FN_
|
|
#define JANET_DEF JANET_DEF_
|
|
#elif defined(JANET_NO_SOURCEMAPS) && !defined(JANET_NO_DOCSTRINGS)
|
|
#define JANET_REG JANET_REG_D
|
|
#define JANET_FN JANET_FN_D
|
|
#define JANET_DEF JANET_DEF_D
|
|
#elif !defined(JANET_NO_SOURCEMAPS) && defined(JANET_NO_DOCSTRINGS)
|
|
#define JANET_REG JANET_REG_S
|
|
#define JANET_FN JANET_FN_S
|
|
#define JANET_DEF JANET_DEF_S
|
|
#elif !defined(JANET_NO_SOURCEMAPS) && !defined(JANET_NO_DOCSTRINGS)
|
|
#define JANET_REG JANET_REG_SD
|
|
#define JANET_FN JANET_FN_SD
|
|
#define JANET_DEF JANET_DEF_SD
|
|
#endif
|
|
|
|
/* Define things with source mapping information */
|
|
JANET_API void janet_cfuns_ext(JanetTable *env, const char *regprefix, const JanetRegExt *cfuns);
|
|
JANET_API void janet_cfuns_ext_prefix(JanetTable *env, const char *regprefix, const JanetRegExt *cfuns);
|
|
JANET_API void janet_def_sm(JanetTable *env, const char *name, Janet val, const char *documentation, const char *source_file, int32_t source_line);
|
|
JANET_API void janet_var_sm(JanetTable *env, const char *name, Janet val, const char *documentation, const char *source_file, int32_t source_line);
|
|
|
|
/* Legacy definition of C functions */
|
|
JANET_API void janet_register(const char *name, JanetCFunction cfun);
|
|
|
|
/* Allow setting entry name for static libraries */
|
|
#ifdef __cplusplus
|
|
#define JANET_MODULE_PREFIX extern "C"
|
|
#else
|
|
#define JANET_MODULE_PREFIX
|
|
#endif
|
|
#ifndef JANET_ENTRY_NAME
|
|
#define JANET_MODULE_ENTRY \
|
|
JANET_MODULE_PREFIX JANET_EXPORT JanetBuildConfig _janet_mod_config(void) { \
|
|
return janet_config_current(); \
|
|
} \
|
|
JANET_MODULE_PREFIX JANET_EXPORT void _janet_init
|
|
#else
|
|
#define JANET_MODULE_ENTRY JANET_MODULE_PREFIX JANET_API void JANET_ENTRY_NAME
|
|
#endif
|
|
|
|
JANET_NO_RETURN JANET_API void janet_signalv(JanetSignal signal, Janet message);
|
|
JANET_NO_RETURN JANET_API void janet_panicv(Janet message);
|
|
JANET_NO_RETURN JANET_API void janet_panic(const char *message);
|
|
JANET_NO_RETURN JANET_API void janet_panics(JanetString message);
|
|
JANET_NO_RETURN JANET_API void janet_panicf(const char *format, ...);
|
|
JANET_API void janet_dynprintf(const char *name, FILE *dflt_file, const char *format, ...);
|
|
#define janet_printf(...) janet_dynprintf("out", stdout, __VA_ARGS__)
|
|
#define janet_eprintf(...) janet_dynprintf("err", stderr, __VA_ARGS__)
|
|
JANET_NO_RETURN JANET_API void janet_panic_type(Janet x, int32_t n, int expected);
|
|
JANET_NO_RETURN JANET_API void janet_panic_abstract(Janet x, int32_t n, const JanetAbstractType *at);
|
|
JANET_API void janet_arity(int32_t arity, int32_t min, int32_t max);
|
|
JANET_API void janet_fixarity(int32_t arity, int32_t fix);
|
|
|
|
JANET_API int janet_getmethod(JanetKeyword method, const JanetMethod *methods, Janet *out);
|
|
JANET_API Janet janet_nextmethod(const JanetMethod *methods, Janet key);
|
|
|
|
JANET_API double janet_getnumber(const Janet *argv, int32_t n);
|
|
JANET_API JanetArray *janet_getarray(const Janet *argv, int32_t n);
|
|
JANET_API JanetTuple janet_gettuple(const Janet *argv, int32_t n);
|
|
JANET_API JanetTable *janet_gettable(const Janet *argv, int32_t n);
|
|
JANET_API JanetStruct janet_getstruct(const Janet *argv, int32_t n);
|
|
JANET_API JanetString janet_getstring(const Janet *argv, int32_t n);
|
|
JANET_API const char *janet_getcstring(const Janet *argv, int32_t n);
|
|
JANET_API const char *janet_getcbytes(const Janet *argv, int32_t n);
|
|
JANET_API JanetSymbol janet_getsymbol(const Janet *argv, int32_t n);
|
|
JANET_API JanetKeyword janet_getkeyword(const Janet *argv, int32_t n);
|
|
JANET_API JanetBuffer *janet_getbuffer(const Janet *argv, int32_t n);
|
|
JANET_API JanetFiber *janet_getfiber(const Janet *argv, int32_t n);
|
|
JANET_API JanetFunction *janet_getfunction(const Janet *argv, int32_t n);
|
|
JANET_API JanetCFunction janet_getcfunction(const Janet *argv, int32_t n);
|
|
JANET_API int janet_getboolean(const Janet *argv, int32_t n);
|
|
JANET_API void *janet_getpointer(const Janet *argv, int32_t n);
|
|
|
|
JANET_API int32_t janet_getnat(const Janet *argv, int32_t n);
|
|
JANET_API int32_t janet_getinteger(const Janet *argv, int32_t n);
|
|
JANET_API int16_t janet_getinteger16(const Janet *argv, int32_t n);
|
|
JANET_API int64_t janet_getinteger64(const Janet *argv, int32_t n);
|
|
JANET_API uint32_t janet_getuinteger(const Janet *argv, int32_t n);
|
|
JANET_API uint16_t janet_getuinteger16(const Janet *argv, int32_t n);
|
|
JANET_API uint64_t janet_getuinteger64(const Janet *argv, int32_t n);
|
|
JANET_API size_t janet_getsize(const Janet *argv, int32_t n);
|
|
JANET_API JanetView janet_getindexed(const Janet *argv, int32_t n);
|
|
JANET_API JanetByteView janet_getbytes(const Janet *argv, int32_t n);
|
|
JANET_API JanetDictView janet_getdictionary(const Janet *argv, int32_t n);
|
|
JANET_API void *janet_getabstract(const Janet *argv, int32_t n, const JanetAbstractType *at);
|
|
JANET_API JanetRange janet_getslice(int32_t argc, const Janet *argv);
|
|
JANET_API int32_t janet_gethalfrange(const Janet *argv, int32_t n, int32_t length, const char *which);
|
|
JANET_API int32_t janet_getstartrange(const Janet *argv, int32_t argc, int32_t n, int32_t length);
|
|
JANET_API int32_t janet_getendrange(const Janet *argv, int32_t argc, int32_t n, int32_t length);
|
|
JANET_API int32_t janet_getargindex(const Janet *argv, int32_t n, int32_t length, const char *which);
|
|
JANET_API uint64_t janet_getflags(const Janet *argv, int32_t n, const char *flags);
|
|
|
|
/* Optionals */
|
|
JANET_API double janet_optnumber(const Janet *argv, int32_t argc, int32_t n, double dflt);
|
|
JANET_API JanetTuple janet_opttuple(const Janet *argv, int32_t argc, int32_t n, JanetTuple dflt);
|
|
JANET_API JanetStruct janet_optstruct(const Janet *argv, int32_t argc, int32_t n, JanetStruct dflt);
|
|
JANET_API JanetString janet_optstring(const Janet *argv, int32_t argc, int32_t n, JanetString dflt);
|
|
JANET_API const char *janet_optcstring(const Janet *argv, int32_t argc, int32_t n, const char *dflt);
|
|
JANET_API const char *janet_optcbytes(const Janet *argv, int32_t argc, int32_t n, const char *dflt);
|
|
JANET_API JanetSymbol janet_optsymbol(const Janet *argv, int32_t argc, int32_t n, JanetString dflt);
|
|
JANET_API JanetKeyword janet_optkeyword(const Janet *argv, int32_t argc, int32_t n, JanetString dflt);
|
|
JANET_API JanetFiber *janet_optfiber(const Janet *argv, int32_t argc, int32_t n, JanetFiber *dflt);
|
|
JANET_API JanetFunction *janet_optfunction(const Janet *argv, int32_t argc, int32_t n, JanetFunction *dflt);
|
|
JANET_API JanetCFunction janet_optcfunction(const Janet *argv, int32_t argc, int32_t n, JanetCFunction dflt);
|
|
JANET_API int janet_optboolean(const Janet *argv, int32_t argc, int32_t n, int dflt);
|
|
JANET_API void *janet_optpointer(const Janet *argv, int32_t argc, int32_t n, void *dflt);
|
|
JANET_API int32_t janet_optnat(const Janet *argv, int32_t argc, int32_t n, int32_t dflt);
|
|
JANET_API int32_t janet_optinteger(const Janet *argv, int32_t argc, int32_t n, int32_t dflt);
|
|
JANET_API int64_t janet_optinteger64(const Janet *argv, int32_t argc, int32_t n, int64_t dflt);
|
|
JANET_API size_t janet_optsize(const Janet *argv, int32_t argc, int32_t n, size_t dflt);
|
|
JANET_API JanetAbstract janet_optabstract(const Janet *argv, int32_t argc, int32_t n, const JanetAbstractType *at, JanetAbstract dflt);
|
|
|
|
/* Mutable optional types specify a size default, and construct a new value if none is provided */
|
|
JANET_API JanetBuffer *janet_optbuffer(const Janet *argv, int32_t argc, int32_t n, int32_t dflt_len);
|
|
JANET_API JanetTable *janet_opttable(const Janet *argv, int32_t argc, int32_t n, int32_t dflt_len);
|
|
JANET_API JanetArray *janet_optarray(const Janet *argv, int32_t argc, int32_t n, int32_t dflt_len);
|
|
|
|
JANET_API Janet janet_dyn(const char *name);
|
|
JANET_API void janet_setdyn(const char *name, Janet value);
|
|
|
|
extern JANET_API const JanetAbstractType janet_file_type;
|
|
|
|
#define JANET_FILE_WRITE 1
|
|
#define JANET_FILE_READ 2
|
|
#define JANET_FILE_APPEND 4
|
|
#define JANET_FILE_UPDATE 8
|
|
#define JANET_FILE_NOT_CLOSEABLE 16
|
|
#define JANET_FILE_CLOSED 32
|
|
#define JANET_FILE_BINARY 64
|
|
#define JANET_FILE_SERIALIZABLE 128
|
|
#define JANET_FILE_NONIL 512
|
|
|
|
JANET_API Janet janet_makefile(FILE *f, int32_t flags);
|
|
JANET_API JanetFile *janet_makejfile(FILE *f, int32_t 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 JanetFile *janet_getjfile(const Janet *argv, int32_t n);
|
|
JANET_API JanetAbstract janet_checkfile(Janet j);
|
|
JANET_API FILE *janet_unwrapfile(Janet j, int32_t *flags);
|
|
JANET_API int janet_file_close(JanetFile *file);
|
|
|
|
JANET_API int janet_cryptorand(uint8_t *out, size_t n);
|
|
|
|
/* Marshal API */
|
|
JANET_API void janet_marshal_size(JanetMarshalContext *ctx, size_t value);
|
|
JANET_API void janet_marshal_int(JanetMarshalContext *ctx, int32_t value);
|
|
JANET_API void janet_marshal_int64(JanetMarshalContext *ctx, int64_t value);
|
|
JANET_API void janet_marshal_ptr(JanetMarshalContext *ctx, const void *value);
|
|
JANET_API void janet_marshal_byte(JanetMarshalContext *ctx, uint8_t value);
|
|
JANET_API void janet_marshal_bytes(JanetMarshalContext *ctx, const uint8_t *bytes, size_t len);
|
|
JANET_API void janet_marshal_janet(JanetMarshalContext *ctx, Janet x);
|
|
JANET_API void janet_marshal_abstract(JanetMarshalContext *ctx, JanetAbstract abstract);
|
|
|
|
JANET_API void janet_unmarshal_ensure(JanetMarshalContext *ctx, size_t size);
|
|
JANET_API size_t janet_unmarshal_size(JanetMarshalContext *ctx);
|
|
JANET_API int32_t janet_unmarshal_int(JanetMarshalContext *ctx);
|
|
JANET_API int64_t janet_unmarshal_int64(JanetMarshalContext *ctx);
|
|
JANET_API void *janet_unmarshal_ptr(JanetMarshalContext *ctx);
|
|
JANET_API uint8_t janet_unmarshal_byte(JanetMarshalContext *ctx);
|
|
JANET_API void janet_unmarshal_bytes(JanetMarshalContext *ctx, uint8_t *dest, size_t len);
|
|
JANET_API Janet janet_unmarshal_janet(JanetMarshalContext *ctx);
|
|
JANET_API JanetAbstract janet_unmarshal_abstract(JanetMarshalContext *ctx, size_t size);
|
|
JANET_API JanetAbstract janet_unmarshal_abstract_threaded(JanetMarshalContext *ctx, size_t size);
|
|
JANET_API void janet_unmarshal_abstract_reuse(JanetMarshalContext *ctx, void *p);
|
|
|
|
JANET_API void janet_register_abstract_type(const JanetAbstractType *at);
|
|
JANET_API const JanetAbstractType *janet_get_abstract_type(Janet key);
|
|
|
|
#ifdef JANET_PEG
|
|
|
|
extern JANET_API const JanetAbstractType janet_peg_type;
|
|
|
|
/* opcodes for peg vm */
|
|
typedef enum {
|
|
RULE_LITERAL, /* [len, bytes...] */
|
|
RULE_NCHAR, /* [n] */
|
|
RULE_NOTNCHAR, /* [n] */
|
|
RULE_RANGE, /* [lo | hi << 16 (1 word)] */
|
|
RULE_SET, /* [bitmap (8 words)] */
|
|
RULE_LOOK, /* [offset, rule] */
|
|
RULE_CHOICE, /* [len, rules...] */
|
|
RULE_SEQUENCE, /* [len, rules...] */
|
|
RULE_IF, /* [rule_a, rule_b (b if a)] */
|
|
RULE_IFNOT, /* [rule_a, rule_b (b if not a)] */
|
|
RULE_NOT, /* [rule] */
|
|
RULE_BETWEEN, /* [lo, hi, rule] */
|
|
RULE_GETTAG, /* [searchtag, tag] */
|
|
RULE_CAPTURE, /* [rule, tag] */
|
|
RULE_POSITION, /* [tag] */
|
|
RULE_ARGUMENT, /* [argument-index, tag] */
|
|
RULE_CONSTANT, /* [constant, tag] */
|
|
RULE_ACCUMULATE, /* [rule, tag] */
|
|
RULE_GROUP, /* [rule, tag] */
|
|
RULE_REPLACE, /* [rule, constant, tag] */
|
|
RULE_MATCHTIME, /* [rule, constant, tag] */
|
|
RULE_ERROR, /* [rule] */
|
|
RULE_DROP, /* [rule] */
|
|
RULE_BACKMATCH, /* [tag] */
|
|
RULE_TO, /* [rule] */
|
|
RULE_THRU, /* [rule] */
|
|
RULE_LENPREFIX, /* [rule_a, rule_b (repeat rule_b rule_a times)] */
|
|
RULE_READINT, /* [(signedness << 4) | (endianness << 5) | bytewidth, tag] */
|
|
RULE_LINE, /* [tag] */
|
|
RULE_COLUMN, /* [tag] */
|
|
RULE_UNREF, /* [rule, tag] */
|
|
RULE_CAPTURE_NUM, /* [rule, tag] */
|
|
RULE_SUB, /* [rule, rule] */
|
|
RULE_SPLIT /* [rule, rule] */
|
|
} JanetPegOpcod;
|
|
|
|
typedef struct {
|
|
uint32_t *bytecode;
|
|
Janet *constants;
|
|
size_t bytecode_len;
|
|
uint32_t num_constants;
|
|
int has_backref;
|
|
} JanetPeg;
|
|
|
|
#endif
|
|
|
|
#ifdef JANET_INT_TYPES
|
|
|
|
extern JANET_API const JanetAbstractType janet_s64_type;
|
|
extern JANET_API const JanetAbstractType janet_u64_type;
|
|
|
|
typedef enum {
|
|
JANET_INT_NONE,
|
|
JANET_INT_S64,
|
|
JANET_INT_U64
|
|
} JanetIntType;
|
|
|
|
JANET_API JanetIntType janet_is_int(Janet x);
|
|
JANET_API Janet janet_wrap_s64(int64_t x);
|
|
JANET_API Janet janet_wrap_u64(uint64_t x);
|
|
JANET_API int64_t janet_unwrap_s64(Janet x);
|
|
JANET_API uint64_t janet_unwrap_u64(Janet x);
|
|
JANET_API int janet_scan_int64(const uint8_t *str, int32_t len, int64_t *out);
|
|
JANET_API int janet_scan_uint64(const uint8_t *str, int32_t len, uint64_t *out);
|
|
|
|
#endif
|
|
|
|
/* Custom allocator support */
|
|
JANET_API void *(janet_malloc)(size_t);
|
|
JANET_API void *(janet_realloc)(void *, size_t);
|
|
JANET_API void *(janet_calloc)(size_t, size_t);
|
|
JANET_API void (janet_free)(void *);
|
|
#ifndef janet_malloc
|
|
#define janet_malloc(X) malloc((X))
|
|
#endif
|
|
#ifndef janet_realloc
|
|
#define janet_realloc(X, Y) realloc((X), (Y))
|
|
#endif
|
|
#ifndef janet_calloc
|
|
#define janet_calloc(X, Y) calloc((X), (Y))
|
|
#endif
|
|
#ifndef janet_free
|
|
#define janet_free(X) free((X))
|
|
#endif
|
|
|
|
/***** END SECTION MAIN *****/
|
|
|
|
/* Re-enable popped variable length array warnings */
|
|
#ifdef _MSC_VER
|
|
#pragma warning( pop )
|
|
#endif
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* JANET_H_defined */
|