- "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:
brendan%netscape.com 1999-06-08 02:15:57 +00:00
Родитель 4d8ab97905
Коммит 85b69beb44
3 изменённых файлов: 196 добавлений и 51 удалений

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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);