зеркало из https://github.com/mozilla/gecko-dev.git
- "varargs" counterpart to JS_ConvertArguments, JS_ConvertArgumentsVA.
- JS_PushArguments{,VA} and JS_PopArguments to convert a list of C/C++ values passed as actual arguments into an 'jsval *argv' on the JS stack. - Clean up and robustify ConvertArgs test command in the js shell.
This commit is contained in:
Родитель
4d8ab97905
Коммит
85b69beb44
28
js/src/js.c
28
js/src/js.c
|
@ -1000,6 +1000,8 @@ EscapeWideString(jschar *w)
|
|||
unsigned char b, c;
|
||||
int i, j;
|
||||
|
||||
if (!w)
|
||||
return "";
|
||||
for (i = j = 0; i < sizeof enuf - 1; i++, j++) {
|
||||
u = w[j];
|
||||
if (u == 0)
|
||||
|
@ -1033,17 +1035,17 @@ EscapeWideString(jschar *w)
|
|||
static JSBool
|
||||
ConvertArgs(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
JSBool b;
|
||||
jschar c;
|
||||
int32 i, j;
|
||||
uint32 u;
|
||||
jsdouble d, I;
|
||||
char *s;
|
||||
JSString *str;
|
||||
jschar *w;
|
||||
JSObject *obj;
|
||||
JSFunction *fun;
|
||||
jsval v;
|
||||
JSBool b = JS_FALSE;
|
||||
jschar c = 0;
|
||||
int32 i = 0, j = 0;
|
||||
uint32 u = 0;
|
||||
jsdouble d = 0, I = 0;
|
||||
char *s = NULL;
|
||||
JSString *str = NULL;
|
||||
jschar *w = NULL;
|
||||
JSObject *obj = NULL;
|
||||
JSFunction *fun = NULL;
|
||||
jsval v = JSVAL_VOID;
|
||||
|
||||
if (!JS_ConvertArguments(cx, argc, argv, "b/ciujdIsSWofv*",
|
||||
&b, &c, &i, &u, &j, &d, &I, &s, &str, &w, &obj,
|
||||
|
@ -1055,9 +1057,9 @@ ConvertArgs(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
b, c, (char)c, i, u, j);
|
||||
fprintf(gOutFile,
|
||||
"d %g, I %g, s %s, S %s, W %s, obj %s, fun %s, v %s\n",
|
||||
d, I, s, JS_GetStringBytes(str), EscapeWideString(w),
|
||||
d, I, s, str ? JS_GetStringBytes(str) : "", EscapeWideString(w),
|
||||
JS_GetStringBytes(JS_ValueToString(cx, OBJECT_TO_JSVAL(obj))),
|
||||
JS_GetStringBytes(JS_DecompileFunction(cx, fun, 4)),
|
||||
fun ? JS_GetStringBytes(JS_DecompileFunction(cx, fun, 4)) : "",
|
||||
JS_GetStringBytes(JS_ValueToString(cx, v)));
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
|
135
js/src/jsapi.c
135
js/src/jsapi.c
|
@ -96,9 +96,20 @@ JS_ConvertArguments(JSContext *cx, uintN argc, jsval *argv, const char *format,
|
|||
...)
|
||||
{
|
||||
va_list ap;
|
||||
JSBool ok;
|
||||
|
||||
va_start(ap, format);
|
||||
ok = JS_ConvertArgumentsVA(cx, argc, argv, format, ap);
|
||||
va_end(ap);
|
||||
return ok;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_ConvertArgumentsVA(JSContext *cx, uintN argc, jsval *argv,
|
||||
const char *format, va_list ap)
|
||||
{
|
||||
uintN i;
|
||||
JSBool required;
|
||||
const char *cp;
|
||||
char c;
|
||||
JSFunction *fun;
|
||||
jsdouble d;
|
||||
|
@ -106,13 +117,12 @@ JS_ConvertArguments(JSContext *cx, uintN argc, jsval *argv, const char *format,
|
|||
JSObject *obj;
|
||||
|
||||
CHECK_REQUEST(cx);
|
||||
va_start(ap, format);
|
||||
i = 0;
|
||||
required = JS_TRUE;
|
||||
for (cp = format; *cp != '\0'; cp++) {
|
||||
if (isspace(*cp))
|
||||
while ((c = *format++) != '\0') {
|
||||
if (isspace(c))
|
||||
continue;
|
||||
if (*cp == '/') {
|
||||
if (c == '/') {
|
||||
required = JS_FALSE;
|
||||
continue;
|
||||
}
|
||||
|
@ -131,7 +141,7 @@ JS_ConvertArguments(JSContext *cx, uintN argc, jsval *argv, const char *format,
|
|||
}
|
||||
break;
|
||||
}
|
||||
switch ((c = *cp)) {
|
||||
switch (c) {
|
||||
case 'b':
|
||||
if (!js_ValueToBoolean(cx, argv[i], va_arg(ap, JSBool *)))
|
||||
return JS_FALSE;
|
||||
|
@ -195,18 +205,125 @@ JS_ConvertArguments(JSContext *cx, uintN argc, jsval *argv, const char *format,
|
|||
break;
|
||||
default: {
|
||||
char charBuf[2] = " ";
|
||||
charBuf[0] = *cp;
|
||||
charBuf[0] = c;
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_CHAR,
|
||||
charBuf);
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
va_end(ap);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(jsval *)
|
||||
JS_PushArguments(JSContext *cx, void **markp, const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
jsval *argv;
|
||||
|
||||
va_start(ap, format);
|
||||
argv = JS_PushArgumentsVA(cx, markp, format, ap);
|
||||
va_end(ap);
|
||||
return argv;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(jsval *)
|
||||
JS_PushArgumentsVA(JSContext *cx, void **markp, const char *format, va_list ap)
|
||||
{
|
||||
uintN argc;
|
||||
jsval *argv, *sp;
|
||||
char c;
|
||||
const char *cp;
|
||||
JSString *str;
|
||||
JSFunction *fun;
|
||||
|
||||
CHECK_REQUEST(cx);
|
||||
*markp = NULL;
|
||||
argc = 0;
|
||||
for (cp = format; (c = *cp) != '\0'; cp++) {
|
||||
if (isspace(c) || c == '*')
|
||||
continue;
|
||||
argc++;
|
||||
}
|
||||
sp = js_AllocStack(cx, argc, markp);
|
||||
if (!sp)
|
||||
return NULL;
|
||||
argv = sp;
|
||||
while ((c = *format++) != '\0') {
|
||||
if (isspace(c) || c == '*')
|
||||
continue;
|
||||
switch (c) {
|
||||
case 'b':
|
||||
*sp = BOOLEAN_TO_JSVAL(va_arg(ap, JSBool));
|
||||
break;
|
||||
case 'c':
|
||||
*sp = INT_TO_JSVAL(va_arg(ap, uint16));
|
||||
break;
|
||||
case 'i':
|
||||
case 'j':
|
||||
if (!js_NewNumberValue(cx, (jsdouble) va_arg(ap, int32), sp))
|
||||
goto bad;
|
||||
break;
|
||||
case 'u':
|
||||
if (!js_NewNumberValue(cx, (jsdouble) va_arg(ap, uint32), sp))
|
||||
goto bad;
|
||||
break;
|
||||
case 'd':
|
||||
case 'I':
|
||||
if (!js_NewDoubleValue(cx, va_arg(ap, jsdouble), sp))
|
||||
goto bad;
|
||||
break;
|
||||
case 's':
|
||||
str = JS_NewStringCopyZ(cx, va_arg(ap, char *));
|
||||
if (!str)
|
||||
goto bad;
|
||||
*sp = STRING_TO_JSVAL(str);
|
||||
break;
|
||||
case 'W':
|
||||
str = JS_NewUCStringCopyZ(cx, va_arg(ap, jschar *));
|
||||
if (!str)
|
||||
goto bad;
|
||||
*sp = STRING_TO_JSVAL(str);
|
||||
break;
|
||||
case 'S':
|
||||
str = va_arg(ap, JSString *);
|
||||
*sp = STRING_TO_JSVAL(str);
|
||||
break;
|
||||
case 'o':
|
||||
*sp = OBJECT_TO_JSVAL(va_arg(ap, JSObject *));
|
||||
break;
|
||||
case 'f':
|
||||
fun = va_arg(ap, JSFunction *);
|
||||
*sp = fun ? OBJECT_TO_JSVAL(fun->object) : JSVAL_NULL;
|
||||
break;
|
||||
case 'v':
|
||||
*sp = va_arg(ap, jsval);
|
||||
break;
|
||||
default: {
|
||||
char charBuf[2] = " ";
|
||||
charBuf[0] = c;
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_CHAR,
|
||||
charBuf);
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
sp++;
|
||||
}
|
||||
return argv;
|
||||
|
||||
bad:
|
||||
js_FreeStack(cx, *markp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS_PopArguments(JSContext *cx, void *mark)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
js_FreeStack(cx, mark);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_ConvertValue(JSContext *cx, jsval v, JSType type, jsval *vp)
|
||||
{
|
||||
|
|
|
@ -165,6 +165,33 @@ extern JS_PUBLIC_API(JSBool)
|
|||
JS_ConvertArguments(JSContext *cx, uintN argc, jsval *argv, const char *format,
|
||||
...);
|
||||
|
||||
#ifdef va_start
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_ConvertArgumentsVA(JSContext *cx, uintN argc, jsval *argv,
|
||||
const char *format, va_list ap);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Inverse of JS_ConvertArguments: scan format and convert trailing arguments
|
||||
* into jsvals, GC-rooted if necessary by the JS stack. Return null on error,
|
||||
* and a pointer to the new argument vector on success. Also return a stack
|
||||
* mark on success via *markp, in which case the caller must eventually clean
|
||||
* up by calling JS_PopArguments.
|
||||
*
|
||||
* Note that the number of actual arguments supplied is specified exclusively
|
||||
* by format, so there is no argc parameter.
|
||||
*/
|
||||
extern JS_PUBLIC_API(jsval *)
|
||||
JS_PushArguments(JSContext *cx, void **markp, const char *format, ...);
|
||||
|
||||
#ifdef va_start
|
||||
extern JS_PUBLIC_API(jsval *)
|
||||
JS_PushArgumentsVA(JSContext *cx, void **markp, const char *format, va_list ap);
|
||||
#endif
|
||||
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_PopArguments(JSContext *cx, void *mark);
|
||||
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_ConvertValue(JSContext *cx, jsval v, JSType type, jsval *vp);
|
||||
|
||||
|
@ -1046,17 +1073,16 @@ extern JS_PUBLIC_API(void)
|
|||
JS_ClearPendingException(JSContext *cx);
|
||||
|
||||
/*
|
||||
* Save the current exception state. This takes a snapshot of the current
|
||||
* exception state without making any change to that state.
|
||||
*
|
||||
* The returned object MUST be later passed to either JS_RestoreExceptionState
|
||||
* (to restore that saved state) or JS_DropExceptionState (to cleanup the state
|
||||
* object in case it is not desireable to restore to that state). Both
|
||||
* JS_RestoreExceptionState and JS_DropExceptionState will destroy the
|
||||
* JSExceptionState object -- so that object can not be referenced again
|
||||
* after making either of those calls.
|
||||
*/
|
||||
|
||||
* Save the current exception state. This takes a snapshot of the current
|
||||
* exception state without making any change to that state.
|
||||
*
|
||||
* The returned object MUST be later passed to either JS_RestoreExceptionState
|
||||
* (to restore that saved state) or JS_DropExceptionState (to cleanup the state
|
||||
* object in case it is not desireable to restore to that state). Both
|
||||
* JS_RestoreExceptionState and JS_DropExceptionState will destroy the
|
||||
* JSExceptionState object -- so that object can not be referenced again
|
||||
* after making either of those calls.
|
||||
*/
|
||||
extern JS_PUBLIC_API(JSExceptionState *)
|
||||
JS_SaveExceptionState(JSContext *cx);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче