mirror of
https://github.com/janet-lang/janet
synced 2025-01-12 16:40:27 +00:00
Better working panic implementation and more cleanup in main vm loop.
This commit is contained in:
parent
cd6a7793e8
commit
5b62c8e6db
@ -681,7 +681,7 @@ const uint8_t *janet_formatc(const char *format, ...) {
|
||||
number_to_string_b(bufp, va_arg(args, double));
|
||||
break;
|
||||
case 'd':
|
||||
integer_to_string_b(bufp, va_arg(args, int32_t));
|
||||
integer_to_string_b(bufp, va_arg(args, long));
|
||||
break;
|
||||
case 'S':
|
||||
{
|
||||
@ -708,7 +708,7 @@ const uint8_t *janet_formatc(const char *format, ...) {
|
||||
}
|
||||
case 'T':
|
||||
{
|
||||
int types = va_arg(args, int32_t);
|
||||
int types = va_arg(args, long);
|
||||
pushtypes(bufp, types);
|
||||
break;
|
||||
}
|
||||
|
@ -145,13 +145,14 @@ int janet_compare(Janet x, Janet y) {
|
||||
return (janet_type(x) < janet_type(y)) ? -1 : 1;
|
||||
}
|
||||
|
||||
/* Gets a value and returns. If successful, return 0. If there is an error,
|
||||
* returns -1 for bad ds, -2 for bad key */
|
||||
int janet_get(Janet ds, Janet key, Janet *out) {
|
||||
/* Gets a value and returns. Can panic. */
|
||||
Janet janet_get(Janet ds, Janet key) {
|
||||
Janet value;
|
||||
switch (janet_type(ds)) {
|
||||
default:
|
||||
return -1;
|
||||
janet_panicf("get: expected %T, got %v", JANET_TFLAG_LENGTHABLE, ds);
|
||||
value = janet_wrap_nil();
|
||||
break;
|
||||
case JANET_STRUCT:
|
||||
value = janet_struct_get(janet_unwrap_struct(ds), key);
|
||||
break;
|
||||
@ -162,7 +163,8 @@ int janet_get(Janet ds, Janet key, Janet *out) {
|
||||
{
|
||||
JanetArray *array = janet_unwrap_array(ds);
|
||||
int32_t index;
|
||||
if (!janet_checkint(key)) return -2;
|
||||
if (!janet_checkint(key))
|
||||
janet_panic("expected integer key");
|
||||
index = janet_unwrap_integer(key);
|
||||
if (index < 0 || index >= array->count) {
|
||||
value = janet_wrap_nil();
|
||||
@ -175,10 +177,10 @@ int janet_get(Janet ds, Janet key, Janet *out) {
|
||||
{
|
||||
const Janet *tuple = janet_unwrap_tuple(ds);
|
||||
int32_t index;
|
||||
if (!janet_checkint(key)) return -2;
|
||||
if (!janet_checkint(key))
|
||||
janet_panic("expected integer key");
|
||||
index = janet_unwrap_integer(key);
|
||||
if (index < 0 || index >= janet_tuple_length(tuple)) {
|
||||
/*vm_throw("index out of bounds");*/
|
||||
value = janet_wrap_nil();
|
||||
} else {
|
||||
value = tuple[index];
|
||||
@ -189,7 +191,8 @@ int janet_get(Janet ds, Janet key, Janet *out) {
|
||||
{
|
||||
JanetBuffer *buffer = janet_unwrap_buffer(ds);
|
||||
int32_t index;
|
||||
if (!janet_checkint(key)) return -2;
|
||||
if (!janet_checkint(key))
|
||||
janet_panic("expected integer key");
|
||||
index = janet_unwrap_integer(key);
|
||||
if (index < 0 || index >= buffer->count) {
|
||||
value = janet_wrap_nil();
|
||||
@ -204,7 +207,8 @@ int janet_get(Janet ds, Janet key, Janet *out) {
|
||||
{
|
||||
const uint8_t *str = janet_unwrap_string(ds);
|
||||
int32_t index;
|
||||
if (!janet_checkint(key)) return -2;
|
||||
if (!janet_checkint(key))
|
||||
janet_panic("expected integer key");
|
||||
index = janet_unwrap_integer(key);
|
||||
if (index < 0 || index >= janet_string_length(str)) {
|
||||
value = janet_wrap_nil();
|
||||
@ -214,17 +218,17 @@ int janet_get(Janet ds, Janet key, Janet *out) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
*out = value;
|
||||
return 0;
|
||||
return value;
|
||||
}
|
||||
|
||||
int janet_getindex(Janet ds, int32_t index, Janet *out) {
|
||||
Janet janet_getindex(Janet ds, int32_t index) {
|
||||
Janet value;
|
||||
if (index < 0)
|
||||
return -2;
|
||||
if (index < 0) janet_panic("expected non-negative index");
|
||||
switch (janet_type(ds)) {
|
||||
default:
|
||||
return -1;
|
||||
janet_panicf("get: expected %T, got %v", JANET_TFLAG_LENGTHABLE, ds);
|
||||
value = janet_wrap_nil();
|
||||
break;
|
||||
case JANET_STRING:
|
||||
case JANET_SYMBOL:
|
||||
case JANET_KEYWORD:
|
||||
@ -262,44 +266,37 @@ int janet_getindex(Janet ds, int32_t index, Janet *out) {
|
||||
value = janet_struct_get(janet_unwrap_struct(ds), janet_wrap_integer(index));
|
||||
break;
|
||||
}
|
||||
*out = value;
|
||||
return 0;
|
||||
return value;
|
||||
}
|
||||
|
||||
int janet_length(Janet x, int32_t *out) {
|
||||
int32_t len;
|
||||
int32_t janet_length(Janet x) {
|
||||
switch (janet_type(x)) {
|
||||
default:
|
||||
return -1;
|
||||
janet_panicf("expected %T, got %v", JANET_TFLAG_LENGTHABLE, x);
|
||||
return 0;
|
||||
case JANET_STRING:
|
||||
case JANET_SYMBOL:
|
||||
case JANET_KEYWORD:
|
||||
len = janet_string_length(janet_unwrap_string(x));
|
||||
break;
|
||||
return janet_string_length(janet_unwrap_string(x));
|
||||
case JANET_ARRAY:
|
||||
len = janet_unwrap_array(x)->count;
|
||||
break;
|
||||
return janet_unwrap_array(x)->count;
|
||||
case JANET_BUFFER:
|
||||
len = janet_unwrap_buffer(x)->count;
|
||||
break;
|
||||
return janet_unwrap_buffer(x)->count;
|
||||
case JANET_TUPLE:
|
||||
len = janet_tuple_length(janet_unwrap_tuple(x));
|
||||
break;
|
||||
return janet_tuple_length(janet_unwrap_tuple(x));
|
||||
case JANET_STRUCT:
|
||||
len = janet_struct_length(janet_unwrap_struct(x));
|
||||
break;
|
||||
return janet_struct_length(janet_unwrap_struct(x));
|
||||
case JANET_TABLE:
|
||||
len = janet_unwrap_table(x)->count;
|
||||
break;
|
||||
return janet_unwrap_table(x)->count;
|
||||
}
|
||||
*out = len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int janet_putindex(Janet ds, int32_t index, Janet value) {
|
||||
void janet_putindex(Janet ds, int32_t index, Janet value) {
|
||||
switch (janet_type(ds)) {
|
||||
default:
|
||||
return -1;
|
||||
janet_panicf("expected %T, got %v",
|
||||
JANET_TFLAG_ARRAY | JANET_TFLAG_BUFFER | JANET_TFLAG_TABLE, ds);
|
||||
break;
|
||||
case JANET_ARRAY:
|
||||
{
|
||||
JanetArray *array = janet_unwrap_array(ds);
|
||||
@ -313,7 +310,8 @@ int janet_putindex(Janet ds, int32_t index, Janet value) {
|
||||
case JANET_BUFFER:
|
||||
{
|
||||
JanetBuffer *buffer = janet_unwrap_buffer(ds);
|
||||
if (!janet_checkint(value)) return -3;
|
||||
if (!janet_checkint(value))
|
||||
janet_panicf("can only put integers in buffers, got %v", value);
|
||||
if (index >= buffer->count) {
|
||||
janet_buffer_ensure(buffer, index + 1, 2);
|
||||
buffer->count = index + 1;
|
||||
@ -328,20 +326,21 @@ int janet_putindex(Janet ds, int32_t index, Janet value) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int janet_put(Janet ds, Janet key, Janet value) {
|
||||
void janet_put(Janet ds, Janet key, Janet value) {
|
||||
switch (janet_type(ds)) {
|
||||
default:
|
||||
return -1;
|
||||
janet_panicf("expected %T, got %v",
|
||||
JANET_TFLAG_ARRAY | JANET_TFLAG_BUFFER | JANET_TFLAG_TABLE, ds);
|
||||
break;
|
||||
case JANET_ARRAY:
|
||||
{
|
||||
int32_t index;
|
||||
JanetArray *array = janet_unwrap_array(ds);
|
||||
if (!janet_checkint(key)) return -2;
|
||||
if (!janet_checkint(key)) janet_panicf("expected integer key, got %v", key);
|
||||
index = janet_unwrap_integer(key);
|
||||
if (index < 0 || index == INT32_MAX) return -2;
|
||||
if (index < 0 || index == INT32_MAX) janet_panicf("bad integer key, got %v", key);
|
||||
if (index >= array->count) {
|
||||
janet_array_setcount(array, index + 1);
|
||||
}
|
||||
@ -352,10 +351,11 @@ int janet_put(Janet ds, Janet key, Janet value) {
|
||||
{
|
||||
int32_t index;
|
||||
JanetBuffer *buffer = janet_unwrap_buffer(ds);
|
||||
if (!janet_checkint(key)) return -2;
|
||||
if (!janet_checkint(key)) janet_panicf("expected integer key, got %v", key);
|
||||
index = janet_unwrap_integer(key);
|
||||
if (index < 0 || index == INT32_MAX) return -2;
|
||||
if (!janet_checkint(value)) return -3;
|
||||
if (index < 0 || index == INT32_MAX) janet_panicf("bad integer key, got %v", key);
|
||||
if (!janet_checkint(value))
|
||||
janet_panicf("can only put integers in buffers, got %v", value);
|
||||
if (index >= buffer->count) {
|
||||
janet_buffer_setcount(buffer, index + 1);
|
||||
}
|
||||
@ -366,5 +366,4 @@ int janet_put(Janet ds, Janet key, Janet value) {
|
||||
janet_table_put(janet_unwrap_table(ds), key, value);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
213
src/core/vm.c
213
src/core/vm.c
@ -162,16 +162,14 @@ static void *op_lookup[255] = {
|
||||
#define vm_assert(cond, e) do {if (!(cond)) vm_throw((e)); } while (0)
|
||||
#define vm_assert_type(X, T) do { \
|
||||
if (!(janet_checktype((X), (T)))) { \
|
||||
expected_types = 1 << (T); \
|
||||
retreg = (X); \
|
||||
goto vm_type_error; \
|
||||
vm_commit(); \
|
||||
janet_panicf("expected %T, got %t", (1 << (T)), (X)); \
|
||||
} \
|
||||
} while (0)
|
||||
#define vm_assert_types(X, TS) do { \
|
||||
if (!(janet_checktypes((X), (TS)))) { \
|
||||
expected_types = (TS); \
|
||||
retreg = (X); \
|
||||
goto vm_type_error; \
|
||||
vm_commit(); \
|
||||
janet_panicf("expected %T, got %t", (TS), (X)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
@ -223,14 +221,13 @@ static void *op_lookup[255] = {
|
||||
|
||||
/* Call a non function type */
|
||||
static Janet call_nonfn(JanetFiber *fiber, Janet callee) {
|
||||
int status;
|
||||
int32_t argn = fiber->stacktop - fiber->stackstart;
|
||||
Janet ds, key, ret;
|
||||
Janet ds, key;
|
||||
if (!janet_checktypes(callee, JANET_TFLAG_FUNCLIKE)) {
|
||||
janet_panicf("attempted to called %v, expected %t", callee,
|
||||
janet_panicf("attempted to call %v, expected %T", callee,
|
||||
JANET_TFLAG_CALLABLE);
|
||||
}
|
||||
if (argn != 1) janet_panicf("%v called with arity %d, expected 1", argn);
|
||||
if (argn != 1) janet_panicf("%v called with arity %d, expected 1", callee, argn);
|
||||
if (janet_checktypes(callee, JANET_TFLAG_INDEXED | JANET_TFLAG_DICTIONARY)) {
|
||||
ds = callee;
|
||||
key = fiber->data[fiber->stackstart];
|
||||
@ -239,13 +236,7 @@ static Janet call_nonfn(JanetFiber *fiber, Janet callee) {
|
||||
key = callee;
|
||||
}
|
||||
fiber->stacktop = fiber->stackstart;
|
||||
status = janet_get(ds, key, &ret);
|
||||
if (status == -2) {
|
||||
janet_panic("expected integer key");
|
||||
} else if (status == -1) {
|
||||
janet_panic("expected table or struct");
|
||||
}
|
||||
return ret;
|
||||
return janet_get(ds, key);
|
||||
}
|
||||
|
||||
/* Interpreter main loop */
|
||||
@ -256,13 +247,6 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in) {
|
||||
register uint32_t *pc;
|
||||
register JanetFunction *func;
|
||||
vm_restore();
|
||||
|
||||
/* Keep in mind the garbage collector cannot see this value.
|
||||
* Values stored here should be used immediately */
|
||||
Janet retreg;
|
||||
|
||||
/* Expected types on type error */
|
||||
uint16_t expected_types;
|
||||
|
||||
/* Only should be hit if the fiber is either waiting for a child, or
|
||||
* waiting to be resumed. In those cases, use input and increment pc. We
|
||||
@ -292,22 +276,31 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in) {
|
||||
vm_pcnext();
|
||||
|
||||
VM_OP(JOP_ERROR)
|
||||
janet_panicv(stack[A]);
|
||||
vm_next(); /* pacify compiler warnings */
|
||||
vm_return(JANET_SIGNAL_ERROR, stack[A]);
|
||||
|
||||
VM_OP(JOP_TYPECHECK)
|
||||
if (!janet_checktypes(stack[A], E)) {
|
||||
janet_panicf("expected %T, got %t", E, stack[A]);
|
||||
}
|
||||
vm_assert_types(stack[A], E);
|
||||
vm_pcnext();
|
||||
|
||||
VM_OP(JOP_RETURN)
|
||||
retreg = stack[D];
|
||||
goto vm_handle_return;
|
||||
{
|
||||
Janet retval = stack[D];
|
||||
janet_fiber_popframe(fiber);
|
||||
if (fiber->frame == 0) vm_return(JANET_SIGNAL_OK, retval);
|
||||
vm_restore();
|
||||
stack[A] = retval;
|
||||
vm_checkgc_pcnext();
|
||||
}
|
||||
|
||||
VM_OP(JOP_RETURN_NIL)
|
||||
retreg = janet_wrap_nil();
|
||||
goto vm_handle_return;
|
||||
{
|
||||
Janet retval = janet_wrap_nil();
|
||||
janet_fiber_popframe(fiber);
|
||||
if (fiber->frame == 0) vm_return(JANET_SIGNAL_OK, retval);
|
||||
vm_restore();
|
||||
stack[A] = retval;
|
||||
vm_checkgc_pcnext();
|
||||
}
|
||||
|
||||
VM_OP(JOP_ADD_IMMEDIATE)
|
||||
vm_binop_immediate(+);
|
||||
@ -555,9 +548,7 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in) {
|
||||
if (janet_indexed_view(stack[D], &vals, &len)) {
|
||||
janet_fiber_pushn(fiber, vals, len);
|
||||
} else {
|
||||
retreg = stack[D];
|
||||
expected_types = JANET_TFLAG_INDEXED;
|
||||
goto vm_type_error;
|
||||
janet_panicf("expected %T, got %t", JANET_TFLAG_INDEXED, stack[D]);
|
||||
}
|
||||
}
|
||||
stack = fiber->data + fiber->frame;
|
||||
@ -582,12 +573,12 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in) {
|
||||
vm_checkgc_next();
|
||||
} else if (janet_checktype(callee, JANET_CFUNCTION)) {
|
||||
JanetArgs args;
|
||||
Janet retreg = janet_wrap_nil();
|
||||
vm_commit();
|
||||
args.n = fiber->stacktop - fiber->stackstart;
|
||||
janet_fiber_cframe(fiber, janet_unwrap_cfunction(callee));
|
||||
retreg = janet_wrap_nil();
|
||||
args.v = fiber->data + fiber->frame;
|
||||
args.ret = &retreg;
|
||||
vm_commit();
|
||||
if (janet_unwrap_cfunction(callee)(args)) janet_panicv(retreg);
|
||||
janet_fiber_popframe(fiber);
|
||||
if (fiber->frame == 0) vm_return(JANET_SIGNAL_OK, retreg);
|
||||
@ -614,30 +605,34 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in) {
|
||||
stack = fiber->data + fiber->frame;
|
||||
pc = func->def->bytecode;
|
||||
vm_checkgc_next();
|
||||
} else if (janet_checktype(callee, JANET_CFUNCTION)) {
|
||||
JanetArgs args;
|
||||
args.n = fiber->stacktop - fiber->stackstart;
|
||||
janet_fiber_cframe(fiber, janet_unwrap_cfunction(callee));
|
||||
retreg = janet_wrap_nil();
|
||||
args.v = fiber->data + fiber->frame;
|
||||
args.ret = &retreg;
|
||||
vm_commit();
|
||||
if (janet_unwrap_cfunction(callee)(args))
|
||||
vm_return(JANET_SIGNAL_ERROR, retreg);
|
||||
janet_fiber_popframe(fiber);
|
||||
} else {
|
||||
vm_commit();
|
||||
retreg = call_nonfn(fiber, callee);
|
||||
Janet retreg = janet_wrap_nil();
|
||||
if (janet_checktype(callee, JANET_CFUNCTION)) {
|
||||
JanetArgs args;
|
||||
vm_commit();
|
||||
args.n = fiber->stacktop - fiber->stackstart;
|
||||
janet_fiber_cframe(fiber, janet_unwrap_cfunction(callee));
|
||||
args.v = fiber->data + fiber->frame;
|
||||
args.ret = &retreg;
|
||||
if (janet_unwrap_cfunction(callee)(args))
|
||||
vm_return(JANET_SIGNAL_ERROR, retreg);
|
||||
janet_fiber_popframe(fiber);
|
||||
} else {
|
||||
vm_commit();
|
||||
retreg = call_nonfn(fiber, callee);
|
||||
}
|
||||
janet_fiber_popframe(fiber);
|
||||
if (fiber->frame == 0)
|
||||
vm_return(JANET_SIGNAL_OK, retreg);
|
||||
vm_restore();
|
||||
stack[A] = retreg;
|
||||
vm_checkgc_pcnext();
|
||||
}
|
||||
/* Make it a tail call */
|
||||
janet_fiber_popframe(fiber);
|
||||
if (fiber->frame == 0)
|
||||
vm_return(JANET_SIGNAL_OK, retreg);
|
||||
goto vm_reset;
|
||||
}
|
||||
|
||||
VM_OP(JOP_RESUME)
|
||||
{
|
||||
Janet retreg;
|
||||
vm_assert_type(stack[B], JANET_FIBER);
|
||||
JanetFiber *child = janet_unwrap_fiber(stack[B]);
|
||||
fiber->child = child;
|
||||
@ -658,78 +653,24 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in) {
|
||||
}
|
||||
|
||||
VM_OP(JOP_PUT)
|
||||
{
|
||||
Janet ds = stack[A];
|
||||
Janet key = stack[B];
|
||||
Janet value = stack[C];
|
||||
int status = janet_put(ds, key, value);
|
||||
if (status == -1) {
|
||||
expected_types = JANET_TFLAG_ARRAY | JANET_TFLAG_BUFFER | JANET_TFLAG_TABLE;
|
||||
retreg = ds;
|
||||
goto vm_type_error;
|
||||
} else if (status == -2) {
|
||||
vm_throw("expected integer key for data structure");
|
||||
} else if (status == -3) {
|
||||
vm_throw("expected integer value for data structure");
|
||||
}
|
||||
vm_checkgc_pcnext();
|
||||
}
|
||||
janet_put(stack[A], stack[B], stack[C]);
|
||||
vm_checkgc_pcnext();
|
||||
|
||||
VM_OP(JOP_PUT_INDEX)
|
||||
{
|
||||
Janet ds = stack[A];
|
||||
Janet value = stack[B];
|
||||
int32_t index = (int32_t)C;
|
||||
int status = janet_putindex(ds, index, value);
|
||||
if (status == -1) {
|
||||
expected_types = JANET_TFLAG_ARRAY | JANET_TFLAG_BUFFER | JANET_TFLAG_TABLE;
|
||||
retreg = ds;
|
||||
goto vm_type_error;
|
||||
} else if (status == -3) {
|
||||
vm_throw("expected integer value for data structure");
|
||||
}
|
||||
vm_checkgc_pcnext();
|
||||
}
|
||||
janet_putindex(stack[A], C, stack[B]);
|
||||
vm_checkgc_pcnext();
|
||||
|
||||
VM_OP(JOP_GET)
|
||||
{
|
||||
Janet ds = stack[B];
|
||||
Janet key = stack[C];
|
||||
int status = janet_get(ds, key, stack + A);
|
||||
if (status == -1) {
|
||||
expected_types = JANET_TFLAG_LENGTHABLE;
|
||||
retreg = ds;
|
||||
goto vm_type_error;
|
||||
} else if (status == -2) {
|
||||
vm_throw("expected integer key for data structure");
|
||||
}
|
||||
vm_pcnext();
|
||||
}
|
||||
stack[A] = janet_get(stack[B], stack[C]);
|
||||
vm_pcnext();
|
||||
|
||||
VM_OP(JOP_GET_INDEX)
|
||||
{
|
||||
Janet ds = stack[B];
|
||||
int32_t index = C;
|
||||
if (janet_getindex(ds, index, stack + A)) {
|
||||
expected_types = JANET_TFLAG_LENGTHABLE;
|
||||
retreg = ds;
|
||||
goto vm_type_error;
|
||||
}
|
||||
vm_pcnext();
|
||||
}
|
||||
stack[A] = janet_getindex(stack[B], C);
|
||||
vm_pcnext();
|
||||
|
||||
VM_OP(JOP_LENGTH)
|
||||
{
|
||||
Janet x = stack[E];
|
||||
int32_t len;
|
||||
if (janet_length(x, &len)) {
|
||||
expected_types = JANET_TFLAG_LENGTHABLE;
|
||||
retreg = x;
|
||||
goto vm_type_error;
|
||||
}
|
||||
stack[A] = janet_wrap_integer(len);
|
||||
vm_pcnext();
|
||||
}
|
||||
stack[A] = janet_wrap_integer(janet_length(stack[E]));
|
||||
vm_pcnext();
|
||||
|
||||
VM_OP(JOP_MAKE_ARRAY)
|
||||
{
|
||||
@ -803,38 +744,6 @@ static JanetSignal run_vm(JanetFiber *fiber, Janet in) {
|
||||
vm_checkgc_pcnext();
|
||||
}
|
||||
|
||||
/* Handle returning from stack frame. Expect return value in retreg */
|
||||
vm_handle_return:
|
||||
{
|
||||
janet_fiber_popframe(fiber);
|
||||
if (fiber->frame == 0) vm_return(JANET_SIGNAL_OK, retreg);
|
||||
goto vm_reset;
|
||||
}
|
||||
|
||||
/* Handle type errors. The found type is the type of retreg,
|
||||
* the expected types are in the expected_types field. */
|
||||
vm_type_error:
|
||||
{
|
||||
JanetBuffer errbuf;
|
||||
const uint8_t *message;
|
||||
janet_buffer_init(&errbuf, 10);
|
||||
janet_buffer_push_cstring(&errbuf, "expected ");
|
||||
janet_buffer_push_types(&errbuf, expected_types);
|
||||
janet_buffer_push_cstring(&errbuf, ", got ");
|
||||
janet_buffer_push_cstring(&errbuf, janet_type_names[janet_type(retreg)]);
|
||||
message = janet_string(errbuf.data, errbuf.count);
|
||||
janet_buffer_deinit(&errbuf);
|
||||
janet_panics(message);
|
||||
}
|
||||
|
||||
/* Reset state of machine */
|
||||
vm_reset:
|
||||
{
|
||||
vm_restore();
|
||||
stack[A] = retreg;
|
||||
vm_checkgc_pcnext();
|
||||
}
|
||||
|
||||
VM_END()
|
||||
}
|
||||
|
||||
|
@ -1094,11 +1094,11 @@ JANET_API int32_t janet_hash(Janet x);
|
||||
JANET_API int janet_compare(Janet x, Janet y);
|
||||
JANET_API int janet_cstrcmp(const uint8_t *str, const char *other);
|
||||
JANET_API JanetBuffer *janet_pretty(JanetBuffer *buffer, int depth, Janet x);
|
||||
JANET_API int janet_get(Janet ds, Janet key, Janet *out);
|
||||
JANET_API int janet_getindex(Janet ds, int32_t index, Janet *out);
|
||||
JANET_API int janet_length(Janet x, int32_t *out);
|
||||
JANET_API int janet_put(Janet ds, Janet key, Janet value);
|
||||
JANET_API int janet_putindex(Janet ds, int32_t index, Janet value);
|
||||
JANET_API Janet janet_get(Janet ds, Janet key);
|
||||
JANET_API Janet janet_getindex(Janet ds, int32_t index);
|
||||
JANET_API int32_t janet_length(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);
|
||||
JANET_API void janet_inspect(Janet x);
|
||||
|
||||
/* VM functions */
|
||||
@ -1132,7 +1132,7 @@ JANET_API int janet_typeabstract_err(JanetArgs args, int32_t n, const JanetAbstr
|
||||
JANET_API void janet_panicv(Janet message);
|
||||
JANET_API void janet_panic(const char *message);
|
||||
JANET_API void janet_panics(const uint8_t *message);
|
||||
#define janet_panicf(message, ...) janet_panics(janet_formatc(message, __VA_ARGS__))
|
||||
#define janet_panicf(...) janet_panics(janet_formatc(__VA_ARGS__))
|
||||
JANET_API void janet_panic_type(Janet x, int32_t n, int expected);
|
||||
|
||||
/* Helpers for writing modules */
|
||||
|
@ -110,5 +110,6 @@
|
||||
(assert (= 2 (@{:ok 2} :ok)) "calling table")
|
||||
(assert (= :bad (try (@{:ok 2} :ok :no) ([err] :bad))) "calling table too many arguments")
|
||||
(assert (= :bad (try (:ok @{:ok 2} :no) ([err] :bad))) "calling keyword too many arguments")
|
||||
(assert (= :oops (try (1 1) ([err] :oops))) "calling number fails")
|
||||
|
||||
(end-suite)
|
||||
|
Loading…
Reference in New Issue
Block a user