mirror of
https://github.com/ccxvii/mujs.git
synced 2026-09-23 16:53:35 +08:00
Clean up error object creation and throwing functions.
This commit is contained in:
@@ -18,9 +18,6 @@ void js_gc(js_State *J, int report);
|
||||
|
||||
const char *js_intern(js_State *J, const char *s);
|
||||
|
||||
/* Push a new Error object with the formatted message and throw it */
|
||||
JS_NORETURN void js_error(js_State *J, const char *fmt, ...) JS_PRINTFLIKE(2,3);
|
||||
|
||||
/* Property attribute flags */
|
||||
enum {
|
||||
JS_READONLY = 1,
|
||||
@@ -28,6 +25,21 @@ enum {
|
||||
JS_DONTDELETE = 4,
|
||||
};
|
||||
|
||||
void js_newerror(js_State *J, const char *message);
|
||||
void js_newevalerror(js_State *J, const char *message);
|
||||
void js_newrangeerror(js_State *J, const char *message);
|
||||
void js_newreferenceerror(js_State *J, const char *message);
|
||||
void js_newsyntaxerror(js_State *J, const char *message);
|
||||
void js_newtypeerror(js_State *J, const char *message);
|
||||
void js_newurierror(js_State *J, const char *message);
|
||||
|
||||
JS_NORETURN void js_error(js_State *J, const char *fmt, ...) JS_PRINTFLIKE(2,3);
|
||||
JS_NORETURN void js_evalerror(js_State *J, const char *fmt, ...) JS_PRINTFLIKE(2,3);
|
||||
JS_NORETURN void js_rangeerror(js_State *J, const char *fmt, ...) JS_PRINTFLIKE(2,3);
|
||||
JS_NORETURN void js_referenceerror(js_State *J, const char *fmt, ...) JS_PRINTFLIKE(2,3);
|
||||
JS_NORETURN void js_syntaxerror(js_State *J, const char *fmt, ...) JS_PRINTFLIKE(2,3);
|
||||
JS_NORETURN void js_typeerror(js_State *J, const char *fmt, ...) JS_PRINTFLIKE(2,3);
|
||||
JS_NORETURN void js_urierror(js_State *J, const char *fmt, ...) JS_PRINTFLIKE(2,3);
|
||||
JS_NORETURN void js_throw(js_State *J);
|
||||
|
||||
void js_loadstring(js_State *J, const char *filename, const char *source);
|
||||
|
||||
+2
-2
@@ -17,7 +17,7 @@ static int jsB_Boolean(js_State *J, int n)
|
||||
static int Bp_toString(js_State *J, int n)
|
||||
{
|
||||
js_Object *self = js_toobject(J, 0);
|
||||
if (self->type != JS_CBOOLEAN) jsR_throwTypeError(J, "not a boolean");
|
||||
if (self->type != JS_CBOOLEAN) js_typeerror(J, "not a boolean");
|
||||
js_pushliteral(J, self->u.boolean ? "true" : "false");
|
||||
return 1;
|
||||
}
|
||||
@@ -25,7 +25,7 @@ static int Bp_toString(js_State *J, int n)
|
||||
static int Bp_valueOf(js_State *J, int n)
|
||||
{
|
||||
js_Object *self = js_toobject(J, 0);
|
||||
if (self->type != JS_CBOOLEAN) jsR_throwTypeError(J, "not a boolean");
|
||||
if (self->type != JS_CBOOLEAN) js_typeerror(J, "not a boolean");
|
||||
js_pushboolean(J, self->u.boolean);
|
||||
return 1;
|
||||
}
|
||||
|
||||
+23
-35
@@ -2,6 +2,9 @@
|
||||
#include "jsvalue.h"
|
||||
#include "jsbuiltin.h"
|
||||
|
||||
#define QQ(X) #X
|
||||
#define Q(X) QQ(X)
|
||||
|
||||
static int Ep_toString(js_State *J, int n)
|
||||
{
|
||||
js_getproperty(J, 0, "name");
|
||||
@@ -12,9 +15,6 @@ static int Ep_toString(js_State *J, int n)
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define STRSTR(X) #X
|
||||
#define STR(X) STRSTR(X)
|
||||
|
||||
#define DECL(NAME) \
|
||||
static int jsB_new_##NAME(js_State *J, int n) { \
|
||||
js_pushobject(J, jsV_newobject(J, JS_CERROR, J->NAME##_prototype)); \
|
||||
@@ -32,22 +32,6 @@ static int Ep_toString(js_State *J, int n)
|
||||
} \
|
||||
return 1; \
|
||||
} \
|
||||
static void jsB_init##NAME(js_State *J) { \
|
||||
js_pushobject(J, J->NAME##_prototype); \
|
||||
{ \
|
||||
jsB_props(J, "name", STR(NAME)); \
|
||||
jsB_props(J, "message", "an error has occurred"); \
|
||||
jsB_propf(J, "toString", Ep_toString, 0); \
|
||||
} \
|
||||
js_newcconstructor(J, jsB_##NAME, jsB_new_##NAME); \
|
||||
js_setglobal(J, STR(NAME)); \
|
||||
} \
|
||||
void jsR_throw##NAME(js_State *J, const char *message) { \
|
||||
js_pushobject(J, jsV_newobject(J, JS_CERROR, J->NAME##_prototype)); \
|
||||
js_pushstring(J, message); \
|
||||
js_setproperty(J, -2, "message"); \
|
||||
js_throw(J); \
|
||||
} \
|
||||
|
||||
DECL(Error);
|
||||
DECL(EvalError);
|
||||
@@ -59,21 +43,25 @@ DECL(URIError);
|
||||
|
||||
void jsB_initerror(js_State *J)
|
||||
{
|
||||
jsB_initError(J);
|
||||
jsB_initEvalError(J);
|
||||
jsB_initRangeError(J);
|
||||
jsB_initReferenceError(J);
|
||||
jsB_initSyntaxError(J);
|
||||
jsB_initTypeError(J);
|
||||
jsB_initURIError(J);
|
||||
}
|
||||
js_pushobject(J, J->Error_prototype);
|
||||
{
|
||||
jsB_props(J, "name", "Error");
|
||||
jsB_props(J, "message", "an error has occurred");
|
||||
jsB_propf(J, "toString", Ep_toString, 0);
|
||||
}
|
||||
js_newcconstructor(J, jsB_Error, jsB_new_Error);
|
||||
js_setglobal(J, "Error");
|
||||
|
||||
void js_error(js_State *J, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char buf[256];
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(buf, sizeof buf, fmt, ap);
|
||||
va_end(ap);
|
||||
jsR_throwError(J, buf);
|
||||
#define INIT(NAME) \
|
||||
js_pushobject(J, J->NAME##_prototype); \
|
||||
jsB_props(J, "name", Q(NAME)); \
|
||||
js_newcconstructor(J, jsB_##NAME, jsB_new_##NAME); \
|
||||
js_setglobal(J, Q(NAME));
|
||||
|
||||
INIT(EvalError);
|
||||
INIT(RangeError);
|
||||
INIT(ReferenceError);
|
||||
INIT(SyntaxError);
|
||||
INIT(TypeError);
|
||||
INIT(URIError);
|
||||
}
|
||||
|
||||
+3
-3
@@ -19,7 +19,7 @@ static int Fp_toString(js_State *J, int nargs)
|
||||
int i, n;
|
||||
|
||||
if (!js_iscallable(J, 0))
|
||||
jsR_throwTypeError(J, "not a function");
|
||||
js_typeerror(J, "not a function");
|
||||
|
||||
if (self->type == JS_CFUNCTION || self->type == JS_CSCRIPT) {
|
||||
js_Function *F = self->u.f.function;
|
||||
@@ -51,7 +51,7 @@ static int Fp_apply(js_State *J, int n)
|
||||
char name[20];
|
||||
|
||||
if (!js_iscallable(J, 0))
|
||||
jsR_throwTypeError(J, "not a function");
|
||||
js_typeerror(J, "not a function");
|
||||
|
||||
js_copy(J, 0);
|
||||
js_copy(J, 1);
|
||||
@@ -74,7 +74,7 @@ static int Fp_call(js_State *J, int n)
|
||||
int i;
|
||||
|
||||
if (!js_iscallable(J, 0))
|
||||
jsR_throwTypeError(J, "not a function");
|
||||
js_typeerror(J, "not a function");
|
||||
|
||||
js_copy(J, 0);
|
||||
js_copy(J, 1);
|
||||
|
||||
+5
-5
@@ -17,7 +17,7 @@ static int jsB_Number(js_State *J, int n)
|
||||
static int Np_valueOf(js_State *J, int n)
|
||||
{
|
||||
js_Object *self = js_toobject(J, 0);
|
||||
if (self->type != JS_CNUMBER) jsR_throwTypeError(J, "not a number");
|
||||
if (self->type != JS_CNUMBER) js_typeerror(J, "not a number");
|
||||
js_pushnumber(J, self->u.number);
|
||||
return 1;
|
||||
}
|
||||
@@ -25,7 +25,7 @@ static int Np_valueOf(js_State *J, int n)
|
||||
static int Np_toString(js_State *J, int n)
|
||||
{
|
||||
js_Object *self = js_toobject(J, 0);
|
||||
if (self->type != JS_CNUMBER) jsR_throwTypeError(J, "not a number");
|
||||
if (self->type != JS_CNUMBER) js_typeerror(J, "not a number");
|
||||
js_pushliteral(J, jsV_numbertostring(J, self->u.number));
|
||||
return 1;
|
||||
}
|
||||
@@ -35,7 +35,7 @@ static int Np_toFixed(js_State *J, int n)
|
||||
char buf[40];
|
||||
js_Object *self = js_toobject(J, 0);
|
||||
int width = js_tonumber(J, 1);
|
||||
if (self->type != JS_CNUMBER) jsR_throwTypeError(J, "not a number");
|
||||
if (self->type != JS_CNUMBER) js_typeerror(J, "not a number");
|
||||
sprintf(buf, "%.*f", width, self->u.number);
|
||||
js_pushstring(J, buf);
|
||||
return 1;
|
||||
@@ -46,7 +46,7 @@ static int Np_toExponential(js_State *J, int n)
|
||||
char buf[40];
|
||||
js_Object *self = js_toobject(J, 0);
|
||||
int width = js_tonumber(J, 1);
|
||||
if (self->type != JS_CNUMBER) jsR_throwTypeError(J, "not a number");
|
||||
if (self->type != JS_CNUMBER) js_typeerror(J, "not a number");
|
||||
sprintf(buf, "%.*e", width, self->u.number);
|
||||
js_pushstring(J, buf);
|
||||
return 1;
|
||||
@@ -57,7 +57,7 @@ static int Np_toPrecision(js_State *J, int n)
|
||||
char buf[40];
|
||||
js_Object *self = js_toobject(J, 0);
|
||||
int width = js_tonumber(J, 1);
|
||||
if (self->type != JS_CNUMBER) jsR_throwTypeError(J, "not a number");
|
||||
if (self->type != JS_CNUMBER) js_typeerror(J, "not a number");
|
||||
sprintf(buf, "%.*g", width, self->u.number);
|
||||
js_pushstring(J, buf);
|
||||
return 1;
|
||||
|
||||
+2
-2
@@ -18,7 +18,7 @@ static int jsB_String(js_State *J, int n)
|
||||
static int Sp_toString(js_State *J, int n)
|
||||
{
|
||||
js_Object *self = js_toobject(J, 0);
|
||||
if (self->type != JS_CSTRING) jsR_throwTypeError(J, "not a string");
|
||||
if (self->type != JS_CSTRING) js_typeerror(J, "not a string");
|
||||
js_pushliteral(J, self->u.string);
|
||||
return 1;
|
||||
}
|
||||
@@ -26,7 +26,7 @@ static int Sp_toString(js_State *J, int n)
|
||||
static int Sp_valueOf(js_State *J, int n)
|
||||
{
|
||||
js_Object *self = js_toobject(J, 0);
|
||||
if (self->type != JS_CSTRING) jsR_throwTypeError(J, "not a string");
|
||||
if (self->type != JS_CSTRING) js_typeerror(J, "not a string");
|
||||
js_pushliteral(J, self->u.string);
|
||||
return 1;
|
||||
}
|
||||
|
||||
+18
-17
@@ -6,12 +6,29 @@
|
||||
|
||||
#define JF js_State *J, js_Function *F
|
||||
|
||||
JS_NORETURN int jsC_error(js_State *J, js_Ast *node, const char *fmt, ...);
|
||||
JS_NORETURN int jsC_error(js_State *J, js_Ast *node, const char *fmt, ...) JS_PRINTFLIKE(3,4);
|
||||
|
||||
static void cfunbody(JF, js_Ast *name, js_Ast *params, js_Ast *body);
|
||||
static void cexp(JF, js_Ast *exp);
|
||||
static void cstmlist(JF, js_Ast *list);
|
||||
|
||||
int jsC_error(js_State *J, js_Ast *node, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char buf[512];
|
||||
char msgbuf[256];
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(msgbuf, 256, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
snprintf(buf, 256, "%s:%d: ", J->filename, node->line);
|
||||
strcat(buf, msgbuf);
|
||||
|
||||
js_newsyntaxerror(J, buf);
|
||||
js_throw(J);
|
||||
}
|
||||
|
||||
static js_Function *newfun(js_State *J, js_Ast *name, js_Ast *params, js_Ast *body)
|
||||
{
|
||||
js_Function *F = malloc(sizeof *F);
|
||||
@@ -738,22 +755,6 @@ static void cfunbody(JF, js_Ast *name, js_Ast *params, js_Ast *body)
|
||||
emit(J, F, OP_RETURN);
|
||||
}
|
||||
|
||||
int jsC_error(js_State *J, js_Ast *node, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char buf[512];
|
||||
char msgbuf[256];
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(msgbuf, 256, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
snprintf(buf, 256, "%s:%d: ", J->filename, node->line);
|
||||
strcat(buf, msgbuf);
|
||||
|
||||
jsR_throwSyntaxError(J, buf);
|
||||
}
|
||||
|
||||
js_Function *jsC_compile(js_State *J, js_Ast *prog)
|
||||
{
|
||||
return newfun(J, NULL, NULL, prog);
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
#include "jsi.h"
|
||||
#include "jsvalue.h"
|
||||
|
||||
static void js_newerrorx(js_State *J, const char *message, js_Object *prototype)
|
||||
{
|
||||
js_pushobject(J, jsV_newobject(J, JS_CERROR, prototype));
|
||||
js_pushstring(J, message);
|
||||
js_setproperty(J, -2, "message");
|
||||
}
|
||||
|
||||
void js_newerror(js_State *J, const char *s) { js_newerrorx(J, s, J->Error_prototype); }
|
||||
void js_newevalerror(js_State *J, const char *s) { js_newerrorx(J, s, J->EvalError_prototype); }
|
||||
void js_newrangeerror(js_State *J, const char *s) { js_newerrorx(J, s, J->RangeError_prototype); }
|
||||
void js_newreferenceerror(js_State *J, const char *s) { js_newerrorx(J, s, J->ReferenceError_prototype); }
|
||||
void js_newsyntaxerror(js_State *J, const char *s) { js_newerrorx(J, s, J->SyntaxError_prototype); }
|
||||
void js_newtypeerror(js_State *J, const char *s) { js_newerrorx(J, s, J->TypeError_prototype); }
|
||||
void js_newurierror(js_State *J, const char *s) { js_newerrorx(J, s, J->URIError_prototype); }
|
||||
|
||||
#define ERR(NAME) \
|
||||
va_list ap; \
|
||||
char buf[256]; \
|
||||
va_start(ap, fmt); \
|
||||
vsnprintf(buf, sizeof buf, fmt, ap); \
|
||||
va_end(ap); \
|
||||
js_newerrorx(J, buf, J->NAME##_prototype); \
|
||||
js_throw(J)
|
||||
|
||||
void js_error(js_State *J, const char *fmt, ...) { ERR(Error); }
|
||||
void js_evalerror(js_State *J, const char *fmt, ...) { ERR(EvalError); }
|
||||
void js_rangeerror(js_State *J, const char *fmt, ...) { ERR(RangeError); }
|
||||
void js_referenceerror(js_State *J, const char *fmt, ...) { ERR(ReferenceError); }
|
||||
void js_syntaxerror(js_State *J, const char *fmt, ...) { ERR(SyntaxError); }
|
||||
void js_typeerror(js_State *J, const char *fmt, ...) { ERR(TypeError); }
|
||||
void js_urierror(js_State *J, const char *fmt, ...) { ERR(URIError); }
|
||||
@@ -27,14 +27,6 @@ typedef struct js_StringNode js_StringNode;
|
||||
void jsS_dumpstrings(js_State *J);
|
||||
void jsS_freestrings(js_State *J);
|
||||
|
||||
JS_NORETURN void jsR_throwError(js_State *J, const char *message);
|
||||
JS_NORETURN void jsR_throwEvalError(js_State *J, const char *message);
|
||||
JS_NORETURN void jsR_throwRangeError(js_State *J, const char *message);
|
||||
JS_NORETURN void jsR_throwReferenceError(js_State *J, const char *message);
|
||||
JS_NORETURN void jsR_throwSyntaxError(js_State *J, const char *message);
|
||||
JS_NORETURN void jsR_throwTypeError(js_State *J, const char *message);
|
||||
JS_NORETURN void jsR_throwURIError(js_State *J, const char *message);
|
||||
|
||||
void js_newfunction(js_State *J, js_Function *function, js_Environment *scope);
|
||||
void js_newscript(js_State *J, js_Function *function);
|
||||
|
||||
|
||||
@@ -19,7 +19,8 @@ static int jsY_error(js_State *J, const char *fmt, ...)
|
||||
snprintf(buf, 256, "%s:%d: ", J->filename, J->lexline);
|
||||
strcat(buf, msgbuf);
|
||||
|
||||
jsR_throwSyntaxError(J, buf);
|
||||
js_newsyntaxerror(J, buf);
|
||||
js_throw(J);
|
||||
}
|
||||
|
||||
static const char *tokenstring[] = {
|
||||
|
||||
@@ -40,7 +40,8 @@ static void jsP_error(js_State *J, const char *fmt, ...)
|
||||
snprintf(buf, 256, "%s:%d: ", J->filename, J->lexline);
|
||||
strcat(buf, msgbuf);
|
||||
|
||||
jsR_throwSyntaxError(J, buf);
|
||||
js_newsyntaxerror(J, buf);
|
||||
js_throw(J);
|
||||
}
|
||||
|
||||
static void jsP_warning(js_State *J, const char *fmt, ...)
|
||||
|
||||
@@ -412,7 +412,7 @@ void js_call(js_State *J, int n)
|
||||
else if (obj->type == JS_CCFUNCTION)
|
||||
jsR_callcfunction(J, n, obj->u.c.function);
|
||||
else
|
||||
jsR_throwTypeError(J, "not a function");
|
||||
js_typeerror(J, "not a function");
|
||||
BOT = savebot;
|
||||
}
|
||||
|
||||
@@ -571,7 +571,7 @@ static void jsR_run(js_State *J, js_Function *F)
|
||||
if (ref)
|
||||
js_pushvalue(J, ref->value);
|
||||
else
|
||||
jsR_throwReferenceError(J, str);
|
||||
js_referenceerror(J, "%s", str);
|
||||
break;
|
||||
|
||||
case OP_SETVAR:
|
||||
|
||||
@@ -64,7 +64,7 @@ js_Value jsV_toprimitive(js_State *J, const js_Value *v, int preferred)
|
||||
return vv;
|
||||
}
|
||||
}
|
||||
jsR_throwTypeError(J, "cannot convert object to primitive");
|
||||
js_typeerror(J, "cannot convert object to primitive");
|
||||
}
|
||||
|
||||
/* ToBoolean() on a value */
|
||||
@@ -169,14 +169,14 @@ static js_Object *jsV_newstring(js_State *J, const char *v)
|
||||
js_Object *jsV_toobject(js_State *J, const js_Value *v)
|
||||
{
|
||||
switch (v->type) {
|
||||
case JS_TUNDEFINED: jsR_throwTypeError(J, "cannot convert undefined to object");
|
||||
case JS_TNULL: jsR_throwTypeError(J, "cannot convert null to object");
|
||||
case JS_TUNDEFINED: js_typeerror(J, "cannot convert undefined to object");
|
||||
case JS_TNULL: js_typeerror(J, "cannot convert null to object");
|
||||
case JS_TBOOLEAN: return jsV_newboolean(J, v->u.boolean);
|
||||
case JS_TNUMBER: return jsV_newnumber(J, v->u.number);
|
||||
case JS_TSTRING: return jsV_newstring(J, v->u.string);
|
||||
case JS_TOBJECT: return v->u.object;
|
||||
}
|
||||
jsR_throwTypeError(J, "cannot convert value to object");
|
||||
js_typeerror(J, "cannot convert value to object");
|
||||
}
|
||||
|
||||
void js_newobject(js_State *J)
|
||||
|
||||
Reference in New Issue
Block a user