Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions api-test.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <stdlib.h>
#include <string.h>
#include "quickjs.h"
#include "cutils.h"

#define MAX_TIME 10

Expand Down Expand Up @@ -506,6 +507,44 @@ static void dump_memory_usage(void)
JS_FreeRuntime(rt);
}

static void new_errors(void)
{
typedef struct {
const char name[16];
JSValue (*func)(JSContext *, const char *, ...);
} Entry;
static const Entry entries[] = {
{"Error", JS_NewPlainError},
{"InternalError", JS_NewInternalError},
{"RangeError", JS_NewRangeError},
{"ReferenceError", JS_NewReferenceError},
{"SyntaxError", JS_NewSyntaxError},
{"TypeError", JS_NewTypeError},
};
const Entry *e;

JSRuntime *rt = JS_NewRuntime();
JSContext *ctx = JS_NewContext(rt);
for (e = entries; e < endof(entries); e++) {
JSValue obj = (*e->func)(ctx, "the %s", "needle");
assert(!JS_IsException(obj));
assert(JS_IsObject(obj));
assert(JS_IsError(ctx, obj));
const char *haystack = JS_ToCString(ctx, obj);
char needle[256];
snprintf(needle, sizeof(needle), "%s: the needle", e->name);
assert(strstr(haystack, needle));
JS_FreeCString(ctx, haystack);
JSValue stack = JS_GetPropertyStr(ctx, obj, "stack");
assert(!JS_IsException(stack));
assert(JS_IsString(stack));
JS_FreeValue(ctx, stack);
JS_FreeValue(ctx, obj);
}
JS_FreeContext(ctx);
JS_FreeRuntime(rt);
}

int main(void)
{
sync_call();
Expand All @@ -518,5 +557,6 @@ int main(void)
weak_map_gc_check();
promise_hook();
dump_memory_usage();
new_errors();
return 0;
}
130 changes: 56 additions & 74 deletions quickjs.c
Original file line number Diff line number Diff line change
Expand Up @@ -6947,8 +6947,8 @@ JSValue JS_NewError(JSContext *ctx)
return obj;
}

static JSValue JS_MakeError(JSContext *ctx, JSErrorEnum error_num,
const char *message, bool add_backtrace)
static JSValue JS_MakeError2(JSContext *ctx, JSErrorEnum error_num,
bool add_backtrace, const char *message)
{
JSValue obj, msg;

Expand All @@ -6972,16 +6972,24 @@ static JSValue JS_MakeError(JSContext *ctx, JSErrorEnum error_num,
return obj;
}

/* fmt and arguments may be pure ASCII or UTF-8 encoded contents */
static JSValue JS_PRINTF_FORMAT_ATTR(4, 0)
JS_ThrowError2(JSContext *ctx, JSErrorEnum error_num,
bool add_backtrace, JS_PRINTF_FORMAT const char *fmt, va_list ap)
JS_MakeError(JSContext *ctx, JSErrorEnum error_num, bool add_backtrace,
JS_PRINTF_FORMAT const char *fmt, va_list ap)
{
char buf[256];
JSValue obj;

vsnprintf(buf, sizeof(buf), fmt, ap);
obj = JS_MakeError(ctx, error_num, buf, add_backtrace);
return JS_MakeError2(ctx, error_num, add_backtrace, buf);
}

/* fmt and arguments may be pure ASCII or UTF-8 encoded contents */
static JSValue JS_PRINTF_FORMAT_ATTR(4, 0)
JS_ThrowError2(JSContext *ctx, JSErrorEnum error_num, bool add_backtrace,
JS_PRINTF_FORMAT const char *fmt, va_list ap)
{
JSValue obj;

obj = JS_MakeError(ctx, error_num, add_backtrace, fmt, ap);
if (unlikely(JS_IsException(obj))) {
/* out of memory: throw JS_NULL to avoid recursing */
obj = JS_NULL;
Expand All @@ -7004,38 +7012,45 @@ JS_ThrowError(JSContext *ctx, JSErrorEnum error_num,
return JS_ThrowError2(ctx, error_num, add_backtrace, fmt, ap);
}

JSValue JS_PRINTF_FORMAT_ATTR(2, 3) JS_ThrowPlainError(JSContext *ctx, JS_PRINTF_FORMAT const char *fmt, ...)
{
JSValue val;
va_list ap;

va_start(ap, fmt);
val = JS_ThrowError(ctx, JS_PLAIN_ERROR, fmt, ap);
va_end(ap);
return val;
}

JSValue JS_PRINTF_FORMAT_ATTR(2, 3) JS_ThrowSyntaxError(JSContext *ctx, JS_PRINTF_FORMAT const char *fmt, ...)
{
JSValue val;
va_list ap;

va_start(ap, fmt);
val = JS_ThrowError(ctx, JS_SYNTAX_ERROR, fmt, ap);
va_end(ap);
return val;
}

JSValue JS_PRINTF_FORMAT_ATTR(2, 3) JS_ThrowTypeError(JSContext *ctx, JS_PRINTF_FORMAT const char *fmt, ...)
{
JSValue val;
va_list ap;

va_start(ap, fmt);
val = JS_ThrowError(ctx, JS_TYPE_ERROR, fmt, ap);
va_end(ap);
return val;
}
#define JS_ERROR_MAP(X) \
X(Internal, INTERNAL) \
X(Plain, PLAIN) \
X(Range, RANGE) \
X(Reference, REFERENCE) \
X(Syntax, SYNTAX) \
X(Type, TYPE) \

#define X(lc, uc) \
JSValue JS_PRINTF_FORMAT_ATTR(2, 3) \
JS_New##lc##Error(JSContext *ctx, \
JS_PRINTF_FORMAT const char *fmt, ...) \
{ \
JSValue val; \
va_list ap; \
\
va_start(ap, fmt); \
val = JS_MakeError(ctx, JS_##uc##_ERROR, \
/*add_backtrace*/true, fmt, ap); \
va_end(ap); \
return val; \
} \
JSValue JS_PRINTF_FORMAT_ATTR(2, 3) \
JS_Throw##lc##Error(JSContext *ctx, \
JS_PRINTF_FORMAT const char *fmt, ...) \
{ \
JSValue val; \
va_list ap; \
\
va_start(ap, fmt); \
val = JS_ThrowError(ctx, JS_##uc##_ERROR, fmt, ap); \
va_end(ap); \
return val; \
} \

JS_ERROR_MAP(X)

#undef X
#undef JS_ERROR_MAP

static int JS_PRINTF_FORMAT_ATTR(3, 4) JS_ThrowTypeErrorOrFalse(JSContext *ctx, int flags, JS_PRINTF_FORMAT const char *fmt, ...)
{
Expand Down Expand Up @@ -7084,39 +7099,6 @@ static int JS_ThrowTypeErrorReadOnly(JSContext *ctx, int flags, JSAtom atom)
}
}

JSValue JS_PRINTF_FORMAT_ATTR(2, 3) JS_ThrowReferenceError(JSContext *ctx, JS_PRINTF_FORMAT const char *fmt, ...)
{
JSValue val;
va_list ap;

va_start(ap, fmt);
val = JS_ThrowError(ctx, JS_REFERENCE_ERROR, fmt, ap);
va_end(ap);
return val;
}

JSValue JS_PRINTF_FORMAT_ATTR(2, 3) JS_ThrowRangeError(JSContext *ctx, JS_PRINTF_FORMAT const char *fmt, ...)
{
JSValue val;
va_list ap;

va_start(ap, fmt);
val = JS_ThrowError(ctx, JS_RANGE_ERROR, fmt, ap);
va_end(ap);
return val;
}

JSValue JS_PRINTF_FORMAT_ATTR(2, 3) JS_ThrowInternalError(JSContext *ctx, JS_PRINTF_FORMAT const char *fmt, ...)
{
JSValue val;
va_list ap;

va_start(ap, fmt);
val = JS_ThrowError(ctx, JS_INTERNAL_ERROR, fmt, ap);
va_end(ap);
return val;
}

JSValue JS_ThrowOutOfMemory(JSContext *ctx)
{
JSRuntime *rt = ctx->rt;
Expand Down Expand Up @@ -51457,8 +51439,8 @@ static JSValue js_async_from_sync_iterator_next(JSContext *ctx, JSValueConst thi
err = JS_GetException(ctx);
is_reject = 1;
} else {
err = JS_MakeError(ctx, JS_TYPE_ERROR, "throw is not a method",
true);
err = JS_MakeError2(ctx, JS_TYPE_ERROR, /*add_backtrace*/true,
"throw is not a method");
is_reject = 1;
}
goto done_resolve;
Expand Down
12 changes: 9 additions & 3 deletions quickjs.h
Original file line number Diff line number Diff line change
Expand Up @@ -756,12 +756,18 @@ JS_EXTERN void JS_ClearUncatchableError(JSContext *ctx, JSValueConst val);
// JS_Throw(ctx, exc);
JS_EXTERN void JS_ResetUncatchableError(JSContext *ctx);
JS_EXTERN JSValue JS_NewError(JSContext *ctx);
JS_EXTERN JSValue JS_PRINTF_FORMAT_ATTR(2, 3) JS_NewInternalError(JSContext *ctx, JS_PRINTF_FORMAT const char *fmt, ...);
JS_EXTERN JSValue JS_PRINTF_FORMAT_ATTR(2, 3) JS_NewPlainError(JSContext *ctx, JS_PRINTF_FORMAT const char *fmt, ...);
JS_EXTERN JSValue JS_PRINTF_FORMAT_ATTR(2, 3) JS_NewRangeError(JSContext *ctx, JS_PRINTF_FORMAT const char *fmt, ...);
JS_EXTERN JSValue JS_PRINTF_FORMAT_ATTR(2, 3) JS_NewReferenceError(JSContext *ctx, JS_PRINTF_FORMAT const char *fmt, ...);
JS_EXTERN JSValue JS_PRINTF_FORMAT_ATTR(2, 3) JS_NewSyntaxError(JSContext *ctx, JS_PRINTF_FORMAT const char *fmt, ...);
JS_EXTERN JSValue JS_PRINTF_FORMAT_ATTR(2, 3) JS_NewTypeError(JSContext *ctx, JS_PRINTF_FORMAT const char *fmt, ...);
JS_EXTERN JSValue JS_PRINTF_FORMAT_ATTR(2, 3) JS_ThrowInternalError(JSContext *ctx, JS_PRINTF_FORMAT const char *fmt, ...);
JS_EXTERN JSValue JS_PRINTF_FORMAT_ATTR(2, 3) JS_ThrowPlainError(JSContext *ctx, JS_PRINTF_FORMAT const char *fmt, ...);
JS_EXTERN JSValue JS_PRINTF_FORMAT_ATTR(2, 3) JS_ThrowRangeError(JSContext *ctx, JS_PRINTF_FORMAT const char *fmt, ...);
JS_EXTERN JSValue JS_PRINTF_FORMAT_ATTR(2, 3) JS_ThrowReferenceError(JSContext *ctx, JS_PRINTF_FORMAT const char *fmt, ...);
JS_EXTERN JSValue JS_PRINTF_FORMAT_ATTR(2, 3) JS_ThrowSyntaxError(JSContext *ctx, JS_PRINTF_FORMAT const char *fmt, ...);
JS_EXTERN JSValue JS_PRINTF_FORMAT_ATTR(2, 3) JS_ThrowTypeError(JSContext *ctx, JS_PRINTF_FORMAT const char *fmt, ...);
JS_EXTERN JSValue JS_PRINTF_FORMAT_ATTR(2, 3) JS_ThrowReferenceError(JSContext *ctx, JS_PRINTF_FORMAT const char *fmt, ...);
JS_EXTERN JSValue JS_PRINTF_FORMAT_ATTR(2, 3) JS_ThrowRangeError(JSContext *ctx, JS_PRINTF_FORMAT const char *fmt, ...);
JS_EXTERN JSValue JS_PRINTF_FORMAT_ATTR(2, 3) JS_ThrowInternalError(JSContext *ctx, JS_PRINTF_FORMAT const char *fmt, ...);
JS_EXTERN JSValue JS_ThrowOutOfMemory(JSContext *ctx);
JS_EXTERN void JS_FreeValue(JSContext *ctx, JSValue v);
JS_EXTERN void JS_FreeValueRT(JSRuntime *rt, JSValue v);
Expand Down
Loading