зеркало из https://github.com/mozilla/pjs.git
js.c jsemit.c jsemit.h jsgc.c jsinterp.c jsopcode.c jsopcode.def
- Switch improvements: - JSOP_CONDSWITCH is a 1 byte nop, not variable length with the same kind of immediate operand as JSOP_LOOKUPSWITCH (which is useless except for decompilation). New scheme uses SRC_COMMA notes on each JSOP_CASE opcode, usually 2 bytes per note, and a typically-1-byte 2nd offset on SRC_SWITCH: 1 + 2 * ncases vs. the previous JSOP_LOOKUPSWITCH immediate, which consumed: 4 * ncases bytes after the switch opcode just for decompilation. - SRC_SWITCH has two offsets, first to end of switch as before, the second to first case if JSOP_CONDSWITCH, for decompilation. - Optimize switches with all-constant cases using JSOP_TABLESWITH, or if that can't be used, JSOP_LOOKUPSWITCH, before falling back on ECMAv2's JSOP_CONDSWITCH. - Use cx->gcDisabled when evaluating case exprs at compile time for old, pre-ECMAv2 switches, to prevent branch-callback-based GC invocations from ripping apart the unrooted temporary script for each case expr. - Fixed up stale SRC_SWITCH comments in jsemit.h. jsemit.c jsemit.h - TREE_CONTEXT_INIT to match ATOM_LIST_INIT, not English word order. - Reorganized JSCodeGenerator to sort of match argument order to js_InitCodeGenerator. - Got rid of confusing CG_RESET* macros and used memset(cg, 0, sizeof *cg) and non-zero-default init in js_InitCodeGenerator. js_ResetCodeGenerator just releases the code and temp arena pools and leaves the cg in a state where it must be re-initialized (as before, but more obvious). - In the same spirit, don't do partial "resets" or src and trynotes in their js_FinishTaking*Notes functions -- those are friends of jsscript.c and are not general, idempotent functions. jsapi.c jsapi.h jsarray.c jsatom.c jsatom.h jscntxt.c jsemit.c jsmsg.def jsnum.c jsobj.c jsopcode.c jsregexp.c jsscan.c jsstr.c jsxdrapi. - Use PR_snprintf rather than sprintf always, so we don't have to worry about systems with 64-bit longs that overflow 12-byte buffers and open Morris-Worm-type security holes. - Trim extra spaces, fix hanging indentation, and similar anal retention. - Renamed JSMSG_BAD_PROTO_SORT to JSMSG_BAD_SORT_ARG cuz that's what it is complaining about. - SRC_CATCHGUARD still lived in comments, but it's SRC_CATCH in code. jscntxt.c jscntxt.h jsinterp.c - Packed nearby JSPackedBools and added a new one: gcDisabled, for use by jsemit.c's pre-ECMAv2 switch case expr eval. - Rip out old js_InterpreterHooks stuff from original liveconnect (moja). - Remove javaData and savedErrors from JSContext. Leaving it to fur or shaver to remove javaData from jsscript.h.
This commit is contained in:
Родитель
97fe5038d8
Коммит
f8bbc56e36
235
js/ref/js.c
235
js/ref/js.c
|
@ -135,19 +135,19 @@ Process(JSContext *cx, JSObject *obj, char *filename)
|
|||
if (isatty(fileno(ts->file))) {
|
||||
ts->flags |= TSF_INTERACTIVE;
|
||||
} else {
|
||||
/* Support the UNIX #! shell hack; gobble the first line if it starts
|
||||
* with '#'. TODO - this isn't quite compatible with sharp variables,
|
||||
* as a legal js program (using sharp variables) might start with '#'.
|
||||
* But that would require multi-character lookahead.
|
||||
*/
|
||||
char ch = fgetc(ts->file);
|
||||
if (ch == '#') {
|
||||
while((ch = fgetc(ts->file)) != EOF) {
|
||||
if(ch == '\n' || ch == '\r')
|
||||
break;
|
||||
}
|
||||
}
|
||||
ungetc(ch, ts->file);
|
||||
/* Support the UNIX #! shell hack; gobble the first line if it starts
|
||||
* with '#'. TODO - this isn't quite compatible with sharp variables,
|
||||
* as a legal js program (using sharp variables) might start with '#'.
|
||||
* But that would require multi-character lookahead.
|
||||
*/
|
||||
char ch = fgetc(ts->file);
|
||||
if (ch == '#') {
|
||||
while((ch = fgetc(ts->file)) != EOF) {
|
||||
if(ch == '\n' || ch == '\r')
|
||||
break;
|
||||
}
|
||||
}
|
||||
ungetc(ch, ts->file);
|
||||
}
|
||||
|
||||
do {
|
||||
|
@ -163,11 +163,11 @@ Process(JSContext *cx, JSObject *obj, char *filename)
|
|||
}
|
||||
} while (ok && !(ts->flags & TSF_EOF) && CG_OFFSET(&cg) == 0);
|
||||
if (ok) {
|
||||
/*
|
||||
* Clear any pending exception, either from previous failed
|
||||
* compiles, or from the last round of execution.
|
||||
*/
|
||||
JS_ClearPendingException(cx);
|
||||
/*
|
||||
* Clear any pending exception, either from previous failed
|
||||
* compiles, or from the last round of execution.
|
||||
*/
|
||||
JS_ClearPendingException(cx);
|
||||
|
||||
script = js_NewScriptFromCG(cx, &cg, NULL);
|
||||
if (script) {
|
||||
|
@ -179,29 +179,29 @@ Process(JSContext *cx, JSObject *obj, char *filename)
|
|||
printf("%s\n", JS_GetStringBytes(str));
|
||||
}
|
||||
|
||||
if (JS_IsExceptionPending(cx) &&
|
||||
JS_GetPendingException(cx, &result))
|
||||
{
|
||||
/*
|
||||
* Calling JS_ValueToString could cause another error (and
|
||||
* throw an associated exception) - so we disable the error
|
||||
* reporter so nothing gets reported, and we always clear
|
||||
* the pending exception... which might be different than
|
||||
* the one we just got in &result.
|
||||
*/
|
||||
JSErrorReporter older;
|
||||
older = JS_SetErrorReporter(cx, NULL);
|
||||
str = JS_ValueToString(cx, result);
|
||||
JS_SetErrorReporter(cx, older);
|
||||
if (JS_IsExceptionPending(cx) &&
|
||||
JS_GetPendingException(cx, &result))
|
||||
{
|
||||
/*
|
||||
* Calling JS_ValueToString could cause another error (and
|
||||
* throw an associated exception) - so we disable the error
|
||||
* reporter so nothing gets reported, and we always clear
|
||||
* the pending exception... which might be different than
|
||||
* the one we just got in &result.
|
||||
*/
|
||||
JSErrorReporter older;
|
||||
older = JS_SetErrorReporter(cx, NULL);
|
||||
str = JS_ValueToString(cx, result);
|
||||
JS_SetErrorReporter(cx, older);
|
||||
|
||||
/* XXX non-i18nized strings... */
|
||||
if (str) {
|
||||
fprintf(stderr, "Uncaught javascript exception:\n%s\n",
|
||||
JS_GetStringBytes(str));
|
||||
} else {
|
||||
fprintf(stderr, "Uncaught javascript exception\n");
|
||||
}
|
||||
}
|
||||
/* XXX non-i18nized strings... */
|
||||
if (str) {
|
||||
fprintf(stderr, "Uncaught javascript exception:\n%s\n",
|
||||
JS_GetStringBytes(str));
|
||||
} else {
|
||||
fprintf(stderr, "Uncaught javascript exception\n");
|
||||
}
|
||||
}
|
||||
JS_DestroyScript(cx, script);
|
||||
}
|
||||
}
|
||||
|
@ -236,37 +236,37 @@ ProcessArgs(JSContext *cx, JSObject *obj, char **argv, int argc)
|
|||
JSObject *argsObj;
|
||||
|
||||
for (i=0; i < argc; i++) {
|
||||
if (argv[i][0] == '-') {
|
||||
switch (argv[i][1]) {
|
||||
case 'v':
|
||||
if (i+1 == argc) {
|
||||
return usage();
|
||||
}
|
||||
JS_SetVersion(cx, atoi(argv[i+1]));
|
||||
i++;
|
||||
break;
|
||||
case 'w':
|
||||
reportWarnings++;
|
||||
break;
|
||||
if (argv[i][0] == '-') {
|
||||
switch (argv[i][1]) {
|
||||
case 'v':
|
||||
if (i+1 == argc) {
|
||||
return usage();
|
||||
}
|
||||
JS_SetVersion(cx, atoi(argv[i+1]));
|
||||
i++;
|
||||
break;
|
||||
case 'w':
|
||||
reportWarnings++;
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
if (i+1 == argc) {
|
||||
return usage();
|
||||
}
|
||||
filename = argv[i+1];
|
||||
/* "-f -" means read from stdin */
|
||||
if (filename[0] == '-' && filename[1] == '\0')
|
||||
filename = NULL;
|
||||
Process(cx, obj, filename);
|
||||
i++;
|
||||
break;
|
||||
default:
|
||||
return usage();
|
||||
}
|
||||
} else {
|
||||
filename = argv[i++];
|
||||
break;
|
||||
}
|
||||
case 'f':
|
||||
if (i+1 == argc) {
|
||||
return usage();
|
||||
}
|
||||
filename = argv[i+1];
|
||||
/* "-f -" means read from stdin */
|
||||
if (filename[0] == '-' && filename[1] == '\0')
|
||||
filename = NULL;
|
||||
Process(cx, obj, filename);
|
||||
i++;
|
||||
break;
|
||||
default:
|
||||
return usage();
|
||||
}
|
||||
} else {
|
||||
filename = argv[i++];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
length = argc - i;
|
||||
|
@ -274,22 +274,22 @@ ProcessArgs(JSContext *cx, JSObject *obj, char **argv, int argc)
|
|||
p = vector;
|
||||
|
||||
if (vector == NULL)
|
||||
return 1;
|
||||
return 1;
|
||||
|
||||
while (i < argc) {
|
||||
JSString *str = JS_NewStringCopyZ(cx, argv[i]);
|
||||
if (str == NULL)
|
||||
return 1;
|
||||
*p++ = STRING_TO_JSVAL(str);
|
||||
i++;
|
||||
JSString *str = JS_NewStringCopyZ(cx, argv[i]);
|
||||
if (str == NULL)
|
||||
return 1;
|
||||
*p++ = STRING_TO_JSVAL(str);
|
||||
i++;
|
||||
}
|
||||
argsObj = JS_NewArrayObject(cx, length, vector);
|
||||
if (argsObj == NULL)
|
||||
return 1;
|
||||
return 1;
|
||||
|
||||
if (!JS_DefineProperty(cx, obj, "arguments",
|
||||
OBJECT_TO_JSVAL(argsObj), NULL, NULL, 0))
|
||||
return 1;
|
||||
OBJECT_TO_JSVAL(argsObj), NULL, NULL, 0))
|
||||
return 1;
|
||||
|
||||
Process(cx, obj, filename);
|
||||
return 0;
|
||||
|
@ -385,13 +385,13 @@ GC(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
preBytes = rt->gcBytes;
|
||||
#ifdef GC_MARK_DEBUG
|
||||
if (argc && JSVAL_IS_STRING(argv[0])) {
|
||||
char *name = JS_GetStringBytes(JSVAL_TO_STRING(argv[0]));
|
||||
FILE *file = fopen(name, "w");
|
||||
if (!file) {
|
||||
char *name = JS_GetStringBytes(JSVAL_TO_STRING(argv[0]));
|
||||
FILE *file = fopen(name, "w");
|
||||
if (!file) {
|
||||
fprintf(stderr, "gc: can't open %s: %s\n", strerror(errno));
|
||||
return JS_FALSE;
|
||||
}
|
||||
js_DumpGCHeap = file;
|
||||
}
|
||||
js_DumpGCHeap = file;
|
||||
} else {
|
||||
js_DumpGCHeap = stdout;
|
||||
}
|
||||
|
@ -399,7 +399,7 @@ GC(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
js_ForceGC(cx);
|
||||
#ifdef GC_MARK_DEBUG
|
||||
if (js_DumpGCHeap != stdout)
|
||||
fclose(js_DumpGCHeap);
|
||||
fclose(js_DumpGCHeap);
|
||||
js_DumpGCHeap = NULL;
|
||||
#endif
|
||||
printf("before %lu, after %lu, break %08lx\n",
|
||||
|
@ -539,7 +539,7 @@ PCToLine(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
static void
|
||||
SrcNotes(JSContext *cx, JSFunction *fun )
|
||||
{
|
||||
uintN offset, delta;
|
||||
uintN offset, delta, caseOff;
|
||||
jssrcnote *notes, *sn;
|
||||
JSSrcNoteType type;
|
||||
jsatomid atomIndex;
|
||||
|
@ -578,6 +578,12 @@ SrcNotes(JSContext *cx, JSFunction *fun )
|
|||
atom = js_GetAtom(cx, &fun->script->atomMap, atomIndex);
|
||||
printf(" atom %u (%s)", (uintN)atomIndex, ATOM_BYTES(atom));
|
||||
break;
|
||||
case SRC_SWITCH:
|
||||
printf(" length %u", (uintN) js_GetSrcNoteOffset(sn, 0));
|
||||
caseOff = (uintN) js_GetSrcNoteOffset(sn, 1);
|
||||
if (caseOff)
|
||||
printf(" first case offset %u", caseOff);
|
||||
break;
|
||||
case SRC_CATCH:
|
||||
delta = (uintN) js_GetSrcNoteOffset(sn, 0);
|
||||
if (delta)
|
||||
|
@ -667,14 +673,14 @@ DisassWithSrc(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval
|
|||
|
||||
if (!fun->script || !fun->script->filename) {
|
||||
JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL,
|
||||
JSSMSG_FILE_SCRIPTS_ONLY);
|
||||
JSSMSG_FILE_SCRIPTS_ONLY);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
file = fopen(fun->script->filename, "r");
|
||||
if (!file) {
|
||||
JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL,
|
||||
JSSMSG_CANT_OPEN,
|
||||
JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL,
|
||||
JSSMSG_CANT_OPEN,
|
||||
fun->script->filename, strerror(errno));
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
@ -702,8 +708,8 @@ DisassWithSrc(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval
|
|||
bupline = 0;
|
||||
while (line1 < line2) {
|
||||
if (!fgets(linebuf, LINE_BUF_LEN, file)) {
|
||||
JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL,
|
||||
JSSMSG_UNEXPECTED_EOF,
|
||||
JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL,
|
||||
JSSMSG_UNEXPECTED_EOF,
|
||||
fun->script->filename);
|
||||
goto bail;
|
||||
}
|
||||
|
@ -723,6 +729,7 @@ DisassWithSrc(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval
|
|||
fclose(file);
|
||||
}
|
||||
return JS_TRUE;
|
||||
#undef LINE_BUF_LEN
|
||||
}
|
||||
|
||||
static JSBool
|
||||
|
@ -800,7 +807,7 @@ DumpScope(JSContext *cx, JSObject *obj, PRHashEnumerator dump, FILE *fp)
|
|||
fprintf(fp, "\n%s scope contents:\n", OBJ_GET_CLASS(cx, obj)->name);
|
||||
scope = (JSScope *)obj->map;
|
||||
if (!MAP_IS_NATIVE(&scope->map))
|
||||
return;
|
||||
return;
|
||||
if (scope->ops == &js_list_scope_ops) {
|
||||
for (sym = (JSSymbol *)scope->data, i = 0; sym;
|
||||
sym = (JSSymbol *)sym->entry.next, i++) {
|
||||
|
@ -854,7 +861,7 @@ DumpStats(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
if (!prop || !JSVAL_IS_OBJECT(value)) {
|
||||
fprintf(stderr, "js: invalid stats argument %s\n",
|
||||
bytes);
|
||||
continue;
|
||||
continue;
|
||||
}
|
||||
obj = JSVAL_TO_OBJECT(value);
|
||||
if (obj)
|
||||
|
@ -925,10 +932,10 @@ ConvertArgs(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
}
|
||||
printf("b %u, c %x (%c), i %ld, u %lu, j %ld\n", b, c, (char)c, i, u, j);
|
||||
printf("d %g, I %g, s %s, S %s, obj %s, fun %s, v %s\n",
|
||||
d, I, s, JS_GetStringBytes(str),
|
||||
JS_GetStringBytes(JS_ValueToString(cx, OBJECT_TO_JSVAL(obj))),
|
||||
JS_GetStringBytes(JS_DecompileFunction(cx, fun, 4)),
|
||||
JS_GetStringBytes(JS_ValueToString(cx, v)));
|
||||
d, I, s, JS_GetStringBytes(str),
|
||||
JS_GetStringBytes(JS_ValueToString(cx, OBJECT_TO_JSVAL(obj))),
|
||||
JS_GetStringBytes(JS_DecompileFunction(cx, fun, 4)),
|
||||
JS_GetStringBytes(JS_ValueToString(cx, v)));
|
||||
return JS_TRUE;
|
||||
}
|
||||
#endif
|
||||
|
@ -1185,7 +1192,7 @@ my_GetErrorMessage(void *userRef, const char *locale, const uintN errorNumber)
|
|||
if ((errorNumber > 0) && (errorNumber < JSShellErr_Limit))
|
||||
return &jsShell_ErrorFormatString[errorNumber];
|
||||
else
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1205,29 +1212,29 @@ my_ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
|
|||
* a toplevel compile.
|
||||
*/
|
||||
if ((JSREPORT_IS_WARNING(report->flags) && !reportWarnings) ||
|
||||
(JSREPORT_IS_EXCEPTION(report->flags) && cx->interpLevel > 0)) {
|
||||
return;
|
||||
(JSREPORT_IS_EXCEPTION(report->flags) && cx->interpLevel > 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (report->filename)
|
||||
prefix = PR_smprintf("%s:", report->filename);
|
||||
if (report->lineno) {
|
||||
tmp = prefix;
|
||||
prefix = PR_smprintf("%s%u: ", tmp ? tmp : "", report->lineno);
|
||||
JS_free(cx, tmp);
|
||||
tmp = prefix;
|
||||
prefix = PR_smprintf("%s%u: ", tmp ? tmp : "", report->lineno);
|
||||
JS_free(cx, tmp);
|
||||
}
|
||||
if (JSREPORT_IS_WARNING(report->flags)) {
|
||||
tmp = prefix;
|
||||
prefix = PR_smprintf("%swarning: ", tmp ? tmp : "");
|
||||
JS_free(cx, tmp);
|
||||
tmp = prefix;
|
||||
prefix = PR_smprintf("%swarning: ", tmp ? tmp : "");
|
||||
JS_free(cx, tmp);
|
||||
}
|
||||
|
||||
/* embedded newlines -- argh! */
|
||||
while ((tmp = strchr(message, '\n'))) {
|
||||
tmp++;
|
||||
if (prefix) fputs(prefix, stderr);
|
||||
fwrite(message, 1, tmp - message, stderr);
|
||||
message = tmp;
|
||||
tmp++;
|
||||
if (prefix) fputs(prefix, stderr);
|
||||
fwrite(message, 1, tmp - message, stderr);
|
||||
message = tmp;
|
||||
}
|
||||
/* If there were no filename or lineno, the prefix might be empty */
|
||||
if (prefix) fputs(prefix, stderr);
|
||||
|
@ -1235,7 +1242,7 @@ my_ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
|
|||
|
||||
if (!report->linebuf) {
|
||||
putc('\n', stderr);
|
||||
goto out;
|
||||
goto out;
|
||||
}
|
||||
|
||||
fprintf(stderr, ":\n%s%s\n%s", prefix, report->linebuf, prefix);
|
||||
|
@ -1419,7 +1426,7 @@ main(int argc, char **argv)
|
|||
|
||||
#ifdef PERLCONNECT
|
||||
if (!JS_InitPerlClass(cx, glob))
|
||||
return 1;
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
#ifdef JSDEBUGGER
|
||||
|
@ -1438,7 +1445,7 @@ main(int argc, char **argv)
|
|||
JSDJ_SetJSDContext(_jsdjc, _jsdc);
|
||||
java_env = JSDJ_CreateJavaVMAndStartDebugger(_jsdjc);
|
||||
if (java_env)
|
||||
(*java_env)->GetJavaVM(java_env, &java_vm);
|
||||
(*java_env)->GetJavaVM(java_env, &java_vm);
|
||||
/*
|
||||
* XXX This would be the place to wait for the debugger to start.
|
||||
* Waiting would be nice in general, but especially when a js file
|
||||
|
@ -1452,7 +1459,7 @@ main(int argc, char **argv)
|
|||
|
||||
#ifdef LIVECONNECT
|
||||
if (!JSJ_SimpleInit(cx, glob, java_vm, getenv("CLASSPATH")))
|
||||
return 1;
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
result = ProcessArgs(cx, glob, argv, argc);
|
||||
|
|
214
js/ref/jsapi.c
214
js/ref/jsapi.c
|
@ -28,6 +28,7 @@
|
|||
#include "prarena.h"
|
||||
#include "prassert.h"
|
||||
#include "prclist.h"
|
||||
#include "prprintf.h"
|
||||
#include "jsapi.h"
|
||||
#include "jsarray.h"
|
||||
#include "jsatom.h"
|
||||
|
@ -104,9 +105,9 @@ JS_ConvertArguments(JSContext *cx, uintN argc, jsval *argv, const char *format,
|
|||
i = 0;
|
||||
required = JS_TRUE;
|
||||
for (cp = format; *cp != '\0'; cp++) {
|
||||
if (isspace(*cp))
|
||||
if (isspace(*cp))
|
||||
continue;
|
||||
if (*cp == '/') {
|
||||
if (*cp == '/') {
|
||||
required = JS_FALSE;
|
||||
continue;
|
||||
}
|
||||
|
@ -115,88 +116,87 @@ JS_ConvertArguments(JSContext *cx, uintN argc, jsval *argv, const char *format,
|
|||
fun = js_ValueToFunction(cx, &argv[-2], JS_FALSE);
|
||||
if (fun) {
|
||||
char numBuf[12];
|
||||
sprintf(numBuf, "%u", argc);
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_MORE_ARGS_NEEDED,
|
||||
JS_GetFunctionName(fun),
|
||||
numBuf,
|
||||
(argc == 1) ? "" : "s");
|
||||
PR_snprintf(numBuf, sizeof numBuf, "%u", argc);
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_MORE_ARGS_NEEDED,
|
||||
JS_GetFunctionName(fun), numBuf,
|
||||
(argc == 1) ? "" : "s");
|
||||
}
|
||||
return JS_FALSE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
switch (*cp) {
|
||||
case 'b':
|
||||
switch (*cp) {
|
||||
case 'b':
|
||||
if (!js_ValueToBoolean(cx, argv[i], va_arg(ap, JSBool *)))
|
||||
return JS_FALSE;
|
||||
return JS_FALSE;
|
||||
break;
|
||||
case 'c':
|
||||
case 'c':
|
||||
if (!js_ValueToUint16(cx, argv[i], va_arg(ap, uint16 *)))
|
||||
return JS_FALSE;
|
||||
return JS_FALSE;
|
||||
break;
|
||||
case 'i':
|
||||
case 'i':
|
||||
if (!js_ValueToECMAInt32(cx, argv[i], va_arg(ap, int32 *)))
|
||||
return JS_FALSE;
|
||||
return JS_FALSE;
|
||||
break;
|
||||
case 'u':
|
||||
case 'u':
|
||||
if (!js_ValueToECMAUint32(cx, argv[i], va_arg(ap, uint32 *)))
|
||||
return JS_FALSE;
|
||||
return JS_FALSE;
|
||||
break;
|
||||
case 'j':
|
||||
case 'j':
|
||||
if (!js_ValueToInt32(cx, argv[i], va_arg(ap, int32 *)))
|
||||
return JS_FALSE;
|
||||
return JS_FALSE;
|
||||
break;
|
||||
case 'd':
|
||||
case 'd':
|
||||
if (!js_ValueToNumber(cx, argv[i], va_arg(ap, jsdouble *)))
|
||||
return JS_FALSE;
|
||||
return JS_FALSE;
|
||||
break;
|
||||
case 'I':
|
||||
case 'I':
|
||||
if (!js_ValueToNumber(cx, argv[i], &d))
|
||||
return JS_FALSE;
|
||||
return JS_FALSE;
|
||||
*va_arg(ap, jsdouble *) = js_DoubleToInteger(d);
|
||||
break;
|
||||
case 's':
|
||||
case 's':
|
||||
str = js_ValueToString(cx, argv[i]);
|
||||
if (!str)
|
||||
return JS_FALSE;
|
||||
return JS_FALSE;
|
||||
argv[i] = STRING_TO_JSVAL(str);
|
||||
*va_arg(ap, char **) = JS_GetStringBytes(str);
|
||||
break;
|
||||
case 'S':
|
||||
case 'S':
|
||||
str = js_ValueToString(cx, argv[i]);
|
||||
if (!str)
|
||||
return JS_FALSE;
|
||||
return JS_FALSE;
|
||||
argv[i] = STRING_TO_JSVAL(str);
|
||||
*va_arg(ap, JSString **) = str;
|
||||
break;
|
||||
case 'o':
|
||||
case 'o':
|
||||
if (!js_ValueToObject(cx, argv[i], &obj))
|
||||
return JS_FALSE;
|
||||
return JS_FALSE;
|
||||
argv[i] = OBJECT_TO_JSVAL(obj);
|
||||
*va_arg(ap, JSObject **) = obj;
|
||||
break;
|
||||
case 'f':
|
||||
case 'f':
|
||||
fun = js_ValueToFunction(cx, &argv[i], JS_FALSE);
|
||||
if (!fun)
|
||||
return JS_FALSE;
|
||||
return JS_FALSE;
|
||||
argv[i] = OBJECT_TO_JSVAL(fun->object);
|
||||
*va_arg(ap, JSFunction **) = fun;
|
||||
break;
|
||||
case 'v':
|
||||
case 'v':
|
||||
*va_arg(ap, jsval *) = argv[i];
|
||||
break;
|
||||
case '*':
|
||||
case '*':
|
||||
break;
|
||||
default: {
|
||||
char charBuf[2] = " ";
|
||||
charBuf[0] = *cp;
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_BAD_CHAR, charBuf);
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_CHAR,
|
||||
charBuf);
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
va_end(ap);
|
||||
return JS_TRUE;
|
||||
|
@ -249,12 +249,12 @@ JS_ConvertValue(JSContext *cx, jsval v, JSType type, jsval *vp)
|
|||
break;
|
||||
default: {
|
||||
char numBuf[12];
|
||||
sprintf(numBuf, "%d", (int)type);
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_BAD_TYPE, numBuf);
|
||||
PR_snprintf(numBuf, sizeof numBuf, "%d", (int)type);
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_TYPE,
|
||||
numBuf);
|
||||
ok = JS_FALSE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
@ -342,16 +342,16 @@ JS_TypeOfValue(JSContext *cx, jsval v)
|
|||
type = JSTYPE_VOID;
|
||||
} else if (JSVAL_IS_OBJECT(v)) {
|
||||
obj = JSVAL_TO_OBJECT(v);
|
||||
if (obj &&
|
||||
(ops = obj->map->ops,
|
||||
if (obj &&
|
||||
(ops = obj->map->ops,
|
||||
ops == &js_ObjectOps
|
||||
? (clasp = OBJ_GET_CLASS(cx, obj),
|
||||
? (clasp = OBJ_GET_CLASS(cx, obj),
|
||||
clasp->call || clasp == &js_FunctionClass)
|
||||
: ops->call != 0)) {
|
||||
type = JSTYPE_FUNCTION;
|
||||
} else {
|
||||
type = JSTYPE_OBJECT;
|
||||
}
|
||||
: ops->call != 0)) {
|
||||
type = JSTYPE_FUNCTION;
|
||||
} else {
|
||||
type = JSTYPE_OBJECT;
|
||||
}
|
||||
} else if (JSVAL_IS_NUMBER(v)) {
|
||||
type = JSTYPE_NUMBER;
|
||||
} else if (JSVAL_IS_STRING(v)) {
|
||||
|
@ -659,9 +659,9 @@ JS_InitStandardClasses(JSContext *cx, JSObject *obj)
|
|||
* (proposed ECMA v2.)
|
||||
*/
|
||||
if (!OBJ_DEFINE_PROPERTY(cx, obj,
|
||||
(jsid)cx->runtime->atomState.typeAtoms[JSTYPE_VOID],
|
||||
JSVAL_VOID, NULL, NULL, 0, NULL))
|
||||
return JS_FALSE;
|
||||
(jsid)cx->runtime->atomState.typeAtoms[JSTYPE_VOID],
|
||||
JSVAL_VOID, NULL, NULL, 0, NULL))
|
||||
return JS_FALSE;
|
||||
#endif
|
||||
|
||||
/* Initialize the function class first so constructors can be made. */
|
||||
|
@ -693,7 +693,7 @@ JS_InitStandardClasses(JSContext *cx, JSObject *obj)
|
|||
js_InitScriptClass(cx, obj) &&
|
||||
#endif
|
||||
#if JS_HAS_ERROR_EXCEPTIONS
|
||||
js_InitExceptionClasses(cx, obj) &&
|
||||
js_InitExceptionClasses(cx, obj) &&
|
||||
#endif
|
||||
js_InitDateClass(cx, obj);
|
||||
}
|
||||
|
@ -894,12 +894,12 @@ JS_ValueToId(JSContext *cx, jsval v, jsid *idp)
|
|||
|
||||
CHECK_REQUEST(cx);
|
||||
if (JSVAL_IS_INT(v)) {
|
||||
*idp = v;
|
||||
*idp = v;
|
||||
} else {
|
||||
atom = js_ValueToStringAtom(cx, v);
|
||||
if (!atom)
|
||||
atom = js_ValueToStringAtom(cx, v);
|
||||
if (!atom)
|
||||
return JS_FALSE;
|
||||
*idp = (jsid)atom;
|
||||
*idp = (jsid)atom;
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
@ -973,12 +973,12 @@ JS_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto,
|
|||
return NULL;
|
||||
|
||||
if (!constructor) {
|
||||
/* Lacking a constructor, name the prototype (e.g., Math). */
|
||||
named = OBJ_DEFINE_PROPERTY(cx, obj, (jsid)atom, OBJECT_TO_JSVAL(proto),
|
||||
/* Lacking a constructor, name the prototype (e.g., Math). */
|
||||
named = OBJ_DEFINE_PROPERTY(cx, obj, (jsid)atom, OBJECT_TO_JSVAL(proto),
|
||||
NULL, NULL, 0, NULL);
|
||||
if (!named)
|
||||
goto bad;
|
||||
ctor = proto;
|
||||
ctor = proto;
|
||||
} else {
|
||||
/* Define the constructor function in obj's scope. */
|
||||
fun = js_DefineFunction(cx, obj, atom, constructor, nargs, 0);
|
||||
|
@ -1046,10 +1046,10 @@ JS_InstanceOf(JSContext *cx, JSObject *obj, JSClass *clasp, jsval *argv)
|
|||
if (argv) {
|
||||
fun = js_ValueToFunction(cx, &argv[-2], JS_FALSE);
|
||||
if (fun) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_INCOMPATIBLE_PROTO,
|
||||
clasp->name, JS_GetFunctionName(fun),
|
||||
OBJ_GET_CLASS(cx, obj)->name);
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_INCOMPATIBLE_PROTO,
|
||||
clasp->name, JS_GetFunctionName(fun),
|
||||
OBJ_GET_CLASS(cx, obj)->name);
|
||||
}
|
||||
}
|
||||
return JS_FALSE;
|
||||
|
@ -1141,7 +1141,7 @@ JS_GetConstructor(JSContext *cx, JSObject *proto)
|
|||
return NULL;
|
||||
if (!JSVAL_IS_FUNCTION(cx, cval)) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NO_CONSTRUCTOR,
|
||||
OBJ_GET_CLASS(cx, proto)->name);
|
||||
OBJ_GET_CLASS(cx, proto)->name);
|
||||
return NULL;
|
||||
}
|
||||
return JSVAL_TO_OBJECT(cval);
|
||||
|
@ -1209,7 +1209,7 @@ JS_DefineObject(JSContext *cx, JSObject *obj, const char *name, JSClass *clasp,
|
|||
CHECK_REQUEST(cx);
|
||||
nobj = js_NewObject(cx, clasp, proto, obj);
|
||||
if (!nobj)
|
||||
return NULL;
|
||||
return NULL;
|
||||
if (!DefineProperty(cx, obj, name, OBJECT_TO_JSVAL(nobj), NULL, NULL, attrs,
|
||||
NULL)) {
|
||||
cx->newborn[GCX_OBJECT] = NULL;
|
||||
|
@ -1233,11 +1233,11 @@ JS_DefineConstDoubles(JSContext *cx, JSObject *obj, JSConstDoubleSpec *cds)
|
|||
* so we don't need to GC-alloc constant doubles.
|
||||
*/
|
||||
jsdouble d = cds->dval;
|
||||
jsint i;
|
||||
jsint i;
|
||||
|
||||
value = (JSDOUBLE_IS_INT(d, i) && INT_FITS_IN_JSVAL(i))
|
||||
? INT_TO_JSVAL(i)
|
||||
: DOUBLE_TO_JSVAL(&cds->dval);
|
||||
value = (JSDOUBLE_IS_INT(d, i) && INT_FITS_IN_JSVAL(i))
|
||||
? INT_TO_JSVAL(i)
|
||||
: DOUBLE_TO_JSVAL(&cds->dval);
|
||||
#else
|
||||
ok = js_NewNumberValue(cx, cds->dval, &value);
|
||||
if (!ok)
|
||||
|
@ -1356,7 +1356,7 @@ JS_AliasProperty(JSContext *cx, JSObject *obj, const char *name,
|
|||
if (obj2 != obj || !OBJ_IS_NATIVE(obj2)) {
|
||||
OBJ_DROP_PROPERTY(cx, obj2, prop);
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_ALIAS,
|
||||
alias, name, OBJ_GET_CLASS(cx, obj2)->name);
|
||||
alias, name, OBJ_GET_CLASS(cx, obj2)->name);
|
||||
return JS_FALSE;
|
||||
}
|
||||
atom = js_Atomize(cx, alias, strlen(alias), 0);
|
||||
|
@ -1420,7 +1420,7 @@ GetPropertyAttributes(JSContext *cx, JSObject *obj, JSAtom *atom,
|
|||
|
||||
static JSBool
|
||||
SetPropertyAttributes(JSContext *cx, JSObject *obj, JSAtom *atom,
|
||||
uintN attrs, JSBool *foundp)
|
||||
uintN attrs, JSBool *foundp)
|
||||
{
|
||||
JSObject *obj2;
|
||||
JSProperty *prop;
|
||||
|
@ -1449,9 +1449,9 @@ JS_GetPropertyAttributes(JSContext *cx, JSObject *obj, const char *name,
|
|||
uintN *attrsp, JSBool *foundp)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
return GetPropertyAttributes(cx, obj,
|
||||
js_Atomize(cx, name, strlen(name), 0),
|
||||
attrsp, foundp);
|
||||
return GetPropertyAttributes(cx, obj,
|
||||
js_Atomize(cx, name, strlen(name), 0),
|
||||
attrsp, foundp);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
|
@ -1459,9 +1459,9 @@ JS_SetPropertyAttributes(JSContext *cx, JSObject *obj, const char *name,
|
|||
uintN attrs, JSBool *foundp)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
return SetPropertyAttributes(cx, obj,
|
||||
js_Atomize(cx, name, strlen(name), 0),
|
||||
attrs, foundp);
|
||||
return SetPropertyAttributes(cx, obj,
|
||||
js_Atomize(cx, name, strlen(name), 0),
|
||||
attrs, foundp);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
|
@ -1474,7 +1474,7 @@ JS_LookupProperty(JSContext *cx, JSObject *obj, const char *name, jsval *vp)
|
|||
CHECK_REQUEST(cx);
|
||||
ok = LookupProperty(cx, obj, name, &obj2, &prop);
|
||||
if (ok)
|
||||
*vp = LookupResult(cx, obj, obj2, prop);
|
||||
*vp = LookupResult(cx, obj, obj2, prop);
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
@ -1536,25 +1536,25 @@ JS_DefineUCProperty(JSContext *cx, JSObject *obj,
|
|||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_GetUCPropertyAttributes(JSContext *cx, JSObject *obj,
|
||||
const jschar *name, size_t namelen,
|
||||
JS_GetUCPropertyAttributes(JSContext *cx, JSObject *obj,
|
||||
const jschar *name, size_t namelen,
|
||||
uintN *attrsp, JSBool *foundp)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
return GetPropertyAttributes(cx, obj,
|
||||
js_AtomizeChars(cx, name, AUTO_NAMELEN(name,namelen), 0),
|
||||
attrsp, foundp);
|
||||
return GetPropertyAttributes(cx, obj,
|
||||
js_AtomizeChars(cx, name, AUTO_NAMELEN(name,namelen), 0),
|
||||
attrsp, foundp);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_SetUCPropertyAttributes(JSContext *cx, JSObject *obj,
|
||||
const jschar *name, size_t namelen,
|
||||
const jschar *name, size_t namelen,
|
||||
uintN attrs, JSBool *foundp)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
return SetPropertyAttributes(cx, obj,
|
||||
js_AtomizeChars(cx, name, AUTO_NAMELEN(name,namelen), 0),
|
||||
attrs, foundp);
|
||||
return SetPropertyAttributes(cx, obj,
|
||||
js_AtomizeChars(cx, name, AUTO_NAMELEN(name,namelen), 0),
|
||||
attrs, foundp);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
|
@ -1570,7 +1570,7 @@ JS_DefineUCPropertyWithTinyId(JSContext *cx, JSObject *obj,
|
|||
|
||||
CHECK_REQUEST(cx);
|
||||
ok = DefineUCProperty(cx, obj, name, namelen, value, getter, setter, attrs,
|
||||
&prop);
|
||||
&prop);
|
||||
if (ok && prop) {
|
||||
if (OBJ_IS_NATIVE(obj)) {
|
||||
sprop = (JSScopeProperty *)prop;
|
||||
|
@ -1594,7 +1594,7 @@ JS_LookupUCProperty(JSContext *cx, JSObject *obj,
|
|||
CHECK_REQUEST(cx);
|
||||
ok = LookupUCProperty(cx, obj, name, namelen, &obj2, &prop);
|
||||
if (ok)
|
||||
*vp = LookupResult(cx, obj, obj2, prop);
|
||||
*vp = LookupResult(cx, obj, obj2, prop);
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
@ -1704,9 +1704,9 @@ JS_AliasElement(JSContext *cx, JSObject *obj, const char *name, jsint alias)
|
|||
if (obj2 != obj || !OBJ_IS_NATIVE(obj2)) {
|
||||
char numBuf[12];
|
||||
OBJ_DROP_PROPERTY(cx, obj2, prop);
|
||||
sprintf(numBuf, "%ld", (long)alias);
|
||||
PR_snprintf(numBuf, sizeof numBuf, "%ld", (long)alias);
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_ALIAS,
|
||||
numBuf, name, OBJ_GET_CLASS(cx, obj2)->name);
|
||||
numBuf, name, OBJ_GET_CLASS(cx, obj2)->name);
|
||||
return JS_FALSE;
|
||||
}
|
||||
scope = (JSScope *) obj->map;
|
||||
|
@ -1727,7 +1727,7 @@ JS_LookupElement(JSContext *cx, JSObject *obj, jsint index, jsval *vp)
|
|||
CHECK_REQUEST(cx);
|
||||
ok = OBJ_LOOKUP_PROPERTY(cx, obj, INT_TO_JSVAL(index), &obj2, &prop);
|
||||
if (ok)
|
||||
*vp = LookupResult(cx, obj, obj2, prop);
|
||||
*vp = LookupResult(cx, obj, obj2, prop);
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
@ -1797,10 +1797,10 @@ JS_Enumerate(JSContext *cx, JSObject *obj)
|
|||
|
||||
/* Get the number of properties to enumerate. */
|
||||
if (!OBJ_ENUMERATE(cx, obj, JSENUMERATE_INIT, &iter_state, &num_properties))
|
||||
goto error;
|
||||
goto error;
|
||||
if (!JSVAL_IS_INT(num_properties)) {
|
||||
PR_ASSERT(0);
|
||||
goto error;
|
||||
PR_ASSERT(0);
|
||||
goto error;
|
||||
}
|
||||
|
||||
n = JSVAL_TO_INT(num_properties);
|
||||
|
@ -1825,9 +1825,9 @@ JS_Enumerate(JSContext *cx, JSObject *obj)
|
|||
|
||||
error:
|
||||
if (iter_state != JSVAL_NULL)
|
||||
OBJ_ENUMERATE(cx, obj, JSENUMERATE_DESTROY, &iter_state, 0);
|
||||
OBJ_ENUMERATE(cx, obj, JSENUMERATE_DESTROY, &iter_state, 0);
|
||||
if (ida)
|
||||
JS_DestroyIdArray(cx, ida);
|
||||
JS_DestroyIdArray(cx, ida);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1849,8 +1849,8 @@ JS_NewFunction(JSContext *cx, JSNative call, uintN nargs, uintN flags,
|
|||
|
||||
atom = NULL;
|
||||
if (name) {
|
||||
atom = js_Atomize(cx, name, strlen(name), 0);
|
||||
if (!atom)
|
||||
atom = js_Atomize(cx, name, strlen(name), 0);
|
||||
if (!atom)
|
||||
return NULL;
|
||||
}
|
||||
return js_NewFunction(cx, NULL, call, nargs, flags, parent, atom);
|
||||
|
@ -1938,7 +1938,7 @@ CompileTokenStream(JSContext *cx, JSObject *obj, JSTokenStream *ts,
|
|||
lineno = ts->lineno;
|
||||
if (!js_CompileTokenStream(cx, obj, ts, &cg)) {
|
||||
script = NULL;
|
||||
goto out;
|
||||
goto out;
|
||||
}
|
||||
script = js_NewScriptFromCG(cx, &cg, NULL);
|
||||
if (!script)
|
||||
|
@ -2012,7 +2012,7 @@ JS_CompileUCScriptForPrincipals(JSContext *cx, JSObject *obj,
|
|||
mark = PR_ARENA_MARK(&cx->tempPool);
|
||||
ts = js_NewTokenStream(cx, chars, length, filename, lineno, principals);
|
||||
if (!ts)
|
||||
return NULL;
|
||||
return NULL;
|
||||
return CompileTokenStream(cx, obj, ts, mark);
|
||||
}
|
||||
|
||||
|
@ -2040,10 +2040,10 @@ JS_NewScriptObject(JSContext *cx, JSScript *script)
|
|||
CHECK_REQUEST(cx);
|
||||
obj = js_NewObject(cx, &js_ScriptClass, NULL, NULL);
|
||||
if (!obj)
|
||||
return NULL;
|
||||
return NULL;
|
||||
if (script) {
|
||||
JS_SetPrivate(cx, obj, script);
|
||||
script->object = obj;
|
||||
JS_SetPrivate(cx, obj, script);
|
||||
script->object = obj;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
@ -2166,7 +2166,7 @@ JS_CompileUCFunctionForPrincipals(JSContext *cx, JSObject *obj,
|
|||
}
|
||||
out:
|
||||
if (ts)
|
||||
js_CloseTokenStream(cx, ts);
|
||||
js_CloseTokenStream(cx, ts);
|
||||
PR_ARENA_RELEASE(&cx->tempPool, mark);
|
||||
return fun;
|
||||
}
|
||||
|
@ -2507,7 +2507,7 @@ JS_ReportErrorNumber(JSContext *cx, JSErrorCallback errorCallback,
|
|||
CHECK_REQUEST(cx);
|
||||
va_start(ap, errorNumber);
|
||||
js_ReportErrorNumberVA(cx, JSREPORT_ERROR, errorCallback, userRef,
|
||||
errorNumber, ap);
|
||||
errorNumber, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
|
|
|
@ -493,8 +493,8 @@ struct JSFunctionSpec {
|
|||
extern JS_PUBLIC_API(JSObject *)
|
||||
JS_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto,
|
||||
JSClass *clasp, JSNative constructor, uintN nargs,
|
||||
JSPropertySpec *ps, JSFunctionSpec *fs,
|
||||
JSPropertySpec *static_ps, JSFunctionSpec *static_fs);
|
||||
JSPropertySpec *ps, JSFunctionSpec *fs,
|
||||
JSPropertySpec *static_ps, JSFunctionSpec *static_fs);
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
extern JS_PUBLIC_API(JSClass *)
|
||||
|
@ -515,7 +515,7 @@ JS_SetPrivate(JSContext *cx, JSObject *obj, void *data);
|
|||
|
||||
extern JS_PUBLIC_API(void *)
|
||||
JS_GetInstancePrivate(JSContext *cx, JSObject *obj, JSClass *clasp,
|
||||
jsval *argv);
|
||||
jsval *argv);
|
||||
|
||||
extern JS_PUBLIC_API(JSObject *)
|
||||
JS_GetPrototype(JSContext *cx, JSObject *obj);
|
||||
|
@ -612,8 +612,8 @@ JS_DefineUCProperty(JSContext *cx, JSObject *obj,
|
|||
* JS_FALSE and the value of *attrsp is undefined.
|
||||
*/
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_GetUCPropertyAttributes(JSContext *cx, JSObject *obj,
|
||||
const jschar *name, size_t namelen,
|
||||
JS_GetUCPropertyAttributes(JSContext *cx, JSObject *obj,
|
||||
const jschar *name, size_t namelen,
|
||||
uintN *attrsp, JSBool *foundp);
|
||||
|
||||
/*
|
||||
|
@ -624,7 +624,7 @@ JS_GetUCPropertyAttributes(JSContext *cx, JSObject *obj,
|
|||
*/
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_SetUCPropertyAttributes(JSContext *cx, JSObject *obj,
|
||||
const jschar *name, size_t namelen,
|
||||
const jschar *name, size_t namelen,
|
||||
uintN attrs, JSBool *foundp);
|
||||
|
||||
|
||||
|
@ -721,8 +721,8 @@ typedef struct JSPrincipals {
|
|||
((principals)->refcount++)
|
||||
#define JSPRINCIPALS_DROP(cx, principals) \
|
||||
((--((principals)->refcount) == 0) \
|
||||
? (*(principals)->destroy)((cx), (principals)) \
|
||||
: (void) 0)
|
||||
? (*(principals)->destroy)((cx), (principals)) \
|
||||
: (void) 0)
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
|
@ -790,10 +790,10 @@ JS_CompileFunction(JSContext *cx, JSObject *obj, const char *name,
|
|||
|
||||
extern JS_PUBLIC_API(JSFunction *)
|
||||
JS_CompileFunctionForPrincipals(JSContext *cx, JSObject *obj,
|
||||
JSPrincipals *principals, const char *name,
|
||||
uintN nargs, const char **argnames,
|
||||
const char *bytes, size_t length,
|
||||
const char *filename, uintN lineno);
|
||||
JSPrincipals *principals, const char *name,
|
||||
uintN nargs, const char **argnames,
|
||||
const char *bytes, size_t length,
|
||||
const char *filename, uintN lineno);
|
||||
|
||||
extern JS_PUBLIC_API(JSFunction *)
|
||||
JS_CompileUCFunction(JSContext *cx, JSObject *obj, const char *name,
|
||||
|
@ -947,14 +947,13 @@ extern JS_PUBLIC_API(void)
|
|||
JS_ReportOutOfMemory(JSContext *cx);
|
||||
|
||||
struct JSErrorReport {
|
||||
const char *filename; /* source file name, URL, etc., or null */
|
||||
uintN lineno; /* source line number */
|
||||
const char *linebuf; /* offending source line without final '\n' */
|
||||
const char *tokenptr; /* pointer to error token in linebuf */
|
||||
const jschar *uclinebuf; /* unicode (original) line buffer */
|
||||
const jschar *uctokenptr;/* unicode (original) token pointer */
|
||||
uintN flags; /* error/warning, etc. */
|
||||
|
||||
const char *filename; /* source file name, URL, etc., or null */
|
||||
uintN lineno; /* source line number */
|
||||
const char *linebuf; /* offending source line without final \n */
|
||||
const char *tokenptr; /* pointer to error token in linebuf */
|
||||
const jschar *uclinebuf; /* unicode (original) line buffer */
|
||||
const jschar *uctokenptr; /* unicode (original) token pointer */
|
||||
uintN flags; /* error/warning, etc. */
|
||||
uintN errorNumber; /* the error number, e.g. see jsmsg.def */
|
||||
JSString *ucmessage; /* the (default) error message */
|
||||
JSString **messageArgs; /* arguments for the error message */
|
||||
|
|
1300
js/ref/jsarray.c
1300
js/ref/jsarray.c
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
664
js/ref/jsatom.c
664
js/ref/jsatom.c
|
@ -1,664 +0,0 @@
|
|||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* JS atom table.
|
||||
*/
|
||||
#include "jsstddef.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "prtypes.h"
|
||||
#include "prassert.h"
|
||||
#include "prhash.h"
|
||||
#include "jsapi.h"
|
||||
#include "jsatom.h"
|
||||
#include "jscntxt.h"
|
||||
#include "jsgc.h"
|
||||
#include "jslock.h"
|
||||
#include "jsnum.h"
|
||||
#include "jsopcode.h"
|
||||
#include "jsstr.h"
|
||||
|
||||
/*
|
||||
* Keep this in sync with jspubtd.h -- an assertion below will insist that
|
||||
* its length match the JSType enum's JSTYPE_LIMIT limit value.
|
||||
*/
|
||||
char *js_type_str[] = {
|
||||
"undefined",
|
||||
"object",
|
||||
"function",
|
||||
"string",
|
||||
"number",
|
||||
"boolean",
|
||||
};
|
||||
|
||||
char *js_boolean_str[] = {
|
||||
js_false_str,
|
||||
js_true_str
|
||||
};
|
||||
|
||||
char js_Array_str[] = "Array";
|
||||
char js_Math_str[] = "Math";
|
||||
char js_Object_str[] = "Object";
|
||||
char js_anonymous_str[] = "anonymous";
|
||||
char js_arguments_str[] = "arguments";
|
||||
char js_arity_str[] = "arity";
|
||||
char js_assign_str[] = "assign";
|
||||
char js_callee_str[] = "callee";
|
||||
char js_caller_str[] = "caller";
|
||||
char js_class_prototype_str[] = "prototype";
|
||||
char js_constructor_str[] = "constructor";
|
||||
char js_count_str[] = "__count__";
|
||||
char js_eval_str[] = "eval";
|
||||
char js_index_str[] = "index";
|
||||
char js_input_str[] = "input";
|
||||
char js_length_str[] = "length";
|
||||
char js_name_str[] = "name";
|
||||
char js_parent_str[] = "__parent__";
|
||||
char js_proto_str[] = "__proto__";
|
||||
char js_toSource_str[] = "toSource";
|
||||
char js_toString_str[] = "toString";
|
||||
char js_valueOf_str[] = "valueOf";
|
||||
|
||||
#define HASH_OBJECT(o) ((prhashcode)(o) >> JSVAL_TAGBITS)
|
||||
#define HASH_INT(i) ((prhashcode)(i))
|
||||
#define HASH_DOUBLE(dp) ((prhashcode)(((uint32*)(dp))[0] ^ ((uint32*)(dp))[1]))
|
||||
#define HASH_BOOLEAN(b) ((prhashcode)(b))
|
||||
|
||||
PR_STATIC_CALLBACK(prhashcode)
|
||||
js_hash_atom_key(const void *key)
|
||||
{
|
||||
jsval v;
|
||||
jsdouble *dp;
|
||||
|
||||
/* Order JSVAL_IS_* tests by likelihood of success. */
|
||||
v = (jsval)key;
|
||||
if (JSVAL_IS_STRING(v))
|
||||
return js_HashString(JSVAL_TO_STRING(v));
|
||||
if (JSVAL_IS_INT(v))
|
||||
return HASH_INT(JSVAL_TO_INT(v));
|
||||
if (JSVAL_IS_DOUBLE(v)) {
|
||||
dp = JSVAL_TO_DOUBLE(v);
|
||||
return HASH_DOUBLE(dp);
|
||||
}
|
||||
if (JSVAL_IS_OBJECT(v))
|
||||
return HASH_OBJECT(JSVAL_TO_OBJECT(v));
|
||||
if (JSVAL_IS_BOOLEAN(v))
|
||||
return HASH_BOOLEAN(JSVAL_TO_BOOLEAN(v));
|
||||
return (prhashcode)v;
|
||||
}
|
||||
|
||||
PR_STATIC_CALLBACK(intN)
|
||||
js_compare_atom_keys(const void *k1, const void *k2)
|
||||
{
|
||||
jsval v1, v2;
|
||||
|
||||
v1 = (jsval)k1, v2 = (jsval)k2;
|
||||
if (JSVAL_IS_STRING(v1) && JSVAL_IS_STRING(v2))
|
||||
return !js_CompareStrings(JSVAL_TO_STRING(v1), JSVAL_TO_STRING(v2));
|
||||
if (JSVAL_IS_DOUBLE(v1) && JSVAL_IS_DOUBLE(v2)) {
|
||||
double d1 = *JSVAL_TO_DOUBLE(v1);
|
||||
double d2 = *JSVAL_TO_DOUBLE(v2);
|
||||
if (JSDOUBLE_IS_NaN(d1))
|
||||
return JSDOUBLE_IS_NaN(d2);
|
||||
#ifdef XP_PC
|
||||
/* XXX MSVC miscompiles such that (NaN == 0) */
|
||||
if (JSDOUBLE_IS_NaN(d2))
|
||||
return JS_FALSE;
|
||||
#endif
|
||||
return d1 == d2;
|
||||
}
|
||||
return v1 == v2;
|
||||
}
|
||||
|
||||
PR_STATIC_CALLBACK(int)
|
||||
js_compare_stub(const void *v1, const void *v2)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
PR_STATIC_CALLBACK(void *)
|
||||
js_alloc_atom_space(void *priv, size_t size)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
PR_STATIC_CALLBACK(void)
|
||||
js_free_atom_space(void *priv, void *item)
|
||||
{
|
||||
free(item);
|
||||
}
|
||||
|
||||
PR_STATIC_CALLBACK(PRHashEntry *)
|
||||
js_alloc_atom(void *priv, const void *key)
|
||||
{
|
||||
JSAtomState *state = priv;
|
||||
JSAtom *atom;
|
||||
|
||||
atom = malloc(sizeof(JSAtom));
|
||||
if (!atom)
|
||||
return NULL;
|
||||
#ifdef JS_THREADSAFE
|
||||
state->tablegen++;
|
||||
#endif
|
||||
atom->entry.key = key;
|
||||
atom->entry.value = NULL;
|
||||
atom->flags = 0;
|
||||
atom->kwindex = -1;
|
||||
atom->number = state->number++;
|
||||
return &atom->entry;
|
||||
}
|
||||
|
||||
PR_STATIC_CALLBACK(void)
|
||||
js_free_atom(void *priv, PRHashEntry *he, uintN flag)
|
||||
{
|
||||
if (flag != HT_FREE_ENTRY)
|
||||
return;
|
||||
#ifdef JS_THREADSAFE
|
||||
((JSAtomState *)priv)->tablegen++;
|
||||
#endif
|
||||
free(he);
|
||||
}
|
||||
|
||||
static PRHashAllocOps atom_alloc_ops = {
|
||||
js_alloc_atom_space, js_free_atom_space,
|
||||
js_alloc_atom, js_free_atom
|
||||
};
|
||||
|
||||
#define JS_ATOM_HASH_SIZE 1024
|
||||
|
||||
JSBool
|
||||
js_InitAtomState(JSContext *cx, JSAtomState *state)
|
||||
{
|
||||
uintN i;
|
||||
|
||||
state->runtime = cx->runtime;
|
||||
state->number = 0;
|
||||
state->table = PR_NewHashTable(JS_ATOM_HASH_SIZE, js_hash_atom_key,
|
||||
js_compare_atom_keys, js_compare_stub,
|
||||
&atom_alloc_ops, state);
|
||||
if (!state->table) {
|
||||
JS_ReportOutOfMemory(cx);
|
||||
return JS_FALSE;
|
||||
}
|
||||
#ifdef JS_THREADSAFE
|
||||
js_NewLock(&state->lock);
|
||||
state->tablegen = 0;
|
||||
#endif
|
||||
|
||||
#define FROB(lval,str) { \
|
||||
if (!(state->lval = js_Atomize(cx, str, strlen(str), ATOM_PINNED))) { \
|
||||
js_FreeAtomState(cx, state); \
|
||||
return JS_FALSE; \
|
||||
} \
|
||||
}
|
||||
|
||||
PR_ASSERT(sizeof js_type_str / sizeof js_type_str[0] == JSTYPE_LIMIT);
|
||||
for (i = 0; i < JSTYPE_LIMIT; i++)
|
||||
FROB(typeAtoms[i], js_type_str[i]);
|
||||
|
||||
FROB(booleanAtoms[0], js_false_str);
|
||||
FROB(booleanAtoms[1], js_true_str);
|
||||
FROB(nullAtom, js_null_str);
|
||||
|
||||
FROB(ArrayAtom, js_Array_str);
|
||||
FROB(MathAtom, js_Math_str);
|
||||
FROB(ObjectAtom, js_Object_str);
|
||||
FROB(anonymousAtom, js_anonymous_str);
|
||||
FROB(argumentsAtom, js_arguments_str);
|
||||
FROB(arityAtom, js_arity_str);
|
||||
FROB(assignAtom, js_assign_str);
|
||||
FROB(calleeAtom, js_callee_str);
|
||||
FROB(callerAtom, js_caller_str);
|
||||
FROB(classPrototypeAtom, js_class_prototype_str);
|
||||
FROB(constructorAtom, js_constructor_str);
|
||||
FROB(countAtom, js_count_str);
|
||||
FROB(indexAtom, js_index_str);
|
||||
FROB(inputAtom, js_input_str);
|
||||
FROB(lengthAtom, js_length_str);
|
||||
FROB(nameAtom, js_name_str);
|
||||
FROB(parentAtom, js_parent_str);
|
||||
FROB(protoAtom, js_proto_str);
|
||||
FROB(toSourceAtom, js_toSource_str);
|
||||
FROB(toStringAtom, js_toString_str);
|
||||
FROB(valueOfAtom, js_valueOf_str);
|
||||
|
||||
#undef FROB
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
js_FreeAtomState(JSContext *cx, JSAtomState *state)
|
||||
{
|
||||
state->runtime = NULL;
|
||||
PR_HashTableDestroy(state->table);
|
||||
state->table = NULL;
|
||||
state->number = 0;
|
||||
#ifdef JS_THREADSAFE
|
||||
js_DestroyLock(&state->lock);
|
||||
#endif
|
||||
}
|
||||
|
||||
typedef struct MarkArgs {
|
||||
JSRuntime *runtime;
|
||||
JSGCThingMarker mark;
|
||||
} MarkArgs;
|
||||
|
||||
PR_STATIC_CALLBACK(intN)
|
||||
js_atom_marker(PRHashEntry *he, intN i, void *arg)
|
||||
{
|
||||
JSAtom *atom;
|
||||
jsval key;
|
||||
MarkArgs *args;
|
||||
|
||||
atom = (JSAtom *)he;
|
||||
if (atom->flags & ATOM_PINNED) {
|
||||
atom->flags |= ATOM_MARK;
|
||||
key = ATOM_KEY(atom);
|
||||
if (JSVAL_IS_GCTHING(key)) {
|
||||
args = arg;
|
||||
args->mark(args->runtime, JSVAL_TO_GCTHING(key));
|
||||
}
|
||||
}
|
||||
return HT_ENUMERATE_NEXT;
|
||||
}
|
||||
|
||||
void
|
||||
js_MarkAtomState(JSAtomState *state, JSGCThingMarker mark)
|
||||
{
|
||||
MarkArgs args;
|
||||
|
||||
args.runtime = state->runtime;
|
||||
args.mark = mark;
|
||||
PR_HashTableEnumerateEntries(state->table, js_atom_marker, &args);
|
||||
}
|
||||
|
||||
PR_STATIC_CALLBACK(intN)
|
||||
js_atom_sweeper(PRHashEntry *he, intN i, void *arg)
|
||||
{
|
||||
JSAtom *atom;
|
||||
|
||||
atom = (JSAtom *)he;
|
||||
if (atom->flags & ATOM_MARK) {
|
||||
atom->flags &= ~ATOM_MARK;
|
||||
return HT_ENUMERATE_NEXT;
|
||||
}
|
||||
PR_ASSERT((atom->flags & ATOM_PINNED) == 0);
|
||||
atom->entry.key = NULL;
|
||||
atom->flags = 0;
|
||||
return HT_ENUMERATE_REMOVE;
|
||||
}
|
||||
|
||||
void
|
||||
js_SweepAtomState(JSAtomState *state)
|
||||
{
|
||||
PR_HashTableEnumerateEntries(state->table, js_atom_sweeper, NULL);
|
||||
}
|
||||
|
||||
PR_STATIC_CALLBACK(intN)
|
||||
js_atom_unpinner(PRHashEntry *he, intN i, void *arg)
|
||||
{
|
||||
JSAtom *atom;
|
||||
|
||||
atom = (JSAtom *)he;
|
||||
atom->flags &= ~ATOM_PINNED;
|
||||
return HT_ENUMERATE_NEXT;
|
||||
}
|
||||
|
||||
void
|
||||
js_UnpinPinnedAtoms(JSAtomState *state)
|
||||
{
|
||||
PR_HashTableEnumerateEntries(state->table, js_atom_unpinner, NULL);
|
||||
}
|
||||
|
||||
static JSAtom *
|
||||
js_AtomizeHashedKey(JSContext *cx, jsval key, prhashcode keyHash, uintN flags)
|
||||
{
|
||||
JSAtomState *state;
|
||||
PRHashTable *table;
|
||||
PRHashEntry *he, **hep;
|
||||
JSAtom *atom;
|
||||
|
||||
state = &cx->runtime->atomState;
|
||||
JS_LOCK(&state->lock,cx);
|
||||
table = state->table;
|
||||
hep = PR_HashTableRawLookup(table, keyHash, (void *)key);
|
||||
if ((he = *hep) == NULL) {
|
||||
he = PR_HashTableRawAdd(table, hep, keyHash, (void *)key, NULL);
|
||||
if (!he) {
|
||||
JS_ReportOutOfMemory(cx);
|
||||
atom = NULL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
atom = (JSAtom *)he;
|
||||
atom->flags |= flags;
|
||||
out:
|
||||
JS_UNLOCK(&state->lock,cx);
|
||||
return atom;
|
||||
}
|
||||
|
||||
JSAtom *
|
||||
js_AtomizeObject(JSContext *cx, JSObject *obj, uintN flags)
|
||||
{
|
||||
jsval key;
|
||||
prhashcode keyHash;
|
||||
|
||||
/* XXX must be set in the following order or MSVC1.52 will crash */
|
||||
keyHash = HASH_OBJECT(obj);
|
||||
key = OBJECT_TO_JSVAL(obj);
|
||||
return js_AtomizeHashedKey(cx, key, keyHash, flags);
|
||||
}
|
||||
|
||||
JSAtom *
|
||||
js_AtomizeBoolean(JSContext *cx, JSBool b, uintN flags)
|
||||
{
|
||||
jsval key;
|
||||
prhashcode keyHash;
|
||||
|
||||
key = BOOLEAN_TO_JSVAL(b);
|
||||
keyHash = HASH_BOOLEAN(b);
|
||||
return js_AtomizeHashedKey(cx, key, keyHash, flags);
|
||||
}
|
||||
|
||||
JSAtom *
|
||||
js_AtomizeInt(JSContext *cx, jsint i, uintN flags)
|
||||
{
|
||||
jsval key;
|
||||
prhashcode keyHash;
|
||||
|
||||
key = INT_TO_JSVAL(i);
|
||||
keyHash = HASH_INT(i);
|
||||
return js_AtomizeHashedKey(cx, key, keyHash, flags);
|
||||
}
|
||||
|
||||
JSAtom *
|
||||
js_AtomizeDouble(JSContext *cx, jsdouble d, uintN flags)
|
||||
{
|
||||
jsdouble *dp;
|
||||
prhashcode keyHash;
|
||||
jsval key;
|
||||
JSAtomState *state;
|
||||
PRHashTable *table;
|
||||
PRHashEntry *he, **hep;
|
||||
JSAtom *atom;
|
||||
|
||||
#if PR_ALIGN_OF_DOUBLE == 8
|
||||
dp = &d;
|
||||
#else
|
||||
char alignbuf[16];
|
||||
|
||||
dp = (jsdouble *)&alignbuf[8 - ((pruword)&alignbuf & 7)];
|
||||
*dp = d;
|
||||
#endif
|
||||
|
||||
keyHash = HASH_DOUBLE(dp);
|
||||
key = DOUBLE_TO_JSVAL(dp);
|
||||
state = &cx->runtime->atomState;
|
||||
JS_LOCK(&state->lock,cx);
|
||||
table = state->table;
|
||||
hep = PR_HashTableRawLookup(table, keyHash, (void *)key);
|
||||
if ((he = *hep) == NULL) {
|
||||
#ifdef JS_THREADSAFE
|
||||
uint32 gen = state->tablegen;
|
||||
#endif
|
||||
JS_UNLOCK(&state->lock,cx);
|
||||
if (!js_NewDoubleValue(cx, d, &key))
|
||||
return NULL;
|
||||
JS_LOCK(&state->lock,cx);
|
||||
#ifdef JS_THREADSAFE
|
||||
if (state->tablegen != gen) {
|
||||
hep = PR_HashTableRawLookup(table, keyHash, (void *)key);
|
||||
if ((he = *hep) != NULL) {
|
||||
atom = (JSAtom *)he;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
he = PR_HashTableRawAdd(table, hep, keyHash, (void *)key, NULL);
|
||||
if (!he) {
|
||||
JS_ReportOutOfMemory(cx);
|
||||
atom = NULL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
atom = (JSAtom *)he;
|
||||
atom->flags |= flags;
|
||||
out:
|
||||
JS_UNLOCK(&state->lock,cx);
|
||||
return atom;
|
||||
}
|
||||
|
||||
JSAtom *
|
||||
js_AtomizeString(JSContext *cx, JSString *str, uintN flags)
|
||||
{
|
||||
prhashcode keyHash;
|
||||
jsval key;
|
||||
JSAtomState *state;
|
||||
PRHashTable *table;
|
||||
PRHashEntry *he, **hep;
|
||||
JSAtom *atom;
|
||||
|
||||
keyHash = js_HashString(str);
|
||||
key = STRING_TO_JSVAL(str);
|
||||
state = &cx->runtime->atomState;
|
||||
JS_LOCK(&state->lock,cx);
|
||||
table = state->table;
|
||||
hep = PR_HashTableRawLookup(table, keyHash, (void *)key);
|
||||
if ((he = *hep) == NULL) {
|
||||
if (flags & ATOM_TMPSTR) {
|
||||
#ifdef JS_THREADSAFE
|
||||
uint32 gen = state->tablegen;
|
||||
#endif
|
||||
JS_UNLOCK(&state->lock,cx);
|
||||
flags &= ~ATOM_TMPSTR;
|
||||
if (flags & ATOM_NOCOPY) {
|
||||
flags &= ~ATOM_NOCOPY;
|
||||
str = js_NewString(cx, str->chars, str->length, 0);
|
||||
} else {
|
||||
str = js_NewStringCopyN(cx, str->chars, str->length, 0);
|
||||
}
|
||||
if (!str)
|
||||
return NULL;
|
||||
key = STRING_TO_JSVAL(str);
|
||||
JS_LOCK(&state->lock,cx);
|
||||
#ifdef JS_THREADSAFE
|
||||
if (state->tablegen != gen) {
|
||||
hep = PR_HashTableRawLookup(table, keyHash, (void *)key);
|
||||
if ((he = *hep) != NULL) {
|
||||
atom = (JSAtom *)he;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
he = PR_HashTableRawAdd(table, hep, keyHash, (void *)key, NULL);
|
||||
if (!he) {
|
||||
JS_ReportOutOfMemory(cx);
|
||||
atom = NULL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
atom = (JSAtom *)he;
|
||||
atom->flags |= flags;
|
||||
out:
|
||||
JS_UNLOCK(&state->lock,cx);
|
||||
return atom;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSAtom *)
|
||||
js_Atomize(JSContext *cx, const char *bytes, size_t length, uintN flags)
|
||||
{
|
||||
jschar *chars;
|
||||
JSString *str;
|
||||
JSAtom *atom;
|
||||
#if PR_ALIGN_OF_DOUBLE == 8
|
||||
union { jsdouble d; JSString s; } u;
|
||||
|
||||
str = &u.s;
|
||||
#else
|
||||
char alignbuf[16];
|
||||
|
||||
str = (JSString *)&alignbuf[8 - ((pruword)&alignbuf & 7)];
|
||||
#endif
|
||||
|
||||
chars = js_InflateString(cx, bytes, length);
|
||||
if (!chars)
|
||||
return NULL;
|
||||
str->chars = chars;
|
||||
str->length = length;
|
||||
atom = js_AtomizeString(cx, str, ATOM_TMPSTR | ATOM_NOCOPY | flags);
|
||||
if (!atom || ATOM_TO_STRING(atom)->chars != chars)
|
||||
JS_free(cx, chars);
|
||||
return atom;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSAtom *)
|
||||
js_AtomizeChars(JSContext *cx, const jschar *chars, size_t length, uintN flags)
|
||||
{
|
||||
JSString *str;
|
||||
#if PR_ALIGN_OF_DOUBLE == 8
|
||||
union { jsdouble d; JSString s; } u;
|
||||
|
||||
str = &u.s;
|
||||
#else
|
||||
char alignbuf[16];
|
||||
|
||||
str = (JSString *)&alignbuf[8 - ((pruword)&alignbuf & 7)];
|
||||
#endif
|
||||
|
||||
str->chars = (jschar *)chars;
|
||||
str->length = length;
|
||||
return js_AtomizeString(cx, str, ATOM_TMPSTR | flags);
|
||||
}
|
||||
|
||||
JSAtom *
|
||||
js_AtomizeValue(JSContext *cx, jsval value, uintN flags)
|
||||
{
|
||||
if (JSVAL_IS_STRING(value))
|
||||
return js_AtomizeString(cx, JSVAL_TO_STRING(value), flags);
|
||||
if (JSVAL_IS_INT(value))
|
||||
return js_AtomizeInt(cx, JSVAL_TO_INT(value), flags);
|
||||
if (JSVAL_IS_DOUBLE(value))
|
||||
return js_AtomizeDouble(cx, *JSVAL_TO_DOUBLE(value), flags);
|
||||
if (JSVAL_IS_OBJECT(value))
|
||||
return js_AtomizeObject(cx, JSVAL_TO_OBJECT(value), flags);
|
||||
if (JSVAL_IS_BOOLEAN(value))
|
||||
return js_AtomizeBoolean(cx, JSVAL_TO_BOOLEAN(value), flags);
|
||||
return js_AtomizeHashedKey(cx, value, (prhashcode)value, flags);
|
||||
}
|
||||
|
||||
JSAtom *
|
||||
js_ValueToStringAtom(JSContext *cx, jsval v)
|
||||
{
|
||||
JSString *str;
|
||||
|
||||
str = js_ValueToString(cx, v);
|
||||
if (!str)
|
||||
return NULL;
|
||||
return js_AtomizeString(cx, str, 0);
|
||||
}
|
||||
|
||||
JSAtomListElement *
|
||||
js_IndexAtom(JSContext *cx, JSAtom *atom, JSAtomList *al)
|
||||
{
|
||||
JSAtomListElement *ale;
|
||||
|
||||
ATOM_LIST_SEARCH(ale, al, atom);
|
||||
if (!ale) {
|
||||
PR_ARENA_ALLOCATE(ale, &cx->tempPool, sizeof(JSAtomListElement));
|
||||
if (!ale) {
|
||||
JS_ReportOutOfMemory(cx);
|
||||
return NULL;
|
||||
}
|
||||
ale->atom = atom;
|
||||
ale->index = (jsatomid) al->count++;
|
||||
ale->next = al->list;
|
||||
al->list = ale;
|
||||
}
|
||||
return ale;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSAtom *)
|
||||
js_GetAtom(JSContext *cx, JSAtomMap *map, jsatomid i)
|
||||
{
|
||||
JSAtom *atom;
|
||||
|
||||
PR_ASSERT(map->vector && i < map->length);
|
||||
if (!map->vector || i >= map->length) {
|
||||
char numBuf[12];
|
||||
sprintf(numBuf, "%s", (long)i);
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_BAD_ATOMIC_NUMBER, numBuf);
|
||||
return NULL;
|
||||
}
|
||||
atom = map->vector[i];
|
||||
PR_ASSERT(atom);
|
||||
return atom;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSBool)
|
||||
js_InitAtomMap(JSContext *cx, JSAtomMap *map, JSAtomList *al)
|
||||
{
|
||||
JSAtom **vector;
|
||||
JSAtomListElement *ale, *next;
|
||||
uint32 count;
|
||||
|
||||
ale = al->list;
|
||||
if (!ale) {
|
||||
map->vector = NULL;
|
||||
map->length = 0;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
count = al->count;
|
||||
if (count >= ATOM_INDEX_LIMIT) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_TOO_MANY_LITERALS);
|
||||
return JS_FALSE;
|
||||
}
|
||||
vector = JS_malloc(cx, (size_t) count * sizeof *vector);
|
||||
if (!vector)
|
||||
return JS_FALSE;
|
||||
|
||||
do {
|
||||
vector[ale->index] = ale->atom;
|
||||
next = ale->next;
|
||||
ale->next = NULL;
|
||||
} while ((ale = next) != NULL);
|
||||
al->list = NULL;
|
||||
al->count = 0;
|
||||
|
||||
map->vector = vector;
|
||||
map->length = (jsatomid)count;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
js_FreeAtomMap(JSContext *cx, JSAtomMap *map)
|
||||
{
|
||||
if (map->vector) {
|
||||
free(map->vector);
|
||||
map->vector = NULL;
|
||||
}
|
||||
map->length = 0;
|
||||
}
|
272
js/ref/jsatom.h
272
js/ref/jsatom.h
|
@ -1,272 +0,0 @@
|
|||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef jsatom_h___
|
||||
#define jsatom_h___
|
||||
/*
|
||||
* JS atom table.
|
||||
*/
|
||||
#include <stddef.h>
|
||||
#include "prtypes.h"
|
||||
#include "prhash.h"
|
||||
#include "jsapi.h"
|
||||
#include "jsprvtd.h"
|
||||
#include "jspubtd.h"
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
#include "jslock.h"
|
||||
#endif
|
||||
|
||||
PR_BEGIN_EXTERN_C
|
||||
|
||||
#define ATOM_NOCOPY 0x01 /* don't copy atom string bytes */
|
||||
#define ATOM_TMPSTR 0x02 /* internal, to avoid extra string */
|
||||
#define ATOM_MARK 0x04 /* atom is reachable via GC */
|
||||
#define ATOM_PINNED 0x08 /* atom is pinned against GC */
|
||||
|
||||
struct JSAtom {
|
||||
PRHashEntry entry; /* key is jsval, value keyword info */
|
||||
uint8 flags; /* flags, PINNED and/or MARK for now */
|
||||
int8 kwindex; /* keyword index, -1 if not keyword */
|
||||
jsatomid number; /* atom serial number and hash code */
|
||||
};
|
||||
|
||||
#define ATOM_KEY(atom) ((jsval)(atom)->entry.key)
|
||||
#define ATOM_IS_OBJECT(atom) JSVAL_IS_OBJECT(ATOM_KEY(atom))
|
||||
#define ATOM_TO_OBJECT(atom) JSVAL_TO_OBJECT(ATOM_KEY(atom))
|
||||
#define ATOM_IS_INT(atom) JSVAL_IS_INT(ATOM_KEY(atom))
|
||||
#define ATOM_TO_INT(atom) JSVAL_TO_INT(ATOM_KEY(atom))
|
||||
#define ATOM_IS_DOUBLE(atom) JSVAL_IS_DOUBLE(ATOM_KEY(atom))
|
||||
#define ATOM_TO_DOUBLE(atom) JSVAL_TO_DOUBLE(ATOM_KEY(atom))
|
||||
#define ATOM_IS_STRING(atom) JSVAL_IS_STRING(ATOM_KEY(atom))
|
||||
#define ATOM_TO_STRING(atom) JSVAL_TO_STRING(ATOM_KEY(atom))
|
||||
#define ATOM_IS_BOOLEAN(atom) JSVAL_IS_BOOLEAN(ATOM_KEY(atom))
|
||||
#define ATOM_TO_BOOLEAN(atom) JSVAL_TO_BOOLEAN(ATOM_KEY(atom))
|
||||
#define ATOM_BYTES(atom) JS_GetStringBytes(ATOM_TO_STRING(atom))
|
||||
|
||||
struct JSAtomListElement {
|
||||
JSAtomListElement *next;
|
||||
jsatomid index; /* index in script-specific atom map */
|
||||
JSAtom *atom;
|
||||
};
|
||||
|
||||
struct JSAtomList {
|
||||
JSAtomListElement *list; /* literals indexed for mapping */
|
||||
jsuint count; /* count of indexed literals */
|
||||
};
|
||||
|
||||
#define ATOM_LIST_INIT(al) ((al)->list = NULL, (al)->count = 0)
|
||||
|
||||
#define ATOM_LIST_SEARCH(_ale,_al,_atom) \
|
||||
PR_BEGIN_MACRO \
|
||||
JSAtomListElement **_alep = &(_al)->list; \
|
||||
while ((_ale = *_alep) != NULL) { \
|
||||
if (_ale->atom == (_atom)) { \
|
||||
/* Hit, move atom's element to the front of the list. */ \
|
||||
*_alep = _ale->next; \
|
||||
_ale->next = (_al)->list; \
|
||||
(_al)->list = _ale; \
|
||||
break; \
|
||||
} \
|
||||
_alep = &_ale->next; \
|
||||
} \
|
||||
PR_END_MACRO
|
||||
|
||||
struct JSAtomMap {
|
||||
JSAtom **vector; /* array of ptrs to indexed atoms */
|
||||
jsatomid length; /* count of (to-be-)indexed atoms */
|
||||
};
|
||||
|
||||
struct JSAtomState {
|
||||
JSRuntime *runtime; /* runtime that owns us */
|
||||
PRHashTable *table; /* hash table containing all atoms */
|
||||
jsatomid number; /* one beyond greatest atom number */
|
||||
|
||||
/* Type names and value literals. */
|
||||
JSAtom *typeAtoms[JSTYPE_LIMIT];
|
||||
JSAtom *booleanAtoms[2];
|
||||
JSAtom *nullAtom;
|
||||
|
||||
/* Various built-in or commonly-used atoms. */
|
||||
JSAtom *ArrayAtom;
|
||||
JSAtom *MathAtom;
|
||||
JSAtom *ObjectAtom;
|
||||
JSAtom *anonymousAtom;
|
||||
JSAtom *argumentsAtom;
|
||||
JSAtom *arityAtom;
|
||||
JSAtom *assignAtom;
|
||||
JSAtom *calleeAtom;
|
||||
JSAtom *callerAtom;
|
||||
JSAtom *classPrototypeAtom;
|
||||
JSAtom *constructorAtom;
|
||||
JSAtom *countAtom;
|
||||
JSAtom *indexAtom;
|
||||
JSAtom *inputAtom;
|
||||
JSAtom *lengthAtom;
|
||||
JSAtom *nameAtom;
|
||||
JSAtom *parentAtom;
|
||||
JSAtom *protoAtom;
|
||||
JSAtom *toSourceAtom;
|
||||
JSAtom *toStringAtom;
|
||||
JSAtom *valueOfAtom;
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
JSThinLock lock;
|
||||
volatile uint32 tablegen;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Well-known predefined strings and their atoms. */
|
||||
extern char *js_type_str[];
|
||||
extern char *js_boolean_str[];
|
||||
|
||||
extern char js_Array_str[];
|
||||
extern char js_Math_str[];
|
||||
extern char js_Object_str[];
|
||||
extern char js_anonymous_str[];
|
||||
extern char js_arguments_str[];
|
||||
extern char js_arity_str[];
|
||||
extern char js_assign_str[];
|
||||
extern char js_callee_str[];
|
||||
extern char js_caller_str[];
|
||||
extern char js_class_prototype_str[];
|
||||
extern char js_constructor_str[];
|
||||
extern char js_count_str[];
|
||||
extern char js_eval_str[];
|
||||
extern char js_index_str[];
|
||||
extern char js_input_str[];
|
||||
extern char js_length_str[];
|
||||
extern char js_name_str[];
|
||||
extern char js_parent_str[];
|
||||
extern char js_proto_str[];
|
||||
extern char js_toSource_str[];
|
||||
extern char js_toString_str[];
|
||||
extern char js_valueOf_str[];
|
||||
|
||||
/*
|
||||
* Initialize atom state. Return true on success, false with an out of
|
||||
* memory error report on failure.
|
||||
*/
|
||||
extern JSBool
|
||||
js_InitAtomState(JSContext *cx, JSAtomState *state);
|
||||
|
||||
/*
|
||||
* Free and clear atom state.
|
||||
*/
|
||||
extern void
|
||||
js_FreeAtomState(JSContext *cx, JSAtomState *state);
|
||||
|
||||
/*
|
||||
* Atom garbage collection hooks.
|
||||
*/
|
||||
typedef void
|
||||
(*JSGCThingMarker)(JSRuntime *rt, void *thing);
|
||||
|
||||
extern void
|
||||
js_MarkAtomState(JSAtomState *state, JSGCThingMarker mark);
|
||||
|
||||
extern void
|
||||
js_SweepAtomState(JSAtomState *state);
|
||||
|
||||
extern void
|
||||
js_UnpinPinnedAtoms(JSAtomState *state);
|
||||
|
||||
/*
|
||||
* Find or create the atom for an object. If we create a new atom, give it the
|
||||
* type indicated in flags. Return 0 on failure to allocate memory.
|
||||
*/
|
||||
extern JSAtom *
|
||||
js_AtomizeObject(JSContext *cx, JSObject *obj, uintN flags);
|
||||
|
||||
/*
|
||||
* Find or create the atom for a Boolean value. If we create a new atom, give
|
||||
* it the type indicated in flags. Return 0 on failure to allocate memory.
|
||||
*/
|
||||
extern JSAtom *
|
||||
js_AtomizeBoolean(JSContext *cx, JSBool b, uintN flags);
|
||||
|
||||
/*
|
||||
* Find or create the atom for an integer value. If we create a new atom, give
|
||||
* it the type indicated in flags. Return 0 on failure to allocate memory.
|
||||
*/
|
||||
extern JSAtom *
|
||||
js_AtomizeInt(JSContext *cx, jsint i, uintN flags);
|
||||
|
||||
/*
|
||||
* Find or create the atom for a double value. If we create a new atom, give
|
||||
* it the type indicated in flags. Return 0 on failure to allocate memory.
|
||||
*/
|
||||
extern JSAtom *
|
||||
js_AtomizeDouble(JSContext *cx, jsdouble d, uintN flags);
|
||||
|
||||
/*
|
||||
* Find or create the atom for a string. If we create a new atom, give it the
|
||||
* type indicated in flags. Return 0 on failure to allocate memory.
|
||||
*/
|
||||
extern JSAtom *
|
||||
js_AtomizeString(JSContext *cx, JSString *str, uintN flags);
|
||||
|
||||
extern JS_FRIEND_API(JSAtom *)
|
||||
js_Atomize(JSContext *cx, const char *bytes, size_t length, uintN flags);
|
||||
|
||||
extern JS_FRIEND_API(JSAtom *)
|
||||
js_AtomizeChars(JSContext *cx, const jschar *chars, size_t length, uintN flags);
|
||||
|
||||
/*
|
||||
* This variant handles all value tag types.
|
||||
*/
|
||||
extern JSAtom *
|
||||
js_AtomizeValue(JSContext *cx, jsval value, uintN flags);
|
||||
|
||||
/*
|
||||
* Convert v to an atomized string.
|
||||
*/
|
||||
extern JSAtom *
|
||||
js_ValueToStringAtom(JSContext *cx, jsval v);
|
||||
|
||||
/*
|
||||
* Assign atom an index and insert it on al.
|
||||
*/
|
||||
extern JSAtomListElement *
|
||||
js_IndexAtom(JSContext *cx, JSAtom *atom, JSAtomList *al);
|
||||
|
||||
/*
|
||||
* Get the atom with index i from map.
|
||||
*/
|
||||
extern JS_FRIEND_API(JSAtom *)
|
||||
js_GetAtom(JSContext *cx, JSAtomMap *map, jsatomid i);
|
||||
|
||||
/*
|
||||
* For all unmapped atoms recorded in al, add a mapping from the atom's index
|
||||
* to its address. The GC must not run until all indexed atoms in atomLists
|
||||
* have been mapped by scripts connected to live objects (Function and Script
|
||||
* class objects have scripts as/in their private data -- the GC knows about
|
||||
* these two classes).
|
||||
*/
|
||||
extern JS_FRIEND_API(JSBool)
|
||||
js_InitAtomMap(JSContext *cx, JSAtomMap *map, JSAtomList *al);
|
||||
|
||||
/*
|
||||
* Free map->vector and clear map.
|
||||
*/
|
||||
extern JS_FRIEND_API(void)
|
||||
js_FreeAtomMap(JSContext *cx, JSAtomMap *map);
|
||||
|
||||
PR_END_EXTERN_C
|
||||
|
||||
#endif /* jsatom_h___ */
|
161
js/ref/jscntxt.c
161
js/ref/jscntxt.c
|
@ -40,14 +40,6 @@
|
|||
#include "jsscan.h"
|
||||
#include "jsscript.h"
|
||||
|
||||
JSInterpreterHooks *js_InterpreterHooks = NULL;
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
js_SetInterpreterHooks(JSInterpreterHooks *hooks)
|
||||
{
|
||||
js_InterpreterHooks = hooks;
|
||||
}
|
||||
|
||||
JSContext *
|
||||
js_NewContext(JSRuntime *rt, size_t stacksize)
|
||||
{
|
||||
|
@ -103,11 +95,6 @@ js_DestroyContext(JSContext *cx)
|
|||
rtempty = (rt->contextList.next == (PRCList *)&rt->contextList);
|
||||
JS_UNLOCK_RUNTIME(rt);
|
||||
|
||||
if (js_InterpreterHooks && js_InterpreterHooks->destroyContext) {
|
||||
/* This is a stub, but in case it removes roots, call it now. */
|
||||
js_InterpreterHooks->destroyContext(cx);
|
||||
}
|
||||
|
||||
if (rtempty) {
|
||||
/* Unpin all pinned atoms before final GC. */
|
||||
js_UnpinPinnedAtoms(&rt->atomState);
|
||||
|
@ -209,21 +196,21 @@ js_ReportErrorVA(JSContext *cx, uintN flags, const char *format, va_list ap)
|
|||
*/
|
||||
JSBool
|
||||
js_ExpandErrorArguments(JSContext *cx, JSErrorCallback callback,
|
||||
void *userRef, const uintN errorNumber, char **message,
|
||||
JSErrorReport *reportp, va_list ap)
|
||||
void *userRef, const uintN errorNumber,
|
||||
char **messagep, JSErrorReport *reportp, va_list ap)
|
||||
{
|
||||
const JSErrorFormatString *fmtData;
|
||||
int i;
|
||||
int argCount;
|
||||
|
||||
*message = NULL;
|
||||
*messagep = NULL;
|
||||
if (callback) {
|
||||
fmtData = (*callback)(userRef, "Mountain View", errorNumber);
|
||||
if (fmtData != NULL) {
|
||||
argCount = fmtData->argCount;
|
||||
if (fmtData != NULL) {
|
||||
argCount = fmtData->argCount;
|
||||
if (argCount > 0) {
|
||||
/*
|
||||
* Gather the arguments into a char * array, the
|
||||
* Gather the arguments into a char * array, the
|
||||
* messageArgs field is supposed to be an array of
|
||||
* JSString's and we'll convert them later.
|
||||
*/
|
||||
|
@ -233,72 +220,73 @@ js_ExpandErrorArguments(JSContext *cx, JSErrorCallback callback,
|
|||
for (i = 0; i < argCount; i++)
|
||||
reportp->messageArgs[i] = (JSString *) va_arg(ap, char *);
|
||||
}
|
||||
/*
|
||||
/*
|
||||
* Parse the error format, substituting the argument X
|
||||
* for {X} in the format.
|
||||
*/
|
||||
if (argCount > 0) {
|
||||
if (fmtData->format) {
|
||||
const char *fmt, *arg;
|
||||
char *out;
|
||||
int expandedArgs = 0;
|
||||
int expandedLength
|
||||
*/
|
||||
if (argCount > 0) {
|
||||
if (fmtData->format) {
|
||||
const char *fmt, *arg;
|
||||
char *out;
|
||||
int expandedArgs = 0;
|
||||
int expandedLength
|
||||
= strlen(fmtData->format)
|
||||
- (3 * argCount); /* exclude the {n} */
|
||||
|
||||
for (i = 0; i < argCount; i++) {
|
||||
expandedLength
|
||||
for (i = 0; i < argCount; i++) {
|
||||
expandedLength
|
||||
+= strlen((char *)reportp->messageArgs[i]);
|
||||
}
|
||||
*message = out = malloc(expandedLength + 1);
|
||||
if (!out) {
|
||||
if (reportp->messageArgs) {
|
||||
}
|
||||
*messagep = out = malloc(expandedLength + 1);
|
||||
if (!out) {
|
||||
if (reportp->messageArgs) {
|
||||
free(reportp->messageArgs);
|
||||
reportp->messageArgs = NULL;
|
||||
}
|
||||
return JS_FALSE;
|
||||
}
|
||||
fmt = fmtData->format;
|
||||
while (*fmt) {
|
||||
if (*fmt == '{') { /* balance} */
|
||||
if (isdigit(fmt[1])) {
|
||||
int d = JS7_UNDEC(fmt[1]);
|
||||
PR_ASSERT(expandedArgs < argCount);
|
||||
arg = (char *)reportp->messageArgs[d];
|
||||
strcpy(out, arg);
|
||||
out += strlen(arg);
|
||||
fmt += 3;
|
||||
expandedArgs++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
fmt = fmtData->format;
|
||||
while (*fmt) {
|
||||
if (*fmt == '{') { /* balance} */
|
||||
if (isdigit(fmt[1])) {
|
||||
int d = JS7_UNDEC(fmt[1]);
|
||||
PR_ASSERT(expandedArgs < argCount);
|
||||
arg = (char *)reportp->messageArgs[d];
|
||||
strcpy(out, arg);
|
||||
out += strlen(arg);
|
||||
fmt += 3;
|
||||
expandedArgs++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
*out++ = *fmt++;
|
||||
}
|
||||
PR_ASSERT(expandedArgs == argCount);
|
||||
*out = '\0';
|
||||
}
|
||||
/*
|
||||
* Now convert all the arguments to JSStrings.
|
||||
*/
|
||||
for (i = 0; i < argCount; i++) {
|
||||
reportp->messageArgs[i] =
|
||||
JS_NewStringCopyZ(cx, (char *)reportp->messageArgs[i]);
|
||||
}
|
||||
} else {
|
||||
*message = JS_strdup(cx, fmtData->format);
|
||||
}
|
||||
PR_ASSERT(expandedArgs == argCount);
|
||||
*out = '\0';
|
||||
}
|
||||
/*
|
||||
* Now convert all the arguments to JSStrings.
|
||||
*/
|
||||
for (i = 0; i < argCount; i++) {
|
||||
reportp->messageArgs[i] =
|
||||
JS_NewStringCopyZ(cx, (char *)reportp->messageArgs[i]);
|
||||
}
|
||||
} else {
|
||||
*messagep = JS_strdup(cx, fmtData->format);
|
||||
}
|
||||
/*
|
||||
* And finally convert the message.
|
||||
*/
|
||||
reportp->ucmessage = JS_NewStringCopyZ(cx, *message);
|
||||
}
|
||||
/*
|
||||
* And finally convert the message.
|
||||
*/
|
||||
reportp->ucmessage = JS_NewStringCopyZ(cx, *messagep);
|
||||
}
|
||||
}
|
||||
if (*message == NULL) {
|
||||
/* where's the right place for this ??? */
|
||||
const char *defaultErrorMessage
|
||||
= "No error message available for error number %d";
|
||||
*message = (char *)malloc(strlen(defaultErrorMessage) + 16);
|
||||
sprintf(*message, defaultErrorMessage, errorNumber);
|
||||
if (*messagep == NULL) {
|
||||
/* where's the right place for this ??? */
|
||||
const char *defaultErrorMessage
|
||||
= "No error message available for error number %d";
|
||||
size_t nbytes = strlen(defaultErrorMessage) + 16;
|
||||
*messagep = (char *)malloc(nbytes);
|
||||
PR_snprintf(*messagep, nbytes, defaultErrorMessage, errorNumber);
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
@ -308,7 +296,7 @@ js_ReportErrorNumberVA(JSContext *cx, uintN flags, JSErrorCallback callback,
|
|||
void *userRef, const uintN errorNumber, va_list ap)
|
||||
{
|
||||
JSStackFrame *fp;
|
||||
JSErrorReport report, *reportp;
|
||||
JSErrorReport report;
|
||||
char *message;
|
||||
|
||||
report.messageArgs = NULL;
|
||||
|
@ -319,23 +307,20 @@ js_ReportErrorNumberVA(JSContext *cx, uintN flags, JSErrorCallback callback,
|
|||
if (fp && fp->script && fp->pc) {
|
||||
report.filename = fp->script->filename;
|
||||
report.lineno = js_PCToLineNumber(fp->script, fp->pc);
|
||||
} else {
|
||||
report.filename = NULL;
|
||||
report.lineno = 0;
|
||||
}
|
||||
else {
|
||||
report.filename = NULL;
|
||||
report.lineno = 0;
|
||||
}
|
||||
|
||||
/* XXX should fetch line somehow */
|
||||
report.linebuf = NULL;
|
||||
report.tokenptr = NULL;
|
||||
report.flags = flags;
|
||||
|
||||
report.errorNumber = errorNumber;
|
||||
|
||||
reportp = &report;
|
||||
|
||||
if (!js_ExpandErrorArguments(cx, callback, userRef, errorNumber,
|
||||
&message, reportp, ap))
|
||||
return;
|
||||
if (!js_ExpandErrorArguments(cx, callback, userRef, errorNumber,
|
||||
&message, &report, ap))
|
||||
return;
|
||||
|
||||
#if JS_HAS_ERROR_EXCEPTIONS
|
||||
/*
|
||||
|
@ -344,15 +329,15 @@ js_ReportErrorNumberVA(JSContext *cx, uintN flags, JSErrorCallback callback,
|
|||
* exception is thrown, then the JSREPORT_EXCEPTION flag will be set
|
||||
* on the error report, and exception-aware hosts should ignore it.
|
||||
*/
|
||||
js_ErrorToException(cx, reportp, message);
|
||||
js_ErrorToException(cx, &report, message);
|
||||
#endif
|
||||
|
||||
js_ReportErrorAgain(cx, message, reportp);
|
||||
js_ReportErrorAgain(cx, message, &report);
|
||||
|
||||
if (message)
|
||||
free(message);
|
||||
free(message);
|
||||
if (report.messageArgs)
|
||||
free(report.messageArgs);
|
||||
free(report.messageArgs);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
|
@ -403,6 +388,6 @@ js_GetErrorMessage(void *userRef, const char *locale, const uintN errorNumber)
|
|||
if ((errorNumber > 0) && (errorNumber < JSErr_Limit))
|
||||
return &js_ErrorFormatString[errorNumber];
|
||||
else
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -150,31 +150,20 @@ struct JSContext {
|
|||
/* Client opaque pointer */
|
||||
void *data;
|
||||
|
||||
/* Java environment and JS errors to throw as exceptions. */
|
||||
void *javaEnv;
|
||||
void *savedErrors;
|
||||
|
||||
/* GC and thread-safe state. */
|
||||
JSStackFrame *dormantFrameChain; /* dormant stack frame to scan */
|
||||
uint32 gcDisabled; /* XXX for pre-ECMAv2 switch */
|
||||
#ifdef JS_THREADSAFE
|
||||
prword thread;
|
||||
JSPackedBool gcActive;
|
||||
jsrefcount requestDepth;
|
||||
JSPackedBool gcActive;
|
||||
#endif
|
||||
JSStackFrame *dormantFrameChain; /* dormant frame chains */
|
||||
|
||||
/* Exception state (NB: throwing is packed with gcActive above). */
|
||||
JSPackedBool throwing; /* is there a pending exception? */
|
||||
jsval exception; /* most-recently-thrown exceptin */
|
||||
};
|
||||
|
||||
typedef struct JSInterpreterHooks {
|
||||
void (*destroyContext)(JSContext *cx);
|
||||
void (*destroyScript)(JSContext *cx, JSScript *script);
|
||||
void (*destroyFrame)(JSContext *cx, JSStackFrame *frame);
|
||||
} JSInterpreterHooks;
|
||||
|
||||
extern JSInterpreterHooks *js_InterpreterHooks;
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
js_SetInterpreterHooks(JSInterpreterHooks *hooks);
|
||||
|
||||
extern JSContext *
|
||||
js_NewContext(JSRuntime *rt, size_t stacksize);
|
||||
|
||||
|
@ -204,13 +193,13 @@ extern void
|
|||
js_ReportErrorVA(JSContext *cx, uintN flags, const char *format, va_list ap);
|
||||
extern void
|
||||
js_ReportErrorNumberVA(JSContext *cx, uintN flags, JSErrorCallback callback,
|
||||
void *userRef, const uintN errorNumber, va_list ap);
|
||||
void *userRef, const uintN errorNumber, va_list ap);
|
||||
|
||||
extern JSBool
|
||||
js_ExpandErrorArguments(JSContext *cx, JSErrorCallback callback,
|
||||
void *userRef, const uintN errorNumber,
|
||||
char **message, JSErrorReport *reportp,
|
||||
va_list ap);
|
||||
void *userRef, const uintN errorNumber,
|
||||
char **message, JSErrorReport *reportp,
|
||||
va_list ap);
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
2022
js/ref/jsdate.c
2022
js/ref/jsdate.c
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,76 +0,0 @@
|
|||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef jsdate_h___
|
||||
#define jsdate_h___
|
||||
/*
|
||||
* JS Date class interface.
|
||||
*/
|
||||
|
||||
PR_BEGIN_EXTERN_C
|
||||
|
||||
extern JSObject *
|
||||
js_InitDateClass(JSContext *cx, JSObject *obj);
|
||||
|
||||
/*
|
||||
* These functions provide a C interface to the date/time object
|
||||
*/
|
||||
extern JS_FRIEND_API(JSObject*)
|
||||
js_NewDateObject(JSContext* cx, int year, int mon, int mday,
|
||||
int hour, int min, int sec);
|
||||
|
||||
extern JS_FRIEND_API(int)
|
||||
js_DateGetYear(JSContext *cx, JSObject* obj);
|
||||
|
||||
extern JS_FRIEND_API(int)
|
||||
js_DateGetMonth(JSContext *cx, JSObject* obj);
|
||||
|
||||
extern JS_FRIEND_API(int)
|
||||
js_DateGetDate(JSContext *cx, JSObject* obj);
|
||||
|
||||
extern JS_FRIEND_API(int)
|
||||
js_DateGetHours(JSContext *cx, JSObject* obj);
|
||||
|
||||
extern JS_FRIEND_API(int)
|
||||
js_DateGetMinutes(JSContext *cx, JSObject* obj);
|
||||
|
||||
extern JS_FRIEND_API(int)
|
||||
js_DateGetSeconds(JSContext *cx, JSObject* obj);
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
js_DateSetYear(JSContext *cx, JSObject *obj, int year);
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
js_DateSetMonth(JSContext *cx, JSObject *obj, int year);
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
js_DateSetDate(JSContext *cx, JSObject *obj, int date);
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
js_DateSetHours(JSContext *cx, JSObject *obj, int hours);
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
js_DateSetMinutes(JSContext *cx, JSObject *obj, int minutes);
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
js_DateSetSeconds(JSContext *cx, JSObject *obj, int seconds);
|
||||
|
||||
|
||||
PR_END_EXTERN_C
|
||||
|
||||
#endif /* jsdate_h___ */
|
|
@ -345,8 +345,8 @@ JS_SetWatchPoint(JSContext *cx, JSObject *obj, jsval id,
|
|||
JSWatchPoint *wp;
|
||||
|
||||
if (!OBJ_IS_NATIVE(obj)) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_WATCH,
|
||||
OBJ_GET_CLASS(cx, obj)->name);
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_WATCH,
|
||||
OBJ_GET_CLASS(cx, obj)->name);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
|
@ -705,7 +705,7 @@ JS_GetPropertyDesc(JSContext *cx, JSObject *obj, JSScopeProperty *sprop,
|
|||
sym = sprop->symbols;
|
||||
pd->id = sym ? js_IdToValue(sym_id(sym)) : JSVAL_VOID;
|
||||
if (!sym || !js_GetProperty(cx, obj, sym_id(sym), &pd->value))
|
||||
pd->value = OBJ_GET_SLOT(cx, obj, sprop->slot);
|
||||
pd->value = OBJ_GET_SLOT(cx, obj, sprop->slot);
|
||||
pd->flags = ((sprop->attrs & JSPROP_ENUMERATE) ? JSPD_ENUMERATE : 0)
|
||||
| ((sprop->attrs & JSPROP_READONLY) ? JSPD_READONLY : 0)
|
||||
| ((sprop->attrs & JSPROP_PERMANENT) ? JSPD_PERMANENT : 0)
|
||||
|
@ -715,10 +715,10 @@ JS_GetPropertyDesc(JSContext *cx, JSObject *obj, JSScopeProperty *sprop,
|
|||
| ((sprop->getter == js_GetArgument) ? JSPD_ARGUMENT : 0)
|
||||
| ((sprop->getter == js_GetLocalVariable) ? JSPD_VARIABLE : 0);
|
||||
#if JS_HAS_CALL_OBJECT
|
||||
/* for Call Object 'real' getter isn't passed in to us */
|
||||
if (OBJ_GET_CLASS(cx, obj) == &js_CallClass &&
|
||||
OBJ_GET_CLASS(cx, obj)->getProperty == sprop->getter)
|
||||
pd->flags |= JSPD_ARGUMENT;
|
||||
/* for Call Object 'real' getter isn't passed in to us */
|
||||
if (OBJ_GET_CLASS(cx, obj) == &js_CallClass &&
|
||||
OBJ_GET_CLASS(cx, obj)->getProperty == sprop->getter)
|
||||
pd->flags |= JSPD_ARGUMENT;
|
||||
#endif /* JS_HAS_CALL_OBJECT */
|
||||
pd->spare = 0;
|
||||
pd->slot = (pd->flags & (JSPD_ARGUMENT | JSPD_VARIABLE))
|
||||
|
@ -747,9 +747,9 @@ JS_GetPropertyDescArray(JSContext *cx, JSObject *obj, JSPropertyDescArray *pda)
|
|||
return JS_FALSE;
|
||||
scope = (JSScope *)obj->map;
|
||||
/* have no props, or object's scope has not mutated from that of proto */
|
||||
if (!scope->props ||
|
||||
(OBJ_GET_PROTO(cx,obj) &&
|
||||
scope == (JSScope *)(OBJ_GET_PROTO(cx,obj)->map))) {
|
||||
if (!scope->props ||
|
||||
(OBJ_GET_PROTO(cx,obj) &&
|
||||
scope == (JSScope *)(OBJ_GET_PROTO(cx,obj)->map))) {
|
||||
pda->length = 0;
|
||||
pda->array = NULL;
|
||||
return JS_TRUE;
|
||||
|
|
3196
js/ref/jsemit.c
3196
js/ref/jsemit.c
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -75,7 +75,7 @@ struct JSTreeContext { /* tree context for semantic checks */
|
|||
#define TCF_RETURN_VOID 0x04 /* function has 'return;' */
|
||||
#define TCF_IN_FOR_INIT 0x08 /* parsing init expr of for; exclude 'in' */
|
||||
|
||||
#define INIT_TREE_CONTEXT(tc) \
|
||||
#define TREE_CONTEXT_INIT(tc) \
|
||||
((tc)->flags = 0, (tc)->tryCount = 0, (tc)->topStmt = NULL)
|
||||
|
||||
struct JSCodeGenerator {
|
||||
|
@ -84,37 +84,24 @@ struct JSCodeGenerator {
|
|||
jsbytecode *base; /* base of JS bytecode vector */
|
||||
jsbytecode *limit; /* one byte beyond end of bytecode */
|
||||
jsbytecode *next; /* pointer to next free bytecode */
|
||||
JSAtomList atomList; /* literals indexed for mapping */
|
||||
ptrdiff_t lastCodeOffset; /* offset of last non-nop opcode */
|
||||
intN stackDepth; /* current stack depth in basic block */
|
||||
uintN maxStackDepth; /* maximum stack depth so far */
|
||||
jssrcnote *notes; /* source notes, see below */
|
||||
uintN noteCount; /* number of source notes so far */
|
||||
ptrdiff_t lastNoteOffset; /* code offset for last source note */
|
||||
const char *filename; /* null or weak link to source filename */
|
||||
uintN firstLine; /* first line, for js_NewScriptFromCG */
|
||||
uintN currentLine; /* line number for tree-based srcnote gen */
|
||||
JSPrincipals *principals; /* principals for constant folding eval */
|
||||
JSTreeContext treeContext; /* for break/continue code generation */
|
||||
JSTryNote *tryBase; /* first exception handling block */
|
||||
JSTryNote *tryNext; /* next avail block */
|
||||
JSTryNote *tryLimit; /* pointer to one-past-end block */
|
||||
JSAtomList atomList; /* literals indexed for mapping */
|
||||
intN stackDepth; /* current stack depth in basic block */
|
||||
uintN maxStackDepth; /* maximum stack depth so far */
|
||||
jssrcnote *notes; /* source notes, see below */
|
||||
uintN noteCount; /* number of source notes so far */
|
||||
ptrdiff_t lastNoteOffset; /* code offset for last source note */
|
||||
JSTryNote *tryBase; /* first exception handling note */
|
||||
JSTryNote *tryLimit; /* pointer to one-past-end note */
|
||||
JSTryNote *tryNext; /* next available note */
|
||||
};
|
||||
|
||||
#define CG_CODE(cg,offset) ((cg)->base + (offset))
|
||||
#define CG_OFFSET(cg) PTRDIFF((cg)->next, (cg)->base, jsbytecode)
|
||||
#define CG_RESET(cg) ((cg)->next = (cg)->base, \
|
||||
ATOM_LIST_INIT(&(cg)->atomList), \
|
||||
(cg)->lastCodeOffset = 0, \
|
||||
(cg)->stackDepth = (cg)->maxStackDepth = 0, \
|
||||
(cg)->currentLine = (cg)->firstLine, \
|
||||
INIT_TREE_CONTEXT(&(cg)->treeContext), \
|
||||
(cg)->tryNext = (cg)->tryBase, \
|
||||
CG_RESET_NOTES(cg))
|
||||
#define CG_RESET_NOTES(cg) ((cg)->notes = NULL, (cg)->noteCount = 0, \
|
||||
(cg)->lastNoteOffset = 0)
|
||||
#define CG_PUSH(cg, newcg) ((newcg)->atomList = (cg)->atomList)
|
||||
#define CG_POP(cg, newcg) ((cg)->atomList = (newcg)->atomList)
|
||||
|
||||
/*
|
||||
* Initialize cg to allocate bytecode space from cx->codePool, and srcnote
|
||||
|
@ -228,7 +215,7 @@ js_EmitFunctionBody(JSContext *cx, JSCodeGenerator *cg, JSParseNode *body,
|
|||
* the previous note. If 3 bits of offset aren't enough, extended delta notes
|
||||
* (SRC_XDELTA) consisting of 2 set high order bits followed by 6 offset bits
|
||||
* are emitted before the next note. Some notes have operand offsets encoded
|
||||
* in note bytes or byte-pairs.
|
||||
* immediately after them, in note bytes or byte-triples.
|
||||
*
|
||||
* At most one "gettable" note (i.e., a note of type other than SRC_NEWLINE,
|
||||
* SRC_SETLINE, and SRC_XDELTA) applies to a given bytecode.
|
||||
|
@ -255,9 +242,10 @@ typedef enum JSSrcNoteType {
|
|||
SRC_ENDBRACE = 15, /* JSOP_NOP for label: {...} end brace */
|
||||
SRC_BREAK2LABEL = 16, /* JSOP_GOTO for 'break label' with atomid */
|
||||
SRC_CONT2LABEL = 17, /* JSOP_GOTO for 'continue label' with atomid */
|
||||
SRC_SWITCH = 18, /* JSOP_*SWITCH with offset to end of switch */
|
||||
SRC_SWITCH = 18, /* JSOP_*SWITCH with offset to end of switch,
|
||||
2nd off to first JSOP_CASE if condswitch */
|
||||
SRC_FUNCDEF = 19, /* JSOP_NOP for function f() with atomid */
|
||||
SRC_TRYFIN = 20, /* JSOP_NOP for try{} or finally{} section */
|
||||
SRC_TRYFIN = 20, /* JSOP_NOP for try or finally section */
|
||||
SRC_CATCH = 21, /* catch block has guard */
|
||||
SRC_NEWLINE = 22, /* bytecode follows a source newline */
|
||||
SRC_SETLINE = 23, /* a file-absolute source line number note */
|
||||
|
@ -351,8 +339,7 @@ js_FinishTakingSrcNotes(JSContext *cx, JSCodeGenerator *cg);
|
|||
/*
|
||||
* Allocate cg->treeContext.tryCount notes (plus one for the end sentinel)
|
||||
* from cx->tempPool and set cg->tryBase/tryNext/tryLimit for exactly tryCount
|
||||
* js_NewTryNote calls. The storage is freed in one fell swoop by JS_Compile*
|
||||
* API entry points at the end of compilation.
|
||||
* js_NewTryNote calls. The storage is freed by js_ResetCodeGenerator.
|
||||
*/
|
||||
extern JSBool
|
||||
js_AllocTryNotes(JSContext *cx, JSCodeGenerator *cg);
|
||||
|
|
254
js/ref/jsexn.c
254
js/ref/jsexn.c
|
@ -80,23 +80,23 @@ exn_initPrivate(JSContext *cx, JSErrorReport *report, const char *message)
|
|||
newReport = (JSErrorReport *)JS_malloc(cx, sizeof (JSErrorReport));
|
||||
|
||||
if (report->filename) {
|
||||
newReport->filename =
|
||||
(const char *)JS_malloc(cx, strlen(report->filename));
|
||||
/* Ack. Const! */
|
||||
strcpy((char *)newReport->filename, report->filename);
|
||||
newReport->filename =
|
||||
(const char *)JS_malloc(cx, strlen(report->filename));
|
||||
/* Ack. Const! */
|
||||
strcpy((char *)newReport->filename, report->filename);
|
||||
} else {
|
||||
newReport->filename = NULL;
|
||||
newReport->filename = NULL;
|
||||
}
|
||||
|
||||
|
||||
newReport->lineno = report->lineno;
|
||||
|
||||
|
||||
/*
|
||||
* We don't need to copy linebuf and tokenptr, because they
|
||||
* point into the deflated string cache. (currently?)
|
||||
*/
|
||||
newReport->linebuf = report->linebuf;
|
||||
newReport->tokenptr = report->tokenptr;
|
||||
|
||||
|
||||
/*
|
||||
* But we do need to copy uclinebuf, uctokenptr, because they're
|
||||
* pointers into internal tokenstream structs, and may go away.
|
||||
|
@ -110,15 +110,15 @@ exn_initPrivate(JSContext *cx, JSErrorReport *report, const char *message)
|
|||
|
||||
#if 0
|
||||
if (report->uclinebuf) {
|
||||
size_t len = js_strlen(report->uclinebuf);
|
||||
newReport->uclinebuf =
|
||||
(const jschar *)JS_malloc(cx, len);
|
||||
js_strncpy(newReport->uclinebuf, report->uclinebuf, len);
|
||||
newReport->uctokenptr = newReport->uclinebuf + (report->uctokenptr -
|
||||
report->uclinebuf);
|
||||
size_t len = js_strlen(report->uclinebuf);
|
||||
newReport->uclinebuf =
|
||||
(const jschar *)JS_malloc(cx, len);
|
||||
js_strncpy(newReport->uclinebuf, report->uclinebuf, len);
|
||||
newReport->uctokenptr = newReport->uclinebuf + (report->uctokenptr -
|
||||
report->uclinebuf);
|
||||
} else
|
||||
#endif
|
||||
newReport->uclinebuf = newReport->uctokenptr = NULL;
|
||||
newReport->uclinebuf = newReport->uctokenptr = NULL;
|
||||
|
||||
/* Note that this is before it gets flagged with JSREPORT_EXCEPTION */
|
||||
newReport->flags = report->flags;
|
||||
|
@ -131,8 +131,8 @@ exn_initPrivate(JSContext *cx, JSErrorReport *report, const char *message)
|
|||
*/
|
||||
|
||||
newPrivate->errorReport = newReport;
|
||||
|
||||
return newPrivate;
|
||||
|
||||
return newPrivate;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -147,10 +147,10 @@ exn_destroyPrivate(JSContext *cx, JSExnPrivate *privateData)
|
|||
|
||||
PR_ASSERT(privateData->errorReport);
|
||||
if (privateData->errorReport->uclinebuf)
|
||||
JS_free(cx, (void *)privateData->errorReport->uclinebuf);
|
||||
JS_free(cx, (void *)privateData->errorReport->uclinebuf);
|
||||
|
||||
if (privateData->errorReport->filename)
|
||||
JS_free(cx, (void *)privateData->errorReport->filename);
|
||||
JS_free(cx, (void *)privateData->errorReport->filename);
|
||||
|
||||
JS_free(cx, privateData->errorReport);
|
||||
|
||||
|
@ -164,10 +164,10 @@ exn_finalize(JSContext *cx, JSObject *obj)
|
|||
JSExnPrivate *privateData;
|
||||
|
||||
privateData = (JSExnPrivate *)
|
||||
JSVAL_TO_PRIVATE(OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE));
|
||||
JSVAL_TO_PRIVATE(OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE));
|
||||
|
||||
if (privateData) {
|
||||
exn_destroyPrivate(cx, privateData);
|
||||
exn_destroyPrivate(cx, privateData);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -176,18 +176,18 @@ typedef enum JSExnType {
|
|||
JSEXN_NONE = -1,
|
||||
JSEXN_EXCEPTION,
|
||||
JSEXN_ERR,
|
||||
JSEXN_INTERNALERR,
|
||||
JSEXN_SYNTAXERR,
|
||||
JSEXN_REFERENCEERR,
|
||||
JSEXN_CALLERR,
|
||||
JSEXN_TARGETERR,
|
||||
JSEXN_CONSTRUCTORERR,
|
||||
JSEXN_CONVERSIONERR,
|
||||
JSEXN_TOOBJECTERR,
|
||||
JSEXN_TOPRIMITIVEERR,
|
||||
JSEXN_DEFAULTVALUEERR,
|
||||
JSEXN_ARRAYERR,
|
||||
JSEXN_LIMIT
|
||||
JSEXN_INTERNALERR,
|
||||
JSEXN_SYNTAXERR,
|
||||
JSEXN_REFERENCEERR,
|
||||
JSEXN_CALLERR,
|
||||
JSEXN_TARGETERR,
|
||||
JSEXN_CONSTRUCTORERR,
|
||||
JSEXN_CONVERSIONERR,
|
||||
JSEXN_TOOBJECTERR,
|
||||
JSEXN_TOPRIMITIVEERR,
|
||||
JSEXN_DEFAULTVALUEERR,
|
||||
JSEXN_ARRAYERR,
|
||||
JSEXN_LIMIT
|
||||
} JSExnType;
|
||||
|
||||
#define FLAGS JSCLASS_HAS_PRIVATE
|
||||
|
@ -204,69 +204,69 @@ struct JSExnSpec {
|
|||
*/
|
||||
static struct JSExnSpec exceptions[] = {
|
||||
{ JSEXN_NONE, /* No proto? */ {
|
||||
"Exception", FLAGS,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, exn_finalize
|
||||
"Exception", FLAGS,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, exn_finalize
|
||||
} },
|
||||
{ JSEXN_EXCEPTION, {
|
||||
"Error", FLAGS,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, exn_finalize
|
||||
"Error", FLAGS,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, exn_finalize
|
||||
} },
|
||||
{ JSEXN_ERR, {
|
||||
"InternalError", FLAGS,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, exn_finalize
|
||||
"InternalError", FLAGS,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, exn_finalize
|
||||
} },
|
||||
{ JSEXN_ERR, {
|
||||
"SyntaxError", FLAGS,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, exn_finalize
|
||||
"SyntaxError", FLAGS,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, exn_finalize
|
||||
} },
|
||||
{ JSEXN_ERR, {
|
||||
"ReferenceError", FLAGS,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, exn_finalize
|
||||
"ReferenceError", FLAGS,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, exn_finalize
|
||||
} },
|
||||
{ JSEXN_ERR, {
|
||||
"CallError", FLAGS,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, exn_finalize
|
||||
"CallError", FLAGS,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, exn_finalize
|
||||
} },
|
||||
{ JSEXN_CALLERR, {
|
||||
"TargetError", FLAGS,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, exn_finalize
|
||||
"TargetError", FLAGS,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, exn_finalize
|
||||
} },
|
||||
{ JSEXN_ERR, {
|
||||
"ConstructorError", FLAGS,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, exn_finalize
|
||||
"ConstructorError", FLAGS,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, exn_finalize
|
||||
} },
|
||||
{ JSEXN_ERR, {
|
||||
"ConversionError", FLAGS,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, exn_finalize
|
||||
"ConversionError", FLAGS,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, exn_finalize
|
||||
} },
|
||||
{ JSEXN_CONVERSIONERR, {
|
||||
"ToObjectError", FLAGS,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, exn_finalize
|
||||
"ToObjectError", FLAGS,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, exn_finalize
|
||||
} },
|
||||
{ JSEXN_CONVERSIONERR, {
|
||||
"ToPrimitiveError", FLAGS,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, exn_finalize
|
||||
"ToPrimitiveError", FLAGS,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, exn_finalize
|
||||
} },
|
||||
{ JSEXN_CONVERSIONERR, {
|
||||
"DefaultValueError", FLAGS,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, exn_finalize
|
||||
"DefaultValueError", FLAGS,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, exn_finalize
|
||||
} },
|
||||
{ JSEXN_ERR, {
|
||||
"ArrayError", FLAGS,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, exn_finalize
|
||||
"ArrayError", FLAGS,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, exn_finalize
|
||||
} },
|
||||
{0}
|
||||
};
|
||||
|
@ -299,46 +299,46 @@ exn_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
jsval v;
|
||||
char *name;
|
||||
JSClass *theclass;
|
||||
|
||||
|
||||
/* Check needed against incompatible target... */
|
||||
|
||||
/* Try to include the exception name in the error message. */
|
||||
theclass = OBJ_GET_CLASS(cx, obj);
|
||||
name = theclass->name;
|
||||
|
||||
|
||||
v = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE);
|
||||
|
||||
if (!JSVAL_IS_NULL(v)) {
|
||||
char *msgbuf, *tmp;
|
||||
char *msgbuf, *tmp;
|
||||
|
||||
privateData = JSVAL_TO_PRIVATE(v);
|
||||
report = privateData->errorReport;
|
||||
privateData = JSVAL_TO_PRIVATE(v);
|
||||
report = privateData->errorReport;
|
||||
|
||||
msgbuf = PR_smprintf("%s:", name);
|
||||
msgbuf = PR_smprintf("%s:", name);
|
||||
|
||||
if (report->filename) {
|
||||
tmp = msgbuf;
|
||||
msgbuf = PR_smprintf("%s%s:", tmp, report->filename);
|
||||
JS_free(cx, tmp);
|
||||
}
|
||||
if (report->lineno) {
|
||||
tmp = msgbuf;
|
||||
msgbuf = PR_smprintf("%s%u: ", tmp ? tmp : "", report->lineno);
|
||||
if (tmp)
|
||||
JS_free(cx, tmp);
|
||||
}
|
||||
PR_ASSERT(privateData->message);
|
||||
tmp = msgbuf;
|
||||
msgbuf = PR_smprintf("%s%s", tmp ? tmp : "", privateData->message);
|
||||
if(tmp)
|
||||
JS_free(cx, tmp);
|
||||
if (report->filename) {
|
||||
tmp = msgbuf;
|
||||
msgbuf = PR_smprintf("%s%s:", tmp, report->filename);
|
||||
JS_free(cx, tmp);
|
||||
}
|
||||
if (report->lineno) {
|
||||
tmp = msgbuf;
|
||||
msgbuf = PR_smprintf("%s%u: ", tmp ? tmp : "", report->lineno);
|
||||
if (tmp)
|
||||
JS_free(cx, tmp);
|
||||
}
|
||||
PR_ASSERT(privateData->message);
|
||||
tmp = msgbuf;
|
||||
msgbuf = PR_smprintf("%s%s", tmp ? tmp : "", privateData->message);
|
||||
if(tmp)
|
||||
JS_free(cx, tmp);
|
||||
|
||||
str = JS_NewStringCopyZ(cx, msgbuf);
|
||||
str = JS_NewStringCopyZ(cx, msgbuf);
|
||||
} else {
|
||||
str = JS_NewStringCopyZ(cx, "some non-engine-thrown exception");
|
||||
str = JS_NewStringCopyZ(cx, "some non-engine-thrown exception");
|
||||
}
|
||||
if (!str)
|
||||
return JS_FALSE;
|
||||
return JS_FALSE;
|
||||
*rval = STRING_TO_JSVAL(str);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
@ -356,18 +356,18 @@ js_InitExceptionClasses(JSContext *cx, JSObject *obj)
|
|||
int i;
|
||||
|
||||
for (i = 0; exceptions[i].theclass.name != 0; i++) {
|
||||
int protoidx = exceptions[i].protoIndex;
|
||||
protos[i] = JS_InitClass(cx, obj,
|
||||
((protoidx >= 0) ? protos[protoidx] : NULL),
|
||||
&(exceptions[i].theclass),
|
||||
Exception, 1,
|
||||
NULL,
|
||||
exception_methods,
|
||||
NULL,
|
||||
NULL);
|
||||
int protoidx = exceptions[i].protoIndex;
|
||||
protos[i] = JS_InitClass(cx, obj,
|
||||
((protoidx >= 0) ? protos[protoidx] : NULL),
|
||||
&(exceptions[i].theclass),
|
||||
Exception, 1,
|
||||
NULL,
|
||||
exception_methods,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
/* So finalize knows whether to. */
|
||||
OBJ_SET_SLOT(cx, protos[i], JSSLOT_PRIVATE, JSVAL_NULL);
|
||||
/* So finalize knows whether to. */
|
||||
OBJ_SET_SLOT(cx, protos[i], JSSLOT_PRIVATE, JSVAL_NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -378,25 +378,26 @@ js_InitExceptionClasses(JSContext *cx, JSObject *obj)
|
|||
*/
|
||||
|
||||
/* protos[0]->slots[JSSLOT_PROTO] = JSVAL_NULL; */
|
||||
|
||||
|
||||
return protos[0];
|
||||
}
|
||||
|
||||
JSErrorReport *
|
||||
js_GetErrorFromException(JSContext *cx, JSObject *errobj) {
|
||||
js_GetErrorFromException(JSContext *cx, JSObject *errobj)
|
||||
{
|
||||
JSExnPrivate *privateData;
|
||||
#if 0
|
||||
#if 0
|
||||
{
|
||||
JSClass *errobjclass;
|
||||
/* Assert that we have an Exception object */
|
||||
/* This assert does the right thing, but we can't use it yet, because
|
||||
* we're throwing lots of different exception classes. */
|
||||
errobjclass = OBJ_GET_CLASS(cx, errobj);
|
||||
PR_ASSERT(errobjclass == &(exceptions[JSEXN_CALLERR].theclass));
|
||||
JSClass *errobjclass;
|
||||
/* Assert that we have an Exception object */
|
||||
/* This assert does the right thing, but we can't use it yet, because
|
||||
* we're throwing lots of different exception classes. */
|
||||
errobjclass = OBJ_GET_CLASS(cx, errobj);
|
||||
PR_ASSERT(errobjclass == &(exceptions[JSEXN_CALLERR].theclass));
|
||||
}
|
||||
#endif
|
||||
privateData = JSVAL_TO_PRIVATE(OBJ_GET_SLOT(cx, errobj, JSSLOT_PRIVATE));
|
||||
|
||||
|
||||
/* Still OK to return NULL, tho. */
|
||||
return privateData->errorReport;
|
||||
}
|
||||
|
@ -419,8 +420,9 @@ static struct exnname { char *name; char *exception; } errortoexnname[] = {
|
|||
#endif /* DEBUG */
|
||||
|
||||
JSBool
|
||||
js_ErrorToException(JSContext *cx, JSErrorReport *reportp, const char *message) {
|
||||
JSErrNum errorNumber;
|
||||
js_ErrorToException(JSContext *cx, JSErrorReport *reportp, const char *message)
|
||||
{
|
||||
JSErrNum errorNumber;
|
||||
JSObject *errobj;
|
||||
JSExnType exn;
|
||||
JSExnPrivate *privateData;
|
||||
|
@ -433,8 +435,8 @@ js_ErrorToException(JSContext *cx, JSErrorReport *reportp, const char *message)
|
|||
#if defined( DEBUG_mccabe ) && defined ( PRINTNAMES )
|
||||
/* Print the error name and the associated exception name to stderr */
|
||||
fprintf(stderr, "%s\t%s\n",
|
||||
errortoexnname[errorNumber].name,
|
||||
errortoexnname[errorNumber].exception);
|
||||
errortoexnname[errorNumber].name,
|
||||
errortoexnname[errorNumber].exception);
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -442,7 +444,7 @@ js_ErrorToException(JSContext *cx, JSErrorReport *reportp, const char *message)
|
|||
* with the given error number.
|
||||
*/
|
||||
if (exn == JSEXN_NONE)
|
||||
return JS_FALSE;
|
||||
return JS_FALSE;
|
||||
|
||||
/*
|
||||
* Should (?) be js_ConstructObject... switching to NewObject
|
||||
|
@ -451,11 +453,11 @@ js_ErrorToException(JSContext *cx, JSErrorReport *reportp, const char *message)
|
|||
* cx->fp was null when trying to construct the object...
|
||||
*/
|
||||
errobj = js_NewObject(cx,
|
||||
&(exceptions[exn].theclass),
|
||||
NULL, NULL);
|
||||
&(exceptions[exn].theclass),
|
||||
NULL, NULL);
|
||||
|
||||
/*
|
||||
* Construct a new copy of the error report, and store it in the
|
||||
* Construct a new copy of the error report, and store it in the
|
||||
* exception objects' private data. We can't use the error report
|
||||
* handed in, because it's stack-allocated, and may point to transient
|
||||
* data in the JSTokenStream.
|
||||
|
|
328
js/ref/jsfun.c
328
js/ref/jsfun.c
|
@ -67,7 +67,7 @@ js_GetArgsObject(JSContext *cx, JSStackFrame *fp)
|
|||
PR_ASSERT(fp->fun);
|
||||
argsobj = fp->argsobj;
|
||||
if (argsobj)
|
||||
return argsobj;
|
||||
return argsobj;
|
||||
|
||||
/* Link the new object to fp so it can get actual argument values. */
|
||||
argsobj = js_NewObject(cx, &js_ArgumentsClass, NULL, NULL);
|
||||
|
@ -205,7 +205,7 @@ args_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
|||
case ARGS_LENGTH:
|
||||
if (fp) {
|
||||
if (!js_ValueToNumber(cx, *vp, &argc))
|
||||
return JS_FALSE;
|
||||
return JS_FALSE;
|
||||
argc = js_DoubleToInteger(argc);
|
||||
if (0 <= argc && argc < fp->argc)
|
||||
fp->argc = (uintN)argc;
|
||||
|
@ -284,7 +284,7 @@ js_GetCallObject(JSContext *cx, JSStackFrame *fp, JSObject *parent,
|
|||
if (!withobj) {
|
||||
for (obj = fp->scopeChain; obj; obj = parent) {
|
||||
if (OBJ_GET_CLASS(cx, obj) != &js_WithClass)
|
||||
break;
|
||||
break;
|
||||
parent = OBJ_GET_PARENT(cx, obj);
|
||||
if (parent == funobj) {
|
||||
withobj = obj;
|
||||
|
@ -373,7 +373,7 @@ call_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
|||
if (fp && !TEST_BIT(slot, fp->overrides)) {
|
||||
JSObject *argsobj = js_GetArgsObject(cx, fp);
|
||||
if (!argsobj)
|
||||
return JS_FALSE;
|
||||
return JS_FALSE;
|
||||
*vp = OBJECT_TO_JSVAL(argsobj);
|
||||
}
|
||||
break;
|
||||
|
@ -556,7 +556,7 @@ call_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
|
|||
getter, setter,
|
||||
JSPROP_ENUMERATE | JSPROP_PERMANENT,
|
||||
(JSProperty **)&sprop)) {
|
||||
return JS_FALSE;
|
||||
return JS_FALSE;
|
||||
}
|
||||
PR_ASSERT(sprop);
|
||||
if (slot < nslots)
|
||||
|
@ -789,15 +789,15 @@ fun_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
|||
break;
|
||||
|
||||
case FUN_CALL:
|
||||
if (fp && fp->fun) {
|
||||
if (fp && fp->fun) {
|
||||
JSObject *callobj = js_GetCallObject(cx, fp, NULL, NULL);
|
||||
if (!callobj)
|
||||
return JS_FALSE;
|
||||
return JS_FALSE;
|
||||
*vp = OBJECT_TO_JSVAL(callobj);
|
||||
} else {
|
||||
} else {
|
||||
*vp = JSVAL_NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
/* XXX fun[0] and fun.arguments[0] are equivalent. */
|
||||
|
@ -832,16 +832,16 @@ fun_enumProperty(JSContext *cx, JSObject *obj)
|
|||
JS_LOCK_OBJ(cx, obj);
|
||||
scope = (JSScope *) obj->map;
|
||||
for (sprop = scope->props; sprop; sprop = sprop->next) {
|
||||
jsval id = sprop->id;
|
||||
if (!JSVAL_IS_INT(id)) {
|
||||
jsval id = sprop->id;
|
||||
if (!JSVAL_IS_INT(id)) {
|
||||
if (id == ATOM_KEY(cx->runtime->atomState.arityAtom) ||
|
||||
id == ATOM_KEY(cx->runtime->atomState.lengthAtom) ||
|
||||
id == ATOM_KEY(cx->runtime->atomState.callerAtom) ||
|
||||
id == ATOM_KEY(cx->runtime->atomState.nameAtom))
|
||||
{
|
||||
sprop->attrs &= ~JSPROP_ENUMERATE;
|
||||
id == ATOM_KEY(cx->runtime->atomState.lengthAtom) ||
|
||||
id == ATOM_KEY(cx->runtime->atomState.callerAtom) ||
|
||||
id == ATOM_KEY(cx->runtime->atomState.nameAtom))
|
||||
{
|
||||
sprop->attrs &= ~JSPROP_ENUMERATE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
@ -877,7 +877,7 @@ fun_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
|||
|
||||
/* Set only if unqualified: 'arguments = ...' not 'fun.arguments = ...'. */
|
||||
if (!fp->pc || (js_CodeSpec[*fp->pc].format & JOF_MODEMASK) != JOF_NAME)
|
||||
goto _readonly;
|
||||
goto _readonly;
|
||||
|
||||
/* Get a Call object for fp and set its arguments property to vp. */
|
||||
callobj = js_GetCallObject(cx, fp, NULL, NULL);
|
||||
|
@ -891,8 +891,8 @@ fun_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
|||
_readonly:
|
||||
if (JSVERSION_IS_ECMA(cx->version))
|
||||
return fun_getProperty(cx, obj, id, vp);
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_READ_ONLY, js_arguments_str);
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_READ_ONLY,
|
||||
js_arguments_str);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
|
@ -919,7 +919,7 @@ fun_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
|
|||
|
||||
/* Hide prototype if fun->object is proxying for a Call object. */
|
||||
if (!(flags & JSRESOLVE_QUALIFIED)) {
|
||||
if (cx->fp && cx->fp->fun == fun && !cx->fp->callobj)
|
||||
if (cx->fp && cx->fp->fun == fun && !cx->fp->callobj)
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
@ -1062,9 +1062,9 @@ fun_xdrObject(JSXDRState *xdr, JSObject **objp)
|
|||
continue;
|
||||
}
|
||||
propname = ATOM_BYTES(sym_atom(sprop->symbols));
|
||||
propid = sprop->id;
|
||||
propid = sprop->id;
|
||||
if (!JS_XDRUint32(xdr, &type) ||
|
||||
!JS_XDRUint32(xdr, (uint32 *)&propid) ||
|
||||
!JS_XDRUint32(xdr, (uint32 *)&propid) ||
|
||||
!JS_XDRCString(xdr, &propname))
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
@ -1074,7 +1074,7 @@ fun_xdrObject(JSXDRState *xdr, JSObject **objp)
|
|||
i = fun->nvars + fun->nargs;
|
||||
while (i--) {
|
||||
if (!JS_XDRUint32(xdr, &type) ||
|
||||
!JS_XDRUint32(xdr, (uint32 *)&propid) ||
|
||||
!JS_XDRUint32(xdr, (uint32 *)&propid) ||
|
||||
!JS_XDRCString(xdr, &propname))
|
||||
return JS_FALSE;
|
||||
PR_ASSERT(type == JSXDR_FUNARG || type == JSXDR_FUNVAR);
|
||||
|
@ -1087,17 +1087,17 @@ fun_xdrObject(JSXDRState *xdr, JSObject **objp)
|
|||
setter = js_SetLocalVariable;
|
||||
PR_ASSERT(nvars++ <= fun->nvars);
|
||||
}
|
||||
atom = js_Atomize(xdr->cx, propname, strlen(propname), 0);
|
||||
atom = js_Atomize(xdr->cx, propname, strlen(propname), 0);
|
||||
if (!atom ||
|
||||
!OBJ_DEFINE_PROPERTY(xdr->cx, fun->object, (jsid)atom,
|
||||
JSVAL_VOID, getter, setter,
|
||||
JSPROP_ENUMERATE | JSPROP_PERMANENT,
|
||||
(JSProperty **)&sprop) ||
|
||||
!sprop){
|
||||
!OBJ_DEFINE_PROPERTY(xdr->cx, fun->object, (jsid)atom,
|
||||
JSVAL_VOID, getter, setter,
|
||||
JSPROP_ENUMERATE | JSPROP_PERMANENT,
|
||||
(JSProperty **)&sprop) ||
|
||||
!sprop){
|
||||
JS_free(xdr->cx, propname);
|
||||
return JS_FALSE;
|
||||
}
|
||||
sprop->id = propid;
|
||||
sprop->id = propid;
|
||||
JS_free(xdr->cx, propname);
|
||||
}
|
||||
}
|
||||
|
@ -1113,11 +1113,11 @@ fun_xdrObject(JSXDRState *xdr, JSObject **objp)
|
|||
return JS_FALSE;
|
||||
}
|
||||
*objp = fun->object;
|
||||
if (!OBJ_DEFINE_PROPERTY(xdr->cx, xdr->cx->globalObject,
|
||||
(jsid)fun->atom, OBJECT_TO_JSVAL(*objp),
|
||||
NULL, NULL, JSPROP_ENUMERATE,
|
||||
(JSProperty **)&sprop))
|
||||
return JS_FALSE;
|
||||
if (!OBJ_DEFINE_PROPERTY(xdr->cx, xdr->cx->globalObject,
|
||||
(jsid)fun->atom, OBJECT_TO_JSVAL(*objp),
|
||||
NULL, NULL, JSPROP_ENUMERATE,
|
||||
(JSProperty **)&sprop))
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
|
@ -1148,7 +1148,7 @@ fun_hasInstance(JSContext *cx, JSObject *obj, jsval v, JSBool *bp)
|
|||
return JS_FALSE;
|
||||
}
|
||||
if (!JSVAL_IS_PRIMITIVE(pval))
|
||||
return js_IsDelegate(cx, JSVAL_TO_OBJECT(pval), v, bp);
|
||||
return js_IsDelegate(cx, JSVAL_TO_OBJECT(pval), v, bp);
|
||||
|
||||
/*
|
||||
* Throw a runtime error if instanceof is called on a function
|
||||
|
@ -1156,8 +1156,8 @@ fun_hasInstance(JSContext *cx, JSObject *obj, jsval v, JSBool *bp)
|
|||
*/
|
||||
str = js_DecompileValueGenerator(cx, OBJECT_TO_JSVAL(obj), NULL);
|
||||
if (str) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_PROTOTYPE,
|
||||
JS_GetStringBytes(str));
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_PROTOTYPE,
|
||||
JS_GetStringBytes(str));
|
||||
}
|
||||
return JS_FALSE;
|
||||
|
||||
|
@ -1274,7 +1274,7 @@ fun_apply(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
!JSVAL_IS_OBJECT(argv[1]) ||
|
||||
!(aobj = JSVAL_TO_OBJECT(argv[1])) ||
|
||||
!js_HasLengthProperty(cx, aobj, &length)) {
|
||||
return fun_call(cx, obj, argc, argv, rval);
|
||||
return fun_call(cx, obj, argc, argv, rval);
|
||||
}
|
||||
|
||||
if (!OBJ_DEFAULT_VALUE(cx, obj, JSTYPE_FUNCTION, &argv[-1]))
|
||||
|
@ -1397,7 +1397,7 @@ Function(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
fun = js_NewFunction(cx, obj, NULL, 0, 0, parent,
|
||||
(JSVERSION_IS_ECMA(cx->version))
|
||||
? cx->runtime->atomState.anonymousAtom
|
||||
: NULL);
|
||||
: NULL);
|
||||
|
||||
if (!fun)
|
||||
return JS_FALSE;
|
||||
|
@ -1405,135 +1405,135 @@ Function(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
if ((fp = cx->fp) != NULL && (fp = fp->down) != NULL && fp->script) {
|
||||
filename = fp->script->filename;
|
||||
lineno = js_PCToLineNumber(fp->script, fp->pc);
|
||||
principals = fp->script->principals;
|
||||
principals = fp->script->principals;
|
||||
} else {
|
||||
filename = NULL;
|
||||
lineno = 0;
|
||||
principals = NULL;
|
||||
principals = NULL;
|
||||
}
|
||||
|
||||
n = argc ? argc - 1 : 0;
|
||||
if (n > 0) {
|
||||
/*
|
||||
* Collect the function-argument arguments into one string, separated
|
||||
* by commas, then make a tokenstream from that string, and scan it to
|
||||
* get the arguments. We need to throw the full scanner at the
|
||||
* problem, because the argument string can legitimately contain
|
||||
* comments and linefeeds. XXX It might be better to concatenate
|
||||
* everything up into a function definition and pass it to the
|
||||
* compiler, but doing it this way is less of a delta from the old
|
||||
* code. See ECMA 15.3.2.1.
|
||||
*/
|
||||
args_length = 0;
|
||||
for (i = 0; i < n; i++) {
|
||||
/* Collect the lengths for all the function-argument arguments. */
|
||||
arg = JSVAL_TO_STRING(argv[i]);
|
||||
args_length += arg->length;
|
||||
}
|
||||
/* Add 1 for each joining comma. */
|
||||
args_length += n - 1;
|
||||
/*
|
||||
* Collect the function-argument arguments into one string, separated
|
||||
* by commas, then make a tokenstream from that string, and scan it to
|
||||
* get the arguments. We need to throw the full scanner at the
|
||||
* problem, because the argument string can legitimately contain
|
||||
* comments and linefeeds. XXX It might be better to concatenate
|
||||
* everything up into a function definition and pass it to the
|
||||
* compiler, but doing it this way is less of a delta from the old
|
||||
* code. See ECMA 15.3.2.1.
|
||||
*/
|
||||
args_length = 0;
|
||||
for (i = 0; i < n; i++) {
|
||||
/* Collect the lengths for all the function-argument arguments. */
|
||||
arg = JSVAL_TO_STRING(argv[i]);
|
||||
args_length += arg->length;
|
||||
}
|
||||
/* Add 1 for each joining comma. */
|
||||
args_length += n - 1;
|
||||
|
||||
/*
|
||||
* Allocate a string to hold the concatenated arguments, including room
|
||||
* for a terminating 0.
|
||||
*/
|
||||
cp = collected_args = (jschar *) JS_malloc(cx, (args_length + 1) *
|
||||
sizeof(jschar));
|
||||
/* Concatenate the arguments into the new string, separated by commas. */
|
||||
for (i = 0; i < n; i++) {
|
||||
arg = JSVAL_TO_STRING(argv[i]);
|
||||
(void)js_strncpy(cp, arg->chars, arg->length);
|
||||
cp += arg->length;
|
||||
/* Add separating comma or terminating 0. */
|
||||
*(cp++) = (i + 1 < n) ? ',' : 0;
|
||||
}
|
||||
/*
|
||||
* Allocate a string to hold the concatenated arguments, including room
|
||||
* for a terminating 0.
|
||||
*/
|
||||
cp = collected_args = (jschar *) JS_malloc(cx, (args_length + 1) *
|
||||
sizeof(jschar));
|
||||
/* Concatenate the arguments into the new string, separated by commas. */
|
||||
for (i = 0; i < n; i++) {
|
||||
arg = JSVAL_TO_STRING(argv[i]);
|
||||
(void)js_strncpy(cp, arg->chars, arg->length);
|
||||
cp += arg->length;
|
||||
/* Add separating comma or terminating 0. */
|
||||
*(cp++) = (i + 1 < n) ? ',' : 0;
|
||||
}
|
||||
|
||||
/* Make a tokenstream that reads from the given string. */
|
||||
ts = js_NewTokenStream(cx, collected_args, args_length, filename, lineno,
|
||||
principals);
|
||||
if (!ts) {
|
||||
JS_free(cx, collected_args);
|
||||
return JS_FALSE;
|
||||
}
|
||||
/* Make a tokenstream that reads from the given string. */
|
||||
ts = js_NewTokenStream(cx, collected_args, args_length, filename, lineno,
|
||||
principals);
|
||||
if (!ts) {
|
||||
JS_free(cx, collected_args);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
tt = js_GetToken(cx, ts);
|
||||
/* The argument string may be empty or contain no tokens. */
|
||||
if (tt != TOK_EOF) {
|
||||
while (1) {
|
||||
/*
|
||||
* Check that it's a name. This also implicitly guards against
|
||||
* TOK_ERROR.
|
||||
*/
|
||||
if (tt != TOK_NAME) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_NO_FORMAL);
|
||||
goto badargs;
|
||||
}
|
||||
/*
|
||||
* Get the atom corresponding to the name from the tokenstream;
|
||||
* we're assured at this point that it's a valid identifier.
|
||||
*/
|
||||
atom = ts->token.t_atom;
|
||||
if (!js_LookupProperty(cx, obj, (jsid)atom, &obj2,
|
||||
(JSProperty **)&sprop)) {
|
||||
goto badargs;
|
||||
}
|
||||
if (sprop && obj2 == obj) {
|
||||
tt = js_GetToken(cx, ts);
|
||||
/* The argument string may be empty or contain no tokens. */
|
||||
if (tt != TOK_EOF) {
|
||||
while (1) {
|
||||
/*
|
||||
* Check that it's a name. This also implicitly guards against
|
||||
* TOK_ERROR.
|
||||
*/
|
||||
if (tt != TOK_NAME) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_NO_FORMAL);
|
||||
goto badargs;
|
||||
}
|
||||
/*
|
||||
* Get the atom corresponding to the name from the tokenstream;
|
||||
* we're assured at this point that it's a valid identifier.
|
||||
*/
|
||||
atom = ts->token.t_atom;
|
||||
if (!js_LookupProperty(cx, obj, (jsid)atom, &obj2,
|
||||
(JSProperty **)&sprop)) {
|
||||
goto badargs;
|
||||
}
|
||||
if (sprop && obj2 == obj) {
|
||||
#ifdef CHECK_ARGUMENT_HIDING
|
||||
PR_ASSERT(sprop->getter == js_GetArgument);
|
||||
OBJ_DROP_PROPERTY(cx, obj2, (JSProperty *)sprop);
|
||||
JS_ReportErrorNumber(cx, JSREPORT_WARNING, JSMSG_SAME_FORMAL,
|
||||
ATOM_BYTES(atom));
|
||||
goto badargs;
|
||||
PR_ASSERT(sprop->getter == js_GetArgument);
|
||||
OBJ_DROP_PROPERTY(cx, obj2, (JSProperty *)sprop);
|
||||
JS_ReportErrorNumber(cx, JSREPORT_WARNING,
|
||||
JSMSG_SAME_FORMAL, ATOM_BYTES(atom));
|
||||
goto badargs;
|
||||
#else
|
||||
/*
|
||||
* A duplicate parameter name. We create a dummy symbol
|
||||
* entry with property id of the parameter number and set
|
||||
* the id to the name of the parameter.
|
||||
* The decompiler will know to treat this case specially.
|
||||
*/
|
||||
jsid oldArgId = (jsid) sprop->id;
|
||||
OBJ_DROP_PROPERTY(cx, obj2, (JSProperty *)sprop);
|
||||
sprop = NULL;
|
||||
if (!js_DefineProperty(cx, obj, oldArgId, JSVAL_VOID,
|
||||
js_GetArgument, js_SetArgument,
|
||||
JSPROP_ENUMERATE | JSPROP_PERMANENT,
|
||||
(JSProperty **)&sprop)) {
|
||||
goto badargs;
|
||||
}
|
||||
sprop->id = (jsid) atom;
|
||||
/*
|
||||
* A duplicate parameter name. We create a dummy symbol
|
||||
* entry with property id of the parameter number and set
|
||||
* the id to the name of the parameter.
|
||||
* The decompiler will know to treat this case specially.
|
||||
*/
|
||||
jsid oldArgId = (jsid) sprop->id;
|
||||
OBJ_DROP_PROPERTY(cx, obj2, (JSProperty *)sprop);
|
||||
sprop = NULL;
|
||||
if (!js_DefineProperty(cx, obj, oldArgId, JSVAL_VOID,
|
||||
js_GetArgument, js_SetArgument,
|
||||
JSPROP_ENUMERATE | JSPROP_PERMANENT,
|
||||
(JSProperty **)&sprop)) {
|
||||
goto badargs;
|
||||
}
|
||||
sprop->id = (jsid) atom;
|
||||
#endif
|
||||
}
|
||||
if (sprop)
|
||||
OBJ_DROP_PROPERTY(cx, obj2, (JSProperty *)sprop);
|
||||
if (!js_DefineProperty(cx, obj, (jsid)atom, JSVAL_VOID,
|
||||
js_GetArgument, js_SetArgument,
|
||||
JSPROP_ENUMERATE | JSPROP_PERMANENT,
|
||||
(JSProperty **)&sprop)) {
|
||||
goto badargs;
|
||||
}
|
||||
PR_ASSERT(sprop);
|
||||
sprop->id = INT_TO_JSVAL(fun->nargs++);
|
||||
OBJ_DROP_PROPERTY(cx, obj, (JSProperty *)sprop);
|
||||
}
|
||||
if (sprop)
|
||||
OBJ_DROP_PROPERTY(cx, obj2, (JSProperty *)sprop);
|
||||
if (!js_DefineProperty(cx, obj, (jsid)atom, JSVAL_VOID,
|
||||
js_GetArgument, js_SetArgument,
|
||||
JSPROP_ENUMERATE | JSPROP_PERMANENT,
|
||||
(JSProperty **)&sprop)) {
|
||||
goto badargs;
|
||||
}
|
||||
PR_ASSERT(sprop);
|
||||
sprop->id = INT_TO_JSVAL(fun->nargs++);
|
||||
OBJ_DROP_PROPERTY(cx, obj, (JSProperty *)sprop);
|
||||
|
||||
/* Done with the NAME; get the next token. */
|
||||
tt = js_GetToken(cx, ts);
|
||||
/* Stop if we've reached the end of the string. */
|
||||
if (tt == TOK_EOF)
|
||||
break;
|
||||
/* Done with the NAME; get the next token. */
|
||||
tt = js_GetToken(cx, ts);
|
||||
/* Stop if we've reached the end of the string. */
|
||||
if (tt == TOK_EOF)
|
||||
break;
|
||||
|
||||
/*
|
||||
* If a comma is seen, get the next token. Otherwise, let the
|
||||
* loop catch the error.
|
||||
*/
|
||||
if (tt == TOK_COMMA)
|
||||
tt = js_GetToken(cx, ts);
|
||||
}
|
||||
}
|
||||
/* Clean up. */
|
||||
JS_free(cx, collected_args);
|
||||
if (!js_CloseTokenStream(cx, ts))
|
||||
return JS_FALSE;
|
||||
/*
|
||||
* If a comma is seen, get the next token. Otherwise, let the
|
||||
* loop catch the error.
|
||||
*/
|
||||
if (tt == TOK_COMMA)
|
||||
tt = js_GetToken(cx, ts);
|
||||
}
|
||||
}
|
||||
/* Clean up. */
|
||||
JS_free(cx, collected_args);
|
||||
if (!js_CloseTokenStream(cx, ts))
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
if (argc) {
|
||||
|
@ -1552,14 +1552,14 @@ Function(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
if ((fp = cx->fp) != NULL && (fp = fp->down) != NULL && fp->script) {
|
||||
filename = fp->script->filename;
|
||||
lineno = js_PCToLineNumber(fp->script, fp->pc);
|
||||
principals = fp->script->principals;
|
||||
principals = fp->script->principals;
|
||||
} else {
|
||||
filename = NULL;
|
||||
lineno = 0;
|
||||
principals = NULL;
|
||||
principals = NULL;
|
||||
}
|
||||
ts = js_NewTokenStream(cx, str->chars, str->length, filename, lineno,
|
||||
principals);
|
||||
principals);
|
||||
if (!ts)
|
||||
return JS_FALSE;
|
||||
return js_ParseFunctionBody(cx, ts, fun) &&
|
||||
|
@ -1592,10 +1592,10 @@ js_InitFunctionClass(JSContext *cx, JSObject *obj)
|
|||
goto bad;
|
||||
fun = js_NewFunction(cx, proto, NULL, 0, 0, obj, atom);
|
||||
if (!fun)
|
||||
goto bad;
|
||||
goto bad;
|
||||
fun->script = js_NewScript(cx, 0);
|
||||
if (!fun->script)
|
||||
goto bad;
|
||||
goto bad;
|
||||
return proto;
|
||||
|
||||
bad:
|
||||
|
@ -1739,8 +1739,8 @@ js_ReportIsNotFunction(JSContext *cx, jsval *vp, JSBool constructing)
|
|||
fp->sp = sp;
|
||||
if (str) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
constructing ? JSMSG_NOT_CONSTRUCTOR
|
||||
: JSMSG_NOT_FUNCTION,
|
||||
JS_GetStringBytes(str));
|
||||
constructing ? JSMSG_NOT_CONSTRUCTOR
|
||||
: JSMSG_NOT_FUNCTION,
|
||||
JS_GetStringBytes(str));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -493,7 +493,7 @@ gc_mark(JSRuntime *rt, void *thing)
|
|||
fun = JSVAL_TO_PRIVATE(v);
|
||||
if (fun) {
|
||||
if (fun->atom)
|
||||
GC_MARK_ATOM(rt, fun->atom, prev);
|
||||
GC_MARK_ATOM(rt, fun->atom, prev);
|
||||
if (fun->script)
|
||||
GC_MARK_SCRIPT(rt, fun->script, prev);
|
||||
}
|
||||
|
@ -589,7 +589,7 @@ gc_root_marker(PRHashEntry *he, intN i, void *arg)
|
|||
JSRuntime *rt = (JSRuntime *)arg;
|
||||
|
||||
for (a = rt->gcArenaPool.first.next; a; a = a->next) {
|
||||
PR_ASSERT(!rp ||
|
||||
PR_ASSERT(!rp ||
|
||||
(*rp >= (void *)a->base && *rp <= (void *)a->avail));
|
||||
}
|
||||
#endif
|
||||
|
@ -624,6 +624,13 @@ js_GC(JSContext *cx)
|
|||
GCFinalizeOp finalizer;
|
||||
JSBool a_all_clear, f_all_clear;
|
||||
|
||||
/*
|
||||
* XXX kludge for pre-ECMAv2 compile-time switch case expr eval, see
|
||||
* jsemit.c:js_EmitTree, under case TOK_SWITCH: (look for XXX).
|
||||
*/
|
||||
if (cx->gcDisabled)
|
||||
return;
|
||||
|
||||
rt = cx->runtime;
|
||||
#ifdef JS_THREADSAFE
|
||||
/* Avoid deadlock. */
|
||||
|
@ -707,18 +714,18 @@ restart:
|
|||
while ((acx = js_ContextIterator(rt, &iter)) != NULL) {
|
||||
/*
|
||||
* Iterate frame chain and dormant chains. Temporarily tack current
|
||||
* frame onto the head of the dormant list to ease iteration.
|
||||
*
|
||||
* (NOTE: see comment on this whole 'dormant' thing in js_Execute)
|
||||
*/
|
||||
* frame onto the head of the dormant list to ease iteration.
|
||||
*
|
||||
* (NOTE: see comment on this whole 'dormant' thing in js_Execute)
|
||||
*/
|
||||
chain = acx->fp;
|
||||
if (chain) {
|
||||
PR_ASSERT(!chain->dormantNext);
|
||||
chain->dormantNext = acx->dormantFrameChain;
|
||||
} else {
|
||||
chain = acx->dormantFrameChain;
|
||||
}
|
||||
for (fp=chain; fp; fp = chain = chain->dormantNext) {
|
||||
if (chain) {
|
||||
PR_ASSERT(!chain->dormantNext);
|
||||
chain->dormantNext = acx->dormantFrameChain;
|
||||
} else {
|
||||
chain = acx->dormantFrameChain;
|
||||
}
|
||||
for (fp=chain; fp; fp = chain = chain->dormantNext) {
|
||||
sp = fp->sp;
|
||||
if (sp) {
|
||||
for (a = acx->stackPool.first.next; a; a = a->next) {
|
||||
|
@ -732,7 +739,7 @@ restart:
|
|||
GC_MARK(rt, JSVAL_TO_GCTHING(v), "stack", NULL);
|
||||
}
|
||||
if (end == (pruword)sp)
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
do {
|
||||
|
@ -750,16 +757,16 @@ restart:
|
|||
GC_MARK(rt, fp->sharpArray, "sharp array", NULL);
|
||||
} while ((fp = fp->down) != NULL);
|
||||
}
|
||||
/* cleanup temporary link */
|
||||
if (acx->fp)
|
||||
acx->fp->dormantNext = NULL;
|
||||
/* cleanup temporary link */
|
||||
if (acx->fp)
|
||||
acx->fp->dormantNext = NULL;
|
||||
GC_MARK(rt, acx->globalObject, "global object", NULL);
|
||||
GC_MARK(rt, acx->newborn[GCX_OBJECT], "newborn object", NULL);
|
||||
GC_MARK(rt, acx->newborn[GCX_STRING], "newborn string", NULL);
|
||||
GC_MARK(rt, acx->newborn[GCX_DOUBLE], "newborn double", NULL);
|
||||
#if JS_HAS_EXCEPTIONS
|
||||
if (acx->throwing)
|
||||
GC_MARK(rt, acx->exception, "exception", NULL);
|
||||
if (acx->throwing)
|
||||
GC_MARK(rt, acx->exception, "exception", NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
3552
js/ref/jsinterp.c
3552
js/ref/jsinterp.c
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -326,20 +326,20 @@ js_SuspendThread(JSThinLock *p)
|
|||
PRStatus stat;
|
||||
|
||||
while ((fl = (JSFatLock*)js_AtomicSet((prword*)&p->fat,1)) == (JSFatLock*)1) /* busy wait */
|
||||
PR_Sleep(PR_INTERVAL_NO_WAIT);
|
||||
PR_Sleep(PR_INTERVAL_NO_WAIT);
|
||||
if (fl == NULL)
|
||||
return 1;
|
||||
PR_Lock(fl->slock);
|
||||
js_AtomicSet((prword*)&p->fat,(prword)fl);
|
||||
fl->susp++;
|
||||
if (fl->susp < 1) {
|
||||
PR_Unlock(fl->slock);
|
||||
return 1;
|
||||
PR_Unlock(fl->slock);
|
||||
return 1;
|
||||
}
|
||||
stat = PR_WaitCondVar(fl->svar,PR_INTERVAL_NO_TIMEOUT);
|
||||
if (stat == PR_FAILURE) {
|
||||
fl->susp--;
|
||||
return 0;
|
||||
fl->susp--;
|
||||
return 0;
|
||||
}
|
||||
PR_Unlock(fl->slock);
|
||||
return 1;
|
||||
|
@ -350,17 +350,17 @@ js_ResumeThread(JSThinLock *p)
|
|||
{
|
||||
JSFatLock *fl;
|
||||
PRStatus stat;
|
||||
|
||||
|
||||
while ((fl = (JSFatLock*)js_AtomicSet((prword*)&p->fat,1)) == (JSFatLock*)1)
|
||||
PR_Sleep(PR_INTERVAL_NO_WAIT);
|
||||
PR_Sleep(PR_INTERVAL_NO_WAIT);
|
||||
if (fl == NULL)
|
||||
return;
|
||||
PR_Lock(fl->slock);
|
||||
js_AtomicSet((prword*)&p->fat,(prword)fl);
|
||||
fl->susp--;
|
||||
if (fl->susp < 0) {
|
||||
PR_Unlock(fl->slock);
|
||||
return;
|
||||
PR_Unlock(fl->slock);
|
||||
return;
|
||||
}
|
||||
stat = PR_NotifyCondVar(fl->svar);
|
||||
PR_ASSERT(stat != PR_FAILURE);
|
||||
|
@ -388,8 +388,8 @@ deleteListOfFatlocks(JSFatLock *m)
|
|||
{
|
||||
JSFatLock *m0;
|
||||
for (; m; m=m0) {
|
||||
m0 = m->next;
|
||||
freeFatlock(m);
|
||||
m0 = m->next;
|
||||
freeFatlock(m);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -521,7 +521,7 @@ emptyFatlock(JSThinLock *p)
|
|||
while ((fl = (JSFatLock*)js_AtomicSet((prword*)&p->fat,1)) == (JSFatLock*)1)
|
||||
PR_Sleep(PR_INTERVAL_NO_WAIT);
|
||||
if (fl == NULL) {
|
||||
js_AtomicSet((prword*)&p->fat,(prword)fl);
|
||||
js_AtomicSet((prword*)&p->fat,(prword)fl);
|
||||
return 1;
|
||||
}
|
||||
lck = fl->slock;
|
||||
|
@ -561,7 +561,7 @@ emptyFatlock(JSThinLock *p)
|
|||
Furthermore, when enqueueing (after the compare-and-swap has failed
|
||||
to lock the object), p->fat is used to serialize the different
|
||||
accesses to the fat lock. The four function thus synchronized are
|
||||
js_Enqueue, emptyFatLock, js_SuspendThread, and js_ResumeThread.
|
||||
js_Enqueue, emptyFatLock, js_SuspendThread, and js_ResumeThread.
|
||||
|
||||
When dequeueing, the lock is released, and one of the threads
|
||||
suspended on the lock is notified. If other threads still are
|
||||
|
@ -569,7 +569,7 @@ emptyFatlock(JSThinLock *p)
|
|||
lock is deallocated (in emptyFatlock()).
|
||||
|
||||
p->fat is set to 1 by enqueue and emptyFatlock to signal that the pointer
|
||||
is being accessed.
|
||||
is being accessed.
|
||||
|
||||
*/
|
||||
|
||||
|
@ -582,31 +582,31 @@ js_Enqueue(JSThinLock *p, prword me)
|
|||
o = ReadWord(p->owner);
|
||||
n = Thin_SetWait(o);
|
||||
if (o != 0 && js_CompareAndSwap(&p->owner,o,n)) {
|
||||
JSFatLock* fl;
|
||||
while ((fl = (JSFatLock*)js_AtomicSet((prword*)&p->fat,1)) == (JSFatLock*)1)
|
||||
PR_Sleep(PR_INTERVAL_NO_WAIT);
|
||||
if (fl == NULL)
|
||||
fl = allocateFatlock();
|
||||
js_AtomicSet((prword*)&p->fat,(prword)fl);
|
||||
js_SuspendThread(p);
|
||||
if (emptyFatlock(p))
|
||||
JSFatLock* fl;
|
||||
while ((fl = (JSFatLock*)js_AtomicSet((prword*)&p->fat,1)) == (JSFatLock*)1)
|
||||
PR_Sleep(PR_INTERVAL_NO_WAIT);
|
||||
if (fl == NULL)
|
||||
fl = allocateFatlock();
|
||||
js_AtomicSet((prword*)&p->fat,(prword)fl);
|
||||
js_SuspendThread(p);
|
||||
if (emptyFatlock(p))
|
||||
me = Thin_RemoveWait(me);
|
||||
else
|
||||
else
|
||||
me = Thin_SetWait(me);
|
||||
}
|
||||
else if (js_CompareAndSwap(&p->owner,0,me)) {
|
||||
return;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
js_Dequeue(JSThinLock *p)
|
||||
{
|
||||
{
|
||||
int o = ReadWord(p->owner);
|
||||
PR_ASSERT(Thin_GetWait(o));
|
||||
if (!js_CompareAndSwap(&p->owner,o,0)) /* release it */
|
||||
PR_ASSERT(0);
|
||||
PR_ASSERT(0);
|
||||
js_ResumeThread(p);
|
||||
}
|
||||
|
||||
|
@ -615,9 +615,9 @@ js_Lock(JSThinLock *p, prword me)
|
|||
{
|
||||
PR_ASSERT(me == CurrentThreadId());
|
||||
if (js_CompareAndSwap(&p->owner, 0, me))
|
||||
return;
|
||||
return;
|
||||
if (Thin_RemoveWait(ReadWord(p->owner)) != me)
|
||||
js_Enqueue(p, me);
|
||||
js_Enqueue(p, me);
|
||||
#ifdef DEBUG
|
||||
else
|
||||
PR_ASSERT(0);
|
||||
|
|
414
js/ref/jsmath.c
414
js/ref/jsmath.c
|
@ -1,414 +0,0 @@
|
|||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* JS math package.
|
||||
*/
|
||||
#include "jsstddef.h"
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include "prtypes.h"
|
||||
#include "prlong.h"
|
||||
#include "prtime.h"
|
||||
#include "jsapi.h"
|
||||
#include "jsatom.h"
|
||||
#include "jscntxt.h"
|
||||
#include "jsconfig.h"
|
||||
#include "jslock.h"
|
||||
#include "jsmath.h"
|
||||
#include "jsnum.h"
|
||||
#include "jsobj.h"
|
||||
|
||||
#ifndef M_E
|
||||
#define M_E 2.7182818284590452354
|
||||
#endif
|
||||
#ifndef M_LOG2E
|
||||
#define M_LOG2E 1.4426950408889634074
|
||||
#endif
|
||||
#ifndef M_LOG10E
|
||||
#define M_LOG10E 0.43429448190325182765
|
||||
#endif
|
||||
#ifndef M_LN2
|
||||
#define M_LN2 0.69314718055994530942
|
||||
#endif
|
||||
#ifndef M_LN10
|
||||
#define M_LN10 2.30258509299404568402
|
||||
#endif
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
#ifndef M_SQRT2
|
||||
#define M_SQRT2 1.41421356237309504880
|
||||
#endif
|
||||
#ifndef M_SQRT1_2
|
||||
#define M_SQRT1_2 0.70710678118654752440
|
||||
#endif
|
||||
|
||||
static JSConstDoubleSpec math_constants[] = {
|
||||
{M_E, "E"},
|
||||
{M_LOG2E, "LOG2E"},
|
||||
{M_LOG10E, "LOG10E"},
|
||||
{M_LN2, "LN2"},
|
||||
{M_LN10, "LN10"},
|
||||
{M_PI, "PI"},
|
||||
{M_SQRT2, "SQRT2"},
|
||||
{M_SQRT1_2, "SQRT1_2"},
|
||||
{0}
|
||||
};
|
||||
|
||||
static JSClass math_class = {
|
||||
"Math",
|
||||
0,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
|
||||
};
|
||||
|
||||
static JSBool
|
||||
math_abs(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
jsdouble x, z;
|
||||
|
||||
if (!js_ValueToNumber(cx, argv[0], &x))
|
||||
return JS_FALSE;
|
||||
z = (x < 0) ? -x : x;
|
||||
return js_NewNumberValue(cx, z, rval);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
math_acos(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
jsdouble x, z;
|
||||
|
||||
if (!js_ValueToNumber(cx, argv[0], &x))
|
||||
return JS_FALSE;
|
||||
z = acos(x);
|
||||
return js_NewNumberValue(cx, z, rval);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
math_asin(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
jsdouble x, z;
|
||||
|
||||
if (!js_ValueToNumber(cx, argv[0], &x))
|
||||
return JS_FALSE;
|
||||
z = asin(x);
|
||||
return js_NewNumberValue(cx, z, rval);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
math_atan(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
jsdouble x, z;
|
||||
|
||||
if (!js_ValueToNumber(cx, argv[0], &x))
|
||||
return JS_FALSE;
|
||||
z = atan(x);
|
||||
return js_NewNumberValue(cx, z, rval);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
math_atan2(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
jsdouble x, y, z;
|
||||
|
||||
if (!js_ValueToNumber(cx, argv[0], &x))
|
||||
return JS_FALSE;
|
||||
if (!js_ValueToNumber(cx, argv[1], &y))
|
||||
return JS_FALSE;
|
||||
z = atan2(x, y);
|
||||
return js_NewNumberValue(cx, z, rval);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
math_ceil(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
jsdouble x, z;
|
||||
|
||||
if (!js_ValueToNumber(cx, argv[0], &x))
|
||||
return JS_FALSE;
|
||||
z = ceil(x);
|
||||
return js_NewNumberValue(cx, z, rval);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
math_cos(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
jsdouble x, z;
|
||||
|
||||
if (!js_ValueToNumber(cx, argv[0], &x))
|
||||
return JS_FALSE;
|
||||
z = cos(x);
|
||||
return js_NewNumberValue(cx, z, rval);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
math_exp(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
jsdouble x, z;
|
||||
|
||||
if (!js_ValueToNumber(cx, argv[0], &x))
|
||||
return JS_FALSE;
|
||||
z = exp(x);
|
||||
return js_NewNumberValue(cx, z, rval);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
math_floor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
jsdouble x, z;
|
||||
|
||||
if (!js_ValueToNumber(cx, argv[0], &x))
|
||||
return JS_FALSE;
|
||||
z = floor(x);
|
||||
return js_NewNumberValue(cx, z, rval);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
math_log(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
jsdouble x, z;
|
||||
|
||||
if (!js_ValueToNumber(cx, argv[0], &x))
|
||||
return JS_FALSE;
|
||||
z = log(x);
|
||||
return js_NewNumberValue(cx, z, rval);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
math_max(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
jsdouble x, y, z;
|
||||
|
||||
if (!js_ValueToNumber(cx, argv[0], &x))
|
||||
return JS_FALSE;
|
||||
if (!js_ValueToNumber(cx, argv[1], &y))
|
||||
return JS_FALSE;
|
||||
z = (x > y) ? x : y;
|
||||
return js_NewNumberValue(cx, z, rval);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
math_min(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
jsdouble x, y, z;
|
||||
|
||||
if (!js_ValueToNumber(cx, argv[0], &x))
|
||||
return JS_FALSE;
|
||||
if (!js_ValueToNumber(cx, argv[1], &y))
|
||||
return JS_FALSE;
|
||||
z = (x < y) ? x : y;
|
||||
return js_NewNumberValue(cx, z, rval);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
math_pow(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
jsdouble x, y, z;
|
||||
|
||||
if (!js_ValueToNumber(cx, argv[0], &x))
|
||||
return JS_FALSE;
|
||||
if (!js_ValueToNumber(cx, argv[1], &y))
|
||||
return JS_FALSE;
|
||||
z = pow(x, y);
|
||||
return js_NewNumberValue(cx, z, rval);
|
||||
}
|
||||
|
||||
/*
|
||||
* Math.random() support, lifted from java.util.Random.java.
|
||||
*/
|
||||
static void
|
||||
random_setSeed(JSRuntime *rt, int64 seed)
|
||||
{
|
||||
int64 tmp;
|
||||
|
||||
LL_I2L(tmp, 1000);
|
||||
LL_DIV(seed, seed, tmp);
|
||||
LL_XOR(tmp, seed, rt->rngMultiplier);
|
||||
LL_AND(rt->rngSeed, tmp, rt->rngMask);
|
||||
}
|
||||
|
||||
static void
|
||||
random_init(JSRuntime *rt)
|
||||
{
|
||||
int64 tmp, tmp2;
|
||||
|
||||
/* Do at most once. */
|
||||
if (rt->rngInitialized)
|
||||
return;
|
||||
rt->rngInitialized = JS_TRUE;
|
||||
|
||||
/* rt->rngMultiplier = 0x5DEECE66DL */
|
||||
LL_ISHL(tmp, 0x5D, 32);
|
||||
LL_UI2L(tmp2, 0xEECE66DL);
|
||||
LL_OR(rt->rngMultiplier, tmp, tmp2);
|
||||
|
||||
/* rt->rngAddend = 0xBL */
|
||||
LL_I2L(rt->rngAddend, 0xBL);
|
||||
|
||||
/* rt->rngMask = (1L << 48) - 1 */
|
||||
LL_I2L(tmp, 1);
|
||||
LL_SHL(tmp2, tmp, 48);
|
||||
LL_SUB(rt->rngMask, tmp2, tmp);
|
||||
|
||||
/* rt->rngDscale = (jsdouble)(1L << 54) */
|
||||
LL_SHL(tmp2, tmp, 54);
|
||||
LL_L2D(rt->rngDscale, tmp2);
|
||||
|
||||
/* Finally, set the seed from current time. */
|
||||
random_setSeed(rt, PR_Now());
|
||||
}
|
||||
|
||||
static uint32
|
||||
random_next(JSRuntime *rt, int bits)
|
||||
{
|
||||
int64 nextseed, tmp;
|
||||
uint32 retval;
|
||||
|
||||
LL_MUL(nextseed, rt->rngSeed, rt->rngMultiplier);
|
||||
LL_ADD(nextseed, nextseed, rt->rngAddend);
|
||||
LL_AND(nextseed, nextseed, rt->rngMask);
|
||||
rt->rngSeed = nextseed;
|
||||
LL_USHR(tmp, nextseed, 48 - bits);
|
||||
LL_L2I(retval, tmp);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static jsdouble
|
||||
random_nextDouble(JSRuntime *rt)
|
||||
{
|
||||
int64 tmp, tmp2;
|
||||
jsdouble d;
|
||||
|
||||
LL_ISHL(tmp, random_next(rt, 27), 27);
|
||||
LL_UI2L(tmp2, random_next(rt, 27));
|
||||
LL_ADD(tmp, tmp, tmp2);
|
||||
LL_L2D(d, tmp);
|
||||
return d / rt->rngDscale;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
math_random(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
JSRuntime *rt;
|
||||
jsdouble z;
|
||||
|
||||
rt = cx->runtime;
|
||||
JS_LOCK_RUNTIME(rt);
|
||||
random_init(rt);
|
||||
z = random_nextDouble(rt);
|
||||
JS_UNLOCK_RUNTIME(rt);
|
||||
return js_NewNumberValue(cx, z, rval);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
math_round(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
jsdouble x, z;
|
||||
|
||||
if (!js_ValueToNumber(cx, argv[0], &x))
|
||||
return JS_FALSE;
|
||||
z = floor(x + 0.5);
|
||||
return js_NewNumberValue(cx, z, rval);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
math_sin(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
jsdouble x, z;
|
||||
|
||||
if (!js_ValueToNumber(cx, argv[0], &x))
|
||||
return JS_FALSE;
|
||||
z = sin(x);
|
||||
return js_NewNumberValue(cx, z, rval);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
math_sqrt(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
jsdouble x, z;
|
||||
|
||||
if (!js_ValueToNumber(cx, argv[0], &x))
|
||||
return JS_FALSE;
|
||||
z = sqrt(x);
|
||||
return js_NewNumberValue(cx, z, rval);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
math_tan(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
jsdouble x, z;
|
||||
|
||||
if (!js_ValueToNumber(cx, argv[0], &x))
|
||||
return JS_FALSE;
|
||||
z = tan(x);
|
||||
return js_NewNumberValue(cx, z, rval);
|
||||
}
|
||||
|
||||
static JSFunctionSpec math_static_methods[] = {
|
||||
{"abs", math_abs, 1},
|
||||
{"acos", math_acos, 1},
|
||||
{"asin", math_asin, 1},
|
||||
{"atan", math_atan, 1},
|
||||
{"atan2", math_atan2, 2},
|
||||
{"ceil", math_ceil, 1},
|
||||
{"cos", math_cos, 1},
|
||||
{"exp", math_exp, 1},
|
||||
{"floor", math_floor, 1},
|
||||
{"log", math_log, 1},
|
||||
{"max", math_max, 2},
|
||||
{"min", math_min, 2},
|
||||
{"pow", math_pow, 2},
|
||||
{"random", math_random, 0},
|
||||
{"round", math_round, 1},
|
||||
{"sin", math_sin, 1},
|
||||
{"sqrt", math_sqrt, 1},
|
||||
{"tan", math_tan, 1},
|
||||
{0}
|
||||
};
|
||||
|
||||
#if JS_HAS_TOSOURCE
|
||||
static JSBool
|
||||
math_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
||||
jsval *rval)
|
||||
{
|
||||
*rval = ATOM_KEY(cx->runtime->atomState.MathAtom);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSFunctionSpec math_methods[] = {
|
||||
{js_toSource_str, math_toSource, 0},
|
||||
{0}
|
||||
};
|
||||
#else
|
||||
#define math_methods NULL
|
||||
#endif
|
||||
|
||||
JSObject *
|
||||
js_InitMathClass(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
JSObject *proto;
|
||||
|
||||
proto = JS_InitClass(cx, obj, NULL, &math_class, NULL, 0,
|
||||
NULL, math_methods, NULL, math_static_methods);
|
||||
if (!proto)
|
||||
return NULL;
|
||||
if (!JS_DefineConstDoubles(cx, proto, math_constants))
|
||||
return NULL;
|
||||
return proto;
|
||||
}
|
127
js/ref/jsmsg.def
127
js/ref/jsmsg.def
|
@ -17,95 +17,95 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
This is the JavaScript error message file.
|
||||
This is the JavaScript error message file.
|
||||
|
||||
The format for each JS error message is:
|
||||
The format for each JS error message is:
|
||||
|
||||
MSG_DEF(<SYMBOLIC_NAME>, <ERROR_NUMBER>, <ARGUMENT_COUNT>, <EXCEPTION_NAME>,
|
||||
<FORMAT_STRING>)
|
||||
|
||||
where ;
|
||||
<SYMBOLIC_NAME> is a legal C identifer that will be used in the
|
||||
JS engine source.
|
||||
<FORMAT_STRING>)
|
||||
|
||||
<ERROR_NUMBER> is an unique integral value identifying this error.
|
||||
where ;
|
||||
<SYMBOLIC_NAME> is a legal C identifer that will be used in the
|
||||
JS engine source.
|
||||
|
||||
<ARGUMENT_COUNT> is an integer literal specifying the total number of
|
||||
replaceable arguments in the following format string.
|
||||
<ERROR_NUMBER> is an unique integral value identifying this error.
|
||||
|
||||
<EXCEPTION_NAME> is an exception index from the enum in jsexn.c;
|
||||
JSEXN_NONE for none. The given exception index will be raised by the
|
||||
engine when the corresponding error occurs.
|
||||
<ARGUMENT_COUNT> is an integer literal specifying the total number of
|
||||
replaceable arguments in the following format string.
|
||||
|
||||
<FORMAT_STRING> is a string literal, optionally containing sequences
|
||||
{X} where X is an integer representing the argument number that will
|
||||
be replaced with a string value when the error is reported.
|
||||
<EXCEPTION_NAME> is an exception index from the enum in jsexn.c;
|
||||
JSEXN_NONE for none. The given exception index will be raised by the
|
||||
engine when the corresponding error occurs.
|
||||
|
||||
e.g.
|
||||
<FORMAT_STRING> is a string literal, optionally containing sequences
|
||||
{X} where X is an integer representing the argument number that will
|
||||
be replaced with a string value when the error is reported.
|
||||
|
||||
MSG_DEF(JSMSG_NOT_A_SUBSPECIES, 73, JSEXN_NONE, 2,
|
||||
"{0} is not a member of the {1} family")
|
||||
e.g.
|
||||
|
||||
can be used :
|
||||
MSG_DEF(JSMSG_NOT_A_SUBSPECIES, 73, JSEXN_NONE, 2,
|
||||
"{0} is not a member of the {1} family")
|
||||
|
||||
JS_ReportErrorNumber(JSMSG_NOT_A_SUBSPECIES, "Rhino", "Monkey");
|
||||
can be used :
|
||||
|
||||
to report :
|
||||
JS_ReportErrorNumber(JSMSG_NOT_A_SUBSPECIES, "Rhino", "Monkey");
|
||||
|
||||
"Rhino is not a member of the Monkey family"
|
||||
to report :
|
||||
|
||||
"Rhino is not a member of the Monkey family"
|
||||
|
||||
*/
|
||||
|
||||
MSG_DEF(JSMSG_NOT_AN_ERROR, 0, 0, JSEXN_NONE, "<Error #0 is reserved>")
|
||||
MSG_DEF(JSMSG_NOT_DEFINED, 1, 1, JSEXN_REFERENCEERR, "{0} is not defined")
|
||||
MSG_DEF(JSMSG_NO_REG_EXPS, 2, 1, JSEXN_INTERNALERR, "sorry, regular expression are not supported")
|
||||
MSG_DEF(JSMSG_MORE_ARGS_NEEDED, 3, 3, JSEXN_NONE, "{0} requires more than {1} argument{2}")
|
||||
MSG_DEF(JSMSG_BAD_CHAR, 4, 1, JSEXN_NONE, "invalid format character {0}")
|
||||
MSG_DEF(JSMSG_BAD_TYPE, 5, 1, JSEXN_NONE, "unknown type {0}")
|
||||
MSG_DEF(JSMSG_CANT_LOCK, 6, 0, JSEXN_NONE, "can't lock memory")
|
||||
MSG_DEF(JSMSG_CANT_UNLOCK, 7, 0, JSEXN_NONE, "can't unlock memory")
|
||||
MSG_DEF(JSMSG_MORE_ARGS_NEEDED, 3, 3, JSEXN_NONE, "{0} requires more than {1} argument{2}")
|
||||
MSG_DEF(JSMSG_BAD_CHAR, 4, 1, JSEXN_NONE, "invalid format character {0}")
|
||||
MSG_DEF(JSMSG_BAD_TYPE, 5, 1, JSEXN_NONE, "unknown type {0}")
|
||||
MSG_DEF(JSMSG_CANT_LOCK, 6, 0, JSEXN_NONE, "can't lock memory")
|
||||
MSG_DEF(JSMSG_CANT_UNLOCK, 7, 0, JSEXN_NONE, "can't unlock memory")
|
||||
MSG_DEF(JSMSG_INCOMPATIBLE_PROTO, 8, 3, JSEXN_TARGETERR, "{0}.prototype.{1} called on incompatible {2}")
|
||||
MSG_DEF(JSMSG_NO_CONSTRUCTOR, 9, 1, JSEXN_NONE, "{0} has no constructor")
|
||||
MSG_DEF(JSMSG_CANT_ALIAS, 10, 3, JSEXN_NONE, "can't alias {0} to {1} in class {2}")
|
||||
MSG_DEF(JSMSG_NO_CONSTRUCTOR, 9, 1, JSEXN_NONE, "{0} has no constructor")
|
||||
MSG_DEF(JSMSG_CANT_ALIAS, 10, 3, JSEXN_NONE, "can't alias {0} to {1} in class {2}")
|
||||
MSG_DEF(JSMSG_NO_PROTO, 11, 1, JSEXN_INTERNALERR, "sorry, Array.prototype.{0} is not yet implemented")
|
||||
MSG_DEF(JSMSG_BAD_PROTO_SORT, 12, 0, JSEXN_ARRAYERR, "invalid Array.prototype.sort argument")
|
||||
MSG_DEF(JSMSG_BAD_SORT_ARG, 12, 0, JSEXN_ARRAYERR, "invalid Array.prototype.sort argument")
|
||||
MSG_DEF(JSMSG_BAD_ATOMIC_NUMBER, 13, 1, JSEXN_INTERNALERR, "internal error: no index for atom {0}")
|
||||
MSG_DEF(JSMSG_TOO_MANY_LITERALS, 14, 0, JSEXN_INTERNALERR, "too many literals")
|
||||
MSG_DEF(JSMSG_CANT_WATCH, 15, 1, JSEXN_NONE, "can't watch non-native objects of class {0}")
|
||||
MSG_DEF(JSMSG_CANT_WATCH, 15, 1, JSEXN_NONE, "can't watch non-native objects of class {0}")
|
||||
MSG_DEF(JSMSG_STACK_UNDERFLOW, 16, 2, JSEXN_INTERNALERR, "internal error compiling {0}: stack underflow at pc {1}")
|
||||
MSG_DEF(JSMSG_NEED_DIET, 17, 1, JSEXN_SYNTAXERR, "{0} too large")
|
||||
MSG_DEF(JSMSG_BAD_CASE, 18, 2, JSEXN_SYNTAXERR, "{0}, line {1}: invalid case expression")
|
||||
MSG_DEF(JSMSG_READ_ONLY, 19, 1, JSEXN_ERR, "{0} is read-only")
|
||||
MSG_DEF(JSMSG_NEED_DIET, 17, 1, JSEXN_SYNTAXERR, "{0} too large")
|
||||
MSG_DEF(JSMSG_BAD_CASE, 18, 2, JSEXN_SYNTAXERR, "{0}, line {1}: invalid case expression")
|
||||
MSG_DEF(JSMSG_READ_ONLY, 19, 1, JSEXN_ERR, "{0} is read-only")
|
||||
MSG_DEF(JSMSG_NO_FORMAL, 20, 0, JSEXN_SYNTAXERR, "missing formal parameter")
|
||||
MSG_DEF(JSMSG_SAME_FORMAL, 21, 1, JSEXN_NONE, "duplicate formal argument {0}")
|
||||
MSG_DEF(JSMSG_SAME_FORMAL, 21, 1, JSEXN_NONE, "duplicate formal argument {0}")
|
||||
MSG_DEF(JSMSG_NOT_FUNCTION, 22, 1, JSEXN_CALLERR, "{0} is not a function")
|
||||
MSG_DEF(JSMSG_NOT_CONSTRUCTOR, 23, 1, JSEXN_CONSTRUCTORERR, "{0} is not a constructor")
|
||||
MSG_DEF(JSMSG_STACK_OVERFLOW, 24, 1, JSEXN_NONE, "stack overflow in {0}")
|
||||
MSG_DEF(JSMSG_NOT_EXPORTED, 25, 1, JSEXN_NONE, "{0} is not exported")
|
||||
MSG_DEF(JSMSG_OVER_RECURSED, 26, 0, JSEXN_NONE, "too much recursion")
|
||||
MSG_DEF(JSMSG_IN_NOT_OBJECT, 27, 0, JSEXN_ERR, "target of 'in' operator must be an object")
|
||||
MSG_DEF(JSMSG_IN_NOT_OBJECT, 27, 0, JSEXN_ERR, "target of 'in' operator must be an object")
|
||||
MSG_DEF(JSMSG_BAD_NEW_RESULT, 28, 1, JSEXN_NONE, "invalid new expression result {0}")
|
||||
MSG_DEF(JSMSG_BAD_SHARP_DEF, 29, 1, JSEXN_ERR, "invalid sharp variable definition #{0}=")
|
||||
MSG_DEF(JSMSG_BAD_SHARP_USE, 30, 1, JSEXN_ERR, "invalid sharp variable use #{0}#")
|
||||
MSG_DEF(JSMSG_BAD_INSTANCEOF_RHS, 31, 1, JSEXN_ERR, "invalid instanceof operand {0}")
|
||||
MSG_DEF(JSMSG_BAD_SHARP_DEF, 29, 1, JSEXN_ERR, "invalid sharp variable definition #{0}=")
|
||||
MSG_DEF(JSMSG_BAD_SHARP_USE, 30, 1, JSEXN_ERR, "invalid sharp variable use #{0}#")
|
||||
MSG_DEF(JSMSG_BAD_INSTANCEOF_RHS, 31, 1, JSEXN_ERR, "invalid instanceof operand {0}")
|
||||
MSG_DEF(JSMSG_BAD_BYTECODE, 32, 1, JSEXN_INTERNALERR, "unimplemented JavaScript bytecode {0}")
|
||||
MSG_DEF(JSMSG_BAD_RADIX, 33, 1, JSEXN_ERR, "illegal radix {0}")
|
||||
MSG_DEF(JSMSG_NAN, 34, 1, JSEXN_ERR, "{0} is not a number")
|
||||
MSG_DEF(JSMSG_BAD_RADIX, 33, 1, JSEXN_ERR, "illegal radix {0}")
|
||||
MSG_DEF(JSMSG_NAN, 34, 1, JSEXN_ERR, "{0} is not a number")
|
||||
MSG_DEF(JSMSG_CANT_CONVERT, 35, 1, JSEXN_TOPRIMITIVEERR, "can't convert {0} to an integer")
|
||||
MSG_DEF(JSMSG_CYCLIC_VALUE, 36, 1, JSEXN_ERR, "cyclic {0} value")
|
||||
MSG_DEF(JSMSG_PERMANENT, 37, 1, JSEXN_ERR, "{0} is permanent")
|
||||
MSG_DEF(JSMSG_CANT_CONVERT_TO, 38, 2, JSEXN_DEFAULTVALUEERR, "can't convert {0} to {1}")
|
||||
MSG_DEF(JSMSG_NO_PROPERTIES, 39, 1, JSEXN_TOOBJECTERR, "{0} has no properties")
|
||||
MSG_DEF(JSMSG_CANT_FIND_CLASS, 40, 1, JSEXN_NONE, "can't find class id {0}")
|
||||
MSG_DEF(JSMSG_NO_PROPERTIES, 39, 1, JSEXN_TOOBJECTERR, "{0} has no properties")
|
||||
MSG_DEF(JSMSG_CANT_FIND_CLASS, 40, 1, JSEXN_NONE, "can't find class id {0}")
|
||||
MSG_DEF(JSMSG_CANT_XDR_CLASS, 41, 1, JSEXN_NONE, "can't XDR class {0}")
|
||||
MSG_DEF(JSMSG_BYTECODE_TOO_BIG, 42, 2, JSEXN_INTERNALERR, "bytecode {0} too large (limit {1})")
|
||||
MSG_DEF(JSMSG_UNKNOWN_FORMAT, 43, 1, JSEXN_INTERNALERR, "unknown bytecode format {0}")
|
||||
MSG_DEF(JSMSG_TOO_MANY_CON_ARGS, 44, 0, JSEXN_SYNTAXERR, "too many constructor arguments")
|
||||
MSG_DEF(JSMSG_TOO_MANY_CON_ARGS, 44, 0, JSEXN_SYNTAXERR, "too many constructor arguments")
|
||||
MSG_DEF(JSMSG_TOO_MANY_FUN_ARGS, 45, 0, JSEXN_SYNTAXERR, "too many function arguments")
|
||||
MSG_DEF(JSMSG_BAD_QUANTIFIER, 46, 1, JSEXN_SYNTAXERR, "invalid quantifier {0}")
|
||||
MSG_DEF(JSMSG_MIN_TOO_BIG, 47, 1, JSEXN_SYNTAXERR, "overlarge minimum {0}")
|
||||
MSG_DEF(JSMSG_MAX_TOO_BIG, 48, 1, JSEXN_SYNTAXERR, "overlarge maximum {0}")
|
||||
MSG_DEF(JSMSG_OUT_OF_ORDER, 49, 1, JSEXN_SYNTAXERR, "maximum {0} less than minimum")
|
||||
MSG_DEF(JSMSG_BAD_QUANTIFIER, 46, 1, JSEXN_SYNTAXERR, "invalid quantifier {0}")
|
||||
MSG_DEF(JSMSG_MIN_TOO_BIG, 47, 1, JSEXN_SYNTAXERR, "overlarge minimum {0}")
|
||||
MSG_DEF(JSMSG_MAX_TOO_BIG, 48, 1, JSEXN_SYNTAXERR, "overlarge maximum {0}")
|
||||
MSG_DEF(JSMSG_OUT_OF_ORDER, 49, 1, JSEXN_SYNTAXERR, "maximum {0} less than minimum")
|
||||
MSG_DEF(JSMSG_ZERO_QUANTIFIER, 50, 1, JSEXN_SYNTAXERR, "zero quantifier {0}")
|
||||
MSG_DEF(JSMSG_UNTERM_QUANTIFIER, 51, 1, JSEXN_SYNTAXERR, "unterminated quantifier {0}")
|
||||
MSG_DEF(JSMSG_EMPTY_BEFORE_STAR, 52, 0, JSEXN_SYNTAXERR, "regular expression before * could be empty")
|
||||
|
@ -116,15 +116,15 @@ MSG_DEF(JSMSG_TRAILING_SLASH, 56, 0, JSEXN_SYNTAXERR, "trailing \\ in r
|
|||
MSG_DEF(JSMSG_BAD_CLASS_RANGE, 57, 0, JSEXN_SYNTAXERR, "invalid range in character class")
|
||||
MSG_DEF(JSMSG_BAD_FLAG, 58, 1, JSEXN_SYNTAXERR, "invalid regular expression flag {0}")
|
||||
MSG_DEF(JSMSG_NO_INPUT, 59, 3, JSEXN_SYNTAXERR, "no input for /{0}/{1}{2}")
|
||||
MSG_DEF(JSMSG_CANT_OPEN, 60, 2, JSEXN_NONE, "can't open {0}: {1}")
|
||||
MSG_DEF(JSMSG_BAD_STRING_MASK, 61, 1, JSEXN_ERR, "invalid string escape mask {0}")
|
||||
MSG_DEF(JSMSG_CANT_OPEN, 60, 2, JSEXN_NONE, "can't open {0}: {1}")
|
||||
MSG_DEF(JSMSG_BAD_STRING_MASK, 61, 1, JSEXN_ERR, "invalid string escape mask {0}")
|
||||
MSG_DEF(JSMSG_NO_STRING_PROTO, 62, 1, JSEXN_INTERNALERR, "sorry, String.prototype.{0} is not yet implemented")
|
||||
MSG_DEF(JSMSG_END_OF_DATA, 63, 0, JSEXN_NONE, "unexpected end of data")
|
||||
MSG_DEF(JSMSG_END_OF_DATA, 63, 0, JSEXN_NONE, "unexpected end of data")
|
||||
MSG_DEF(JSMSG_SEEK_BEYOND_START, 64, 0, JSEXN_NONE, "illegal seek beyond start")
|
||||
MSG_DEF(JSMSG_SEEK_BEYOND_END, 65, 0, JSEXN_NONE, "illegal seek beyond end")
|
||||
MSG_DEF(JSMSG_END_SEEK, 66, 0, JSEXN_NONE, "illegal end-based seek")
|
||||
MSG_DEF(JSMSG_WHITHER_WHENCE, 67, 1, JSEXN_NONE, "unknown seek whence: {0}")
|
||||
MSG_DEF(JSMSG_BAD_JVAL_TYPE, 68, 1, JSEXN_NONE, "unknown jsval type {0} for XDR")
|
||||
MSG_DEF(JSMSG_BAD_JVAL_TYPE, 68, 1, JSEXN_NONE, "unknown jsval type {0} for XDR")
|
||||
MSG_DEF(JSMSG_PAREN_BEFORE_FORMAL, 69, 0, JSEXN_SYNTAXERR, "missing ( before formal parameters")
|
||||
MSG_DEF(JSMSG_MISSING_FORMAL, 70, 0, JSEXN_SYNTAXERR, "missing formal parameter")
|
||||
MSG_DEF(JSMSG_PAREN_AFTER_FORMAL, 71, 0, JSEXN_SYNTAXERR, "missing ) after formal parameters")
|
||||
|
@ -137,7 +137,7 @@ MSG_DEF(JSMSG_NAME_AFTER_DOT, 77, 0, JSEXN_SYNTAXERR, "missing name aft
|
|||
MSG_DEF(JSMSG_BRACKET_IN_INDEX, 78, 0, JSEXN_SYNTAXERR, "missing ] in index expression")
|
||||
MSG_DEF(JSMSG_NO_EXPORT_NAME, 79, 0, JSEXN_SYNTAXERR, "missing name in export statement")
|
||||
MSG_DEF(JSMSG_PAREN_BEFORE_SWITCH, 80, 0, JSEXN_SYNTAXERR, "missing ( before switch expression")
|
||||
MSG_DEF(JSMSG_PAREN_AFTER_SWITCH, 81, 0, JSEXN_SYNTAXERR, "missing ) after switch expression")
|
||||
MSG_DEF(JSMSG_PAREN_AFTER_SWITCH, 81, 0, JSEXN_SYNTAXERR, "missing ) after switch expression")
|
||||
MSG_DEF(JSMSG_CURLY_BEFORE_SWITCH, 82, 0, JSEXN_SYNTAXERR, "missing { before switch body")
|
||||
MSG_DEF(JSMSG_COLON_AFTER_CASE, 83, 0, JSEXN_SYNTAXERR, "missing : after case label")
|
||||
MSG_DEF(JSMSG_WHILE_AFTER_DO, 84, 0, JSEXN_SYNTAXERR, "missing while after do-loop body")
|
||||
|
@ -166,15 +166,15 @@ MSG_DEF(JSMSG_COLON_AFTER_ID, 106, 0, JSEXN_SYNTAXERR, "missing : after
|
|||
MSG_DEF(JSMSG_CURLY_AFTER_LIST, 107, 0, JSEXN_SYNTAXERR, "missing } after property list")
|
||||
MSG_DEF(JSMSG_PAREN_IN_PAREN, 108, 0, JSEXN_SYNTAXERR, "missing ) in parenthetical")
|
||||
MSG_DEF(JSMSG_SEMI_BEFORE_STMNT, 109, 0, JSEXN_SYNTAXERR, "missing ; before statement")
|
||||
MSG_DEF(JSMSG_NO_RETURN_VALUE, 110, 0, JSEXN_NONE, "function does not always return a value")
|
||||
MSG_DEF(JSMSG_DUPLICATE_FORMAL, 111, 1, JSEXN_NONE, "duplicate formal argument {0}")
|
||||
MSG_DEF(JSMSG_EQUAL_AS_ASSIGN, 112, 1, JSEXN_NONE, "test for equality (==) mistyped as assignment (=)?{0}")
|
||||
MSG_DEF(JSMSG_BAD_IMPORT, 113, 0, JSEXN_SYNTAXERR, "invalid import expression")
|
||||
MSG_DEF(JSMSG_NO_RETURN_VALUE, 110, 0, JSEXN_NONE, "function does not always return a value")
|
||||
MSG_DEF(JSMSG_DUPLICATE_FORMAL, 111, 1, JSEXN_NONE, "duplicate formal argument {0}")
|
||||
MSG_DEF(JSMSG_EQUAL_AS_ASSIGN, 112, 1, JSEXN_NONE, "test for equality (==) mistyped as assignment (=)?{0}")
|
||||
MSG_DEF(JSMSG_BAD_IMPORT, 113, 0, JSEXN_SYNTAXERR, "invalid import expression")
|
||||
MSG_DEF(JSMSG_TOO_MANY_DEFAULTS, 114, 0, JSEXN_SYNTAXERR, "more than one switch default")
|
||||
MSG_DEF(JSMSG_TOO_MANY_CASES, 115, 0, JSEXN_INTERNALERR, "too many switch cases")
|
||||
MSG_DEF(JSMSG_BAD_SWITCH, 116, 0, JSEXN_SYNTAXERR, "invalid switch statement")
|
||||
MSG_DEF(JSMSG_BAD_FOR_LEFTSIDE, 117, 0, JSEXN_SYNTAXERR, "invalid for/in left-hand side")
|
||||
MSG_DEF(JSMSG_CATCH_AFTER_GENERAL, 118, 0, JSEXN_NONE, "catch clause after general catch")
|
||||
MSG_DEF(JSMSG_CATCH_AFTER_GENERAL, 118, 0, JSEXN_NONE, "catch clause after general catch")
|
||||
MSG_DEF(JSMSG_CATCH_WITHOUT_TRY, 119, 0, JSEXN_SYNTAXERR, "catch without try")
|
||||
MSG_DEF(JSMSG_FINALLY_WITHOUT_TRY, 120, 0, JSEXN_SYNTAXERR, "finally without try")
|
||||
MSG_DEF(JSMSG_LABEL_NOT_FOUND, 121, 0, JSEXN_SYNTAXERR, "label not found")
|
||||
|
@ -182,16 +182,13 @@ MSG_DEF(JSMSG_TOUGH_BREAK, 122, 0, JSEXN_SYNTAXERR, "invalid break")
|
|||
MSG_DEF(JSMSG_BAD_CONTINUE, 123, 0, JSEXN_SYNTAXERR, "invalid continue")
|
||||
MSG_DEF(JSMSG_BAD_RETURN, 124, 0, JSEXN_SYNTAXERR, "invalid return")
|
||||
MSG_DEF(JSMSG_BAD_LABEL, 125, 0, JSEXN_SYNTAXERR, "invalid label")
|
||||
MSG_DEF(JSMSG_DUPLICATE_LABEL, 126, 0, JSEXN_SYNTAXERR, "duplicate label")
|
||||
MSG_DEF(JSMSG_VAR_HIDES_ARG, 127, 1, JSEXN_NONE, "variable {0} hides argument")
|
||||
MSG_DEF(JSMSG_DUPLICATE_LABEL, 126, 0, JSEXN_SYNTAXERR, "duplicate label")
|
||||
MSG_DEF(JSMSG_VAR_HIDES_ARG, 127, 1, JSEXN_NONE, "variable {0} hides argument")
|
||||
MSG_DEF(JSMSG_BAD_VAR_INIT, 128, 0, JSEXN_SYNTAXERR, "invalid variable initialization")
|
||||
MSG_DEF(JSMSG_BAD_LEFTSIDE_OF_ASS, 129, 0, JSEXN_SYNTAXERR, "invalid assignment left-hand side")
|
||||
MSG_DEF(JSMSG_BAD_OPERAND, 130, 1, JSEXN_SYNTAXERR, "invalid {0} operand")
|
||||
MSG_DEF(JSMSG_BAD_PROP_ID, 131, 0, JSEXN_SYNTAXERR, "invalid property id")
|
||||
MSG_DEF(JSMSG_RESERVED_ID, 132, 1, JSEXN_SYNTAXERR, "{0} is a reserved identifier")
|
||||
MSG_DEF(JSMSG_SYNTAX_ERROR, 133, 0, JSEXN_SYNTAXERR, "syntax error")
|
||||
MSG_DEF(JSMSG_BAD_SHARP_VAR_DEF, 134, 0, JSEXN_SYNTAXERR, "invalid sharp variable definition")
|
||||
MSG_DEF(JSMSG_BAD_SHARP_VAR_DEF, 134, 0, JSEXN_SYNTAXERR, "invalid sharp variable definition")
|
||||
MSG_DEF(JSMSG_BAD_PROTOTYPE, 135, 1, JSEXN_ERR, "'prototype' property of {0} is not an object")
|
||||
|
||||
|
||||
|
||||
|
|
182
js/ref/jsnum.c
182
js/ref/jsnum.c
|
@ -86,10 +86,10 @@ num_parseFloat(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rva
|
|||
if (!str)
|
||||
return JS_FALSE;
|
||||
if (!js_strtod(cx, str->chars, &ep, &d))
|
||||
return JS_FALSE;
|
||||
return JS_FALSE;
|
||||
if (ep == str->chars) {
|
||||
*rval = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
|
||||
return JS_TRUE;
|
||||
return JS_TRUE;
|
||||
}
|
||||
return js_NewNumberValue(cx, d, rval);
|
||||
}
|
||||
|
@ -111,17 +111,17 @@ num_parseInt(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
if (!js_ValueToECMAInt32(cx, argv[1], &radix))
|
||||
return JS_FALSE;
|
||||
} else
|
||||
radix = 0;
|
||||
radix = 0;
|
||||
|
||||
if (radix != 0 && (radix < 2 || radix > 36)) {
|
||||
*rval = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
|
||||
return JS_TRUE;
|
||||
*rval = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
|
||||
return JS_TRUE;
|
||||
}
|
||||
if (!js_strtointeger(cx, str->chars, &ep, radix, &d))
|
||||
return JS_FALSE;
|
||||
return JS_FALSE;
|
||||
if (ep == str->chars) {
|
||||
*rval = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
|
||||
return JS_TRUE;
|
||||
return JS_TRUE;
|
||||
}
|
||||
return js_NewNumberValue(cx, d, rval);
|
||||
}
|
||||
|
@ -213,9 +213,9 @@ num_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
return JS_FALSE;
|
||||
if (base < 2 || base > 36) {
|
||||
char numBuf[12];
|
||||
sprintf(numBuf, "%d", base);
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_BAD_RADIX, numBuf);
|
||||
PR_snprintf(numBuf, sizeof numBuf, "%ld", (long) base);
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_RADIX,
|
||||
numBuf);
|
||||
return JS_FALSE;
|
||||
}
|
||||
if (base != 10 && JSDOUBLE_IS_FINITE(d)) {
|
||||
|
@ -477,7 +477,7 @@ js_ValueToNumber(JSContext *cx, jsval v, jsdouble *dp)
|
|||
badstr:
|
||||
if (str) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NAN,
|
||||
JS_GetStringBytes(str));
|
||||
JS_GetStringBytes(str));
|
||||
|
||||
}
|
||||
return JS_FALSE;
|
||||
|
@ -495,7 +495,7 @@ js_ValueToECMAInt32(JSContext *cx, jsval v, int32 *ip)
|
|||
jsdouble d;
|
||||
|
||||
if (!js_ValueToNumber(cx, v, &d))
|
||||
return JS_FALSE;
|
||||
return JS_FALSE;
|
||||
return js_DoubleToECMAInt32(cx, d, ip);
|
||||
}
|
||||
|
||||
|
@ -506,15 +506,15 @@ js_DoubleToECMAInt32(JSContext *cx, jsdouble d, int32 *ip)
|
|||
jsdouble two31 = 2147483648.0;
|
||||
|
||||
if (!JSDOUBLE_IS_FINITE(d) || d == 0) {
|
||||
*ip = 0;
|
||||
return JS_TRUE;
|
||||
*ip = 0;
|
||||
return JS_TRUE;
|
||||
}
|
||||
d = fmod(d, two32);
|
||||
d = d >= 0 ? d : d + two32;
|
||||
if (d >= two31)
|
||||
*ip = (int32)(d - two32);
|
||||
*ip = (int32)(d - two32);
|
||||
else
|
||||
*ip = (int32)d;
|
||||
*ip = (int32)d;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
@ -524,7 +524,7 @@ js_ValueToECMAUint32(JSContext *cx, jsval v, uint32 *ip)
|
|||
jsdouble d;
|
||||
|
||||
if (!js_ValueToNumber(cx, v, &d))
|
||||
return JS_FALSE;
|
||||
return JS_FALSE;
|
||||
return js_DoubleToECMAUint32(cx, d, ip);
|
||||
}
|
||||
|
||||
|
@ -535,8 +535,8 @@ js_DoubleToECMAUint32(JSContext *cx, jsdouble d, uint32 *ip)
|
|||
jsdouble two32 = 4294967296.0;
|
||||
|
||||
if (!JSDOUBLE_IS_FINITE(d) || d == 0) {
|
||||
*ip = 0;
|
||||
return JS_TRUE;
|
||||
*ip = 0;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
neg = (d < 0);
|
||||
|
@ -561,8 +561,8 @@ js_ValueToInt32(JSContext *cx, jsval v, int32 *ip)
|
|||
if (JSDOUBLE_IS_NaN(d) || d <= -2147483649.0 || 2147483648.0 <= d) {
|
||||
str = js_DecompileValueGenerator(cx, v, NULL);
|
||||
if (str) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_CANT_CONVERT, JS_GetStringBytes(str));
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_CANT_CONVERT, JS_GetStringBytes(str));
|
||||
|
||||
}
|
||||
return JS_FALSE;
|
||||
|
@ -641,10 +641,10 @@ js_strtod(JSContext *cx, const jschar *s, const jschar **ep, jsdouble *dp)
|
|||
|
||||
istr = cstr;
|
||||
if ((negative = (*istr == '-')) != 0 || *istr == '+')
|
||||
istr++;
|
||||
istr++;
|
||||
if (!strncmp(istr, "Infinity", 8)) {
|
||||
d = *(negative ? cx->runtime->jsNegativeInfinity : cx->runtime->jsPositiveInfinity);
|
||||
estr = istr + 8;
|
||||
d = *(negative ? cx->runtime->jsNegativeInfinity : cx->runtime->jsPositiveInfinity);
|
||||
estr = istr + 8;
|
||||
} else {
|
||||
errno = 0;
|
||||
d = PR_strtod(cstr, &estr);
|
||||
|
@ -677,18 +677,18 @@ static intN GetNextBinaryDigit(struct BinaryDigitReader *bdr)
|
|||
intN bit;
|
||||
|
||||
if (bdr->digitMask == 0) {
|
||||
uintN c;
|
||||
uintN c;
|
||||
|
||||
if (bdr->digits == bdr->end)
|
||||
return -1;
|
||||
if (bdr->digits == bdr->end)
|
||||
return -1;
|
||||
|
||||
c = *bdr->digits++;
|
||||
if ('0' <= c && c <= '9')
|
||||
bdr->digit = c - '0';
|
||||
else if ('a' <= c && c <= 'z')
|
||||
bdr->digit = c - 'a' + 10;
|
||||
else bdr->digit = c - 'A' + 10;
|
||||
bdr->digitMask = bdr->base >> 1;
|
||||
c = *bdr->digits++;
|
||||
if ('0' <= c && c <= '9')
|
||||
bdr->digit = c - '0';
|
||||
else if ('a' <= c && c <= 'z')
|
||||
bdr->digit = c - 'a' + 10;
|
||||
else bdr->digit = c - 'A' + 10;
|
||||
bdr->digitMask = bdr->base >> 1;
|
||||
}
|
||||
bit = (bdr->digit & bdr->digitMask) != 0;
|
||||
bdr->digitMask >>= 1;
|
||||
|
@ -704,22 +704,22 @@ js_strtointeger(JSContext *cx, const jschar *s, const jschar **ep, jsint base, j
|
|||
const jschar *s1 = js_SkipWhiteSpace(s);
|
||||
|
||||
if ((negative = (*s1 == '-')) != 0 || *s1 == '+')
|
||||
s1++;
|
||||
s1++;
|
||||
|
||||
if (base == 0)
|
||||
/* No base supplied, or some base that evaluated to 0. */
|
||||
if (*s1 == '0')
|
||||
/* It's either hex or octal; only increment char if str isn't '0' */
|
||||
if (s1[1] == 'X' || s1[1] == 'x') { /* Hex */
|
||||
s1 += 2;
|
||||
base = 16;
|
||||
} else /* Octal */
|
||||
base = 8;
|
||||
else
|
||||
base = 10; /* Default to decimal. */
|
||||
/* No base supplied, or some base that evaluated to 0. */
|
||||
if (*s1 == '0')
|
||||
/* It's either hex or octal; only increment char if str isn't '0' */
|
||||
if (s1[1] == 'X' || s1[1] == 'x') { /* Hex */
|
||||
s1 += 2;
|
||||
base = 16;
|
||||
} else /* Octal */
|
||||
base = 8;
|
||||
else
|
||||
base = 10; /* Default to decimal. */
|
||||
else if (base == 16 && *s1 == '0' && (s1[1] == 'X' || s1[1] == 'x'))
|
||||
/* If base is 16, ignore hex prefix. */
|
||||
s1 += 2;
|
||||
/* If base is 16, ignore hex prefix. */
|
||||
s1 += 2;
|
||||
|
||||
/* Done with the preliminaries; find some prefix of the string that's
|
||||
* a number in the given base.
|
||||
|
@ -727,24 +727,24 @@ js_strtointeger(JSContext *cx, const jschar *s, const jschar **ep, jsint base, j
|
|||
start = s1; /* Mark - if string is empty, we return NaN. */
|
||||
value = 0.0;
|
||||
while (1) {
|
||||
uintN digit;
|
||||
jschar c = *s1;
|
||||
if ('0' <= c && c <= '9')
|
||||
digit = c - '0';
|
||||
else if ('a' <= c && c <= 'z')
|
||||
digit = c - 'a' + 10;
|
||||
else if ('A' <= c && c <= 'Z')
|
||||
digit = c - 'A' + 10;
|
||||
else
|
||||
break;
|
||||
if (digit >= (uintN)base)
|
||||
break;
|
||||
value = value*base + digit;
|
||||
s1++;
|
||||
uintN digit;
|
||||
jschar c = *s1;
|
||||
if ('0' <= c && c <= '9')
|
||||
digit = c - '0';
|
||||
else if ('a' <= c && c <= 'z')
|
||||
digit = c - 'a' + 10;
|
||||
else if ('A' <= c && c <= 'Z')
|
||||
digit = c - 'A' + 10;
|
||||
else
|
||||
break;
|
||||
if (digit >= (uintN)base)
|
||||
break;
|
||||
value = value*base + digit;
|
||||
s1++;
|
||||
}
|
||||
|
||||
if (value >= 9007199254740992.0)
|
||||
if (base == 10) {
|
||||
if (base == 10) {
|
||||
/* If we're accumulating a decimal number and the number is >= 2^53, then
|
||||
* the result from the repeated multiply-add above may be inaccurate. Call
|
||||
* PR_strtod to get the correct answer.
|
||||
|
@ -755,15 +755,15 @@ js_strtointeger(JSContext *cx, const jschar *s, const jschar **ep, jsint base, j
|
|||
char *estr;
|
||||
|
||||
if (!cstr)
|
||||
return JS_FALSE;
|
||||
return JS_FALSE;
|
||||
for (i = 0; i != length; i++)
|
||||
cstr[i] = (char)start[i];
|
||||
cstr[i] = (char)start[i];
|
||||
cstr[length] = 0;
|
||||
|
||||
errno = 0;
|
||||
value = PR_strtod(cstr, &estr);
|
||||
if (errno == ERANGE && value == HUGE_VAL)
|
||||
value = *cx->runtime->jsPositiveInfinity;
|
||||
value = *cx->runtime->jsPositiveInfinity;
|
||||
free(cstr);
|
||||
|
||||
} else if (base == 2 || base == 4 || base == 8 || base == 16 || base == 32) {
|
||||
|
@ -788,43 +788,43 @@ js_strtointeger(JSContext *cx, const jschar *s, const jschar **ep, jsint base, j
|
|||
|
||||
/* Skip leading zeros. */
|
||||
do {
|
||||
bit = GetNextBinaryDigit(&bdr);
|
||||
bit = GetNextBinaryDigit(&bdr);
|
||||
} while (bit == 0);
|
||||
|
||||
if (bit == 1) {
|
||||
/* Gather the 53 significant bits (including the leading 1) */
|
||||
value = 1.0;
|
||||
for (j = 52; j; j--) {
|
||||
bit = GetNextBinaryDigit(&bdr);
|
||||
if (bit < 0)
|
||||
goto done;
|
||||
value = value*2 + bit;
|
||||
}
|
||||
/* bit2 is the 54th bit (the first dropped from the mantissa) */
|
||||
bit2 = GetNextBinaryDigit(&bdr);
|
||||
if (bit2 >= 0) {
|
||||
jsdouble factor = 2.0;
|
||||
intN sticky = 0; /* sticky is 1 if any bit beyond the 54th is 1 */
|
||||
intN bit3;
|
||||
/* Gather the 53 significant bits (including the leading 1) */
|
||||
value = 1.0;
|
||||
for (j = 52; j; j--) {
|
||||
bit = GetNextBinaryDigit(&bdr);
|
||||
if (bit < 0)
|
||||
goto done;
|
||||
value = value*2 + bit;
|
||||
}
|
||||
/* bit2 is the 54th bit (the first dropped from the mantissa) */
|
||||
bit2 = GetNextBinaryDigit(&bdr);
|
||||
if (bit2 >= 0) {
|
||||
jsdouble factor = 2.0;
|
||||
intN sticky = 0; /* sticky is 1 if any bit beyond the 54th is 1 */
|
||||
intN bit3;
|
||||
|
||||
while ((bit3 = GetNextBinaryDigit(&bdr)) >= 0) {
|
||||
sticky |= bit3;
|
||||
factor *= 2;
|
||||
}
|
||||
value += bit2 & (bit | sticky);
|
||||
value *= factor;
|
||||
}
|
||||
while ((bit3 = GetNextBinaryDigit(&bdr)) >= 0) {
|
||||
sticky |= bit3;
|
||||
factor *= 2;
|
||||
}
|
||||
value += bit2 & (bit | sticky);
|
||||
value *= factor;
|
||||
}
|
||||
done:;
|
||||
}
|
||||
}
|
||||
/* We don't worry about inaccurate numbers for any other base. */
|
||||
|
||||
if (s1 == start) {
|
||||
*dp = 0.0;
|
||||
*ep = s;
|
||||
*dp = 0.0;
|
||||
*ep = s;
|
||||
} else {
|
||||
*dp = negative ? -value : value;
|
||||
*ep = s1;
|
||||
*dp = negative ? -value : value;
|
||||
*ep = s1;
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
|
167
js/ref/jsnum.h
167
js/ref/jsnum.h
|
@ -1,167 +0,0 @@
|
|||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef jsnum_h___
|
||||
#define jsnum_h___
|
||||
/*
|
||||
* JS number (IEEE double) interface.
|
||||
*
|
||||
* JS numbers are optimistically stored in the top 31 bits of 32-bit integers,
|
||||
* but floating point literals, results that overflow 31 bits, and division and
|
||||
* modulus operands and results require a 64-bit IEEE double. These are GC'ed
|
||||
* and pointed to by 32-bit jsvals on the stack and in object properties.
|
||||
*
|
||||
* When a JS number is treated as an object (followed by . or []), the runtime
|
||||
* wraps it with a JSObject whose valueOf method returns the unwrapped number.
|
||||
*/
|
||||
|
||||
PR_BEGIN_EXTERN_C
|
||||
|
||||
#ifdef IS_LITTLE_ENDIAN
|
||||
#define JSDOUBLE_HI32(x) (((uint32 *)&(x))[1])
|
||||
#define JSDOUBLE_LO32(x) (((uint32 *)&(x))[0])
|
||||
#else
|
||||
#define JSDOUBLE_HI32(x) (((uint32 *)&(x))[0])
|
||||
#define JSDOUBLE_LO32(x) (((uint32 *)&(x))[1])
|
||||
#endif
|
||||
#define JSDOUBLE_HI32_SIGNBIT 0x80000000
|
||||
#define JSDOUBLE_HI32_EXPMASK 0x7ff00000
|
||||
#define JSDOUBLE_HI32_MANTMASK 0x000fffff
|
||||
|
||||
#define JSDOUBLE_IS_NaN(x) \
|
||||
((JSDOUBLE_HI32(x) & JSDOUBLE_HI32_EXPMASK) == JSDOUBLE_HI32_EXPMASK && \
|
||||
(JSDOUBLE_LO32(x) || (JSDOUBLE_HI32(x) & JSDOUBLE_HI32_MANTMASK)))
|
||||
|
||||
#define JSDOUBLE_IS_INFINITE(x) \
|
||||
((JSDOUBLE_HI32(x) & ~JSDOUBLE_HI32_SIGNBIT) == JSDOUBLE_HI32_EXPMASK && \
|
||||
!JSDOUBLE_LO32(x))
|
||||
|
||||
#define JSDOUBLE_IS_FINITE(x) \
|
||||
((JSDOUBLE_HI32(x) & JSDOUBLE_HI32_EXPMASK) != JSDOUBLE_HI32_EXPMASK)
|
||||
|
||||
#define JSDOUBLE_IS_NEGZERO(d) (JSDOUBLE_HI32(d) == JSDOUBLE_HI32_SIGNBIT && \
|
||||
JSDOUBLE_LO32(d) == 0)
|
||||
|
||||
/*
|
||||
* JSDOUBLE_IS_INT first checks that d is neither NaN nor infinite, to avoid
|
||||
* raising SIGFPE on platforms such as Alpha Linux, then (only if the cast is
|
||||
* safe) leaves i as (jsint)d. This also avoid anomalous NaN floating point
|
||||
* comparisons under MSVC.
|
||||
*/
|
||||
#define JSDOUBLE_IS_INT(d, i) (JSDOUBLE_IS_FINITE(d) && !JSDOUBLE_IS_NEGZERO(d) \
|
||||
&& ((d) == (i = (jsint)(d))))
|
||||
|
||||
/* Initialize the Number class, returning its prototype object. */
|
||||
extern JSObject *
|
||||
js_InitNumberClass(JSContext *cx, JSObject *obj);
|
||||
|
||||
/* GC-allocate a new JS number. */
|
||||
extern jsdouble *
|
||||
js_NewDouble(JSContext *cx, jsdouble d);
|
||||
|
||||
extern void
|
||||
js_FinalizeDouble(JSContext *cx, jsdouble *dp);
|
||||
|
||||
extern JSBool
|
||||
js_NewDoubleValue(JSContext *cx, jsdouble d, jsval *rval);
|
||||
|
||||
extern JSBool
|
||||
js_NewNumberValue(JSContext *cx, jsdouble d, jsval *rval);
|
||||
|
||||
/* Construct a Number instance that wraps around d. */
|
||||
extern JSObject *
|
||||
js_NumberToObject(JSContext *cx, jsdouble d);
|
||||
|
||||
/* Convert a number to a GC'ed string. */
|
||||
extern JSString *
|
||||
js_NumberToString(JSContext *cx, jsdouble d);
|
||||
|
||||
/*
|
||||
* Convert a value to a number, returning false after reporting any error,
|
||||
* otherwise returning true with *dp set.
|
||||
*/
|
||||
extern JSBool
|
||||
js_ValueToNumber(JSContext *cx, jsval v, jsdouble *dp);
|
||||
|
||||
/*
|
||||
* Convert a value or a double to an int32, according to the ECMA rules
|
||||
* for ToInt32.
|
||||
*/
|
||||
extern JSBool
|
||||
js_ValueToECMAInt32(JSContext *cx, jsval v, int32 *ip);
|
||||
|
||||
extern JSBool
|
||||
js_DoubleToECMAInt32(JSContext *cx, jsdouble d, int32 *ip);
|
||||
|
||||
/*
|
||||
* Convert a value or a double to a uint32, according to the ECMA rules
|
||||
* for ToUint32.
|
||||
*/
|
||||
extern JSBool
|
||||
js_ValueToECMAUint32(JSContext *cx, jsval v, uint32 *ip);
|
||||
|
||||
extern JSBool
|
||||
js_DoubleToECMAUint32(JSContext *cx, jsdouble d, uint32 *ip);
|
||||
|
||||
/*
|
||||
* Convert a value to a number, then to an int32 if it fits by rounding to
|
||||
* nearest; but failing with an error report if the double is out of range
|
||||
* or unordered.
|
||||
*/
|
||||
extern JSBool
|
||||
js_ValueToInt32(JSContext *cx, jsval v, int32 *ip);
|
||||
|
||||
/*
|
||||
* Convert a value to a number, then to a uint16 according to the ECMA rules
|
||||
* for ToUint16.
|
||||
*/
|
||||
extern JSBool
|
||||
js_ValueToUint16(JSContext *cx, jsval v, uint16 *ip);
|
||||
|
||||
/*
|
||||
* Convert a jsdouble to an integral number, stored in a jsdouble.
|
||||
* If d is NaN, return 0. If d is an infinity, return it without conversion.
|
||||
*/
|
||||
extern jsdouble
|
||||
js_DoubleToInteger(jsdouble d);
|
||||
|
||||
/*
|
||||
* Similar to strtod except that replaces overflows with infinities of the correct
|
||||
* sign and underflows with zeros of the correct sign. Guaranteed to return the
|
||||
* closest double number to the given input in dp.
|
||||
* Also allows inputs of the form [+|-]Infinity, which produce an infinity of the
|
||||
* appropriate sign. The case of the "Infinity" string must match.
|
||||
* If the string does not have a number in it, set *ep to s and return 0.0 in dp.
|
||||
* Return false if out of memory.
|
||||
*/
|
||||
extern JSBool
|
||||
js_strtod(JSContext *cx, const jschar *s, const jschar **ep, jsdouble *dp);
|
||||
|
||||
/*
|
||||
* Similar to strtol except that handles integers of arbitrary size. Guaranteed to
|
||||
* return the closest double number to the given input when radix is 10 or a power of 2.
|
||||
* May experience roundoff errors for very large numbers of a different radix.
|
||||
* If the string does not have a number in it, set *ep to s and return 0.0 in dp.
|
||||
* Return false if out of memory.
|
||||
*/
|
||||
extern JSBool
|
||||
js_strtointeger(JSContext *cx, const jschar *s, const jschar **ep, jsint radix, jsdouble *dp);
|
||||
|
||||
PR_END_EXTERN_C
|
||||
|
||||
#endif /* jsnum_h___ */
|
326
js/ref/jsobj.c
326
js/ref/jsobj.c
|
@ -138,8 +138,8 @@ obj_setSlot(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
|||
slot = JSVAL_TO_INT(id);
|
||||
while (obj2) {
|
||||
if (obj2 == obj) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_CYCLIC_VALUE, object_props[slot].name);
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_CYCLIC_VALUE, object_props[slot].name);
|
||||
return JS_FALSE;
|
||||
}
|
||||
obj2 = JSVAL_TO_OBJECT(OBJ_GET_SLOT(cx, obj2, slot));
|
||||
|
@ -158,17 +158,17 @@ obj_getCount(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
|||
|
||||
/* Get the number of properties to enumerate. */
|
||||
if (!OBJ_ENUMERATE(cx, obj, JSENUMERATE_INIT, &iter_state, &num_properties))
|
||||
goto error;
|
||||
goto error;
|
||||
if (!JSVAL_IS_INT(num_properties)) {
|
||||
PR_ASSERT(0);
|
||||
goto error;
|
||||
PR_ASSERT(0);
|
||||
goto error;
|
||||
}
|
||||
*vp = num_properties;
|
||||
return JS_TRUE;
|
||||
|
||||
error:
|
||||
if (iter_state != JSVAL_NULL)
|
||||
OBJ_ENUMERATE(cx, obj, JSENUMERATE_DESTROY, &iter_state, 0);
|
||||
OBJ_ENUMERATE(cx, obj, JSENUMERATE_DESTROY, &iter_state, 0);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
|
@ -216,7 +216,7 @@ MarkSharpObjects(JSContext *cx, JSObject *obj, JSIdArray **idap)
|
|||
for (i = 0, length = ida->length; i < length; i++) {
|
||||
ok = OBJ_GET_PROPERTY(cx, obj, ida->vector[i], &val);
|
||||
if (!ok)
|
||||
break;
|
||||
break;
|
||||
if (!JSVAL_IS_PRIMITIVE(val) &&
|
||||
!MarkSharpObjects(cx, JSVAL_TO_OBJECT(val), NULL)) {
|
||||
ok = JS_FALSE;
|
||||
|
@ -276,24 +276,24 @@ js_EnterSharpObject(JSContext *cx, JSObject *obj, JSIdArray **idap,
|
|||
ida = NULL;
|
||||
}
|
||||
} else {
|
||||
hash = js_hash_object(obj);
|
||||
hep = PR_HashTableRawLookup(table, hash, obj);
|
||||
he = *hep;
|
||||
hash = js_hash_object(obj);
|
||||
hep = PR_HashTableRawLookup(table, hash, obj);
|
||||
he = *hep;
|
||||
|
||||
/*
|
||||
* It's possible that the value of a property has changed from the
|
||||
* first time the object's properties are traversed (when the property
|
||||
* ids are entered into the hash table) to the second (when they are
|
||||
* converted to strings), i.e. the getProperty() call is not
|
||||
* idempotent.
|
||||
*/
|
||||
if (!he) {
|
||||
/*
|
||||
* It's possible that the value of a property has changed from the
|
||||
* first time the object's properties are traversed (when the property
|
||||
* ids are entered into the hash table) to the second (when they are
|
||||
* converted to strings), i.e. the getProperty() call is not
|
||||
* idempotent.
|
||||
*/
|
||||
if (!he) {
|
||||
he = PR_HashTableRawAdd(table, hep, hash, obj, (void *)0);
|
||||
if (!he)
|
||||
JS_ReportOutOfMemory(cx);
|
||||
*sp = NULL;
|
||||
goto out;
|
||||
}
|
||||
JS_ReportOutOfMemory(cx);
|
||||
*sp = NULL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
sharpid = (jsatomid) he->value;
|
||||
|
@ -312,7 +312,7 @@ js_EnterSharpObject(JSContext *cx, JSObject *obj, JSIdArray **idap,
|
|||
|
||||
out:
|
||||
if ((sharpid & SHARP_BIT) == 0) {
|
||||
if (idap && !ida) {
|
||||
if (idap && !ida) {
|
||||
ida = JS_Enumerate(cx, obj);
|
||||
if (!ida) {
|
||||
if (*sp) {
|
||||
|
@ -454,8 +454,8 @@ js_obj_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
|||
goto done;
|
||||
}
|
||||
if (IS_SHARP(he)) {
|
||||
vchars = vsharp;
|
||||
vlength = js_strlen(vchars);
|
||||
vchars = vsharp;
|
||||
vlength = js_strlen(vchars);
|
||||
} else {
|
||||
if (vsharp) {
|
||||
vsharplength = js_strlen(vsharp);
|
||||
|
@ -602,9 +602,9 @@ obj_eval(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
*/
|
||||
scopeobj = NULL;
|
||||
if (argc >= 2) {
|
||||
if (!js_ValueToObject(cx, argv[1], &scopeobj))
|
||||
if (!js_ValueToObject(cx, argv[1], &scopeobj))
|
||||
return JS_FALSE;
|
||||
argv[1] = OBJECT_TO_JSVAL(scopeobj);
|
||||
argv[1] = OBJECT_TO_JSVAL(scopeobj);
|
||||
}
|
||||
if (!scopeobj)
|
||||
#endif
|
||||
|
@ -748,8 +748,8 @@ static JSBool
|
|||
Object(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
if (argc == 0) {
|
||||
/* Trigger logic below to construct a blank object. */
|
||||
obj = NULL;
|
||||
/* Trigger logic below to construct a blank object. */
|
||||
obj = NULL;
|
||||
} else {
|
||||
/* If argv[0] is null or undefined, obj comes back null. */
|
||||
if (!js_ValueToObject(cx, argv[0], &obj))
|
||||
|
@ -780,7 +780,7 @@ with_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp,
|
|||
{
|
||||
JSObject *proto = OBJ_GET_PROTO(cx, obj);
|
||||
if (!proto)
|
||||
return js_LookupProperty(cx, obj, id, objp, propp);
|
||||
return js_LookupProperty(cx, obj, id, objp, propp);
|
||||
return OBJ_LOOKUP_PROPERTY(cx, proto, id, objp, propp);
|
||||
}
|
||||
|
||||
|
@ -789,7 +789,7 @@ with_GetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
|||
{
|
||||
JSObject *proto = OBJ_GET_PROTO(cx, obj);
|
||||
if (!proto)
|
||||
return js_GetProperty(cx, obj, id, vp);
|
||||
return js_GetProperty(cx, obj, id, vp);
|
||||
return OBJ_GET_PROPERTY(cx, proto, id, vp);
|
||||
}
|
||||
|
||||
|
@ -798,7 +798,7 @@ with_SetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
|||
{
|
||||
JSObject *proto = OBJ_GET_PROTO(cx, obj);
|
||||
if (!proto)
|
||||
return js_SetProperty(cx, obj, id, vp);
|
||||
return js_SetProperty(cx, obj, id, vp);
|
||||
return OBJ_SET_PROPERTY(cx, proto, id, vp);
|
||||
}
|
||||
|
||||
|
@ -808,7 +808,7 @@ with_GetAttributes(JSContext *cx, JSObject *obj, jsid id, JSProperty *prop,
|
|||
{
|
||||
JSObject *proto = OBJ_GET_PROTO(cx, obj);
|
||||
if (!proto)
|
||||
return js_GetAttributes(cx, obj, id, prop, attrsp);
|
||||
return js_GetAttributes(cx, obj, id, prop, attrsp);
|
||||
return OBJ_GET_ATTRIBUTES(cx, proto, id, prop, attrsp);
|
||||
}
|
||||
|
||||
|
@ -818,7 +818,7 @@ with_SetAttributes(JSContext *cx, JSObject *obj, jsid id, JSProperty *prop,
|
|||
{
|
||||
JSObject *proto = OBJ_GET_PROTO(cx, obj);
|
||||
if (!proto)
|
||||
return js_SetAttributes(cx, obj, id, prop, attrsp);
|
||||
return js_SetAttributes(cx, obj, id, prop, attrsp);
|
||||
return OBJ_SET_ATTRIBUTES(cx, proto, id, prop, attrsp);
|
||||
}
|
||||
|
||||
|
@ -827,7 +827,7 @@ with_DeleteProperty(JSContext *cx, JSObject *obj, jsid id, jsval *rval)
|
|||
{
|
||||
JSObject *proto = OBJ_GET_PROTO(cx, obj);
|
||||
if (!proto)
|
||||
return js_DeleteProperty(cx, obj, id, rval);
|
||||
return js_DeleteProperty(cx, obj, id, rval);
|
||||
return OBJ_DELETE_PROPERTY(cx, proto, id, rval);
|
||||
}
|
||||
|
||||
|
@ -842,11 +842,11 @@ with_DefaultValue(JSContext *cx, JSObject *obj, JSType hint, jsval *vp)
|
|||
|
||||
static JSBool
|
||||
with_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
|
||||
jsval *statep, jsid *idp)
|
||||
jsval *statep, jsid *idp)
|
||||
{
|
||||
JSObject *proto = OBJ_GET_PROTO(cx, obj);
|
||||
if (!proto)
|
||||
return js_Enumerate(cx, obj, enum_op, statep, idp);
|
||||
return js_Enumerate(cx, obj, enum_op, statep, idp);
|
||||
return OBJ_ENUMERATE(cx, proto, enum_op, statep, idp);
|
||||
}
|
||||
|
||||
|
@ -856,7 +856,7 @@ with_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode,
|
|||
{
|
||||
JSObject *proto = OBJ_GET_PROTO(cx, obj);
|
||||
if (!proto)
|
||||
return js_CheckAccess(cx, obj, id, mode, vp, attrsp);
|
||||
return js_CheckAccess(cx, obj, id, mode, vp, attrsp);
|
||||
return OBJ_CHECK_ACCESS(cx, proto, id, mode, vp, attrsp);
|
||||
}
|
||||
|
||||
|
@ -865,7 +865,7 @@ with_ThisObject(JSContext *cx, JSObject *obj)
|
|||
{
|
||||
JSObject *proto = OBJ_GET_PROTO(cx, obj);
|
||||
if (!proto)
|
||||
return obj;
|
||||
return obj;
|
||||
return OBJ_THIS_OBJECT(cx, proto);
|
||||
}
|
||||
|
||||
|
@ -1025,7 +1025,7 @@ js_NewObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent)
|
|||
goto bad;
|
||||
}
|
||||
if (JSVAL_IS_OBJECT(cval) && (ctor = JSVAL_TO_OBJECT(cval)) != NULL)
|
||||
parent = OBJ_GET_PARENT(cx, ctor);
|
||||
parent = OBJ_GET_PARENT(cx, ctor);
|
||||
}
|
||||
|
||||
/* Share the given prototype's map. */
|
||||
|
@ -1107,7 +1107,7 @@ js_ConstructObject(JSContext *cx, JSClass *clasp, JSObject *proto,
|
|||
|
||||
ok = FindConstructor(cx, clasp->name, &cval);
|
||||
if (!ok)
|
||||
return NULL;
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* If proto or parent are NULL, set them to Constructor.prototype and/or
|
||||
|
@ -1115,15 +1115,15 @@ js_ConstructObject(JSContext *cx, JSClass *clasp, JSObject *proto,
|
|||
*/
|
||||
ctor = JSVAL_TO_OBJECT(cval);
|
||||
if (!parent)
|
||||
parent = OBJ_GET_PARENT(cx, ctor);
|
||||
parent = OBJ_GET_PARENT(cx, ctor);
|
||||
if (!proto) {
|
||||
if (!OBJ_GET_PROPERTY(cx, ctor,
|
||||
(jsid)cx->runtime->atomState.classPrototypeAtom,
|
||||
&rval)) {
|
||||
return NULL;
|
||||
}
|
||||
if (JSVAL_IS_OBJECT(rval))
|
||||
proto = JSVAL_TO_OBJECT(rval);
|
||||
if (!OBJ_GET_PROPERTY(cx, ctor,
|
||||
(jsid)cx->runtime->atomState.classPrototypeAtom,
|
||||
&rval)) {
|
||||
return NULL;
|
||||
}
|
||||
if (JSVAL_IS_OBJECT(rval))
|
||||
proto = JSVAL_TO_OBJECT(rval);
|
||||
}
|
||||
|
||||
obj = js_NewObject(cx, clasp, proto, parent);
|
||||
|
@ -1263,28 +1263,28 @@ js_FreeSlot(JSContext *cx, JSObject *obj, uint32 slot)
|
|||
|
||||
#define CHECK_FOR_FUNNY_INDEX(id) \
|
||||
PR_BEGIN_MACRO \
|
||||
if (!JSVAL_IS_INT(id)) { \
|
||||
if (!JSVAL_IS_INT(id)) { \
|
||||
JSAtom *_atom = (JSAtom *)id; \
|
||||
JSString *_str = ATOM_TO_STRING(_atom); \
|
||||
const jschar *_cp = _str->chars; \
|
||||
if (JS7_ISDEC(*_cp) && \
|
||||
_str->length <= sizeof(JSVAL_INT_MAX_STRING)-1) \
|
||||
{ \
|
||||
_str->length <= sizeof(JSVAL_INT_MAX_STRING)-1) \
|
||||
{ \
|
||||
jsuint _index = JS7_UNDEC(*_cp++); \
|
||||
jsuint _oldIndex = 0; \
|
||||
jsuint _c; \
|
||||
if (_index != 0) { \
|
||||
while (JS7_ISDEC(*_cp)) { \
|
||||
_oldIndex = _index; \
|
||||
_c = JS7_UNDEC(*_cp); \
|
||||
_index = 10*_index + _c; \
|
||||
_cp++; \
|
||||
} \
|
||||
} \
|
||||
if (*_cp == 0 && \
|
||||
(_oldIndex < (JSVAL_INT_MAX / 10) || \
|
||||
(_oldIndex == (JSVAL_INT_MAX / 10) && \
|
||||
_c < (JSVAL_INT_MAX % 10)))) \
|
||||
jsuint _oldIndex = 0; \
|
||||
jsuint _c; \
|
||||
if (_index != 0) { \
|
||||
while (JS7_ISDEC(*_cp)) { \
|
||||
_oldIndex = _index; \
|
||||
_c = JS7_UNDEC(*_cp); \
|
||||
_index = 10*_index + _c; \
|
||||
_cp++; \
|
||||
} \
|
||||
} \
|
||||
if (*_cp == 0 && \
|
||||
(_oldIndex < (JSVAL_INT_MAX / 10) || \
|
||||
(_oldIndex == (JSVAL_INT_MAX / 10) && \
|
||||
_c < (JSVAL_INT_MAX % 10)))) \
|
||||
id = INT_TO_JSVAL(_index); \
|
||||
} else { \
|
||||
CHECK_FOR_EMPTY_INDEX(id); \
|
||||
|
@ -1341,7 +1341,7 @@ js_DefineProperty(JSContext *cx, JSObject *obj, jsid id, jsval value,
|
|||
#ifdef JS_THREADSAFE
|
||||
js_HoldScopeProperty(cx, scope, sprop);
|
||||
#endif
|
||||
*propp = (JSProperty *) sprop;
|
||||
*propp = (JSProperty *) sprop;
|
||||
} else {
|
||||
JS_UNLOCK_OBJ(cx, obj);
|
||||
}
|
||||
|
@ -1559,8 +1559,8 @@ js_FindVariableScope(JSContext *cx, JSFunction **funp)
|
|||
if (fp)
|
||||
obj = js_GetCallObject(cx, fp, parent, withobj);
|
||||
} else if (clasp == &js_CallClass) {
|
||||
fp = (JSStackFrame *) JS_GetPrivate(cx, obj);
|
||||
fun = fp->fun;
|
||||
fp = (JSStackFrame *) JS_GetPrivate(cx, obj);
|
||||
fun = fp->fun;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1578,8 +1578,8 @@ js_GetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
|||
if (!js_LookupProperty(cx, obj, id, &obj2, (JSProperty **)&sprop))
|
||||
return JS_FALSE;
|
||||
if (!sprop) {
|
||||
/* Handle old bug that treated empty string as zero index.
|
||||
* Also convert string indices to numbers if applicable. */
|
||||
/* Handle old bug that treated empty string as zero index.
|
||||
* Also convert string indices to numbers if applicable. */
|
||||
CHECK_FOR_FUNNY_INDEX(id);
|
||||
|
||||
#if JS_BUG_NULL_INDEX_PROPS
|
||||
|
@ -1597,7 +1597,7 @@ js_GetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
|||
|
||||
if (!OBJ_IS_NATIVE(obj2)) {
|
||||
OBJ_DROP_PROPERTY(cx, obj2, (JSProperty *)sprop);
|
||||
return OBJ_GET_PROPERTY(cx, obj2, id, vp);
|
||||
return OBJ_GET_PROPERTY(cx, obj2, id, vp);
|
||||
}
|
||||
|
||||
/* Unlock obj2 before calling getter, relock after to avoid deadlock. */
|
||||
|
@ -1807,8 +1807,8 @@ _readonly:
|
|||
return JS_TRUE;
|
||||
str = js_DecompileValueGenerator(cx, js_IdToValue(id), NULL);
|
||||
if (str)
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_READ_ONLY, JS_GetStringBytes(str));
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_READ_ONLY, JS_GetStringBytes(str));
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
|
@ -1943,9 +1943,10 @@ js_DeleteProperty(JSContext *cx, JSObject *obj, jsid id, jsval *rval)
|
|||
return JS_TRUE;
|
||||
}
|
||||
str = js_DecompileValueGenerator(cx, js_IdToValue(id), NULL);
|
||||
if (str)
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_PERMANENT, JS_GetStringBytes(str));
|
||||
if (str) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_PERMANENT, JS_GetStringBytes(str));
|
||||
}
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
|
@ -2012,47 +2013,47 @@ js_DefaultValue(JSContext *cx, JSObject *obj, JSType hint, jsval *vp)
|
|||
if (!OBJ_GET_CLASS(cx, obj)->convert(cx, obj, hint, &v))
|
||||
return JS_FALSE;
|
||||
|
||||
/*
|
||||
* JS1.2 never failed (except for malloc failure) to convert an
|
||||
* object to a string. ECMA requires an error if both toString
|
||||
* and valueOf fail to produce a primitive value.
|
||||
*/
|
||||
if (!JSVAL_IS_PRIMITIVE(v) && cx->version == JSVERSION_1_2) {
|
||||
char *bytes = PR_smprintf("[object %s]",
|
||||
OBJ_GET_CLASS(cx, obj)->name);
|
||||
if (!bytes)
|
||||
return JS_FALSE;
|
||||
str = JS_NewString(cx, bytes, strlen(bytes));
|
||||
if (!str) {
|
||||
free(bytes);
|
||||
return JS_FALSE;
|
||||
}
|
||||
v = STRING_TO_JSVAL(str);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
break;
|
||||
/*
|
||||
* JS1.2 never failed (except for malloc failure) to convert an
|
||||
* object to a string. ECMA requires an error if both toString
|
||||
* and valueOf fail to produce a primitive value.
|
||||
*/
|
||||
if (!JSVAL_IS_PRIMITIVE(v) && cx->version == JSVERSION_1_2) {
|
||||
char *bytes = PR_smprintf("[object %s]",
|
||||
OBJ_GET_CLASS(cx, obj)->name);
|
||||
if (!bytes)
|
||||
return JS_FALSE;
|
||||
str = JS_NewString(cx, bytes, strlen(bytes));
|
||||
if (!str) {
|
||||
free(bytes);
|
||||
return JS_FALSE;
|
||||
}
|
||||
v = STRING_TO_JSVAL(str);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (!OBJ_GET_CLASS(cx, obj)->convert(cx, obj, hint, &v))
|
||||
return JS_FALSE;
|
||||
if (!JSVAL_IS_PRIMITIVE(v)) {
|
||||
if (JS_TypeOfValue(cx, v) == hint)
|
||||
goto out;
|
||||
goto out;
|
||||
/* Don't convert to string (source object literal) for JS1.2. */
|
||||
if (cx->version == JSVERSION_1_2 && hint == JSTYPE_BOOLEAN)
|
||||
goto out;
|
||||
goto out;
|
||||
js_TryMethod(cx, obj, cx->runtime->atomState.toStringAtom, 0, NULL,
|
||||
&v);
|
||||
}
|
||||
break;
|
||||
break;
|
||||
}
|
||||
if (!JSVAL_IS_PRIMITIVE(v)) {
|
||||
/* Avoid recursive death through js_DecompileValueGenerator. */
|
||||
if (hint == JSTYPE_STRING) {
|
||||
str = JS_InternString(cx, OBJ_GET_CLASS(cx, obj)->name);
|
||||
if (!str)
|
||||
return JS_FALSE;
|
||||
return JS_FALSE;
|
||||
} else {
|
||||
str = NULL;
|
||||
}
|
||||
|
@ -2060,11 +2061,11 @@ js_DefaultValue(JSContext *cx, JSObject *obj, JSType hint, jsval *vp)
|
|||
str = js_DecompileValueGenerator(cx, v, str);
|
||||
if (str) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_CANT_CONVERT_TO,
|
||||
JS_GetStringBytes(str),
|
||||
(hint == JSTYPE_VOID)
|
||||
? "primitive type"
|
||||
: js_type_str[hint]);
|
||||
JSMSG_CANT_CONVERT_TO,
|
||||
JS_GetStringBytes(str),
|
||||
(hint == JSTYPE_VOID)
|
||||
? "primitive type"
|
||||
: js_type_str[hint]);
|
||||
}
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
@ -2080,7 +2081,7 @@ js_NewIdArray(JSContext *cx, jsint length)
|
|||
|
||||
ida = JS_malloc(cx, sizeof(JSIdArray) + (length - 1) * sizeof(jsval));
|
||||
if (ida)
|
||||
ida->length = length;
|
||||
ida->length = length;
|
||||
return ida;
|
||||
}
|
||||
|
||||
|
@ -2097,7 +2098,7 @@ typedef struct JSNativeIteratorState {
|
|||
*/
|
||||
JSBool
|
||||
js_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
|
||||
jsval *statep, jsid *idp)
|
||||
jsval *statep, jsid *idp)
|
||||
{
|
||||
JSObject *proto_obj;
|
||||
JSClass *clasp;
|
||||
|
@ -2111,22 +2112,22 @@ js_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
|
|||
clasp = OBJ_GET_CLASS(cx, obj);
|
||||
enumerate = clasp->enumerate;
|
||||
if (clasp->flags & JSCLASS_NEW_ENUMERATE)
|
||||
return ((JSNewEnumerateOp) enumerate)(cx, obj, enum_op, statep, idp);
|
||||
return ((JSNewEnumerateOp) enumerate)(cx, obj, enum_op, statep, idp);
|
||||
|
||||
switch (enum_op) {
|
||||
|
||||
case JSENUMERATE_INIT:
|
||||
if (!enumerate(cx, obj))
|
||||
goto init_error;
|
||||
length = 0;
|
||||
if (!enumerate(cx, obj))
|
||||
goto init_error;
|
||||
length = 0;
|
||||
|
||||
/*
|
||||
* The set of all property ids is pre-computed when the iterator
|
||||
* is initialized so as to avoid problems with properties being
|
||||
* deleted during the iteration.
|
||||
*/
|
||||
JS_LOCK_OBJ(cx, obj);
|
||||
scope = (JSScope *) obj->map;
|
||||
/*
|
||||
* The set of all property ids is pre-computed when the iterator
|
||||
* is initialized so as to avoid problems with properties being
|
||||
* deleted during the iteration.
|
||||
*/
|
||||
JS_LOCK_OBJ(cx, obj);
|
||||
scope = (JSScope *) obj->map;
|
||||
|
||||
/*
|
||||
* If this object shares a scope with its prototype, don't enumerate
|
||||
|
@ -2159,41 +2160,41 @@ js_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
|
|||
}
|
||||
}
|
||||
}
|
||||
JS_UNLOCK_OBJ(cx, obj);
|
||||
JS_UNLOCK_OBJ(cx, obj);
|
||||
|
||||
state = JS_malloc(cx, sizeof(JSNativeIteratorState));
|
||||
if (!state) {
|
||||
JS_DestroyIdArray(cx, ida);
|
||||
goto init_error;
|
||||
}
|
||||
state->ida = ida;
|
||||
state->next_index = 0;
|
||||
*statep = PRIVATE_TO_JSVAL(state);
|
||||
if (idp)
|
||||
*idp = INT_TO_JSVAL(length);
|
||||
return JS_TRUE;
|
||||
state = JS_malloc(cx, sizeof(JSNativeIteratorState));
|
||||
if (!state) {
|
||||
JS_DestroyIdArray(cx, ida);
|
||||
goto init_error;
|
||||
}
|
||||
state->ida = ida;
|
||||
state->next_index = 0;
|
||||
*statep = PRIVATE_TO_JSVAL(state);
|
||||
if (idp)
|
||||
*idp = INT_TO_JSVAL(length);
|
||||
return JS_TRUE;
|
||||
|
||||
case JSENUMERATE_NEXT:
|
||||
state = JSVAL_TO_PRIVATE(*statep);
|
||||
ida = state->ida;
|
||||
length = ida->length;
|
||||
if (state->next_index != length) {
|
||||
*idp = ida->vector[state->next_index++];
|
||||
return JS_TRUE;
|
||||
}
|
||||
state = JSVAL_TO_PRIVATE(*statep);
|
||||
ida = state->ida;
|
||||
length = ida->length;
|
||||
if (state->next_index != length) {
|
||||
*idp = ida->vector[state->next_index++];
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/* Fall through ... */
|
||||
/* Fall through ... */
|
||||
|
||||
case JSENUMERATE_DESTROY:
|
||||
state = JSVAL_TO_PRIVATE(*statep);
|
||||
JS_DestroyIdArray(cx, state->ida);
|
||||
JS_free(cx, state);
|
||||
*statep = JSVAL_NULL;
|
||||
return JS_TRUE;
|
||||
state = JSVAL_TO_PRIVATE(*statep);
|
||||
JS_DestroyIdArray(cx, state->ida);
|
||||
JS_free(cx, state);
|
||||
*statep = JSVAL_NULL;
|
||||
return JS_TRUE;
|
||||
|
||||
default:
|
||||
PR_ASSERT(0);
|
||||
return JS_FALSE;
|
||||
PR_ASSERT(0);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
init_error:
|
||||
|
@ -2393,8 +2394,7 @@ js_ValueToNonNullObject(JSContext *cx, jsval v)
|
|||
str = js_DecompileValueGenerator(cx, v, NULL);
|
||||
if (str) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_NO_PROPERTIES,
|
||||
JS_GetStringBytes(str));
|
||||
JSMSG_NO_PROPERTIES, JS_GetStringBytes(str));
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
|
@ -2480,9 +2480,9 @@ js_XDRObject(JSXDRState *xdr, JSObject **objp)
|
|||
clasp = JS_FindClassById(xdr, classId);
|
||||
if (!clasp) {
|
||||
char numBuf[12];
|
||||
sprintf(numBuf, "%d", (long)classId);
|
||||
PR_snprintf(numBuf, sizeof numBuf, "%ld", (long)classId);
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_CANT_FIND_CLASS, numBuf);
|
||||
JSMSG_CANT_FIND_CLASS, numBuf);
|
||||
ok = JS_FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
@ -2491,7 +2491,7 @@ js_XDRObject(JSXDRState *xdr, JSObject **objp)
|
|||
|
||||
if (!clasp->xdrObject) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_CANT_XDR_CLASS, clasp->name);
|
||||
JSMSG_CANT_XDR_CLASS, clasp->name);
|
||||
ok = JS_FALSE;
|
||||
} else {
|
||||
ok = clasp->xdrObject(xdr, objp);
|
||||
|
@ -2511,7 +2511,7 @@ out:
|
|||
void printChar(jschar *cp) {
|
||||
fprintf(stderr, "jschar* (0x%x) \"", cp);
|
||||
while (*cp)
|
||||
fputc(*cp++, stderr);
|
||||
fputc(*cp++, stderr);
|
||||
fputc('"', stderr);
|
||||
fputc('\n', stderr);
|
||||
}
|
||||
|
@ -2520,7 +2520,7 @@ void printString(JSString *str) {
|
|||
jsuint i;
|
||||
fprintf(stderr, "string (0x%x) \"", str);
|
||||
for (i=0; i < str->length; i++)
|
||||
fputc(str->chars[i], stderr);
|
||||
fputc(str->chars[i], stderr);
|
||||
fputc('"', stderr);
|
||||
fputc('\n', stderr);
|
||||
}
|
||||
|
@ -2528,22 +2528,22 @@ void printString(JSString *str) {
|
|||
void printVal(jsval val) {
|
||||
fprintf(stderr, "val %d (0x%x) = ", val, val);
|
||||
if (JSVAL_IS_NULL(val)) {
|
||||
fprintf(stderr, "null\n");
|
||||
fprintf(stderr, "null\n");
|
||||
} else if (JSVAL_IS_VOID(val)) {
|
||||
fprintf(stderr, "undefined\n");
|
||||
fprintf(stderr, "undefined\n");
|
||||
} else if (JSVAL_IS_OBJECT(val)) {
|
||||
/* XXX can do more here */
|
||||
fprintf(stderr, "object\n");
|
||||
/* XXX can do more here */
|
||||
fprintf(stderr, "object\n");
|
||||
} else if (JSVAL_IS_INT(val)) {
|
||||
fprintf(stderr, "(int) %d\n", JSVAL_TO_INT(val));
|
||||
fprintf(stderr, "(int) %d\n", JSVAL_TO_INT(val));
|
||||
} else if (JSVAL_IS_STRING(val)) {
|
||||
printString(JSVAL_TO_STRING(val));
|
||||
printString(JSVAL_TO_STRING(val));
|
||||
} else if (JSVAL_IS_DOUBLE(val)) {
|
||||
fprintf(stderr, "(double) %g\n", *JSVAL_TO_DOUBLE(val));
|
||||
fprintf(stderr, "(double) %g\n", *JSVAL_TO_DOUBLE(val));
|
||||
} else {
|
||||
PR_ASSERT(JSVAL_IS_BOOLEAN(val));
|
||||
fprintf(stderr, "(boolean) %s\n",
|
||||
JSVAL_TO_BOOLEAN(val) ? "true" : "false");
|
||||
PR_ASSERT(JSVAL_IS_BOOLEAN(val));
|
||||
fprintf(stderr, "(boolean) %s\n",
|
||||
JSVAL_TO_BOOLEAN(val) ? "true" : "false");
|
||||
}
|
||||
fflush(stderr);
|
||||
}
|
||||
|
|
|
@ -174,7 +174,7 @@ js_obj_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
|||
|
||||
extern JSBool
|
||||
js_obj_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
||||
jsval *rval);
|
||||
jsval *rval);
|
||||
|
||||
extern JSObject *
|
||||
js_InitObjectClass(JSContext *cx, JSObject *obj);
|
||||
|
@ -277,7 +277,7 @@ js_DefaultValue(JSContext *cx, JSObject *obj, JSType hint, jsval *vp);
|
|||
|
||||
extern JSBool
|
||||
js_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
|
||||
jsval *statep, jsid *idp);
|
||||
jsval *statep, jsid *idp);
|
||||
|
||||
extern JSBool
|
||||
js_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode,
|
||||
|
|
|
@ -111,12 +111,11 @@ js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc, uintN loc,
|
|||
|
||||
op = (JSOp)*pc;
|
||||
if (op >= JSOP_LIMIT) {
|
||||
char numBuf1[12];
|
||||
char numBuf2[12];
|
||||
sprintf(numBuf1, "%d", op);
|
||||
sprintf(numBuf2, "%d", JSOP_LIMIT);
|
||||
char numBuf1[12], numBuf2[12];
|
||||
PR_snprintf(numBuf1, sizeof numBuf1, "%d", op);
|
||||
PR_snprintf(numBuf2, sizeof numBuf2, "%d", JSOP_LIMIT);
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_BYTECODE_TOO_BIG, numBuf1, numBuf2);
|
||||
JSMSG_BYTECODE_TOO_BIG, numBuf1, numBuf2);
|
||||
return 0;
|
||||
}
|
||||
cs = &js_CodeSpec[op];
|
||||
|
@ -228,11 +227,11 @@ js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc, uintN loc,
|
|||
|
||||
default: {
|
||||
char numBuf[12];
|
||||
sprintf(numBuf, "%x", cs->format);
|
||||
PR_snprintf(numBuf, sizeof numBuf, "%lx", (unsigned long) cs->format);
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_UNKNOWN_FORMAT, numBuf);
|
||||
JSMSG_UNKNOWN_FORMAT, numBuf);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
fputs("\n", fp);
|
||||
return len;
|
||||
|
@ -422,7 +421,7 @@ js_NewPrinter(JSContext *cx, const char *name, uintN indent)
|
|||
map = obj->map;
|
||||
if (map->ops == &js_ObjectOps) {
|
||||
if (OBJ_GET_CLASS(cx, obj) == &js_CallClass) {
|
||||
obj = fp->fun ? fp->fun->object : NULL;
|
||||
obj = fp->fun ? fp->fun->object : NULL;
|
||||
if (obj)
|
||||
map = obj->map;
|
||||
}
|
||||
|
@ -567,8 +566,8 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb);
|
|||
|
||||
static JSBool
|
||||
DecompileSwitch(SprintStack *ss, TableEntry *table, uintN tableLength,
|
||||
jsbytecode *pc, ptrdiff_t switchLength,
|
||||
ptrdiff_t defaultOffset, JSBool isCondSwitch)
|
||||
jsbytecode *pc, ptrdiff_t switchLength,
|
||||
ptrdiff_t defaultOffset, JSBool isCondSwitch)
|
||||
{
|
||||
JSContext *cx;
|
||||
JSPrinter *jp;
|
||||
|
@ -594,37 +593,53 @@ DecompileSwitch(SprintStack *ss, TableEntry *table, uintN tableLength,
|
|||
return JS_FALSE;
|
||||
jp->indent -= 4;
|
||||
}
|
||||
caseExprOff = 1 + JUMP_OFFSET_LEN + ATOM_INDEX_LEN +
|
||||
tableLength * (ATOM_INDEX_LEN + JUMP_OFFSET_LEN);
|
||||
|
||||
if (isCondSwitch)
|
||||
caseExprOff = (ptrdiff_t) js_CodeSpec[JSOP_CONDSWITCH].length;
|
||||
|
||||
for (i = 0; i < tableLength; i++) {
|
||||
off = table[i].offset;
|
||||
if (i + 1 < tableLength)
|
||||
off2 = table[i + 1].offset;
|
||||
else
|
||||
off2 = switchLength;
|
||||
|
||||
key = table[i].key;
|
||||
if (isCondSwitch) {
|
||||
uint32 caseLen = js_CodeSpec[JSOP_CASE].length;
|
||||
ptrdiff_t caseOff = JSVAL_TO_INT(key);
|
||||
jp->indent += 2;
|
||||
if (!Decompile(ss, pc + caseExprOff,
|
||||
caseOff - caseExprOff + caseLen))
|
||||
if (isCondSwitch) {
|
||||
ptrdiff_t nextCaseExprOff;
|
||||
|
||||
/*
|
||||
* key encodes the JSOP_CASE bytecode's offset from switchtop.
|
||||
* The next case expression follows immediately, unless we are
|
||||
* at the last case.
|
||||
*/
|
||||
nextCaseExprOff = (ptrdiff_t)
|
||||
(JSVAL_TO_INT(key) + js_CodeSpec[JSOP_CASE].length);
|
||||
jp->indent += 2;
|
||||
if (!Decompile(ss, pc + caseExprOff,
|
||||
nextCaseExprOff - caseExprOff)) {
|
||||
return JS_FALSE;
|
||||
caseExprOff = caseOff + caseLen;
|
||||
} else {
|
||||
str = js_ValueToString(cx, key);
|
||||
if (!str)
|
||||
}
|
||||
caseExprOff = nextCaseExprOff;
|
||||
} else {
|
||||
/*
|
||||
* key comes from an atom, not the decompiler, so we need to
|
||||
* quote it if it's a string literal.
|
||||
*/
|
||||
str = js_ValueToString(cx, key);
|
||||
if (!str)
|
||||
return JS_FALSE;
|
||||
jp->indent += 2;
|
||||
if (JSVAL_IS_STRING(key)) {
|
||||
jp->indent += 2;
|
||||
if (JSVAL_IS_STRING(key)) {
|
||||
rval = QuoteString(&ss->sprinter, str, '"');
|
||||
if (!rval)
|
||||
return JS_FALSE;
|
||||
} else {
|
||||
return JS_FALSE;
|
||||
} else {
|
||||
rval = JS_GetStringBytes(str);
|
||||
}
|
||||
js_printf(jp, "\tcase %s:\n", rval);
|
||||
}
|
||||
}
|
||||
js_printf(jp, "\tcase %s:\n", rval);
|
||||
}
|
||||
|
||||
jp->indent += 2;
|
||||
if (off <= defaultOffset && defaultOffset < off2) {
|
||||
diff = defaultOffset - off;
|
||||
|
@ -642,6 +657,7 @@ DecompileSwitch(SprintStack *ss, TableEntry *table, uintN tableLength,
|
|||
jp->indent -= 4;
|
||||
}
|
||||
}
|
||||
|
||||
if (defaultOffset == switchLength) {
|
||||
jp->indent += 2;
|
||||
js_printf(jp, "\tdefault:\n");
|
||||
|
@ -808,7 +824,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
|
|||
/* Do the loop body. */
|
||||
js_puts(jp, ") {\n");
|
||||
jp->indent += 4;
|
||||
oplen = (cond) ? js_CodeSpec[pc[cond]].length : 0;
|
||||
oplen = (cond) ? js_CodeSpec[pc[cond]].length : 0;
|
||||
DECOMPILE_CODE(pc + cond + oplen, next - cond - oplen);
|
||||
jp->indent -= 4;
|
||||
js_printf(jp, "\t}\n");
|
||||
|
@ -1543,7 +1559,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
|
|||
} else if (JSVAL_IS_OBJECT(key)) {
|
||||
#if JS_HAS_LEXICAL_CLOSURE
|
||||
if (JSVAL_IS_FUNCTION(cx, key))
|
||||
goto do_closure;
|
||||
goto do_closure;
|
||||
#endif
|
||||
str = js_ValueToString(cx, key);
|
||||
if (!str)
|
||||
|
@ -1593,8 +1609,8 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
|
|||
}
|
||||
js_qsort(table, (size_t)j, sizeof *table, CompareOffsets, NULL);
|
||||
|
||||
ok = DecompileSwitch(ss, table, (uintN)j, pc, len, off,
|
||||
JS_FALSE);
|
||||
ok = DecompileSwitch(ss, table, (uintN)j, pc, len, off,
|
||||
JS_FALSE);
|
||||
JS_free(cx, table);
|
||||
if (!ok)
|
||||
return ok;
|
||||
|
@ -1603,9 +1619,8 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
|
|||
}
|
||||
|
||||
case JSOP_LOOKUPSWITCH:
|
||||
case JSOP_CONDSWITCH:
|
||||
{
|
||||
jsbytecode *pc2 = pc;
|
||||
jsbytecode *pc2;
|
||||
ptrdiff_t off, off2;
|
||||
jsint npairs;
|
||||
TableEntry *table;
|
||||
|
@ -1613,6 +1628,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
|
|||
sn = js_GetSrcNote(jp->script, pc);
|
||||
PR_ASSERT(sn && SN_TYPE(sn) == SRC_SWITCH);
|
||||
len = js_GetSrcNoteOffset(sn, 0);
|
||||
pc2 = pc;
|
||||
off = GET_JUMP_OFFSET(pc2);
|
||||
pc2 += JUMP_OFFSET_LEN;
|
||||
npairs = (jsint) GET_ATOM_INDEX(pc2);
|
||||
|
@ -1629,21 +1645,9 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
|
|||
table[i].key = ATOM_KEY(atom);
|
||||
table[i].offset = off2;
|
||||
}
|
||||
if (op == JSOP_CONDSWITCH) {
|
||||
/*
|
||||
* Find offset of default code by finding the default
|
||||
* instruction and adding its offset.
|
||||
*/
|
||||
jsbytecode *pc3;
|
||||
|
||||
off = JSVAL_TO_INT(table[npairs-1].key) +
|
||||
js_CodeSpec[JSOP_CASE].length;
|
||||
pc3 = pc + off;
|
||||
off += GET_JUMP_OFFSET(pc3);
|
||||
}
|
||||
|
||||
ok = DecompileSwitch(ss, table, (uintN)npairs, pc, len, off,
|
||||
op == JSOP_CONDSWITCH);
|
||||
JS_FALSE);
|
||||
JS_free(cx, table);
|
||||
if (!ok)
|
||||
return ok;
|
||||
|
@ -1651,15 +1655,87 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
|
|||
break;
|
||||
}
|
||||
|
||||
case JSOP_CASE:
|
||||
{
|
||||
lval = POP_STR();
|
||||
if (!lval)
|
||||
return JS_FALSE;
|
||||
js_printf(jp, "\tcase %s:\n", lval);
|
||||
todo = -2;
|
||||
break;
|
||||
}
|
||||
case JSOP_CONDSWITCH:
|
||||
{
|
||||
jsbytecode *pc2;
|
||||
ptrdiff_t off, off2, caseOff;
|
||||
jsint ncases;
|
||||
TableEntry *table;
|
||||
|
||||
sn = js_GetSrcNote(jp->script, pc);
|
||||
PR_ASSERT(sn && SN_TYPE(sn) == SRC_SWITCH);
|
||||
len = js_GetSrcNoteOffset(sn, 0);
|
||||
off = js_GetSrcNoteOffset(sn, 1);
|
||||
|
||||
/*
|
||||
* Count the cases using offsets from switch to first case,
|
||||
* and case to case, stored in srcnote immediates.
|
||||
*/
|
||||
pc2 = pc;
|
||||
off2 = off;
|
||||
for (ncases = 0; off2 != 0; ncases++) {
|
||||
pc2 += off2;
|
||||
PR_ASSERT(*pc2 == JSOP_CASE || *pc2 == JSOP_DEFAULT);
|
||||
if (*pc2 == JSOP_DEFAULT) {
|
||||
/* End of cases, but count default as a case. */
|
||||
off2 = 0;
|
||||
} else {
|
||||
sn = js_GetSrcNote(jp->script, pc2);
|
||||
PR_ASSERT(sn && SN_TYPE(sn) == SRC_COMMA);
|
||||
off2 = js_GetSrcNoteOffset(sn, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate table and rescan the cases using their srcnotes,
|
||||
* stashing each case's delta from switch top in table[i].key,
|
||||
* and the distance to its statements in table[i].offset.
|
||||
*/
|
||||
table = JS_malloc(cx, (size_t)ncases * sizeof *table);
|
||||
if (!table)
|
||||
return JS_FALSE;
|
||||
pc2 = pc;
|
||||
off2 = off;
|
||||
for (i = 0; i < ncases; i++) {
|
||||
pc2 += off2;
|
||||
PR_ASSERT(*pc2 == JSOP_CASE || *pc2 == JSOP_DEFAULT);
|
||||
caseOff = pc2 - pc;
|
||||
table[i].key = INT_TO_JSVAL((jsint) caseOff);
|
||||
table[i].offset = caseOff + GET_JUMP_OFFSET(pc2);
|
||||
if (*pc2 == JSOP_CASE) {
|
||||
sn = js_GetSrcNote(jp->script, pc2);
|
||||
PR_ASSERT(sn && SN_TYPE(sn) == SRC_COMMA);
|
||||
off2 = js_GetSrcNoteOffset(sn, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Find offset of default code by fetching the default offset
|
||||
* from the end of table. JSOP_CONDSWITCH always has a default
|
||||
* case at the end.
|
||||
*/
|
||||
off = JSVAL_TO_INT(table[ncases-1].key);
|
||||
pc2 = pc + off;
|
||||
off += GET_JUMP_OFFSET(pc2);
|
||||
|
||||
ok = DecompileSwitch(ss, table, (uintN)ncases, pc, len, off,
|
||||
JS_TRUE);
|
||||
JS_free(cx, table);
|
||||
if (!ok)
|
||||
return ok;
|
||||
todo = -2;
|
||||
break;
|
||||
}
|
||||
|
||||
case JSOP_CASE:
|
||||
{
|
||||
lval = POP_STR();
|
||||
if (!lval)
|
||||
return JS_FALSE;
|
||||
js_printf(jp, "\tcase %s:\n", lval);
|
||||
todo = -2;
|
||||
break;
|
||||
}
|
||||
|
||||
#endif /* JS_HAS_SWITCH_STATEMENT */
|
||||
|
||||
|
@ -1818,7 +1894,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
|
|||
i = (jsint) GET_ATOM_INDEX(pc);
|
||||
rval = POP_STR();
|
||||
todo = Sprint(&ss->sprinter, "#%u=%s", (unsigned) i, rval);
|
||||
break;
|
||||
break;
|
||||
|
||||
case JSOP_USESHARP:
|
||||
i = (jsint) GET_ATOM_INDEX(pc);
|
||||
|
@ -1829,7 +1905,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb)
|
|||
|
||||
#if JS_HAS_DEBUGGER_KEYWORD
|
||||
case JSOP_DEBUGGER:
|
||||
js_printf(jp, "\tdebugger;\n");
|
||||
js_printf(jp, "\tdebugger;\n");
|
||||
todo = -2;
|
||||
break;
|
||||
#endif /* JS_HAS_DEBUGGER_KEYWORD */
|
||||
|
@ -1932,36 +2008,36 @@ js_DecompileFunction(JSPrinter *jp, JSFunction *fun, JSBool newlines)
|
|||
js_printf(jp, "function %s(", fun->atom ? ATOM_BYTES(fun->atom) : "");
|
||||
|
||||
if (fun->script && fun->object) {
|
||||
/* Print the parameters.
|
||||
*
|
||||
* This code is complicated by the need to handle duplicate parameter names.
|
||||
* A duplicate parameter is stored as a property with id equal to the parameter
|
||||
* number, but will not be in order in the linked list of symbols. So for each
|
||||
* parameter we search the list of symbols for the appropriately numbered
|
||||
* parameter, which we can then print.
|
||||
*/
|
||||
for (i=0;;i++) {
|
||||
jsid id;
|
||||
atom = NULL;
|
||||
scope = (JSScope *)fun->object->map;
|
||||
for (sprop = scope->props; sprop; sprop = snext) {
|
||||
snext = sprop->next;
|
||||
if (sprop->getter != js_GetArgument)
|
||||
continue;
|
||||
if (JSVAL_IS_INT(sprop->id) && JSVAL_TO_INT(sprop->id) == i) {
|
||||
atom = sym_atom(sprop->symbols);
|
||||
break;
|
||||
}
|
||||
id = (jsid) sym_atom(sprop->symbols);
|
||||
if (JSVAL_IS_INT(id) && JSVAL_TO_INT(id) == i) {
|
||||
atom = (JSAtom *) sprop->id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (atom == NULL)
|
||||
break;
|
||||
js_printf(jp, (i > 0 ? ", %s" : "%s"), ATOM_BYTES(atom));
|
||||
}
|
||||
/* Print the parameters.
|
||||
*
|
||||
* This code is complicated by the need to handle duplicate parameter names.
|
||||
* A duplicate parameter is stored as a property with id equal to the parameter
|
||||
* number, but will not be in order in the linked list of symbols. So for each
|
||||
* parameter we search the list of symbols for the appropriately numbered
|
||||
* parameter, which we can then print.
|
||||
*/
|
||||
for (i=0;;i++) {
|
||||
jsid id;
|
||||
atom = NULL;
|
||||
scope = (JSScope *)fun->object->map;
|
||||
for (sprop = scope->props; sprop; sprop = snext) {
|
||||
snext = sprop->next;
|
||||
if (sprop->getter != js_GetArgument)
|
||||
continue;
|
||||
if (JSVAL_IS_INT(sprop->id) && JSVAL_TO_INT(sprop->id) == i) {
|
||||
atom = sym_atom(sprop->symbols);
|
||||
break;
|
||||
}
|
||||
id = (jsid) sym_atom(sprop->symbols);
|
||||
if (JSVAL_IS_INT(id) && JSVAL_TO_INT(id) == i) {
|
||||
atom = (JSAtom *) sprop->id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (atom == NULL)
|
||||
break;
|
||||
js_printf(jp, (i > 0 ? ", %s" : "%s"), ATOM_BYTES(atom));
|
||||
}
|
||||
}
|
||||
js_puts(jp, ") {\n");
|
||||
indent = jp->indent;
|
||||
|
|
|
@ -1,211 +0,0 @@
|
|||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
/*
|
||||
* JavaScript operation bytecodes.
|
||||
*
|
||||
* Includers must define an OPDEF macro of the following form:
|
||||
*
|
||||
* #define OPDEF(op,val,name,image,length,nuses,ndefs,prec,format) ...
|
||||
*
|
||||
* Selected arguments can be expanded in initializers. The op argument is
|
||||
* expanded followed by comma in the JSOp enum (jsopcode.h), e.g. The value
|
||||
* field must be dense for now, because jsopcode.c uses an OPDEF() expansion
|
||||
* inside the js_CodeSpec[] initializer.
|
||||
*
|
||||
* Field Description
|
||||
* op Bytecode name, which is the JSOp enumerator name
|
||||
* value Bytecode value, which is the JSOp enumerator value
|
||||
* name C string containing name for disassembler
|
||||
* image C string containing "image" for pretty-printer, null if ugly
|
||||
* length Number of bytes including any immediate operands
|
||||
* nuses Number of stack slots consumed by bytecode, -1 if variadic
|
||||
* ndefs Number of stack slots produced by bytecode
|
||||
* prec Operator precedence, zero if not an operator
|
||||
* format Bytecode plus immediate operand encoding format
|
||||
*
|
||||
* This file is best viewed with 116 columns:
|
||||
01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345
|
||||
*/
|
||||
|
||||
/* legend: op val name image len use def prec format */
|
||||
|
||||
/* Permanently-assigned bytecodes. */
|
||||
OPDEF(JSOP_NOP, 0, "nop", NULL, 1, 0, 0, 0, JOF_BYTE)
|
||||
OPDEF(JSOP_PUSH, 1, "push", NULL, 1, 0, 1, 0, JOF_BYTE)
|
||||
OPDEF(JSOP_POPV, 2, "popv", NULL, 1, 1, 0, 0, JOF_BYTE)
|
||||
OPDEF(JSOP_ENTERWITH, 3, "enterwith", NULL, 1, 1, 1, 0, JOF_BYTE)
|
||||
OPDEF(JSOP_LEAVEWITH, 4, "leavewith", NULL, 1, 1, 0, 0, JOF_BYTE)
|
||||
OPDEF(JSOP_RETURN, 5, "return", NULL, 1, 1, 0, 0, JOF_BYTE)
|
||||
OPDEF(JSOP_GOTO, 6, "goto", NULL, 3, 0, 0, 0, JOF_JUMP)
|
||||
OPDEF(JSOP_IFEQ, 7, "ifeq", NULL, 3, 1, 0, 0, JOF_JUMP)
|
||||
OPDEF(JSOP_IFNE, 8, "ifne", NULL, 3, 1, 0, 0, JOF_JUMP)
|
||||
OPDEF(JSOP_FORNAME, 9, "forname", NULL, 3, 1, 1, 0, JOF_CONST|JOF_NAME|JOF_SET)
|
||||
OPDEF(JSOP_FORPROP, 10, "forprop", NULL, 3, 2, 1, 0, JOF_CONST|JOF_PROP|JOF_SET)
|
||||
OPDEF(JSOP_FORELEM, 11, "forelem", NULL, 1, 3, 1, 0, JOF_BYTE |JOF_ELEM|JOF_SET)
|
||||
OPDEF(JSOP_DUP, 12, "dup", NULL, 1, 1, 2, 0, JOF_BYTE)
|
||||
OPDEF(JSOP_DUP2, 13, "dup2", NULL, 1, 2, 4, 0, JOF_BYTE)
|
||||
OPDEF(JSOP_SETNAME, 14, "setname", NULL, 3, 1, 1, 1, JOF_CONST|JOF_NAME|JOF_SET)
|
||||
OPDEF(JSOP_BITOR, 15, "bitor", "|", 1, 2, 1, 2, JOF_BYTE)
|
||||
OPDEF(JSOP_BITXOR, 16, "bitxor", "^", 1, 2, 1, 3, JOF_BYTE)
|
||||
OPDEF(JSOP_BITAND, 17, "bitand", "&", 1, 2, 1, 4, JOF_BYTE)
|
||||
OPDEF(JSOP_EQ, 18, "eq", "==", 1, 2, 1, 5, JOF_BYTE)
|
||||
OPDEF(JSOP_NE, 19, "ne", "!=", 1, 2, 1, 5, JOF_BYTE)
|
||||
OPDEF(JSOP_LT, 20, "lt", "<", 1, 2, 1, 6, JOF_BYTE)
|
||||
OPDEF(JSOP_LE, 21, "le", "<=", 1, 2, 1, 6, JOF_BYTE)
|
||||
OPDEF(JSOP_GT, 22, "gt", ">", 1, 2, 1, 6, JOF_BYTE)
|
||||
OPDEF(JSOP_GE, 23, "ge", ">=", 1, 2, 1, 6, JOF_BYTE)
|
||||
OPDEF(JSOP_LSH, 24, "lsh", "<<", 1, 2, 1, 7, JOF_BYTE)
|
||||
OPDEF(JSOP_RSH, 25, "rsh", ">>", 1, 2, 1, 7, JOF_BYTE)
|
||||
OPDEF(JSOP_URSH, 26, "ursh", ">>>", 1, 2, 1, 7, JOF_BYTE)
|
||||
OPDEF(JSOP_ADD, 27, "add", "+", 1, 2, 1, 8, JOF_BYTE)
|
||||
OPDEF(JSOP_SUB, 28, "sub", "-", 1, 2, 1, 8, JOF_BYTE)
|
||||
OPDEF(JSOP_MUL, 29, "mul", "*", 1, 2, 1, 9, JOF_BYTE)
|
||||
OPDEF(JSOP_DIV, 30, "div", "/", 1, 2, 1, 9, JOF_BYTE)
|
||||
OPDEF(JSOP_MOD, 31, "mod", "%", 1, 2, 1, 9, JOF_BYTE)
|
||||
OPDEF(JSOP_NOT, 32, "not", "!", 1, 1, 1, 10, JOF_BYTE)
|
||||
OPDEF(JSOP_BITNOT, 33, "bitnot", "~", 1, 1, 1, 10, JOF_BYTE)
|
||||
OPDEF(JSOP_NEG, 34, "neg", "-", 1, 1, 1, 10, JOF_BYTE)
|
||||
OPDEF(JSOP_NEW, 35, js_new_str, NULL, 3, -1, 1, 10, JOF_UINT16)
|
||||
OPDEF(JSOP_DELNAME, 36, "delname", NULL, 3, 0, 1, 10, JOF_CONST|JOF_NAME|JOF_DEL)
|
||||
OPDEF(JSOP_DELPROP, 37, "delprop", NULL, 3, 1, 1, 10, JOF_CONST|JOF_PROP|JOF_DEL)
|
||||
OPDEF(JSOP_DELELEM, 38, "delelem", NULL, 1, 2, 1, 10, JOF_BYTE |JOF_ELEM|JOF_DEL)
|
||||
OPDEF(JSOP_TYPEOF, 39, js_typeof_str,NULL, 1, 1, 1, 10, JOF_BYTE)
|
||||
OPDEF(JSOP_VOID, 40, js_void_str, NULL, 1, 1, 1, 10, JOF_BYTE)
|
||||
OPDEF(JSOP_INCNAME, 41, "incname", NULL, 3, 0, 1, 10, JOF_CONST|JOF_NAME|JOF_INC)
|
||||
OPDEF(JSOP_INCPROP, 42, "incprop", NULL, 3, 1, 1, 10, JOF_CONST|JOF_PROP|JOF_INC)
|
||||
OPDEF(JSOP_INCELEM, 43, "incelem", NULL, 1, 2, 1, 10, JOF_BYTE |JOF_ELEM|JOF_INC)
|
||||
OPDEF(JSOP_DECNAME, 44, "decname", NULL, 3, 0, 1, 10, JOF_CONST|JOF_NAME|JOF_DEC)
|
||||
OPDEF(JSOP_DECPROP, 45, "decprop", NULL, 3, 1, 1, 10, JOF_CONST|JOF_PROP|JOF_DEC)
|
||||
OPDEF(JSOP_DECELEM, 46, "decelem", NULL, 1, 2, 1, 10, JOF_BYTE |JOF_ELEM|JOF_DEC)
|
||||
OPDEF(JSOP_NAMEINC, 47, "nameinc", NULL, 3, 0, 1, 10, JOF_CONST|JOF_NAME|JOF_INC|JOF_POST)
|
||||
OPDEF(JSOP_PROPINC, 48, "propinc", NULL, 3, 1, 1, 10, JOF_CONST|JOF_PROP|JOF_INC|JOF_POST)
|
||||
OPDEF(JSOP_ELEMINC, 49, "eleminc", NULL, 1, 2, 1, 10, JOF_BYTE |JOF_ELEM|JOF_INC|JOF_POST)
|
||||
OPDEF(JSOP_NAMEDEC, 50, "namedec", NULL, 3, 0, 1, 10, JOF_CONST|JOF_NAME|JOF_DEC|JOF_POST)
|
||||
OPDEF(JSOP_PROPDEC, 51, "propdec", NULL, 3, 1, 1, 10, JOF_CONST|JOF_PROP|JOF_DEC|JOF_POST)
|
||||
OPDEF(JSOP_ELEMDEC, 52, "elemdec", NULL, 1, 2, 1, 10, JOF_BYTE |JOF_ELEM|JOF_DEC|JOF_POST)
|
||||
OPDEF(JSOP_GETPROP, 53, "getprop", NULL, 3, 1, 1, 11, JOF_CONST|JOF_PROP)
|
||||
OPDEF(JSOP_SETPROP, 54, "setprop", NULL, 3, 2, 1, 1, JOF_CONST|JOF_PROP|JOF_SET)
|
||||
OPDEF(JSOP_GETELEM, 55, "getelem", NULL, 1, 2, 1, 11, JOF_BYTE |JOF_ELEM)
|
||||
OPDEF(JSOP_SETELEM, 56, "setelem", NULL, 1, 3, 1, 1, JOF_BYTE |JOF_ELEM|JOF_SET)
|
||||
OPDEF(JSOP_PUSHOBJ, 57, "pushobj", NULL, 1, 0, 1, 0, JOF_BYTE)
|
||||
OPDEF(JSOP_CALL, 58, "call", NULL, 3, -1, 1, 11, JOF_UINT16)
|
||||
OPDEF(JSOP_NAME, 59, "name", NULL, 3, 0, 1, 12, JOF_CONST|JOF_NAME)
|
||||
OPDEF(JSOP_NUMBER, 60, "number", NULL, 3, 0, 1, 12, JOF_CONST)
|
||||
OPDEF(JSOP_STRING, 61, "string", NULL, 3, 0, 1, 12, JOF_CONST)
|
||||
OPDEF(JSOP_ZERO, 62, "zero", "0", 1, 0, 1, 12, JOF_BYTE)
|
||||
OPDEF(JSOP_ONE, 63, "one", "1", 1, 0, 1, 12, JOF_BYTE)
|
||||
OPDEF(JSOP_NULL, 64, js_null_str, js_null_str, 1, 0, 1, 12, JOF_BYTE)
|
||||
OPDEF(JSOP_THIS, 65, js_this_str, js_this_str, 1, 0, 1, 12, JOF_BYTE)
|
||||
OPDEF(JSOP_FALSE, 66, js_false_str, js_false_str, 1, 0, 1, 12, JOF_BYTE)
|
||||
OPDEF(JSOP_TRUE, 67, js_true_str, js_true_str, 1, 0, 1, 12, JOF_BYTE)
|
||||
OPDEF(JSOP_OR, 68, "or", NULL, 3, 1, 0, 0, JOF_JUMP)
|
||||
OPDEF(JSOP_AND, 69, "and", NULL, 3, 1, 0, 0, JOF_JUMP)
|
||||
|
||||
/* The switch bytecodes have variable length. */
|
||||
OPDEF(JSOP_TABLESWITCH, 70, "tableswitch", NULL, -1, 1, 0, 0, JOF_TABLESWITCH)
|
||||
OPDEF(JSOP_LOOKUPSWITCH, 71, "lookupswitch", NULL, -1, 1, 0, 0, JOF_LOOKUPSWITCH)
|
||||
|
||||
/* New, infallible/transitive identity ops. */
|
||||
OPDEF(JSOP_NEW_EQ, 72, "eq", NULL, 1, 2, 1, 5, JOF_BYTE)
|
||||
OPDEF(JSOP_NEW_NE, 73, "ne", NULL, 1, 2, 1, 5, JOF_BYTE)
|
||||
|
||||
/* Lexical closure constructor. */
|
||||
OPDEF(JSOP_CLOSURE, 74, "closure", NULL, 3, 0, 1, 0, JOF_CONST)
|
||||
|
||||
/* Export and import ops. */
|
||||
OPDEF(JSOP_EXPORTALL, 75, "exportall", NULL, 1, 0, 0, 0, JOF_BYTE)
|
||||
OPDEF(JSOP_EXPORTNAME,76, "exportname", NULL, 3, 0, 0, 0, JOF_CONST|JOF_NAME)
|
||||
OPDEF(JSOP_IMPORTALL, 77, "importall", NULL, 1, 1, 0, 0, JOF_BYTE)
|
||||
OPDEF(JSOP_IMPORTPROP,78, "importprop", NULL, 3, 1, 0, 0, JOF_CONST|JOF_PROP|JOF_IMPORT)
|
||||
OPDEF(JSOP_IMPORTELEM,79, "importelem", NULL, 3, 2, 0, 0, JOF_BYTE |JOF_ELEM|JOF_IMPORT)
|
||||
|
||||
/* Push object literal. */
|
||||
OPDEF(JSOP_OBJECT, 80, "object", NULL, 3, 0, 1, 12, JOF_CONST)
|
||||
|
||||
/* Pop value and discard it. */
|
||||
OPDEF(JSOP_POP, 81, "pop", NULL, 1, 1, 0, 0, JOF_BYTE)
|
||||
|
||||
/* Convert value to number, for unary +. */
|
||||
OPDEF(JSOP_POS, 82, "pos", "+", 1, 1, 1, 10, JOF_BYTE)
|
||||
|
||||
/* Trap into debugger for breakpoint, etc. */
|
||||
OPDEF(JSOP_TRAP, 83, "trap", NULL, 1, 0, 0, 0, JOF_BYTE)
|
||||
|
||||
/* Fast get/set ops for function arguments and local variables. */
|
||||
OPDEF(JSOP_GETARG, 84, "getarg", NULL, 3, 0, 1, 12, JOF_QARG |JOF_NAME)
|
||||
OPDEF(JSOP_SETARG, 85, "setarg", NULL, 3, 1, 1, 1, JOF_QARG |JOF_NAME|JOF_SET)
|
||||
OPDEF(JSOP_GETVAR, 86, "getvar", NULL, 3, 0, 1, 12, JOF_QVAR |JOF_NAME)
|
||||
OPDEF(JSOP_SETVAR, 87, "setvar", NULL, 3, 1, 1, 1, JOF_QVAR |JOF_NAME|JOF_SET)
|
||||
|
||||
/* Push unsigned 16-bit int constant. */
|
||||
OPDEF(JSOP_UINT16, 88, "uint16", NULL, 3, 0, 1, 12, JOF_UINT16)
|
||||
|
||||
/* Object and array literal support. */
|
||||
OPDEF(JSOP_NEWINIT, 89, "newinit", NULL, 1, 2, 1, 10, JOF_BYTE)
|
||||
OPDEF(JSOP_ENDINIT, 90, "endinit", NULL, 1, 0, 0, 0, JOF_BYTE)
|
||||
OPDEF(JSOP_INITPROP, 91, "initprop", NULL, 3, 1, 0, 0, JOF_CONST|JOF_PROP)
|
||||
OPDEF(JSOP_INITELEM, 92, "initelem", NULL, 1, 2, 0, 0, JOF_BYTE |JOF_ELEM)
|
||||
OPDEF(JSOP_DEFSHARP, 93, "defsharp", NULL, 3, 0, 0, 0, JOF_UINT16)
|
||||
OPDEF(JSOP_USESHARP, 94, "usesharp", NULL, 3, 0, 1, 0, JOF_UINT16)
|
||||
|
||||
/* Fast inc/dec ops for args and local vars. */
|
||||
OPDEF(JSOP_INCARG, 95, "incarg", NULL, 3, 0, 1, 10, JOF_QARG |JOF_NAME|JOF_INC)
|
||||
OPDEF(JSOP_INCVAR, 96, "incvar", NULL, 3, 0, 1, 10, JOF_QVAR |JOF_NAME|JOF_INC)
|
||||
OPDEF(JSOP_DECARG, 97, "decarg", NULL, 3, 0, 1, 10, JOF_QARG |JOF_NAME|JOF_DEC)
|
||||
OPDEF(JSOP_DECVAR, 98, "decvar", NULL, 3, 0, 1, 10, JOF_QVAR |JOF_NAME|JOF_DEC)
|
||||
OPDEF(JSOP_ARGINC, 99, "arginc", NULL, 3, 0, 1, 10, JOF_QARG |JOF_NAME|JOF_INC|JOF_POST)
|
||||
OPDEF(JSOP_VARINC, 100,"varinc", NULL, 3, 0, 1, 10, JOF_QVAR |JOF_NAME|JOF_INC|JOF_POST)
|
||||
OPDEF(JSOP_ARGDEC, 101,"argdec", NULL, 3, 0, 1, 10, JOF_QARG |JOF_NAME|JOF_DEC|JOF_POST)
|
||||
OPDEF(JSOP_VARDEC, 102,"vardec", NULL, 3, 0, 1, 10, JOF_QVAR |JOF_NAME|JOF_DEC|JOF_POST)
|
||||
|
||||
/* ECMA-compliant for/in ops. */
|
||||
OPDEF(JSOP_TOOBJECT, 103,"toobject", NULL, 1, 1, 1, 0, JOF_BYTE)
|
||||
OPDEF(JSOP_FORNAME2, 104,"forname2", NULL, 3, 0, 1, 0, JOF_CONST|JOF_NAME|JOF_SET|JOF_FOR2)
|
||||
OPDEF(JSOP_FORPROP2, 105,"forprop2", NULL, 3, 1, 1, 0, JOF_CONST|JOF_PROP|JOF_SET|JOF_FOR2)
|
||||
OPDEF(JSOP_FORELEM2, 106,"forelem2", NULL, 1, 2, 1, 0, JOF_BYTE |JOF_ELEM|JOF_SET|JOF_FOR2)
|
||||
OPDEF(JSOP_POP2, 107,"pop2", NULL, 1, 2, 0, 0, JOF_BYTE)
|
||||
|
||||
/* ECMA-complaint assignment ops. */
|
||||
OPDEF(JSOP_BINDNAME, 108,"bindname", NULL, 3, 0, 1, 0, JOF_CONST|JOF_NAME)
|
||||
OPDEF(JSOP_SETNAME2, 109,"setname2", NULL, 3, 2, 1, 1, JOF_CONST|JOF_NAME|JOF_SET)
|
||||
|
||||
/* Exception handling ops. */
|
||||
OPDEF(JSOP_THROW, 110,"throw", NULL, 1, 1, 0, 0, JOF_BYTE)
|
||||
|
||||
/* 'in' and 'instanceof' ops. */
|
||||
OPDEF(JSOP_IN, 111,js_in_str, js_in_str, 1, 2, 1, 6, JOF_BYTE)
|
||||
OPDEF(JSOP_INSTANCEOF,112,js_instanceof_str,js_instanceof_str,1,2,1,6,JOF_BYTE)
|
||||
|
||||
/* debugger op */
|
||||
OPDEF(JSOP_DEBUGGER, 113,"debugger", NULL, 1, 0, 0, 0, JOF_BYTE)
|
||||
|
||||
/* gosub/retsub for finally handling */
|
||||
OPDEF(JSOP_GOSUB, 114,"gosub", NULL, 3, 0, 1, 0, JOF_JUMP)
|
||||
OPDEF(JSOP_RETSUB, 115,"retsub", NULL, 1, 1, 0, 0, JOF_BYTE)
|
||||
|
||||
/* more exception handling ops */
|
||||
OPDEF(JSOP_EXCEPTION, 116,"exception", NULL, 1, 0, 1, 0, JOF_BYTE)
|
||||
OPDEF(JSOP_SETSP, 117,"setsp", NULL, 3, 0, 0, 0, JOF_UINT16)
|
||||
|
||||
/*
|
||||
* ECMA-compliant switch statement ops.
|
||||
* "switch" is essentially "nop" and "default" is essentially "pop" + "goto".
|
||||
*/
|
||||
OPDEF(JSOP_CONDSWITCH,118,"switch", NULL, -1, 0, 0, 0, JOF_LOOKUPSWITCH)
|
||||
OPDEF(JSOP_CASE, 119,"case", NULL, 3, 1, 0, 0, JOF_JUMP)
|
||||
OPDEF(JSOP_DEFAULT, 120,"default", NULL, 3, 1, 0, 0, JOF_JUMP)
|
401
js/ref/jsparse.c
401
js/ref/jsparse.c
|
@ -38,7 +38,6 @@
|
|||
#include "prtypes.h"
|
||||
#include "prarena.h"
|
||||
#include "prassert.h"
|
||||
#include "prprintf.h"
|
||||
#include "jsapi.h"
|
||||
#include "jsatom.h"
|
||||
#include "jscntxt.h"
|
||||
|
@ -162,17 +161,17 @@ WellTerminated(JSContext *cx, JSTokenStream *ts, JSTokenType lastExprType)
|
|||
#if JS_HAS_LEXICAL_CLOSURE
|
||||
if ((tt == TOK_FUNCTION || lastExprType == TOK_FUNCTION) &&
|
||||
cx->version < JSVERSION_1_2) {
|
||||
/*
|
||||
* Checking against version < 1.2 and version >= 1.0
|
||||
* in the above line breaks old javascript, so we keep it
|
||||
* this way for now... XXX warning needed?
|
||||
*/
|
||||
/*
|
||||
* Checking against version < 1.2 and version >= 1.0
|
||||
* in the above line breaks old javascript, so we keep it
|
||||
* this way for now... XXX warning needed?
|
||||
*/
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
#endif
|
||||
js_ReportCompileErrorNumber(cx, ts, JSREPORT_ERROR,
|
||||
JSMSG_SEMI_BEFORE_STMNT);
|
||||
JSMSG_SEMI_BEFORE_STMNT);
|
||||
return JS_FALSE;
|
||||
}
|
||||
return JS_TRUE;
|
||||
|
@ -219,11 +218,11 @@ js_CompileTokenStream(JSContext *cx, JSObject *chain, JSTokenStream *ts,
|
|||
switch (tt) {
|
||||
case TOK_FUNCTION:
|
||||
pn = FunctionStmt(cx, ts, &cg->treeContext);
|
||||
if (pn && pn->pn_pos.end.lineno == ts->lineno) {
|
||||
if (pn && pn->pn_pos.end.lineno == ts->lineno) {
|
||||
ok = WellTerminated(cx, ts, TOK_FUNCTION);
|
||||
if (!ok)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -268,34 +267,34 @@ CheckFinalReturn(JSParseNode *pn)
|
|||
|
||||
switch (pn->pn_type) {
|
||||
case TOK_LC:
|
||||
if (!pn->pn_head)
|
||||
if (!pn->pn_head)
|
||||
return JS_FALSE;
|
||||
return CheckFinalReturn(PN_LAST(pn));
|
||||
case TOK_IF:
|
||||
ok = CheckFinalReturn(pn->pn_kid2);
|
||||
ok = CheckFinalReturn(pn->pn_kid2);
|
||||
ok &= pn->pn_kid3 && CheckFinalReturn(pn->pn_kid3);
|
||||
return ok;
|
||||
#if JS_HAS_SWITCH_STATEMENT
|
||||
case TOK_SWITCH:
|
||||
ok = JS_TRUE;
|
||||
for (pn2 = pn->pn_kid2->pn_head; ok && pn2; pn2 = pn2->pn_next) {
|
||||
if (pn2->pn_type == TOK_DEFAULT)
|
||||
hasDefault = JS_TRUE;
|
||||
ok = JS_TRUE;
|
||||
for (pn2 = pn->pn_kid2->pn_head; ok && pn2; pn2 = pn2->pn_next) {
|
||||
if (pn2->pn_type == TOK_DEFAULT)
|
||||
hasDefault = JS_TRUE;
|
||||
pn3 = pn2->pn_right;
|
||||
PR_ASSERT(pn3->pn_type == TOK_LC);
|
||||
if (pn3->pn_head)
|
||||
ok &= CheckFinalReturn(PN_LAST(pn3));
|
||||
}
|
||||
/* If a final switch has no default case, we judge it harshly. */
|
||||
ok &= hasDefault;
|
||||
ok &= hasDefault;
|
||||
return ok;
|
||||
#endif /* JS_HAS_SWITCH_STATEMENT */
|
||||
case TOK_WITH:
|
||||
return CheckFinalReturn(pn->pn_right);
|
||||
case TOK_RETURN:
|
||||
return JS_TRUE;
|
||||
return JS_TRUE;
|
||||
default:
|
||||
return JS_FALSE;
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -398,7 +397,7 @@ FunctionDef(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
|
|||
/* Make a TOK_FUNCTION node. */
|
||||
pn = NewParseNode(cx, &ts->token, PN_FUNC);
|
||||
if (!pn)
|
||||
return NULL;
|
||||
return NULL;
|
||||
|
||||
/* Scan the optional function name into funAtom. */
|
||||
if (js_MatchToken(cx, ts, TOK_NAME))
|
||||
|
@ -443,35 +442,35 @@ FunctionDef(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
|
|||
if (!ok)
|
||||
goto out;
|
||||
if (sprop && pobj == fun->object) {
|
||||
if (sprop->getter == js_GetArgument) {
|
||||
if (sprop->getter == js_GetArgument) {
|
||||
#ifdef CHECK_ARGUMENT_HIDING
|
||||
OBJ_DROP_PROPERTY(cx, pobj, (JSProperty *)sprop);
|
||||
js_ReportCompileErrorNumber(cx, ts, JSREPORT_WARNING,
|
||||
JSMSG_DUPLICATE_FORMAL,
|
||||
ATOM_BYTES(argAtom));
|
||||
ok = JS_FALSE;
|
||||
goto out;
|
||||
OBJ_DROP_PROPERTY(cx, pobj, (JSProperty *)sprop);
|
||||
js_ReportCompileErrorNumber(cx, ts, JSREPORT_WARNING,
|
||||
JSMSG_DUPLICATE_FORMAL,
|
||||
ATOM_BYTES(argAtom));
|
||||
ok = JS_FALSE;
|
||||
goto out;
|
||||
#else
|
||||
/*
|
||||
* A duplicate parameter name. We create a dummy symbol
|
||||
* entry with property id of the parameter number and set
|
||||
* the id to the name of the parameter.
|
||||
* The decompiler will know to treat this case specially.
|
||||
*/
|
||||
jsid oldArgId = (jsid) sprop->id;
|
||||
OBJ_DROP_PROPERTY(cx, pobj, (JSProperty *)sprop);
|
||||
sprop = NULL;
|
||||
ok = js_DefineProperty(cx, fun->object,
|
||||
oldArgId, JSVAL_VOID,
|
||||
js_GetArgument, js_SetArgument,
|
||||
JSPROP_ENUMERATE | JSPROP_PERMANENT,
|
||||
(JSProperty **)&sprop);
|
||||
if (!ok)
|
||||
goto out;
|
||||
sprop->id = (jsid) argAtom;
|
||||
/*
|
||||
* A duplicate parameter name. We create a dummy symbol
|
||||
* entry with property id of the parameter number and set
|
||||
* the id to the name of the parameter.
|
||||
* The decompiler will know to treat this case specially.
|
||||
*/
|
||||
jsid oldArgId = (jsid) sprop->id;
|
||||
OBJ_DROP_PROPERTY(cx, pobj, (JSProperty *)sprop);
|
||||
sprop = NULL;
|
||||
ok = js_DefineProperty(cx, fun->object,
|
||||
oldArgId, JSVAL_VOID,
|
||||
js_GetArgument, js_SetArgument,
|
||||
JSPROP_ENUMERATE | JSPROP_PERMANENT,
|
||||
(JSProperty **)&sprop);
|
||||
if (!ok)
|
||||
goto out;
|
||||
sprop->id = (jsid) argAtom;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sprop) {
|
||||
OBJ_DROP_PROPERTY(cx, pobj, (JSProperty *)sprop);
|
||||
sprop = NULL;
|
||||
|
@ -496,11 +495,11 @@ FunctionDef(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
|
|||
ok = JS_FALSE; goto out);
|
||||
pn->pn_pos.begin = ts->token.pos.begin;
|
||||
|
||||
INIT_TREE_CONTEXT(&funtc);
|
||||
TREE_CONTEXT_INIT(&funtc);
|
||||
pn2 = FunctionBody(cx, ts, fun, &funtc);
|
||||
if (!pn2) {
|
||||
ok = JS_FALSE;
|
||||
goto out;
|
||||
ok = JS_FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
MUST_MATCH_TOKEN_THROW(TOK_RC, JSMSG_CURLY_AFTER_BODY,
|
||||
|
@ -558,7 +557,7 @@ Statements(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
|
|||
PR_ASSERT(ts->token.type == TOK_LC);
|
||||
pn = NewParseNode(cx, &ts->token, PN_LIST);
|
||||
if (!pn)
|
||||
return NULL;
|
||||
return NULL;
|
||||
PN_INIT_LIST(pn);
|
||||
|
||||
newlines = ts->flags & TSF_NEWLINES;
|
||||
|
@ -603,10 +602,10 @@ Condition(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
|
|||
JSMSG_EQUAL_AS_ASSIGN,
|
||||
JSVERSION_IS_ECMA(cx->version) ? ""
|
||||
: "\nAssuming equality test");
|
||||
if (JSVERSION_IS_ECMA(cx->version))
|
||||
goto no_rewrite;
|
||||
pn->pn_type = TOK_EQOP;
|
||||
pn->pn_op = cx->jsop_eq;
|
||||
if (JSVERSION_IS_ECMA(cx->version))
|
||||
goto no_rewrite;
|
||||
pn->pn_type = TOK_EQOP;
|
||||
pn->pn_op = cx->jsop_eq;
|
||||
pn2 = pn->pn_left;
|
||||
switch (pn2->pn_op) {
|
||||
case JSOP_SETARG:
|
||||
|
@ -667,7 +666,7 @@ ImportExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
|
|||
MUST_MATCH_TOKEN(TOK_NAME, JSMSG_NO_IMPORT_NAME);
|
||||
pn = NewParseNode(cx, &ts->token, PN_NULLARY);
|
||||
if (!pn)
|
||||
return NULL;
|
||||
return NULL;
|
||||
pn->pn_op = JSOP_NAME;
|
||||
pn->pn_atom = ts->token.t_atom;
|
||||
pn->pn_slot = -1;
|
||||
|
@ -698,7 +697,7 @@ ImportExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
|
|||
/* Make a TOK_LB node. */
|
||||
pn2 = NewParseNode(cx, &ts->token, PN_BINARY);
|
||||
if (!pn2)
|
||||
return NULL;
|
||||
return NULL;
|
||||
pn3 = Expr(cx, ts, tc);
|
||||
if (!pn3)
|
||||
return NULL;
|
||||
|
@ -771,7 +770,7 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
|
|||
if (js_MatchToken(cx, ts, TOK_STAR)) {
|
||||
pn2 = NewParseNode(cx, &ts->token, PN_NULLARY);
|
||||
if (!pn2)
|
||||
return NULL;
|
||||
return NULL;
|
||||
PN_APPEND(pn, pn2);
|
||||
} else {
|
||||
do {
|
||||
|
@ -843,8 +842,8 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
|
|||
case TOK_SWITCH:
|
||||
{
|
||||
uintN newlines;
|
||||
JSParseNode *pn5, *pn6;
|
||||
JSBool seenDefault = JS_FALSE;
|
||||
JSParseNode *pn5;
|
||||
JSBool seenDefault = JS_FALSE;
|
||||
|
||||
pn = NewParseNode(cx, &ts->token, PN_BINARY);
|
||||
if (!pn)
|
||||
|
@ -878,27 +877,27 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
|
|||
JSMSG_TOO_MANY_DEFAULTS);
|
||||
goto bad_switch;
|
||||
}
|
||||
seenDefault = JS_TRUE;
|
||||
seenDefault = JS_TRUE;
|
||||
/* fall through */
|
||||
|
||||
case TOK_CASE:
|
||||
pn4 = NewParseNode(cx, &ts->token, PN_BINARY);
|
||||
if (!pn4)
|
||||
pn3 = NewParseNode(cx, &ts->token, PN_BINARY);
|
||||
if (!pn3)
|
||||
goto bad_switch;
|
||||
if (tt == TOK_DEFAULT) {
|
||||
pn4->pn_left = NULL;
|
||||
} else {
|
||||
pn4->pn_left = Expr(cx, ts, tc);
|
||||
if (!pn4->pn_left)
|
||||
goto bad_switch;
|
||||
}
|
||||
PN_APPEND(pn2, pn4);
|
||||
if (pn2->pn_count == PR_BIT(16)) {
|
||||
if (tt == TOK_DEFAULT) {
|
||||
pn3->pn_left = NULL;
|
||||
} else {
|
||||
pn3->pn_left = Expr(cx, ts, tc);
|
||||
if (!pn3->pn_left)
|
||||
goto bad_switch;
|
||||
}
|
||||
PN_APPEND(pn2, pn3);
|
||||
if (pn2->pn_count == PR_BIT(16)) {
|
||||
js_ReportCompileErrorNumber(cx, ts, JSREPORT_ERROR,
|
||||
JSMSG_TOO_MANY_CASES);
|
||||
goto bad_switch;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case TOK_ERROR:
|
||||
goto bad_switch;
|
||||
|
@ -910,23 +909,23 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
|
|||
}
|
||||
MUST_MATCH_TOKEN(TOK_COLON, JSMSG_COLON_AFTER_CASE);
|
||||
|
||||
pn5 = NewParseNode(cx, &ts->token, PN_LIST);
|
||||
if (!pn5)
|
||||
goto bad_switch;
|
||||
pn5->pn_type = TOK_LC;
|
||||
PN_INIT_LIST(pn5);
|
||||
pn4 = NewParseNode(cx, &ts->token, PN_LIST);
|
||||
if (!pn4)
|
||||
goto bad_switch;
|
||||
pn4->pn_type = TOK_LC;
|
||||
PN_INIT_LIST(pn4);
|
||||
while ((tt = js_PeekToken(cx, ts)) != TOK_RC &&
|
||||
tt != TOK_CASE && tt != TOK_DEFAULT) {
|
||||
if (tt == TOK_ERROR)
|
||||
goto bad_switch;
|
||||
pn6 = Statement(cx, ts, tc);
|
||||
if (!pn6)
|
||||
pn5 = Statement(cx, ts, tc);
|
||||
if (!pn5)
|
||||
goto bad_switch;
|
||||
pn5->pn_pos.end = pn6->pn_pos.end;
|
||||
PN_APPEND(pn5, pn6);
|
||||
pn4->pn_pos.end = pn5->pn_pos.end;
|
||||
PN_APPEND(pn4, pn5);
|
||||
}
|
||||
pn4->pn_pos.end = pn5->pn_pos.end;
|
||||
pn4->pn_right = pn5;
|
||||
pn3->pn_pos.end = pn4->pn_pos.end;
|
||||
pn3->pn_right = pn4;
|
||||
}
|
||||
|
||||
if (newlines)
|
||||
|
@ -934,14 +933,14 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
|
|||
js_PopStatement(tc);
|
||||
|
||||
pn->pn_pos.end = pn2->pn_pos.end = ts->token.pos.end;
|
||||
pn->pn_kid1 = pn1;
|
||||
pn->pn_kid2 = pn2;
|
||||
return pn;
|
||||
pn->pn_kid1 = pn1;
|
||||
pn->pn_kid2 = pn2;
|
||||
return pn;
|
||||
|
||||
bad_switch:
|
||||
if (newlines)
|
||||
SCAN_NEWLINES(ts);
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
#endif /* JS_HAS_SWITCH_STATEMENT */
|
||||
|
||||
|
@ -997,16 +996,16 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
|
|||
} else {
|
||||
/* Set pn1 to a var list or an initializing expression. */
|
||||
#if JS_HAS_IN_OPERATOR
|
||||
/*
|
||||
* Set the TCF_IN_FOR_INIT flag during parsing of the first clause
|
||||
* of the for statement. This flag will be used by the RelExpr
|
||||
* production; if it is set, then the 'in' keyword will not be
|
||||
* recognized as an operator, leaving it available to be parsed as
|
||||
* part of a for/in loop. A side effect of this restriction is
|
||||
* that (unparenthesized) expressions involving an 'in' operator
|
||||
* are illegal in the init clause of an ordinary for loop.
|
||||
*/
|
||||
tc->flags |= TCF_IN_FOR_INIT;
|
||||
/*
|
||||
* Set the TCF_IN_FOR_INIT flag during parsing of the first clause
|
||||
* of the for statement. This flag will be used by the RelExpr
|
||||
* production; if it is set, then the 'in' keyword will not be
|
||||
* recognized as an operator, leaving it available to be parsed as
|
||||
* part of a for/in loop. A side effect of this restriction is
|
||||
* that (unparenthesized) expressions involving an 'in' operator
|
||||
* are illegal in the init clause of an ordinary for loop.
|
||||
*/
|
||||
tc->flags |= TCF_IN_FOR_INIT;
|
||||
#endif /* JS_HAS_IN_OPERATOR */
|
||||
if (tt == TOK_VAR) {
|
||||
(void) js_GetToken(cx, ts);
|
||||
|
@ -1015,18 +1014,18 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
|
|||
pn1 = Expr(cx, ts, tc);
|
||||
}
|
||||
#if JS_HAS_IN_OPERATOR
|
||||
tc->flags &= ~TCF_IN_FOR_INIT;
|
||||
tc->flags &= ~TCF_IN_FOR_INIT;
|
||||
#endif /* JS_HAS_IN_OPERATOR */
|
||||
if (!pn1)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* We can be sure that if it's a for/in loop, there's still an 'in'
|
||||
* keyword here, even if Javascript recognizes it as an operator,
|
||||
* because we've excluded it from parsing by setting the
|
||||
* TCF_IN_FOR_INIT flag on the JSTreeContext argument.
|
||||
*/
|
||||
* We can be sure that if it's a for/in loop, there's still an 'in'
|
||||
* keyword here, even if Javascript recognizes it as an operator,
|
||||
* because we've excluded it from parsing by setting the
|
||||
* TCF_IN_FOR_INIT flag on the JSTreeContext argument.
|
||||
*/
|
||||
if (pn1 && js_MatchToken(cx, ts, TOK_IN)) {
|
||||
stmtInfo.type = STMT_FOR_IN_LOOP;
|
||||
|
||||
|
@ -1041,9 +1040,9 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
|
|||
}
|
||||
|
||||
/* Parse the object expression as the right operand of 'in'. */
|
||||
pn2 = NewBinary(cx, TOK_IN, JSOP_NOP, pn1, Expr(cx, ts, tc));
|
||||
if (!pn2)
|
||||
return NULL;
|
||||
pn2 = NewBinary(cx, TOK_IN, JSOP_NOP, pn1, Expr(cx, ts, tc));
|
||||
if (!pn2)
|
||||
return NULL;
|
||||
pn->pn_left = pn2;
|
||||
} else {
|
||||
/* Parse the loop condition or null into pn2. */
|
||||
|
@ -1201,11 +1200,11 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
|
|||
pn->pn_pos.end = pn2->pn_pos.end;
|
||||
if (pn->pn_pos.end.lineno == ts->lineno &&
|
||||
!WellTerminated(cx, ts, TOK_ERROR)) {
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
pn->pn_op = JSOP_THROW;
|
||||
pn->pn_kid = pn2;
|
||||
break;
|
||||
break;
|
||||
|
||||
/* TOK_CATCH and TOK_FINALLY are both handled in the TOK_TRY case */
|
||||
case TOK_CATCH:
|
||||
|
@ -1393,7 +1392,7 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
|
|||
|
||||
#if JS_HAS_DEBUGGER_KEYWORD
|
||||
case TOK_DEBUGGER:
|
||||
if(!WellTerminated(cx, ts, TOK_ERROR))
|
||||
if(!WellTerminated(cx, ts, TOK_ERROR))
|
||||
return NULL;
|
||||
pn = NewParseNode(cx, &ts->token, PN_NULLARY);
|
||||
if (!pn)
|
||||
|
@ -1434,7 +1433,7 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
|
|||
stmtInfo.label = label;
|
||||
pn = Statement(cx, ts, tc);
|
||||
if (!pn)
|
||||
return NULL;
|
||||
return NULL;
|
||||
|
||||
/* Pop the label, set pn_expr, and return early. */
|
||||
js_PopStatement(tc);
|
||||
|
@ -1444,7 +1443,7 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
|
|||
return pn2;
|
||||
}
|
||||
|
||||
/* Check explicity against (multi-line) function statement */
|
||||
/* Check explicity against (multi-line) function statement */
|
||||
if (pn2->pn_pos.end.lineno == ts->lineno &&
|
||||
!WellTerminated(cx, ts, lastExprType)) {
|
||||
return NULL;
|
||||
|
@ -1498,11 +1497,11 @@ Variables(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
|
|||
return NULL;
|
||||
clasp = OBJ_GET_CLASS(cx, obj);
|
||||
if (fun && clasp == &js_FunctionClass) {
|
||||
/* We are compiling code inside a function */
|
||||
/* We are compiling code inside a function */
|
||||
getter = js_GetLocalVariable;
|
||||
setter = js_SetLocalVariable;
|
||||
} else if (fun && clasp == &js_CallClass) {
|
||||
/* We are compiling code from an eval inside a function */
|
||||
/* We are compiling code from an eval inside a function */
|
||||
getter = js_GetCallVariable;
|
||||
setter = js_SetCallVariable;
|
||||
} else {
|
||||
|
@ -1546,25 +1545,25 @@ Variables(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
|
|||
PR_ASSERT(sprop->getter == js_GetLocalVariable);
|
||||
PR_ASSERT(JSVAL_IS_INT(sprop->id) &&
|
||||
JSVAL_TO_INT(sprop->id) < fun->nvars);
|
||||
} else if (clasp == &js_CallClass) {
|
||||
if (sprop->getter == js_GetCallVariable) {
|
||||
/*
|
||||
* Referencing a variable introduced by a var
|
||||
* statement in the enclosing function. Check
|
||||
* that the slot number we have is in range.
|
||||
*/
|
||||
} else if (clasp == &js_CallClass) {
|
||||
if (sprop->getter == js_GetCallVariable) {
|
||||
/*
|
||||
* Referencing a variable introduced by a var
|
||||
* statement in the enclosing function. Check
|
||||
* that the slot number we have is in range.
|
||||
*/
|
||||
PR_ASSERT(JSVAL_IS_INT(sprop->id) &&
|
||||
JSVAL_TO_INT(sprop->id) < fun->nvars);
|
||||
} else {
|
||||
/*
|
||||
* A variable introduced through another eval:
|
||||
* don't use the special getters and setters
|
||||
* since we can't allocate a slot in the frame.
|
||||
*/
|
||||
getter = sprop->getter;
|
||||
setter = sprop->setter;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* A variable introduced through another eval:
|
||||
* don't use the special getters and setters
|
||||
* since we can't allocate a slot in the frame.
|
||||
*/
|
||||
getter = sprop->getter;
|
||||
setter = sprop->setter;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Global var: (re-)set id a la js_DefineProperty. */
|
||||
sprop->id = ATOM_KEY(atom);
|
||||
|
@ -1575,22 +1574,22 @@ Variables(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
|
|||
sprop->attrs &= ~JSPROP_READONLY;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Property not found in current variable scope: we have not
|
||||
* seen this variable before.
|
||||
* Define a new variable by adding a property to the current
|
||||
* scope, or by allocating more slots in the function's frame.
|
||||
*/
|
||||
/*
|
||||
* Property not found in current variable scope: we have not
|
||||
* seen this variable before.
|
||||
* Define a new variable by adding a property to the current
|
||||
* scope, or by allocating more slots in the function's frame.
|
||||
*/
|
||||
sprop = NULL;
|
||||
if (prop) {
|
||||
OBJ_DROP_PROPERTY(cx, pobj, prop);
|
||||
prop = NULL;
|
||||
}
|
||||
if (getter == js_GetCallVariable) {
|
||||
/* Can't increase fun->nvars in an active frame! */
|
||||
getter = clasp->getProperty;
|
||||
setter = clasp->setProperty;
|
||||
}
|
||||
if (getter == js_GetCallVariable) {
|
||||
/* Can't increase fun->nvars in an active frame! */
|
||||
getter = clasp->getProperty;
|
||||
setter = clasp->setProperty;
|
||||
}
|
||||
ok = OBJ_DEFINE_PROPERTY(cx, obj, (jsid)atom, JSVAL_VOID,
|
||||
getter, setter,
|
||||
JSPROP_ENUMERATE | JSPROP_PERMANENT,
|
||||
|
@ -1598,14 +1597,14 @@ Variables(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
|
|||
if (ok && prop) {
|
||||
pobj = obj;
|
||||
if (getter == js_GetLocalVariable) {
|
||||
/*
|
||||
* Allocate more room for variables in the
|
||||
* function's frame. We can do this only
|
||||
* before the function is called.
|
||||
*/
|
||||
/*
|
||||
* Allocate more room for variables in the
|
||||
* function's frame. We can do this only
|
||||
* before the function is called.
|
||||
*/
|
||||
sprop = (JSScopeProperty *)prop;
|
||||
sprop->id = INT_TO_JSVAL(fun->nvars++);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1624,12 +1623,12 @@ Variables(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
|
|||
}
|
||||
|
||||
if (ok && fun && (clasp == &js_FunctionClass ||
|
||||
clasp == &js_CallClass) &&
|
||||
!InWithStatement(tc))
|
||||
{
|
||||
/* Depending on the value of the getter, change the
|
||||
* opcodes to the forms for arguments and variables.
|
||||
*/
|
||||
clasp == &js_CallClass) &&
|
||||
!InWithStatement(tc))
|
||||
{
|
||||
/* Depending on the value of the getter, change the
|
||||
* opcodes to the forms for arguments and variables.
|
||||
*/
|
||||
if (getter == js_GetArgument) {
|
||||
PR_ASSERT(sprop && JSVAL_IS_INT(sprop->id));
|
||||
pn2->pn_op = (pn2->pn_op == JSOP_NAME)
|
||||
|
@ -1637,14 +1636,14 @@ Variables(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
|
|||
: JSOP_SETARG;
|
||||
pn2->pn_slot = JSVAL_TO_INT(sprop->id);
|
||||
} else if (getter == js_GetLocalVariable ||
|
||||
getter == js_GetCallVariable)
|
||||
{
|
||||
getter == js_GetCallVariable)
|
||||
{
|
||||
PR_ASSERT(sprop && JSVAL_IS_INT(sprop->id));
|
||||
pn2->pn_op = (pn2->pn_op == JSOP_NAME)
|
||||
? JSOP_GETVAR
|
||||
: JSOP_SETVAR;
|
||||
pn2->pn_slot = JSVAL_TO_INT(sprop->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (prop)
|
||||
|
@ -1673,7 +1672,7 @@ Expr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
|
|||
do {
|
||||
pn2 = AssignExpr(cx, ts, tc);
|
||||
if (!pn2)
|
||||
return NULL;
|
||||
return NULL;
|
||||
PN_APPEND(pn, pn2);
|
||||
} while (js_MatchToken(cx, ts, TOK_COMMA));
|
||||
pn->pn_pos.end = PN_LAST(pn)->pn_pos.end;
|
||||
|
@ -1695,9 +1694,9 @@ LookupArgOrVar(JSContext *cx, JSAtom *atom, JSTreeContext *tc,
|
|||
obj = js_FindVariableScope(cx, &fun);
|
||||
clasp = OBJ_GET_CLASS(cx, obj);
|
||||
if (clasp != &js_FunctionClass && clasp != &js_CallClass)
|
||||
return JS_TRUE;
|
||||
return JS_TRUE;
|
||||
if (InWithStatement(tc))
|
||||
return JS_TRUE;
|
||||
return JS_TRUE;
|
||||
if (!js_LookupProperty(cx, obj, (jsid)atom, &pobj, (JSProperty **)&sprop))
|
||||
return JS_FALSE;
|
||||
*opp = JSOP_NAME;
|
||||
|
@ -1707,8 +1706,8 @@ LookupArgOrVar(JSContext *cx, JSAtom *atom, JSTreeContext *tc,
|
|||
*opp = JSOP_GETARG;
|
||||
*slotp = JSVAL_TO_INT(sprop->id);
|
||||
} else if (sprop->getter == js_GetLocalVariable ||
|
||||
sprop->getter == js_GetCallVariable)
|
||||
{
|
||||
sprop->getter == js_GetCallVariable)
|
||||
{
|
||||
*opp = JSOP_GETVAR;
|
||||
*slotp = JSVAL_TO_INT(sprop->id);
|
||||
}
|
||||
|
@ -1771,17 +1770,17 @@ CondExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
|
|||
if (!pn)
|
||||
return NULL;
|
||||
#if JS_HAS_IN_OPERATOR
|
||||
/*
|
||||
* Always accept the 'in' operator in the middle clause of a ternary,
|
||||
* where it's unambiguous, even if we might be parsing the init of a
|
||||
* for statement.
|
||||
*/
|
||||
oldflags = tc->flags;
|
||||
tc->flags &= ~TCF_IN_FOR_INIT;
|
||||
/*
|
||||
* Always accept the 'in' operator in the middle clause of a ternary,
|
||||
* where it's unambiguous, even if we might be parsing the init of a
|
||||
* for statement.
|
||||
*/
|
||||
oldflags = tc->flags;
|
||||
tc->flags &= ~TCF_IN_FOR_INIT;
|
||||
#endif /* JS_HAS_IN_OPERATOR */
|
||||
pn2 = AssignExpr(cx, ts, tc);
|
||||
#if JS_HAS_IN_OPERATOR
|
||||
tc->flags = oldflags;
|
||||
tc->flags = oldflags;
|
||||
#endif /* JS_HAS_IN_OPERATOR */
|
||||
|
||||
if (!pn2)
|
||||
|
@ -1889,10 +1888,10 @@ RelExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
|
|||
while (pn &&
|
||||
(js_MatchToken(cx, ts, TOK_RELOP)
|
||||
#if JS_HAS_IN_OPERATOR
|
||||
/*
|
||||
* Only recognize the 'in' token as an operator if we're not
|
||||
* currently in the init expr of a for loop.
|
||||
*/
|
||||
/*
|
||||
* Only recognize the 'in' token as an operator if we're not
|
||||
* currently in the init expr of a for loop.
|
||||
*/
|
||||
|| (inForInitFlag == 0 && js_MatchToken(cx, ts, TOK_IN))
|
||||
#endif /* JS_HAS_IN_OPERATOR */
|
||||
#if JS_HAS_INSTANCEOF
|
||||
|
@ -1972,7 +1971,7 @@ SetLvalKid(JSContext *cx, JSTokenStream *ts, JSParseNode *pn, JSParseNode *kid,
|
|||
kid->pn_type != TOK_LB) {
|
||||
js_ReportCompileErrorNumber(cx, ts, JSREPORT_ERROR,
|
||||
JSMSG_BAD_OPERAND, name);
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
pn->pn_kid = kid;
|
||||
return kid;
|
||||
|
@ -1990,7 +1989,7 @@ SetIncOpKid(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
|
|||
|
||||
kid = SetLvalKid(cx, ts, pn, kid, incop_name_str[tt == TOK_DEC]);
|
||||
if (!kid)
|
||||
return JS_FALSE;
|
||||
return JS_FALSE;
|
||||
num = -1;
|
||||
switch (kid->pn_type) {
|
||||
case TOK_NAME:
|
||||
|
@ -2098,9 +2097,9 @@ UnaryExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
|
|||
(void) js_GetToken(cx, ts);
|
||||
pn2 = NewParseNode(cx, &ts->token, PN_UNARY);
|
||||
if (!pn2)
|
||||
return NULL;
|
||||
return NULL;
|
||||
if (!SetIncOpKid(cx, ts, tc, pn2, pn, tt, JS_FALSE))
|
||||
return NULL;
|
||||
return NULL;
|
||||
pn2->pn_pos.begin = pn->pn_pos.begin;
|
||||
pn = pn2;
|
||||
}
|
||||
|
@ -2157,7 +2156,7 @@ MemberExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
|
|||
if (js_MatchToken(cx, ts, TOK_LP)) {
|
||||
pn = ArgumentList(cx, ts, tc, pn);
|
||||
if (!pn)
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
if (pn->pn_count - 1 >= ARGC_LIMIT) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
|
@ -2175,7 +2174,7 @@ MemberExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
|
|||
if (tt == TOK_DOT) {
|
||||
pn2 = NewParseNode(cx, &ts->token, PN_NAME);
|
||||
if (!pn2)
|
||||
return NULL;
|
||||
return NULL;
|
||||
MUST_MATCH_TOKEN(TOK_NAME, JSMSG_NAME_AFTER_DOT);
|
||||
pn2->pn_pos.begin = pn->pn_pos.begin;
|
||||
pn2->pn_pos.end = ts->token.pos.end;
|
||||
|
@ -2185,7 +2184,7 @@ MemberExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
|
|||
} else if (tt == TOK_LB) {
|
||||
pn2 = NewParseNode(cx, &ts->token, PN_BINARY);
|
||||
if (!pn2)
|
||||
return NULL;
|
||||
return NULL;
|
||||
pn3 = Expr(cx, ts, tc);
|
||||
if (!pn3)
|
||||
return NULL;
|
||||
|
@ -2209,13 +2208,13 @@ MemberExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
|
|||
} else if (allowCallSyntax && tt == TOK_LP) {
|
||||
pn2 = NewParseNode(cx, &ts->token, PN_LIST);
|
||||
if (!pn2)
|
||||
return NULL;
|
||||
return NULL;
|
||||
pn2->pn_op = JSOP_CALL;
|
||||
PN_INIT_LIST_1(pn2, pn);
|
||||
|
||||
pn2 = ArgumentList(cx, ts, tc, pn2);
|
||||
if (!pn2)
|
||||
return NULL;
|
||||
return NULL;
|
||||
if (pn2->pn_count - 1 >= ARGC_LIMIT) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_TOO_MANY_FUN_ARGS);
|
||||
|
@ -2230,7 +2229,7 @@ MemberExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
|
|||
pn = pn2;
|
||||
}
|
||||
if (tt == TOK_ERROR)
|
||||
return NULL;
|
||||
return NULL;
|
||||
return pn;
|
||||
}
|
||||
|
||||
|
@ -2306,7 +2305,7 @@ PrimaryExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
|
|||
pn2 = AssignExpr(cx, ts, tc);
|
||||
if (!pn2)
|
||||
return NULL;
|
||||
PN_APPEND(pn, pn2);
|
||||
PN_APPEND(pn, pn2);
|
||||
|
||||
if (!js_MatchToken(cx, ts, TOK_COMMA))
|
||||
break;
|
||||
|
@ -2339,7 +2338,7 @@ PrimaryExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
|
|||
case TOK_NUMBER:
|
||||
pn3 = NewParseNode(cx, &ts->token, PN_NULLARY);
|
||||
if (pn3)
|
||||
pn3->pn_dval = ts->token.t_dval;
|
||||
pn3->pn_dval = ts->token.t_dval;
|
||||
break;
|
||||
case TOK_NAME:
|
||||
case TOK_STRING:
|
||||
|
@ -2360,7 +2359,7 @@ PrimaryExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
|
|||
AssignExpr(cx, ts, tc));
|
||||
if (!pn2)
|
||||
return NULL;
|
||||
PN_APPEND(pn, pn2);
|
||||
PN_APPEND(pn, pn2);
|
||||
} while (js_MatchToken(cx, ts, TOK_COMMA));
|
||||
|
||||
MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_LIST);
|
||||
|
@ -2394,23 +2393,23 @@ PrimaryExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
|
|||
case TOK_LP:
|
||||
{
|
||||
#if JS_HAS_IN_OPERATOR
|
||||
uintN oldflags;
|
||||
uintN oldflags;
|
||||
#endif
|
||||
pn = NewParseNode(cx, &ts->token, PN_UNARY);
|
||||
if (!pn)
|
||||
return NULL;
|
||||
#if JS_HAS_IN_OPERATOR
|
||||
/*
|
||||
* Always accept the 'in' operator in a parenthesized expression,
|
||||
* where it's unambiguous, even if we might be parsing the init of a
|
||||
* for statement.
|
||||
*/
|
||||
oldflags = tc->flags;
|
||||
tc->flags &= ~TCF_IN_FOR_INIT;
|
||||
/*
|
||||
* Always accept the 'in' operator in a parenthesized expression,
|
||||
* where it's unambiguous, even if we might be parsing the init of a
|
||||
* for statement.
|
||||
*/
|
||||
oldflags = tc->flags;
|
||||
tc->flags &= ~TCF_IN_FOR_INIT;
|
||||
#endif /* JS_HAS_IN_OPERATOR */
|
||||
pn2 = Expr(cx, ts, tc);
|
||||
#if JS_HAS_IN_OPERATOR
|
||||
tc->flags = oldflags;
|
||||
tc->flags = oldflags;
|
||||
#endif /* JS_HAS_IN_OPERATOR */
|
||||
if (!pn2)
|
||||
return NULL;
|
||||
|
@ -2548,8 +2547,8 @@ js_FoldConstants(JSContext *cx, JSParseNode *pn)
|
|||
break;
|
||||
|
||||
case PN_NAME:
|
||||
pn1 = pn->pn_expr;
|
||||
if (pn1 && !js_FoldConstants(cx, pn1))
|
||||
pn1 = pn->pn_expr;
|
||||
if (pn1 && !js_FoldConstants(cx, pn1))
|
||||
return JS_FALSE;
|
||||
break;
|
||||
|
||||
|
@ -2688,20 +2687,20 @@ js_FoldConstants(JSContext *cx, JSParseNode *pn)
|
|||
if (!js_DoubleToECMAInt32(cx, d, &i))
|
||||
return JS_FALSE;
|
||||
d = ~i;
|
||||
break;
|
||||
break;
|
||||
|
||||
case JSOP_NEG:
|
||||
d = -d;
|
||||
break;
|
||||
break;
|
||||
|
||||
case JSOP_POS:
|
||||
break;
|
||||
break;
|
||||
|
||||
case JSOP_NOT:
|
||||
pn->pn_type = TOK_PRIMARY;
|
||||
pn->pn_op = (d == 0) ? JSOP_TRUE : JSOP_FALSE;
|
||||
pn->pn_arity = PN_NULLARY;
|
||||
/* FALL THROUGH */
|
||||
/* FALL THROUGH */
|
||||
|
||||
default:
|
||||
/* Return early to dodge the common TOK_NUMBER code. */
|
||||
|
|
|
@ -151,34 +151,34 @@ struct JSParseNode {
|
|||
JSParseNodeArity pn_arity;
|
||||
union {
|
||||
struct { /* TOK_FUNCTION node */
|
||||
JSFunction *fun; /* function object private data */
|
||||
JSParseNode *body; /* TOK_LC list of statements */
|
||||
JSFunction *fun; /* function object private data */
|
||||
JSParseNode *body; /* TOK_LC list of statements */
|
||||
uint32 tryCount; /* try statement count */
|
||||
} func;
|
||||
struct { /* list of next-linked nodes */
|
||||
struct { /* list of next-linked nodes */
|
||||
JSParseNode *head; /* first node in list */
|
||||
JSParseNode **tail; /* ptr to ptr to last node in list */
|
||||
uint32 count; /* number of nodes in list */
|
||||
JSBool extra; /* extra comma flag for [1,2,,] */
|
||||
} list;
|
||||
struct { /* ternary: if, for(;;), ?: */
|
||||
JSParseNode *kid1; /* condition, discriminant, etc. */
|
||||
JSParseNode *kid2; /* then-part, case list, etc. */
|
||||
JSParseNode *kid3; /* else-part, default case, etc. */
|
||||
} list;
|
||||
struct { /* ternary: if, for(;;), ?: */
|
||||
JSParseNode *kid1; /* condition, discriminant, etc. */
|
||||
JSParseNode *kid2; /* then-part, case list, etc. */
|
||||
JSParseNode *kid3; /* else-part, default case, etc. */
|
||||
} ternary;
|
||||
struct { /* two kids if binary */
|
||||
JSParseNode *left;
|
||||
JSParseNode *right;
|
||||
struct { /* two kids if binary */
|
||||
JSParseNode *left;
|
||||
JSParseNode *right;
|
||||
jsval val; /* switch case value */
|
||||
} binary;
|
||||
struct { /* one kid if unary */
|
||||
JSParseNode *kid;
|
||||
jsint num; /* -1 or arg or local/sharp var num */
|
||||
} unary;
|
||||
struct { /* name, labeled statement, etc. */
|
||||
JSAtom *atom; /* name or label atom, null if slot */
|
||||
JSParseNode *expr; /* object or initializer */
|
||||
jsint slot; /* -1 or arg or local var slot */
|
||||
} binary;
|
||||
struct { /* one kid if unary */
|
||||
JSParseNode *kid;
|
||||
jsint num; /* -1 or arg or local/sharp var num */
|
||||
} unary;
|
||||
struct { /* name, labeled statement, etc. */
|
||||
JSAtom *atom; /* name or label atom, null if slot */
|
||||
JSParseNode *expr; /* object or initializer */
|
||||
jsint slot; /* -1 or arg or local var slot */
|
||||
} name;
|
||||
jsdouble dval; /* aligned numeric literal value */
|
||||
} pn_u;
|
||||
|
@ -214,16 +214,16 @@ struct JSParseNode {
|
|||
|
||||
#define PN_INIT_LIST(list) \
|
||||
PR_BEGIN_MACRO \
|
||||
(list)->pn_head = NULL; \
|
||||
(list)->pn_tail = &(list)->pn_head; \
|
||||
(list)->pn_count = 0; \
|
||||
(list)->pn_head = NULL; \
|
||||
(list)->pn_tail = &(list)->pn_head; \
|
||||
(list)->pn_count = 0; \
|
||||
PR_END_MACRO
|
||||
|
||||
#define PN_INIT_LIST_1(list, pn) \
|
||||
PR_BEGIN_MACRO \
|
||||
(list)->pn_head = (pn); \
|
||||
(list)->pn_tail = &(pn)->pn_next; \
|
||||
(list)->pn_count = 1; \
|
||||
(list)->pn_head = (pn); \
|
||||
(list)->pn_tail = &(pn)->pn_next; \
|
||||
(list)->pn_count = 1; \
|
||||
PR_END_MACRO
|
||||
|
||||
#define PN_APPEND(list, pn) \
|
||||
|
|
|
@ -194,8 +194,8 @@ typedef JSBool
|
|||
*/
|
||||
typedef JSBool
|
||||
(* CRT_CALL JSNewEnumerateOp)(JSContext *cx, JSObject *obj,
|
||||
JSIterateOp enum_op,
|
||||
jsval *statep, jsid *idp);
|
||||
JSIterateOp enum_op,
|
||||
jsval *statep, jsid *idp);
|
||||
|
||||
typedef JSBool
|
||||
(* CRT_CALL JSEnumerateOp)(JSContext *cx, JSObject *obj);
|
||||
|
@ -295,7 +295,7 @@ typedef struct JSErrorFormatString {
|
|||
const uintN argCount;
|
||||
} JSErrorFormatString;
|
||||
|
||||
typedef const JSErrorFormatString *
|
||||
typedef const JSErrorFormatString *
|
||||
(* CRT_CALL JSErrorCallback)(void *userRef, const char *locale,
|
||||
const uintN errorNumber);
|
||||
|
||||
|
|
|
@ -139,17 +139,17 @@ struct RENode {
|
|||
RENode *next; /* next in concatenation order */
|
||||
void *kid; /* first operand */
|
||||
union {
|
||||
void *kid2; /* second operand */
|
||||
jsint num; /* could be a number */
|
||||
jschar chr; /* or a character */
|
||||
struct { /* or a quantifier range */
|
||||
uint16 min;
|
||||
uint16 max;
|
||||
} range;
|
||||
struct { /* or a Unicode character class */
|
||||
uint16 kidlen; /* length of string at kid, in jschars */
|
||||
uint16 bmsize; /* bitmap size, based on max char code */
|
||||
} ucclass;
|
||||
void *kid2; /* second operand */
|
||||
jsint num; /* could be a number */
|
||||
jschar chr; /* or a character */
|
||||
struct { /* or a quantifier range */
|
||||
uint16 min;
|
||||
uint16 max;
|
||||
} range;
|
||||
struct { /* or a Unicode character class */
|
||||
uint16 kidlen; /* length of string at kid, in jschars */
|
||||
uint16 bmsize; /* bitmap size, based on max char code */
|
||||
} ucclass;
|
||||
} u;
|
||||
};
|
||||
|
||||
|
@ -649,18 +649,16 @@ loop:
|
|||
case '{':
|
||||
c = *++cp;
|
||||
if (!JS7_ISDEC(c)) {
|
||||
JS_ReportErrorNumber(state->context,
|
||||
js_GetErrorMessage, NULL,
|
||||
JSMSG_BAD_QUANTIFIER, state->cp);
|
||||
JS_ReportErrorNumber(state->context, js_GetErrorMessage, NULL,
|
||||
JSMSG_BAD_QUANTIFIER, state->cp);
|
||||
return NULL;
|
||||
}
|
||||
min = (uint32)JS7_UNDEC(c);
|
||||
for (c = *++cp; JS7_ISDEC(c); c = *++cp) {
|
||||
min = 10 * min + (uint32)JS7_UNDEC(c);
|
||||
if (min >> 16) {
|
||||
JS_ReportErrorNumber(state->context,
|
||||
js_GetErrorMessage, NULL,
|
||||
JSMSG_MIN_TOO_BIG, state->cp);
|
||||
JS_ReportErrorNumber(state->context, js_GetErrorMessage, NULL,
|
||||
JSMSG_MIN_TOO_BIG, state->cp);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
@ -671,18 +669,18 @@ loop:
|
|||
for (c = *++cp; JS7_ISDEC(c); c = *++cp) {
|
||||
max = 10 * max + (uint32)JS7_UNDEC(c);
|
||||
if (max >> 16) {
|
||||
JS_ReportErrorNumber(state->context,
|
||||
js_GetErrorMessage, NULL,
|
||||
JSMSG_MAX_TOO_BIG, up);
|
||||
JS_ReportErrorNumber(state->context,
|
||||
js_GetErrorMessage, NULL,
|
||||
JSMSG_MAX_TOO_BIG, up);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (max == 0)
|
||||
goto zero_quant;
|
||||
if (min > max) {
|
||||
JS_ReportErrorNumber(state->context,
|
||||
js_GetErrorMessage, NULL,
|
||||
JSMSG_OUT_OF_ORDER, up);
|
||||
JS_ReportErrorNumber(state->context,
|
||||
js_GetErrorMessage, NULL,
|
||||
JSMSG_OUT_OF_ORDER, up);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
|
@ -693,17 +691,15 @@ loop:
|
|||
/* Exactly n times. */
|
||||
if (min == 0) {
|
||||
zero_quant:
|
||||
JS_ReportErrorNumber(state->context,
|
||||
js_GetErrorMessage, NULL,
|
||||
JSMSG_ZERO_QUANTIFIER, state->cp);
|
||||
JS_ReportErrorNumber(state->context, js_GetErrorMessage, NULL,
|
||||
JSMSG_ZERO_QUANTIFIER, state->cp);
|
||||
return NULL;
|
||||
}
|
||||
max = min;
|
||||
}
|
||||
if (*cp != '}') {
|
||||
JS_ReportErrorNumber(state->context,
|
||||
js_GetErrorMessage, NULL,
|
||||
JSMSG_UNTERM_QUANTIFIER, state->cp);
|
||||
JS_ReportErrorNumber(state->context, js_GetErrorMessage, NULL,
|
||||
JSMSG_UNTERM_QUANTIFIER, state->cp);
|
||||
return NULL;
|
||||
}
|
||||
cp++;
|
||||
|
@ -720,9 +716,8 @@ loop:
|
|||
|
||||
case '*':
|
||||
if (!(ren->flags & RENODE_NONEMPTY)) {
|
||||
JS_ReportErrorNumber(state->context,
|
||||
js_GetErrorMessage, NULL,
|
||||
JSMSG_EMPTY_BEFORE_STAR);
|
||||
JS_ReportErrorNumber(state->context, js_GetErrorMessage, NULL,
|
||||
JSMSG_EMPTY_BEFORE_STAR);
|
||||
return NULL;
|
||||
}
|
||||
cp++;
|
||||
|
@ -731,9 +726,8 @@ loop:
|
|||
|
||||
case '+':
|
||||
if (!(ren->flags & RENODE_NONEMPTY)) {
|
||||
JS_ReportErrorNumber(state->context,
|
||||
js_GetErrorMessage, NULL,
|
||||
JSMSG_EMPTY_BEFORE_PLUS);
|
||||
JS_ReportErrorNumber(state->context, js_GetErrorMessage, NULL,
|
||||
JSMSG_EMPTY_BEFORE_PLUS);
|
||||
return NULL;
|
||||
}
|
||||
cp++;
|
||||
|
@ -815,9 +809,8 @@ ParseAtom(CompilerState *state)
|
|||
return NULL;
|
||||
cp = state->cp;
|
||||
if (*cp != ')') {
|
||||
JS_ReportErrorNumber(state->context,
|
||||
js_GetErrorMessage, NULL,
|
||||
JSMSG_MISSING_PAREN, ocp);
|
||||
JS_ReportErrorNumber(state->context, js_GetErrorMessage, NULL,
|
||||
JSMSG_MISSING_PAREN, ocp);
|
||||
return NULL;
|
||||
}
|
||||
cp++;
|
||||
|
@ -857,9 +850,8 @@ ParseAtom(CompilerState *state)
|
|||
while ((c = *++cp) != ']') {
|
||||
if (c == 0) {
|
||||
bad_cclass:
|
||||
JS_ReportErrorNumber(state->context,
|
||||
js_GetErrorMessage, NULL,
|
||||
JSMSG_UNTERM_CLASS, ocp);
|
||||
JS_ReportErrorNumber(state->context, js_GetErrorMessage, NULL,
|
||||
JSMSG_UNTERM_CLASS, ocp);
|
||||
return NULL;
|
||||
}
|
||||
if (c == '\\' && cp[1] != 0)
|
||||
|
@ -875,9 +867,8 @@ ParseAtom(CompilerState *state)
|
|||
c = *++cp;
|
||||
switch (c) {
|
||||
case 0:
|
||||
JS_ReportErrorNumber(state->context,
|
||||
js_GetErrorMessage, NULL,
|
||||
JSMSG_TRAILING_SLASH);
|
||||
JS_ReportErrorNumber(state->context, js_GetErrorMessage, NULL,
|
||||
JSMSG_TRAILING_SLASH);
|
||||
return NULL;
|
||||
|
||||
case 'f':
|
||||
|
@ -1055,13 +1046,13 @@ CountFirstChars(RENode *alt)
|
|||
switch (REOP(kid)) {
|
||||
case REOP_QUANT:
|
||||
if (kid->u.range.min == 0)
|
||||
return -1;
|
||||
return -1;
|
||||
/* FALL THROUGH */
|
||||
case REOP_PLUS:
|
||||
case REOP_ALT:
|
||||
sublen = CountFirstChars(kid);
|
||||
if (sublen < 0)
|
||||
return sublen;
|
||||
return sublen;
|
||||
len += sublen;
|
||||
break;
|
||||
case REOP_FLAT:
|
||||
|
@ -1072,7 +1063,7 @@ CountFirstChars(RENode *alt)
|
|||
count_char:
|
||||
/* Only '\\' and '-' need escaping within a character class. */
|
||||
if (c == '\\' || c == '-')
|
||||
len += 2;
|
||||
len += 2;
|
||||
else
|
||||
len++;
|
||||
break;
|
||||
|
@ -1267,8 +1258,8 @@ AnchorRegExp(CompilerState *state, RENode *ren)
|
|||
goto do_first_char;
|
||||
|
||||
case REOP_FLAT1:
|
||||
cp = &ren2->u.chr;
|
||||
op = REOP_FLAT1;
|
||||
cp = &ren2->u.chr;
|
||||
op = REOP_FLAT1;
|
||||
goto do_first_char;
|
||||
|
||||
case REOP_DOTSTAR:
|
||||
|
@ -1538,7 +1529,7 @@ OptimizeRegExp(CompilerState *state, RENode *ren)
|
|||
JS7_ISHEX(cp[1]) && JS7_ISHEX(cp[2]) &&
|
||||
JS7_ISHEX(cp[3]) && JS7_ISHEX(cp[4])) {
|
||||
c = (((((JS7_UNHEX(cp[1]) << 4)
|
||||
+ JS7_UNHEX(cp[2])) << 4)
|
||||
+ JS7_UNHEX(cp[2])) << 4)
|
||||
+ JS7_UNHEX(cp[3])) << 4)
|
||||
+ JS7_UNHEX(cp[4]);
|
||||
cp += 5;
|
||||
|
@ -1849,8 +1840,8 @@ EmitRegExp(CompilerState *state, RENode *ren, JSRegExp *re)
|
|||
if (inrange) {
|
||||
if (lastc > c) {
|
||||
JS_ReportErrorNumber(state->context,
|
||||
js_GetErrorMessage, NULL,
|
||||
JSMSG_BAD_CLASS_RANGE);
|
||||
js_GetErrorMessage, NULL,
|
||||
JSMSG_BAD_CLASS_RANGE);
|
||||
return JS_FALSE;
|
||||
}
|
||||
inrange = JS_FALSE;
|
||||
|
@ -2010,17 +2001,17 @@ js_NewRegExp(JSContext *cx, JSString *str, uintN flags)
|
|||
|
||||
#ifdef DEBUG_notme
|
||||
{
|
||||
/* print the compiled regexp program bytecode */
|
||||
size_t i;
|
||||
for (i = 0; i < state.progLength; i++) {
|
||||
int b = (int) re->program[i];
|
||||
fprintf(stderr, "%d", b);
|
||||
if ((i > 0 && i % 8 == 0) || i == state.progLength-1)
|
||||
fprintf(stderr, "\n");
|
||||
else
|
||||
fprintf(stderr, ", ");
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
/* print the compiled regexp program bytecode */
|
||||
size_t i;
|
||||
for (i = 0; i < state.progLength; i++) {
|
||||
int b = (int) re->program[i];
|
||||
fprintf(stderr, "%d", b);
|
||||
if ((i > 0 && i % 8 == 0) || i == state.progLength-1)
|
||||
fprintf(stderr, "\n");
|
||||
else
|
||||
fprintf(stderr, ", ");
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -2050,10 +2041,10 @@ js_NewRegExpOpt(JSContext *cx, JSString *str, JSString *opt)
|
|||
default: {
|
||||
char charBuf[2] = " ";
|
||||
charBuf[0] = (char)*cp;
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_BAD_FLAG, charBuf);
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_BAD_FLAG, charBuf);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2294,7 +2285,7 @@ MatchRegExp(MatchState *state, jsbytecode *pc, const jschar *cp)
|
|||
matched = (cp != cpend && *cp != '\n'); \
|
||||
matchlen = 1; \
|
||||
break; \
|
||||
\
|
||||
\
|
||||
NONDOT_SINGLE_CASES \
|
||||
/* END SINGLE_CASES */
|
||||
|
||||
|
@ -2312,65 +2303,65 @@ MatchRegExp(MatchState *state, jsbytecode *pc, const jschar *cp)
|
|||
} \
|
||||
matchlen = 1; \
|
||||
break; \
|
||||
\
|
||||
\
|
||||
case REOP_DIGIT: \
|
||||
matched = JS_ISDIGIT(*cp); \
|
||||
matchlen = 1; \
|
||||
break; \
|
||||
\
|
||||
\
|
||||
case REOP_NONDIGIT: \
|
||||
matched = !JS_ISDIGIT(*cp); \
|
||||
matchlen = 1; \
|
||||
break; \
|
||||
\
|
||||
\
|
||||
case REOP_ALNUM: \
|
||||
matched = JS_ISWORD(*cp); \
|
||||
matchlen = 1; \
|
||||
break; \
|
||||
\
|
||||
\
|
||||
case REOP_NONALNUM: \
|
||||
matched = !JS_ISWORD(*cp); \
|
||||
matchlen = 1; \
|
||||
break; \
|
||||
\
|
||||
\
|
||||
case REOP_SPACE: \
|
||||
matched = JS_ISSPACE(*cp); \
|
||||
matchlen = 1; \
|
||||
break; \
|
||||
\
|
||||
\
|
||||
case REOP_NONSPACE: \
|
||||
matched = !JS_ISSPACE(*cp); \
|
||||
matchlen = 1; \
|
||||
break; \
|
||||
\
|
||||
\
|
||||
case REOP_FLAT1: \
|
||||
c = *cp; \
|
||||
c2 = (jschar)pc[1]; \
|
||||
matched = (c == c2); \
|
||||
matchlen = 1; \
|
||||
break; \
|
||||
\
|
||||
\
|
||||
case REOP_FLAT1i: \
|
||||
c = *cp; \
|
||||
c2 = (jschar)pc[1]; \
|
||||
matched = MATCH_CHARS_IGNORING_CASE(c, c2); \
|
||||
matchlen = 1; \
|
||||
break; \
|
||||
\
|
||||
\
|
||||
case REOP_UCFLAT1: \
|
||||
c = *cp; \
|
||||
c2 = ((pc[1] << 8) | pc[2]); \
|
||||
matched = (c == c2); \
|
||||
matchlen = 1; \
|
||||
break; \
|
||||
\
|
||||
\
|
||||
case REOP_UCFLAT1i: \
|
||||
c = *cp; \
|
||||
c2 = ((pc[1] << 8) | pc[2]); \
|
||||
matched = MATCH_CHARS_IGNORING_CASE(c, c2); \
|
||||
matchlen = 1; \
|
||||
break; \
|
||||
\
|
||||
\
|
||||
case REOP_UCCLASS: \
|
||||
case REOP_NUCCLASS: \
|
||||
size = (pc[1] << 8) | pc[2]; \
|
||||
|
@ -3083,7 +3074,7 @@ JSClass js_RegExpClass = {
|
|||
|
||||
static JSBool
|
||||
regexp_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
||||
jsval *rval)
|
||||
jsval *rval)
|
||||
{
|
||||
JSBool ok;
|
||||
JSRegExp *re;
|
||||
|
@ -3098,7 +3089,7 @@ regexp_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
|||
JS_LOCK_OBJ(cx, obj);
|
||||
re = JS_GetPrivate(cx, obj);
|
||||
if (!re) {
|
||||
*rval = STRING_TO_JSVAL(cx->runtime->emptyString);
|
||||
*rval = STRING_TO_JSVAL(cx->runtime->emptyString);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -3197,16 +3188,16 @@ regexp_exec_sub(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
|||
return JS_FALSE;
|
||||
re = JS_GetPrivate(cx, obj);
|
||||
if (!re)
|
||||
return JS_TRUE;
|
||||
return JS_TRUE;
|
||||
ok = locked = JS_FALSE;
|
||||
if (argc == 0) {
|
||||
str = cx->regExpStatics.input;
|
||||
if (!str) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_NO_INPUT,
|
||||
JS_GetStringBytes(re->source),
|
||||
(re->flags & JSREG_GLOB) ? "g" : "",
|
||||
(re->flags & JSREG_FOLD) ? "i" : "");
|
||||
JSMSG_NO_INPUT,
|
||||
JS_GetStringBytes(re->source),
|
||||
(re->flags & JSREG_GLOB) ? "g" : "",
|
||||
(re->flags & JSREG_FOLD) ? "i" : "");
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
|
@ -3263,8 +3254,8 @@ RegExp(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
{
|
||||
/* If not constructing, replace obj with a new RegExp object. */
|
||||
if (!cx->fp->constructing) {
|
||||
obj = js_NewObject(cx, &js_RegExpClass, NULL, NULL);
|
||||
if (!obj)
|
||||
obj = js_NewObject(cx, &js_RegExpClass, NULL, NULL);
|
||||
if (!obj)
|
||||
return JS_FALSE;
|
||||
}
|
||||
return regexp_compile(cx, obj, argc, argv, rval);
|
||||
|
|
139
js/ref/jsscan.c
139
js/ref/jsscan.c
|
@ -150,7 +150,7 @@ js_InitScanner(JSContext *cx)
|
|||
if (!atom)
|
||||
return JS_FALSE;
|
||||
atom->kwindex = (JSVERSION_IS_ECMA(cx->version)
|
||||
|| kw->version <= cx->version) ? kw - keywords : -1;
|
||||
|| kw->version <= cx->version) ? kw - keywords : -1;
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
@ -177,7 +177,7 @@ js_NewTokenStream(JSContext *cx, const jschar *base, size_t length,
|
|||
ts->filename = filename;
|
||||
ts->lineno = lineno;
|
||||
if (principals)
|
||||
JSPRINCIPALS_HOLD(cx, principals);
|
||||
JSPRINCIPALS_HOLD(cx, principals);
|
||||
ts->principals = principals;
|
||||
return ts;
|
||||
}
|
||||
|
@ -217,7 +217,7 @@ js_NewFileTokenStream(JSContext *cx, const char *filename, FILE *defaultfp)
|
|||
|
||||
PR_ARENA_ALLOCATE(base, &cx->tempPool, JS_LINE_LIMIT * sizeof(jschar));
|
||||
if (!base)
|
||||
return NULL;
|
||||
return NULL;
|
||||
ts = js_NewBufferTokenStream(cx, base, JS_LINE_LIMIT);
|
||||
if (!ts)
|
||||
return NULL;
|
||||
|
@ -226,8 +226,8 @@ js_NewFileTokenStream(JSContext *cx, const char *filename, FILE *defaultfp)
|
|||
} else {
|
||||
file = fopen(filename, "r");
|
||||
if (!file) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_CANT_OPEN, filename, strerror(errno));
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_OPEN,
|
||||
filename, strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
@ -242,7 +242,7 @@ JS_FRIEND_API(JSBool)
|
|||
js_CloseTokenStream(JSContext *cx, JSTokenStream *ts)
|
||||
{
|
||||
if (ts->principals)
|
||||
JSPRINCIPALS_DROP(cx, ts->principals);
|
||||
JSPRINCIPALS_DROP(cx, ts->principals);
|
||||
#ifdef JSFILE
|
||||
return !ts->file || fclose(ts->file) == 0;
|
||||
#else
|
||||
|
@ -255,39 +255,39 @@ static void
|
|||
SendSourceToJSDebugger(JSTokenStream *ts, jschar *str, size_t length)
|
||||
{
|
||||
if (!ts->jsdsrc) {
|
||||
const char* filename = ts->filename ? ts->filename : "typein";
|
||||
const char* filename = ts->filename ? ts->filename : "typein";
|
||||
|
||||
if (1 == ts->lineno) {
|
||||
ts->jsdsrc = JSD_NewSourceText(ts->jsdc, filename);
|
||||
} else {
|
||||
ts->jsdsrc = JSD_FindSourceForURL(ts->jsdc, filename);
|
||||
if (ts->jsdsrc && JSD_SOURCE_PARTIAL !=
|
||||
JSD_GetSourceStatus(ts->jsdc, ts->jsdsrc)) {
|
||||
ts->jsdsrc = NULL;
|
||||
}
|
||||
}
|
||||
if (1 == ts->lineno) {
|
||||
ts->jsdsrc = JSD_NewSourceText(ts->jsdc, filename);
|
||||
} else {
|
||||
ts->jsdsrc = JSD_FindSourceForURL(ts->jsdc, filename);
|
||||
if (ts->jsdsrc && JSD_SOURCE_PARTIAL !=
|
||||
JSD_GetSourceStatus(ts->jsdc, ts->jsdsrc)) {
|
||||
ts->jsdsrc = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ts->jsdsrc) {
|
||||
/* here we convert our Unicode into a C string to pass to JSD */
|
||||
/* here we convert our Unicode into a C string to pass to JSD */
|
||||
#define JSD_BUF_SIZE 1024
|
||||
static char* buf = NULL;
|
||||
int remaining = length;
|
||||
static char* buf = NULL;
|
||||
int remaining = length;
|
||||
|
||||
if (!buf)
|
||||
buf = malloc(JSD_BUF_SIZE);
|
||||
if (buf)
|
||||
{
|
||||
while (remaining && ts->jsdsrc) {
|
||||
int bytes = PR_MIN(remaining, JSD_BUF_SIZE);
|
||||
int i;
|
||||
for (i = 0; i < bytes; i++)
|
||||
buf[i] = (const char) *(str++);
|
||||
ts->jsdsrc = JSD_AppendSourceText(ts->jsdc,ts->jsdsrc,
|
||||
buf, bytes,
|
||||
JSD_SOURCE_PARTIAL);
|
||||
remaining -= bytes;
|
||||
}
|
||||
}
|
||||
if (!buf)
|
||||
buf = malloc(JSD_BUF_SIZE);
|
||||
if (buf)
|
||||
{
|
||||
while (remaining && ts->jsdsrc) {
|
||||
int bytes = PR_MIN(remaining, JSD_BUF_SIZE);
|
||||
int i;
|
||||
for (i = 0; i < bytes; i++)
|
||||
buf[i] = (const char) *(str++);
|
||||
ts->jsdsrc = JSD_AppendSourceText(ts->jsdc,ts->jsdsrc,
|
||||
buf, bytes,
|
||||
JSD_SOURCE_PARTIAL);
|
||||
remaining -= bytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -486,7 +486,7 @@ MatchChar(JSTokenStream *ts, int32 nextChar)
|
|||
|
||||
void
|
||||
js_ReportCompileError(JSContext *cx, JSTokenStream *ts, uintN flags,
|
||||
const char *format, ...)
|
||||
const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char *message;
|
||||
|
@ -521,20 +521,20 @@ js_ReportCompileError(JSContext *cx, JSTokenStream *ts, uintN flags,
|
|||
: NULL;
|
||||
report.uclinebuf = ts->linebuf.base;
|
||||
report.uctokenptr = ts->token.ptr;
|
||||
report.flags = flags;
|
||||
report.flags = flags;
|
||||
(*onError)(cx, message, &report);
|
||||
#if !defined XP_PC || !defined _MSC_VER || _MSC_VER > 800
|
||||
} else {
|
||||
if (!(ts->flags & TSF_INTERACTIVE))
|
||||
fprintf(stderr, "JavaScript %s: ",
|
||||
JSREPORT_IS_WARNING(flags) ? "warning" : "error");
|
||||
JSREPORT_IS_WARNING(flags) ? "warning" : "error");
|
||||
if (ts->filename)
|
||||
fprintf(stderr, "%s, ", ts->filename);
|
||||
if (ts->lineno)
|
||||
fprintf(stderr, "line %u: ", ts->lineno);
|
||||
fprintf(stderr, "%s:\n%s\n",message,
|
||||
js_DeflateString(cx, ts->linebuf.base,
|
||||
ts->linebuf.limit - ts->linebuf.base));
|
||||
js_DeflateString(cx, ts->linebuf.base,
|
||||
ts->linebuf.limit - ts->linebuf.base));
|
||||
#endif
|
||||
}
|
||||
if (lastc == '\n')
|
||||
|
@ -544,7 +544,7 @@ js_ReportCompileError(JSContext *cx, JSTokenStream *ts, uintN flags,
|
|||
|
||||
void
|
||||
js_ReportCompileErrorNumber(JSContext *cx, JSTokenStream *ts, uintN flags,
|
||||
const uintN errorNumber, ...)
|
||||
const uintN errorNumber, ...)
|
||||
{
|
||||
va_list ap;
|
||||
jschar *limit, lastc;
|
||||
|
@ -559,9 +559,9 @@ js_ReportCompileErrorNumber(JSContext *cx, JSTokenStream *ts, uintN flags,
|
|||
message = NULL;
|
||||
|
||||
va_start(ap, errorNumber);
|
||||
if (!js_ExpandErrorArguments(cx, js_GetErrorMessage, NULL,
|
||||
errorNumber, &message, &report, ap))
|
||||
return;
|
||||
if (!js_ExpandErrorArguments(cx, js_GetErrorMessage, NULL,
|
||||
errorNumber, &message, &report, ap))
|
||||
return;
|
||||
va_end(ap);
|
||||
|
||||
PR_ASSERT(ts->linebuf.limit < ts->linebuf.base + JS_LINE_LIMIT);
|
||||
|
@ -582,24 +582,24 @@ js_ReportCompileErrorNumber(JSContext *cx, JSTokenStream *ts, uintN flags,
|
|||
: NULL;
|
||||
report.uclinebuf = ts->linebuf.base;
|
||||
report.uctokenptr = ts->token.ptr;
|
||||
report.flags = flags;
|
||||
report.flags = flags;
|
||||
|
||||
#if JS_HAS_ERROR_EXCEPTIONS
|
||||
/*
|
||||
* If there's a runtime exception type associated with this error
|
||||
* number, set that as the pending exception. For errors occuring at
|
||||
* compile time, this is very likely to be a JSEXN_SYNTAXERR. If an
|
||||
* exception is thrown, then the JSREPORT_EXCEPTION flag will be set in
|
||||
* report.flags. Proper behavior for error reporters is probably to
|
||||
* ignore this for all but toplevel compilation errors.
|
||||
/*
|
||||
* If there's a runtime exception type associated with this error
|
||||
* number, set that as the pending exception. For errors occuring at
|
||||
* compile time, this is very likely to be a JSEXN_SYNTAXERR. If an
|
||||
* exception is thrown, then the JSREPORT_EXCEPTION flag will be set in
|
||||
* report.flags. Proper behavior for error reporters is probably to
|
||||
* ignore this for all but toplevel compilation errors.
|
||||
|
||||
* XXXmccabe it's still at issue if there's a public API to distinguish
|
||||
* between toplevel compilation and other types.
|
||||
* XXXmccabe it's still at issue if there's a public API to distinguish
|
||||
* between toplevel compilation and other types.
|
||||
|
||||
* XXX it'd probably be best if there was only one call to this
|
||||
* function, but there seem to be two error reporter call points.
|
||||
*/
|
||||
(void)js_ErrorToException(cx, &report, message);
|
||||
* XXX it'd probably be best if there was only one call to this
|
||||
* function, but there seem to be two error reporter call points.
|
||||
*/
|
||||
(void)js_ErrorToException(cx, &report, message);
|
||||
#endif
|
||||
|
||||
(*onError)(cx, message, &report);
|
||||
|
@ -608,14 +608,14 @@ js_ReportCompileErrorNumber(JSContext *cx, JSTokenStream *ts, uintN flags,
|
|||
} else {
|
||||
if (!(ts->flags & TSF_INTERACTIVE))
|
||||
fprintf(stderr, "JavaScript %s: ",
|
||||
JSREPORT_IS_WARNING(flags) ? "warning" : "error");
|
||||
JSREPORT_IS_WARNING(flags) ? "warning" : "error");
|
||||
if (ts->filename)
|
||||
fprintf(stderr, "%s, ", ts->filename);
|
||||
if (ts->lineno)
|
||||
fprintf(stderr, "line %u: ", ts->lineno);
|
||||
fprintf(stderr, "%s:\n%s\n",message,
|
||||
js_DeflateString(cx, ts->linebuf.base,
|
||||
ts->linebuf.limit - ts->linebuf.base));
|
||||
js_DeflateString(cx, ts->linebuf.base,
|
||||
ts->linebuf.limit - ts->linebuf.base));
|
||||
#endif
|
||||
}
|
||||
if (lastc == '\n')
|
||||
|
@ -779,14 +779,13 @@ retry:
|
|||
radix = 16;
|
||||
} else if (JS7_ISDEC(c)) {
|
||||
/*
|
||||
* We permit 08 and 09 as decimal numbers, which makes our
|
||||
* We permit 08 and 09 as decimal numbers, which makes our
|
||||
* behaviour superset of the ECMA numeric grammar. We might
|
||||
* not always be so permissive, so we warn about it.
|
||||
*/
|
||||
if (c > '7' && JSVERSION_IS_ECMA(cx->version)) {
|
||||
js_ReportCompileError(cx, ts, JSREPORT_WARNING,
|
||||
"0%c is not an ECMA-legal numeric constant",
|
||||
c);
|
||||
"0%c is not a legal ECMA-262 numeric constant", c);
|
||||
radix = 10;
|
||||
} else {
|
||||
radix = 8;
|
||||
|
@ -821,7 +820,7 @@ retry:
|
|||
}
|
||||
if (!JS7_ISDEC(c)) {
|
||||
js_ReportCompileError(cx, ts, JSREPORT_ERROR,
|
||||
"missing exponent");
|
||||
"missing exponent");
|
||||
RETURN(TOK_ERROR);
|
||||
}
|
||||
do {
|
||||
|
@ -838,13 +837,13 @@ retry:
|
|||
if (radix == 10) {
|
||||
if (!js_strtod(cx, ts->tokenbuf.base, &endptr, &dval)) {
|
||||
js_ReportCompileError(cx, ts, JSREPORT_ERROR,
|
||||
"out of memory");
|
||||
"out of memory");
|
||||
RETURN(TOK_ERROR);
|
||||
}
|
||||
} else {
|
||||
if (!js_strtointeger(cx, ts->tokenbuf.base, &endptr, radix, &dval)) {
|
||||
js_ReportCompileError(cx, ts, JSREPORT_ERROR,
|
||||
"out of memory");
|
||||
"out of memory");
|
||||
RETURN(TOK_ERROR);
|
||||
}
|
||||
}
|
||||
|
@ -860,7 +859,7 @@ retry:
|
|||
if (c == '\n' || c == EOF) {
|
||||
UngetChar(ts, c);
|
||||
js_ReportCompileError(cx, ts, JSREPORT_ERROR,
|
||||
"unterminated string literal");
|
||||
"unterminated string literal");
|
||||
RETURN(TOK_ERROR);
|
||||
}
|
||||
if (c == '\\') {
|
||||
|
@ -1050,12 +1049,12 @@ skipline:
|
|||
if (MatchChar(ts, '/'))
|
||||
goto retry;
|
||||
js_ReportCompileError(cx, ts, JSREPORT_ERROR,
|
||||
"nested comment");
|
||||
"nested comment");
|
||||
}
|
||||
}
|
||||
if (c == EOF) {
|
||||
js_ReportCompileError(cx, ts, JSREPORT_ERROR,
|
||||
"unterminated comment");
|
||||
"unterminated comment");
|
||||
RETURN(TOK_ERROR);
|
||||
}
|
||||
goto retry;
|
||||
|
@ -1179,7 +1178,7 @@ skipline:
|
|||
|
||||
default:
|
||||
js_ReportCompileError(cx, ts, JSREPORT_ERROR,
|
||||
"illegal character");
|
||||
"illegal character");
|
||||
RETURN(TOK_ERROR);
|
||||
}
|
||||
|
||||
|
|
|
@ -114,11 +114,11 @@ struct JSToken {
|
|||
JSTokenPos pos; /* token position in file */
|
||||
jschar *ptr; /* beginning of token in line buffer */
|
||||
union {
|
||||
struct {
|
||||
struct {
|
||||
JSOp op; /* operator, for minimal parser */
|
||||
JSAtom *atom; /* atom table entry */
|
||||
} s;
|
||||
jsdouble dval; /* floating point number */
|
||||
} s;
|
||||
jsdouble dval; /* floating point number */
|
||||
} u;
|
||||
};
|
||||
|
||||
|
@ -133,7 +133,7 @@ typedef struct JSTokenBuf {
|
|||
} JSTokenBuf;
|
||||
|
||||
#define JS_LINE_LIMIT 256 /* logical line buffer size limit --
|
||||
physical line length is unlimited */
|
||||
physical line length is unlimited */
|
||||
|
||||
struct JSTokenStream {
|
||||
JSToken token; /* last token scanned */
|
||||
|
@ -227,11 +227,11 @@ js_MapKeywords(void (*mapfun)(const char *));
|
|||
*/
|
||||
extern void
|
||||
js_ReportCompileError(JSContext *cx, JSTokenStream *ts, uintN flags,
|
||||
const char *format, ...);
|
||||
const char *format, ...);
|
||||
|
||||
void
|
||||
js_ReportCompileErrorNumber(JSContext *cx, JSTokenStream *ts, uintN flags,
|
||||
const uintN errorNumber, ...);
|
||||
const uintN errorNumber, ...);
|
||||
/*
|
||||
* Look ahead one token and return its type.
|
||||
*/
|
||||
|
|
518
js/ref/jsscope.c
518
js/ref/jsscope.c
|
@ -1,518 +0,0 @@
|
|||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* JS symbol tables.
|
||||
*/
|
||||
#include "jsstddef.h"
|
||||
#include <string.h>
|
||||
#include "prtypes.h"
|
||||
#include "prassert.h"
|
||||
#include "jsapi.h"
|
||||
#include "jsatom.h"
|
||||
#include "jscntxt.h"
|
||||
#include "jsinterp.h"
|
||||
#include "jslock.h"
|
||||
#include "jsnum.h"
|
||||
#include "jsscope.h"
|
||||
#include "jsstr.h"
|
||||
|
||||
PR_STATIC_CALLBACK(prhashcode)
|
||||
js_hash_id(const void *key)
|
||||
{
|
||||
jsval v;
|
||||
const JSAtom *atom;
|
||||
|
||||
v = (jsval)key;
|
||||
if (JSVAL_IS_INT(v))
|
||||
return JSVAL_TO_INT(v);
|
||||
atom = key;
|
||||
return atom->number;
|
||||
}
|
||||
|
||||
typedef struct JSScopePrivate {
|
||||
JSContext *context;
|
||||
JSScope *scope;
|
||||
} JSScopePrivate;
|
||||
|
||||
PR_STATIC_CALLBACK(void *)
|
||||
js_alloc_scope_space(void *priv, size_t size)
|
||||
{
|
||||
return JS_malloc(((JSScopePrivate *)priv)->context, size);
|
||||
}
|
||||
|
||||
PR_STATIC_CALLBACK(void)
|
||||
js_free_scope_space(void *priv, void *item)
|
||||
{
|
||||
JS_free(((JSScopePrivate *)priv)->context, item);
|
||||
}
|
||||
|
||||
PR_STATIC_CALLBACK(PRHashEntry *)
|
||||
js_alloc_symbol(void *priv, const void *key)
|
||||
{
|
||||
JSScopePrivate *spriv;
|
||||
JSContext *cx;
|
||||
JSSymbol *sym;
|
||||
|
||||
spriv = priv;
|
||||
PR_ASSERT(JS_IS_SCOPE_LOCKED(spriv->scope));
|
||||
cx = spriv->context;
|
||||
sym = JS_malloc(cx, sizeof(JSSymbol));
|
||||
if (!sym)
|
||||
return NULL;
|
||||
sym->entry.key = key;
|
||||
return &sym->entry;
|
||||
}
|
||||
|
||||
PR_STATIC_CALLBACK(void)
|
||||
js_free_symbol(void *priv, PRHashEntry *he, uintN flag)
|
||||
{
|
||||
JSScopePrivate *spriv;
|
||||
JSContext *cx;
|
||||
JSSymbol *sym, **sp;
|
||||
JSScopeProperty *sprop;
|
||||
|
||||
spriv = priv;
|
||||
PR_ASSERT(JS_IS_SCOPE_LOCKED(spriv->scope));
|
||||
cx = spriv->context;
|
||||
sym = (JSSymbol *)he;
|
||||
sprop = sym->entry.value;
|
||||
if (sprop) {
|
||||
sym->entry.value = NULL;
|
||||
sprop = js_DropScopeProperty(cx, spriv->scope, sprop);
|
||||
if (sprop) {
|
||||
for (sp = &sprop->symbols; *sp; sp = &(*sp)->next) {
|
||||
if (*sp == sym) {
|
||||
*sp = sym->next;
|
||||
if (!*sp)
|
||||
break;
|
||||
}
|
||||
}
|
||||
sym->next = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (flag == HT_FREE_ENTRY)
|
||||
JS_free(cx, he);
|
||||
}
|
||||
|
||||
static PRHashAllocOps hash_scope_alloc_ops = {
|
||||
js_alloc_scope_space, js_free_scope_space,
|
||||
js_alloc_symbol, js_free_symbol
|
||||
};
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
PR_STATIC_CALLBACK(JSSymbol *)
|
||||
js_hash_scope_lookup(JSContext *cx, JSScope *scope, jsid id, prhashcode hash)
|
||||
{
|
||||
PRHashTable *table = scope->data;
|
||||
PRHashEntry **hep;
|
||||
JSSymbol *sym;
|
||||
|
||||
hep = PR_HashTableRawLookup(table, hash, (const void *)id);
|
||||
sym = (JSSymbol *) *hep;
|
||||
return sym;
|
||||
}
|
||||
|
||||
#define SCOPE_ADD(PRIV, CLASS_SPECIFIC_CODE) \
|
||||
PR_BEGIN_MACRO \
|
||||
if (sym) { \
|
||||
if (sym->entry.value == sprop) \
|
||||
return sym; \
|
||||
if (sym->entry.value) \
|
||||
js_free_symbol(PRIV, &sym->entry, HT_FREE_VALUE); \
|
||||
} else { \
|
||||
CLASS_SPECIFIC_CODE \
|
||||
sym->scope = scope; \
|
||||
sym->next = NULL; \
|
||||
} \
|
||||
if (sprop) { \
|
||||
sym->entry.value = js_HoldScopeProperty(cx, scope, sprop); \
|
||||
for (sp = &sprop->symbols; *sp; sp = &(*sp)->next) \
|
||||
; \
|
||||
*sp = sym; \
|
||||
} else { \
|
||||
sym->entry.value = NULL; \
|
||||
} \
|
||||
PR_END_MACRO
|
||||
|
||||
PR_STATIC_CALLBACK(JSSymbol *)
|
||||
js_hash_scope_add(JSContext *cx, JSScope *scope, jsid id, JSScopeProperty *sprop)
|
||||
{
|
||||
PRHashTable *table = scope->data;
|
||||
const void *key;
|
||||
prhashcode keyHash;
|
||||
PRHashEntry **hep;
|
||||
JSSymbol *sym, **sp;
|
||||
JSScopePrivate *priv;
|
||||
|
||||
PR_ASSERT(JS_IS_SCOPE_LOCKED(scope));
|
||||
priv = table->allocPriv;
|
||||
priv->context = cx;
|
||||
key = (const void *)id;
|
||||
keyHash = js_hash_id(key);
|
||||
hep = PR_HashTableRawLookup(table, keyHash, key);
|
||||
sym = (JSSymbol *) *hep;
|
||||
SCOPE_ADD(priv,
|
||||
sym = (JSSymbol *) PR_HashTableRawAdd(table, hep, keyHash, key, NULL);
|
||||
if (!sym)
|
||||
return NULL;
|
||||
);
|
||||
return sym;
|
||||
}
|
||||
|
||||
PR_STATIC_CALLBACK(JSBool)
|
||||
js_hash_scope_remove(JSContext *cx, JSScope *scope, jsid id)
|
||||
{
|
||||
PRHashTable *table = scope->data;
|
||||
JSScopePrivate *priv;
|
||||
|
||||
PR_ASSERT(JS_IS_SCOPE_LOCKED(scope));
|
||||
priv = table->allocPriv;
|
||||
priv->context = cx;
|
||||
return PR_HashTableRemove(table, (const void *)id);
|
||||
}
|
||||
|
||||
/* Forward declaration for use by js_hash_scope_clear(). */
|
||||
extern JS_FRIEND_DATA(JSScopeOps) js_list_scope_ops;
|
||||
|
||||
PR_STATIC_CALLBACK(void)
|
||||
js_hash_scope_clear(JSContext *cx, JSScope *scope)
|
||||
{
|
||||
PRHashTable *table = scope->data;
|
||||
JSScopePrivate *priv;
|
||||
|
||||
PR_ASSERT(JS_IS_SCOPE_LOCKED(scope));
|
||||
priv = table->allocPriv;
|
||||
priv->context = cx;
|
||||
PR_HashTableDestroy(table);
|
||||
JS_free(cx, priv);
|
||||
scope->ops = &js_list_scope_ops;
|
||||
scope->data = NULL;
|
||||
}
|
||||
|
||||
JSScopeOps js_hash_scope_ops = {
|
||||
js_hash_scope_lookup,
|
||||
js_hash_scope_add,
|
||||
js_hash_scope_remove,
|
||||
js_hash_scope_clear
|
||||
};
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
PR_STATIC_CALLBACK(JSSymbol *)
|
||||
js_list_scope_lookup(JSContext *cx, JSScope *scope, jsid id, prhashcode hash)
|
||||
{
|
||||
JSSymbol *sym, **sp;
|
||||
|
||||
PR_ASSERT(JS_IS_SCOPE_LOCKED(scope));
|
||||
for (sp = (JSSymbol **)&scope->data; (sym = *sp) != 0;
|
||||
sp = (JSSymbol **)&sym->entry.next) {
|
||||
if (sym_id(sym) == id) {
|
||||
/* Move sym to the front for shorter searches. */
|
||||
*sp = (JSSymbol *)sym->entry.next;
|
||||
sym->entry.next = scope->data;
|
||||
scope->data = sym;
|
||||
return sym;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define HASH_THRESHOLD 5
|
||||
|
||||
PR_STATIC_CALLBACK(JSSymbol *)
|
||||
js_list_scope_add(JSContext *cx, JSScope *scope, jsid id, JSScopeProperty *sprop)
|
||||
{
|
||||
JSSymbol *list = scope->data;
|
||||
uint32 nsyms;
|
||||
JSSymbol *sym, *next, **sp;
|
||||
PRHashTable *table;
|
||||
PRHashEntry **hep;
|
||||
JSScopePrivate priv;
|
||||
|
||||
PR_ASSERT(JS_IS_SCOPE_LOCKED(scope));
|
||||
nsyms = 0;
|
||||
for (sym = list; sym; sym = (JSSymbol *)sym->entry.next) {
|
||||
if (sym_id(sym) == id)
|
||||
break;
|
||||
nsyms++;
|
||||
}
|
||||
|
||||
if (nsyms >= HASH_THRESHOLD) {
|
||||
JSScopePrivate *priv = JS_malloc(cx, sizeof(JSScopePrivate));
|
||||
if (!priv) return NULL;
|
||||
priv->context = cx;
|
||||
priv->scope = scope;
|
||||
table = PR_NewHashTable(nsyms, js_hash_id,
|
||||
PR_CompareValues, PR_CompareValues,
|
||||
&hash_scope_alloc_ops, priv);
|
||||
if (table) {
|
||||
for (sym = list; sym; sym = next) {
|
||||
/* Save next for loop update, before it changes in lookup. */
|
||||
next = (JSSymbol *)sym->entry.next;
|
||||
|
||||
/* Now compute missing keyHash fields. */
|
||||
sym->entry.keyHash = js_hash_id(sym->entry.key);
|
||||
sym->entry.next = NULL;
|
||||
hep = PR_HashTableRawLookup(table,
|
||||
sym->entry.keyHash,
|
||||
sym->entry.key);
|
||||
*hep = &sym->entry;
|
||||
}
|
||||
table->nentries = nsyms;
|
||||
scope->ops = &js_hash_scope_ops;
|
||||
scope->data = table;
|
||||
return scope->ops->add(cx, scope, id, sprop);
|
||||
}
|
||||
}
|
||||
|
||||
priv.context = cx;
|
||||
priv.scope = scope;
|
||||
SCOPE_ADD(&priv,
|
||||
sym = (JSSymbol *)js_alloc_symbol(&priv, (const void *)id);
|
||||
if (!sym)
|
||||
return NULL;
|
||||
/* Don't set keyHash until we know we need it, above. */
|
||||
sym->entry.next = scope->data;
|
||||
scope->data = sym;
|
||||
);
|
||||
return sym;
|
||||
}
|
||||
|
||||
PR_STATIC_CALLBACK(JSBool)
|
||||
js_list_scope_remove(JSContext *cx, JSScope *scope, jsid id)
|
||||
{
|
||||
JSSymbol *sym, **sp;
|
||||
JSScopePrivate priv;
|
||||
|
||||
PR_ASSERT(JS_IS_SCOPE_LOCKED(scope));
|
||||
for (sp = (JSSymbol **)&scope->data; (sym = *sp) != 0;
|
||||
sp = (JSSymbol **)&sym->entry.next) {
|
||||
if (sym_id(sym) == id) {
|
||||
*sp = (JSSymbol *)sym->entry.next;
|
||||
priv.context = cx;
|
||||
priv.scope = scope;
|
||||
js_free_symbol(&priv, &sym->entry, HT_FREE_ENTRY);
|
||||
return JS_TRUE;
|
||||
}
|
||||
}
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
PR_STATIC_CALLBACK(void)
|
||||
js_list_scope_clear(JSContext *cx, JSScope *scope)
|
||||
{
|
||||
JSSymbol *sym;
|
||||
JSScopePrivate priv;
|
||||
|
||||
PR_ASSERT(JS_IS_SCOPE_LOCKED(scope));
|
||||
while ((sym = scope->data) != NULL) {
|
||||
scope->data = sym->entry.next;
|
||||
priv.context = cx;
|
||||
priv.scope = scope;
|
||||
js_free_symbol(&priv, &sym->entry, HT_FREE_ENTRY);
|
||||
}
|
||||
}
|
||||
|
||||
JSScopeOps JS_FRIEND_DATA(js_list_scope_ops) = {
|
||||
js_list_scope_lookup,
|
||||
js_list_scope_add,
|
||||
js_list_scope_remove,
|
||||
js_list_scope_clear
|
||||
};
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
JSScope *
|
||||
js_GetMutableScope(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
JSScope *scope, *newscope;
|
||||
|
||||
scope = (JSScope *) obj->map;
|
||||
PR_ASSERT(JS_IS_SCOPE_LOCKED(scope));
|
||||
if (scope->object == obj)
|
||||
return scope;
|
||||
newscope = js_NewScope(cx, 0, scope->map.ops, LOCKED_OBJ_GET_CLASS(obj),
|
||||
obj);
|
||||
if (!newscope)
|
||||
return NULL;
|
||||
JS_LOCK_SCOPE(cx, newscope);
|
||||
obj->map = js_HoldObjectMap(cx, &newscope->map);
|
||||
scope = (JSScope *) js_DropObjectMap(cx, &scope->map, obj);
|
||||
JS_TRANSFER_SCOPE_LOCK(cx, scope, newscope);
|
||||
return newscope;
|
||||
}
|
||||
|
||||
JSScope *
|
||||
js_MutateScope(JSContext *cx, JSObject *obj, jsid id,
|
||||
JSPropertyOp getter, JSPropertyOp setter, uintN attrs,
|
||||
JSScopeProperty **propp)
|
||||
{
|
||||
/* XXX pessimal */
|
||||
*propp = NULL;
|
||||
return js_GetMutableScope(cx, obj);
|
||||
}
|
||||
|
||||
JSScope *
|
||||
js_NewScope(JSContext *cx, jsrefcount nrefs, JSObjectOps *ops, JSClass *clasp,
|
||||
JSObject *obj)
|
||||
{
|
||||
JSScope *scope;
|
||||
|
||||
scope = JS_malloc(cx, sizeof(JSScope));
|
||||
if (!scope)
|
||||
return NULL;
|
||||
js_InitObjectMap(&scope->map, nrefs, ops, clasp);
|
||||
scope->object = obj;
|
||||
scope->props = NULL;
|
||||
scope->proptail = &scope->props;
|
||||
scope->ops = &js_list_scope_ops;
|
||||
scope->data = NULL;
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
js_NewLock(&scope->lock);
|
||||
scope->count = 0;
|
||||
#ifdef DEBUG
|
||||
scope->file[0] = scope->file[1] = scope->file[2] = scope->file[3] = NULL;
|
||||
scope->line[0] = scope->line[1] = scope->line[2] = scope->line[3] = 0;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return scope;
|
||||
}
|
||||
|
||||
void
|
||||
js_DestroyScope(JSContext *cx, JSScope *scope)
|
||||
{
|
||||
JS_LOCK_SCOPE(cx, scope);
|
||||
scope->ops->clear(cx, scope);
|
||||
JS_UNLOCK_SCOPE(cx, scope);
|
||||
#ifdef JS_THREADSAFE
|
||||
PR_ASSERT(scope->count == 0);
|
||||
js_DestroyLock(&scope->lock);
|
||||
#endif
|
||||
JS_free(cx, scope);
|
||||
}
|
||||
|
||||
prhashcode
|
||||
js_HashValue(jsval v)
|
||||
{
|
||||
return js_hash_id((const void *)v);
|
||||
}
|
||||
|
||||
jsval
|
||||
js_IdToValue(jsid id)
|
||||
{
|
||||
JSAtom *atom;
|
||||
|
||||
if (JSVAL_IS_INT(id))
|
||||
return id;
|
||||
atom = (JSAtom *)id;
|
||||
return ATOM_KEY(atom);
|
||||
}
|
||||
|
||||
JSScopeProperty *
|
||||
js_NewScopeProperty(JSContext *cx, JSScope *scope, jsid id,
|
||||
JSPropertyOp getter, JSPropertyOp setter, uintN attrs)
|
||||
{
|
||||
uint32 slot;
|
||||
JSScopeProperty *sprop;
|
||||
|
||||
PR_ASSERT(JS_IS_SCOPE_LOCKED(scope));
|
||||
if (!js_AllocSlot(cx, scope->object, &slot))
|
||||
return NULL;
|
||||
sprop = JS_malloc(cx, sizeof(JSScopeProperty));
|
||||
if (!sprop) {
|
||||
js_FreeSlot(cx, scope->object, slot);
|
||||
return NULL;
|
||||
}
|
||||
sprop->nrefs = 0;
|
||||
sprop->id = js_IdToValue(id);
|
||||
sprop->getter = getter;
|
||||
sprop->setter = setter;
|
||||
sprop->slot = slot;
|
||||
sprop->attrs = attrs;
|
||||
sprop->spare = 0;
|
||||
sprop->symbols = NULL;
|
||||
sprop->next = NULL;
|
||||
sprop->prevp = scope->proptail;
|
||||
*scope->proptail = sprop;
|
||||
scope->proptail = &sprop->next;
|
||||
return sprop;
|
||||
}
|
||||
|
||||
void
|
||||
js_DestroyScopeProperty(JSContext *cx, JSScope *scope, JSScopeProperty *sprop)
|
||||
{
|
||||
/*
|
||||
* Test whether obj was finalized before prop's last dereference.
|
||||
*
|
||||
* This can happen when a deleted property is held by a property iterator
|
||||
* object (which points to obj, keeping obj alive so long as the property
|
||||
* iterator is reachable). As soon as the GC finds the iterator to be
|
||||
* unreachable, it will finalize the iterator, and may also finalize obj,
|
||||
* in an unpredictable order. If obj is finalized first, its map will be
|
||||
* null below, and we need only free prop.
|
||||
*
|
||||
* In the more typical case of a property whose last reference (from a
|
||||
* symbol in obj's scope) goes away before obj is finalized, we must be
|
||||
* sure to free prop's slot and unlink it from obj's property list.
|
||||
*/
|
||||
if (scope) {
|
||||
PR_ASSERT(JS_IS_SCOPE_LOCKED(scope));
|
||||
if (scope->object) {
|
||||
js_FreeSlot(cx, scope->object, sprop->slot);
|
||||
*sprop->prevp = sprop->next;
|
||||
if (sprop->next)
|
||||
sprop->next->prevp = sprop->prevp;
|
||||
else
|
||||
scope->proptail = sprop->prevp;
|
||||
}
|
||||
}
|
||||
|
||||
/* Purge any cached weak links to prop, then free it. */
|
||||
js_FlushPropertyCacheByProp(cx, (JSProperty *)sprop);
|
||||
JS_free(cx, sprop);
|
||||
}
|
||||
|
||||
JSScopeProperty *
|
||||
js_HoldScopeProperty(JSContext *cx, JSScope *scope, JSScopeProperty *sprop)
|
||||
{
|
||||
PR_ASSERT(JS_IS_SCOPE_LOCKED(scope));
|
||||
if (sprop) {
|
||||
PR_ASSERT(sprop->nrefs >= 0);
|
||||
sprop->nrefs++;
|
||||
}
|
||||
return sprop;
|
||||
}
|
||||
|
||||
JSScopeProperty *
|
||||
js_DropScopeProperty(JSContext *cx, JSScope *scope, JSScopeProperty *sprop)
|
||||
{
|
||||
PR_ASSERT(JS_IS_SCOPE_LOCKED(scope));
|
||||
if (sprop) {
|
||||
PR_ASSERT(sprop->nrefs > 0);
|
||||
if (--sprop->nrefs == 0) {
|
||||
js_DestroyScopeProperty(cx, scope, sprop);
|
||||
sprop = NULL;
|
||||
}
|
||||
}
|
||||
return sprop;
|
||||
}
|
|
@ -1,785 +0,0 @@
|
|||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* JS script operations.
|
||||
*/
|
||||
#include "jsstddef.h"
|
||||
#include <string.h>
|
||||
#include "prtypes.h"
|
||||
#include "prassert.h"
|
||||
#include "prprintf.h"
|
||||
#include "jsapi.h"
|
||||
#include "jsatom.h"
|
||||
#include "jscntxt.h"
|
||||
#include "jsconfig.h"
|
||||
#include "jsdbgapi.h"
|
||||
#include "jsemit.h"
|
||||
#include "jsfun.h"
|
||||
#include "jsinterp.h"
|
||||
#include "jsnum.h"
|
||||
#include "jsopcode.h"
|
||||
#include "jsscript.h"
|
||||
#if JS_HAS_XDR
|
||||
#include "jsxdrapi.h"
|
||||
#endif
|
||||
|
||||
#if JS_HAS_SCRIPT_OBJECT
|
||||
|
||||
#if JS_HAS_TOSOURCE
|
||||
static JSBool
|
||||
script_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
||||
jsval *rval)
|
||||
{
|
||||
JSScript *script;
|
||||
size_t i, j, k, n;
|
||||
char buf[16];
|
||||
jschar *s, *t;
|
||||
uint32 indent;
|
||||
JSString *str;
|
||||
|
||||
if (!JS_InstanceOf(cx, obj, &js_ScriptClass, argv))
|
||||
return JS_FALSE;
|
||||
script = JS_GetPrivate(cx, obj);
|
||||
|
||||
/* Let n count the source string length, j the "front porch" length. */
|
||||
j = PR_snprintf(buf, sizeof buf, "(new %s(", js_ScriptClass.name);
|
||||
n = j + 2;
|
||||
if (!script) {
|
||||
/* Let k count the constructor argument string length. */
|
||||
k = 0;
|
||||
} else {
|
||||
indent = 0;
|
||||
if (argc && !js_ValueToECMAUint32(cx, argv[0], &indent))
|
||||
return JS_FALSE;
|
||||
str = JS_DecompileScript(cx, script, "Script.prototype.toSource",
|
||||
(uintN)indent);
|
||||
if (!str)
|
||||
return JS_FALSE;
|
||||
str = js_QuoteString(cx, str, '\'');
|
||||
if (!str)
|
||||
return JS_FALSE;
|
||||
s = str->chars;
|
||||
k = str->length;
|
||||
n += k;
|
||||
}
|
||||
|
||||
/* Allocate the source string and copy into it. */
|
||||
t = JS_malloc(cx, (n + 1) * sizeof(jschar));
|
||||
if (!t)
|
||||
return JS_FALSE;
|
||||
for (i = 0; i < j; i++)
|
||||
t[i] = buf[i];
|
||||
for (j = 0; j < k; i++, j++)
|
||||
t[i] = s[j];
|
||||
t[i++] = ')';
|
||||
t[i++] = ')';
|
||||
t[i] = 0;
|
||||
|
||||
/* Create and return a JS string for t. */
|
||||
str = JS_NewUCString(cx, t, n);
|
||||
if (!str) {
|
||||
JS_free(cx, t);
|
||||
return JS_FALSE;
|
||||
}
|
||||
*rval = STRING_TO_JSVAL(str);
|
||||
return JS_TRUE;
|
||||
}
|
||||
#endif /* JS_HAS_TOSOURCE */
|
||||
|
||||
static JSBool
|
||||
script_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
||||
jsval *rval)
|
||||
{
|
||||
JSScript *script;
|
||||
uint32 indent;
|
||||
JSString *str;
|
||||
|
||||
if (!JS_InstanceOf(cx, obj, &js_ScriptClass, argv))
|
||||
return JS_FALSE;
|
||||
script = JS_GetPrivate(cx, obj);
|
||||
if (!script) {
|
||||
*rval = STRING_TO_JSVAL(cx->runtime->emptyString);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
indent = 0;
|
||||
if (argc && !js_ValueToECMAUint32(cx, argv[0], &indent))
|
||||
return JS_FALSE;
|
||||
str = JS_DecompileScript(cx, script, "Script.prototype.toString",
|
||||
(uintN)indent);
|
||||
if (!str)
|
||||
return JS_FALSE;
|
||||
*rval = STRING_TO_JSVAL(str);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
script_compile(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
||||
jsval *rval)
|
||||
{
|
||||
JSScript *oldscript, *script;
|
||||
JSString *str;
|
||||
JSStackFrame *fp, *caller;
|
||||
JSObject *scopeobj;
|
||||
const char *file;
|
||||
uintN line;
|
||||
JSPrincipals *principals;
|
||||
|
||||
/* If no args, leave private undefined and return early. */
|
||||
if (argc == 0)
|
||||
goto out;
|
||||
|
||||
/* Otherwise, the first arg is the script source to compile. */
|
||||
str = js_ValueToString(cx, argv[0]);
|
||||
if (!str)
|
||||
return JS_FALSE;
|
||||
|
||||
/* Compile using the caller's scope chain, which js_Invoke passes to fp. */
|
||||
fp = cx->fp;
|
||||
caller = fp->down;
|
||||
PR_ASSERT(fp->scopeChain == caller->scopeChain);
|
||||
|
||||
scopeobj = NULL;
|
||||
if (argc >= 2) {
|
||||
if (!js_ValueToObject(cx, argv[1], &scopeobj))
|
||||
return JS_FALSE;
|
||||
argv[1] = OBJECT_TO_JSVAL(scopeobj);
|
||||
}
|
||||
if (!scopeobj)
|
||||
scopeobj = caller->scopeChain;
|
||||
|
||||
if (caller->script) {
|
||||
file = caller->script->filename;
|
||||
line = js_PCToLineNumber(caller->script, caller->pc);
|
||||
principals = caller->script->principals;
|
||||
} else {
|
||||
file = NULL;
|
||||
line = 0;
|
||||
principals = NULL;
|
||||
}
|
||||
|
||||
/* Compile the new script using the caller's scope chain, a la eval(). */
|
||||
script = JS_CompileUCScriptForPrincipals(cx, scopeobj, principals,
|
||||
str->chars, str->length,
|
||||
file, line);
|
||||
if (!script)
|
||||
return JS_FALSE;
|
||||
|
||||
/* Swap script for obj's old script, if any. */
|
||||
oldscript = JS_GetPrivate(cx, obj);
|
||||
if (!JS_SetPrivate(cx, obj, script)) {
|
||||
js_DestroyScript(cx, script);
|
||||
return JS_FALSE;
|
||||
}
|
||||
if (oldscript)
|
||||
js_DestroyScript(cx, oldscript);
|
||||
|
||||
script->object = obj;
|
||||
out:
|
||||
/* Return the object. */
|
||||
*rval = OBJECT_TO_JSVAL(obj);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
script_exec(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
JSScript *script;
|
||||
JSStackFrame *fp, *caller;
|
||||
JSObject *scopeobj;
|
||||
|
||||
if (!JS_InstanceOf(cx, obj, &js_ScriptClass, argv))
|
||||
return JS_FALSE;
|
||||
script = JS_GetPrivate(cx, obj);
|
||||
if (!script)
|
||||
return JS_TRUE;
|
||||
|
||||
scopeobj = NULL;
|
||||
if (argc) {
|
||||
if (!js_ValueToObject(cx, argv[0], &scopeobj))
|
||||
return JS_FALSE;
|
||||
argv[0] = OBJECT_TO_JSVAL(scopeobj);
|
||||
}
|
||||
|
||||
/* Emulate eval() by using caller's this, scope chain, and sharp array. */
|
||||
fp = cx->fp;
|
||||
caller = fp->down;
|
||||
if (!scopeobj)
|
||||
scopeobj = caller->scopeChain;
|
||||
fp->thisp = caller->thisp;
|
||||
PR_ASSERT(fp->scopeChain == caller->scopeChain);
|
||||
fp->sharpArray = caller->sharpArray;
|
||||
return js_Execute(cx, scopeobj, script, NULL, fp, JS_FALSE, rval);
|
||||
}
|
||||
|
||||
#if JS_HAS_XDR
|
||||
static JSBool
|
||||
XDRAtom1(JSXDRState *xdr, JSAtomListElement *ale)
|
||||
{
|
||||
uint32 type;
|
||||
jsval value;
|
||||
|
||||
if (xdr->mode == JSXDR_ENCODE) {
|
||||
type = JSVAL_TAG(ATOM_KEY(ale->atom));
|
||||
value = ATOM_KEY(ale->atom);
|
||||
}
|
||||
|
||||
if (!JS_XDRUint32(xdr, &ale->index) ||
|
||||
!JS_XDRValue(xdr, &value))
|
||||
return JS_FALSE;
|
||||
|
||||
if (xdr->mode == JSXDR_DECODE) {
|
||||
ale->atom = js_AtomizeValue(xdr->cx, value, 0);
|
||||
if (!ale->atom)
|
||||
return JS_FALSE;
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
XDRAtomMap(JSXDRState *xdr, JSAtomMap *map)
|
||||
{
|
||||
uint32 length;
|
||||
uintN i;
|
||||
|
||||
if (xdr->mode == JSXDR_ENCODE)
|
||||
length = map->length;
|
||||
|
||||
if (!JS_XDRUint32(xdr, &length))
|
||||
return JS_FALSE;
|
||||
|
||||
if (xdr->mode == JSXDR_DECODE) {
|
||||
JSContext *cx;
|
||||
void *mark;
|
||||
JSAtomList al;
|
||||
JSAtomListElement *ale;
|
||||
|
||||
cx = xdr->cx;
|
||||
mark = PR_ARENA_MARK(&cx->tempPool);
|
||||
ATOM_LIST_INIT(&al);
|
||||
for (i = 0; i < length; i++) {
|
||||
PR_ARENA_ALLOCATE(ale, &cx->tempPool, sizeof(*ale));
|
||||
if (!ale ||
|
||||
!XDRAtom1(xdr, ale)) {
|
||||
if (!ale)
|
||||
JS_ReportOutOfMemory(cx);
|
||||
PR_ARENA_RELEASE(&cx->tempPool, mark);
|
||||
return JS_FALSE;
|
||||
}
|
||||
ale->next = al.list;
|
||||
al.count++;
|
||||
al.list = ale;
|
||||
}
|
||||
if (!js_InitAtomMap(cx, map, &al)) {
|
||||
PR_ARENA_RELEASE(&cx->tempPool, mark);
|
||||
return JS_FALSE;
|
||||
}
|
||||
PR_ARENA_RELEASE(&cx->tempPool, mark);
|
||||
} else if (xdr->mode == JSXDR_ENCODE) {
|
||||
JSAtomListElement ale;
|
||||
|
||||
for (i = 0; i < map->length; i++) {
|
||||
ale.atom = map->vector[i];
|
||||
ale.index = i;
|
||||
if (!XDRAtom1(xdr, &ale))
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSBool
|
||||
js_XDRScript(JSXDRState *xdr, JSScript **scriptp, JSBool *magic)
|
||||
{
|
||||
JSScript *script;
|
||||
uint32 length, lineno, depth, magicval;
|
||||
|
||||
if (xdr->mode == JSXDR_ENCODE)
|
||||
magicval = SCRIPT_XDRMAGIC;
|
||||
if (!JS_XDRUint32(xdr, &magicval))
|
||||
return JS_FALSE;
|
||||
if (magicval != SCRIPT_XDRMAGIC) {
|
||||
*magic = JS_FALSE;
|
||||
return JS_TRUE;
|
||||
}
|
||||
*magic = JS_TRUE;
|
||||
if (xdr->mode == JSXDR_ENCODE) {
|
||||
script = *scriptp;
|
||||
length = script->length;
|
||||
lineno = (uint32)script->lineno;
|
||||
depth = (uint32)script->depth;
|
||||
}
|
||||
if (!JS_XDRUint32(xdr, &length))
|
||||
return JS_FALSE;
|
||||
if (xdr->mode == JSXDR_DECODE) {
|
||||
script = js_NewScript(xdr->cx, length);
|
||||
if (!script)
|
||||
return JS_FALSE;
|
||||
*scriptp = script;
|
||||
}
|
||||
if (!JS_XDRBytes(xdr, (char **)&script->code, length) ||
|
||||
!XDRAtomMap(xdr, &script->atomMap) ||
|
||||
!JS_XDRCStringOrNull(xdr, (char **)&script->notes) ||
|
||||
!JS_XDRCStringOrNull(xdr, (char **)&script->filename) ||
|
||||
!JS_XDRUint32(xdr, &lineno) ||
|
||||
!JS_XDRUint32(xdr, &depth)) {
|
||||
if (xdr->mode == JSXDR_DECODE) {
|
||||
js_DestroyScript(xdr->cx, script);
|
||||
*scriptp = NULL;
|
||||
}
|
||||
return JS_FALSE;
|
||||
}
|
||||
if (xdr->mode == JSXDR_DECODE) {
|
||||
script->lineno = (uintN)lineno;
|
||||
script->depth = (uintN)depth;
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
script_freeze(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
||||
jsval *rval)
|
||||
{
|
||||
JSXDRState *xdr;
|
||||
JSScript *script;
|
||||
JSBool ok, magic;
|
||||
uint32 len;
|
||||
void *buf;
|
||||
JSString *str;
|
||||
|
||||
if (!JS_InstanceOf(cx, obj, &js_ScriptClass, argv))
|
||||
return JS_FALSE;
|
||||
script = JS_GetPrivate(cx, obj);
|
||||
if (!script)
|
||||
return JS_TRUE;
|
||||
|
||||
/* create new XDR */
|
||||
xdr = JS_XDRNewMem(cx, JSXDR_ENCODE);
|
||||
if (!xdr)
|
||||
return JS_FALSE;
|
||||
|
||||
/* write */
|
||||
ok = js_XDRScript(xdr, &script, &magic);
|
||||
if (!ok)
|
||||
goto out;
|
||||
if (!magic) {
|
||||
*rval = JSVAL_VOID;
|
||||
goto out;
|
||||
}
|
||||
|
||||
buf = JS_XDRMemGetData(xdr, &len);
|
||||
if (!buf) {
|
||||
ok = JS_FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
PR_ASSERT((prword)buf % sizeof(jschar) == 0);
|
||||
len /= sizeof(jschar);
|
||||
str = JS_NewUCStringCopyN(cx, (jschar *)buf, len);
|
||||
if (!str) {
|
||||
ok = JS_FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
#if IS_BIG_ENDIAN
|
||||
{
|
||||
jschar *chars;
|
||||
uint32 i;
|
||||
|
||||
/* Swap bytes in Unichars to keep frozen strings machine-independent. */
|
||||
chars = JS_GetStringChars(str);
|
||||
for (i = 0; i < len; i++)
|
||||
chars[i] = JSXDR_SWAB16(chars[i]);
|
||||
}
|
||||
#endif
|
||||
*rval = STRING_TO_JSVAL(str);
|
||||
|
||||
out:
|
||||
JS_XDRDestroy(xdr);
|
||||
return ok;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
script_thaw(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
||||
jsval *rval)
|
||||
{
|
||||
JSXDRState *xdr;
|
||||
JSString *str;
|
||||
void *buf;
|
||||
uint32 len;
|
||||
JSScript *script, *oldscript;
|
||||
JSBool ok, magic;
|
||||
|
||||
if (!JS_InstanceOf(cx, obj, &js_ScriptClass, argv))
|
||||
return JS_FALSE;
|
||||
|
||||
if (argc == 0)
|
||||
return JS_TRUE;
|
||||
str = js_ValueToString(cx, argv[0]);
|
||||
if (!str)
|
||||
return JS_FALSE;
|
||||
|
||||
/* create new XDR */
|
||||
xdr = JS_XDRNewMem(cx, JSXDR_DECODE);
|
||||
if (!xdr)
|
||||
return JS_FALSE;
|
||||
|
||||
buf = JS_GetStringChars(str);
|
||||
len = JS_GetStringLength(str);
|
||||
#if IS_BIG_ENDIAN
|
||||
{
|
||||
jschar *from, *to;
|
||||
uint32 i;
|
||||
|
||||
/* Swap bytes in Unichars to keep frozen strings machine-independent. */
|
||||
from = (jschar *)buf;
|
||||
to = JS_malloc(cx, len * sizeof(jschar));
|
||||
if (!to)
|
||||
return JS_FALSE;
|
||||
for (i = 0; i < len; i++)
|
||||
to[i] = JSXDR_SWAB16(from[i]);
|
||||
buf = (char *)to;
|
||||
}
|
||||
#endif
|
||||
len *= sizeof(jschar);
|
||||
JS_XDRMemSetData(xdr, buf, len);
|
||||
|
||||
/* XXXbe should magic mismatch be error, or false return value? */
|
||||
ok = js_XDRScript(xdr, &script, &magic);
|
||||
if (!ok)
|
||||
goto out;
|
||||
if (!magic) {
|
||||
*rval = JSVAL_FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Swap script for obj's old script, if any. */
|
||||
oldscript = JS_GetPrivate(cx, obj);
|
||||
ok = JS_SetPrivate(cx, obj, script);
|
||||
if (!ok) {
|
||||
JS_free(cx, script);
|
||||
goto out;
|
||||
}
|
||||
if (oldscript)
|
||||
js_DestroyScript(cx, oldscript);
|
||||
|
||||
script->object = obj;
|
||||
|
||||
out:
|
||||
/*
|
||||
* We reset the buffer to be NULL so that it doesn't free the chars
|
||||
* memory owned by str (argv[0]).
|
||||
*/
|
||||
JS_XDRMemSetData(xdr, NULL, 0);
|
||||
JS_XDRDestroy(xdr);
|
||||
#if IS_BIG_ENDIAN
|
||||
JS_free(cx, buf);
|
||||
#endif
|
||||
*rval = JSVAL_TRUE;
|
||||
return ok;
|
||||
}
|
||||
|
||||
#endif /* JS_HAS_XDR */
|
||||
|
||||
static char js_thaw_str[] = "thaw";
|
||||
|
||||
static JSFunctionSpec script_methods[] = {
|
||||
#if JS_HAS_TOSOURCE
|
||||
{js_toSource_str, script_toSource, 0},
|
||||
#endif
|
||||
{js_toString_str, script_toString, 0},
|
||||
{"compile", script_compile, 2},
|
||||
{"exec", script_exec, 1},
|
||||
#if JS_HAS_XDR
|
||||
{"freeze", script_freeze, 0},
|
||||
{js_thaw_str, script_thaw, 1},
|
||||
#endif /* JS_HAS_XDR */
|
||||
{0}
|
||||
};
|
||||
|
||||
#endif /* JS_HAS_SCRIPT_OBJECT */
|
||||
|
||||
static void
|
||||
script_finalize(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
JSScript *script;
|
||||
|
||||
script = JS_GetPrivate(cx, obj);
|
||||
if (script)
|
||||
js_DestroyScript(cx, script);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
script_call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
return script_exec(cx, JSVAL_TO_OBJECT(argv[-2]), argc, argv, rval);
|
||||
}
|
||||
|
||||
JSClass js_ScriptClass = {
|
||||
"Script",
|
||||
JSCLASS_HAS_PRIVATE,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, script_finalize,
|
||||
NULL, NULL, script_call, NULL,/*XXXbe xdr*/
|
||||
};
|
||||
|
||||
#if JS_HAS_SCRIPT_OBJECT
|
||||
|
||||
static JSBool
|
||||
Script(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
/* If not constructing, replace obj with a new Script object. */
|
||||
if (!cx->fp->constructing) {
|
||||
obj = js_NewObject(cx, &js_ScriptClass, NULL, NULL);
|
||||
if (!obj)
|
||||
return JS_FALSE;
|
||||
}
|
||||
return script_compile(cx, obj, argc, argv, rval);
|
||||
}
|
||||
|
||||
#if JS_HAS_XDR
|
||||
|
||||
static JSBool
|
||||
script_static_thaw(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
||||
jsval *rval)
|
||||
{
|
||||
obj = js_NewObject(cx, &js_ScriptClass, NULL, NULL);
|
||||
if (!obj)
|
||||
return JS_FALSE;
|
||||
if (!script_thaw(cx, obj, argc, argv, rval))
|
||||
return JS_FALSE;
|
||||
*rval = OBJECT_TO_JSVAL(obj);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSFunctionSpec script_static_methods[] = {
|
||||
{js_thaw_str, script_static_thaw, 1},
|
||||
{0}
|
||||
};
|
||||
|
||||
#else /* !JS_HAS_XDR */
|
||||
|
||||
#define script_static_methods NULL
|
||||
|
||||
#endif /* !JS_HAS_XDR */
|
||||
|
||||
JSObject *
|
||||
js_InitScriptClass(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
return JS_InitClass(cx, obj, NULL, &js_ScriptClass, Script, 1,
|
||||
NULL, script_methods, NULL, script_static_methods);
|
||||
}
|
||||
|
||||
#endif /* JS_HAS_SCRIPT_OBJECT */
|
||||
|
||||
JSScript *
|
||||
js_NewScript(JSContext *cx, uint32 length)
|
||||
{
|
||||
JSScript *script;
|
||||
|
||||
script = JS_malloc(cx, sizeof(JSScript) + length * sizeof(jsbytecode));
|
||||
if (!script)
|
||||
return NULL;
|
||||
memset(script, 0, sizeof(JSScript));
|
||||
script->code = (jsbytecode *)(script + 1);
|
||||
script->length = length;
|
||||
return script;
|
||||
}
|
||||
|
||||
JSScript *
|
||||
js_NewScriptFromParams(JSContext *cx, jsbytecode *code, uint32 length,
|
||||
const char *filename, uintN lineno, uintN depth,
|
||||
jssrcnote *notes, JSTryNote *trynotes,
|
||||
JSPrincipals *principals)
|
||||
{
|
||||
JSScript *script;
|
||||
|
||||
script = js_NewScript(cx, length);
|
||||
if (!script)
|
||||
return NULL;
|
||||
memcpy(script->code, code, length * sizeof(jsbytecode));
|
||||
if (filename) {
|
||||
script->filename = JS_strdup(cx, filename);
|
||||
if (!script->filename) {
|
||||
js_DestroyScript(cx, script);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
script->lineno = lineno;
|
||||
script->depth = depth;
|
||||
script->notes = notes;
|
||||
script->trynotes = trynotes;
|
||||
if (principals)
|
||||
JSPRINCIPALS_HOLD(cx, principals);
|
||||
script->principals = principals;
|
||||
return script;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSScript *)
|
||||
js_NewScriptFromCG(JSContext *cx, JSCodeGenerator *cg, JSFunction *fun)
|
||||
{
|
||||
JSTryNote *trynotes;
|
||||
jssrcnote *notes;
|
||||
JSScript *script;
|
||||
JSRuntime *rt;
|
||||
JSNewScriptHook hook;
|
||||
|
||||
if (!js_FinishTakingTryNotes(cx, cg, &trynotes))
|
||||
return NULL;
|
||||
notes = js_FinishTakingSrcNotes(cx, cg);
|
||||
script = js_NewScriptFromParams(cx, cg->base, CG_OFFSET(cg),
|
||||
cg->filename, cg->firstLine,
|
||||
cg->maxStackDepth, notes, trynotes,
|
||||
cg->principals);
|
||||
if (!script)
|
||||
return NULL;
|
||||
if (!notes || !js_InitAtomMap(cx, &script->atomMap, &cg->atomList)) {
|
||||
js_DestroyScript(cx, script);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Tell the debugger about this compiled script. */
|
||||
rt = cx->runtime;
|
||||
hook = rt->newScriptHook;
|
||||
if (hook) {
|
||||
(*hook)(cx, cg->filename, cg->firstLine, script, fun,
|
||||
rt->newScriptHookData);
|
||||
}
|
||||
return script;
|
||||
}
|
||||
|
||||
void
|
||||
js_DestroyScript(JSContext *cx, JSScript *script)
|
||||
{
|
||||
JSRuntime *rt;
|
||||
JSDestroyScriptHook hook;
|
||||
|
||||
rt = cx->runtime;
|
||||
hook = rt->destroyScriptHook;
|
||||
if (hook)
|
||||
(*hook)(cx, script, rt->destroyScriptHookData);
|
||||
|
||||
JS_ClearScriptTraps(cx, script);
|
||||
js_FreeAtomMap(cx, &script->atomMap);
|
||||
if (js_InterpreterHooks && js_InterpreterHooks->destroyScript)
|
||||
js_InterpreterHooks->destroyScript(cx, script);
|
||||
JS_free(cx, (void *)script->filename);
|
||||
JS_free(cx, script->notes);
|
||||
JS_free(cx, script->trynotes);
|
||||
if (script->principals)
|
||||
JSPRINCIPALS_DROP(cx, script->principals);
|
||||
JS_free(cx, script);
|
||||
}
|
||||
|
||||
jssrcnote *
|
||||
js_GetSrcNote(JSScript *script, jsbytecode *pc)
|
||||
{
|
||||
jssrcnote *sn;
|
||||
ptrdiff_t offset, target;
|
||||
|
||||
sn = script->notes;
|
||||
if (!sn)
|
||||
return NULL;
|
||||
target = PTRDIFF(pc, script->code, jsbytecode);
|
||||
if ((uintN)target >= script->length)
|
||||
return NULL;
|
||||
for (offset = 0; !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) {
|
||||
offset += SN_DELTA(sn);
|
||||
if (offset == target && SN_IS_GETTABLE(sn))
|
||||
return sn;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uintN
|
||||
js_PCToLineNumber(JSScript *script, jsbytecode *pc)
|
||||
{
|
||||
jssrcnote *sn;
|
||||
ptrdiff_t offset, target;
|
||||
uintN lineno;
|
||||
JSSrcNoteType type;
|
||||
|
||||
sn = script->notes;
|
||||
if (!sn)
|
||||
return 0;
|
||||
target = PTRDIFF(pc, script->code, jsbytecode);
|
||||
lineno = script->lineno;
|
||||
for (offset = 0; !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) {
|
||||
offset += SN_DELTA(sn);
|
||||
type = SN_TYPE(sn);
|
||||
if (type == SRC_SETLINE) {
|
||||
if (offset <= target)
|
||||
lineno = (uintN) js_GetSrcNoteOffset(sn, 0);
|
||||
} else if (type == SRC_NEWLINE) {
|
||||
if (offset <= target)
|
||||
lineno++;
|
||||
}
|
||||
if (offset > target)
|
||||
break;
|
||||
}
|
||||
return lineno;
|
||||
}
|
||||
|
||||
jsbytecode *
|
||||
js_LineNumberToPC(JSScript *script, uintN target)
|
||||
{
|
||||
jssrcnote *sn;
|
||||
uintN lineno;
|
||||
ptrdiff_t offset;
|
||||
JSSrcNoteType type;
|
||||
|
||||
sn = script->notes;
|
||||
if (!sn)
|
||||
return NULL;
|
||||
lineno = script->lineno;
|
||||
for (offset = 0; !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) {
|
||||
if (lineno >= target)
|
||||
break;
|
||||
offset += SN_DELTA(sn);
|
||||
type = SN_TYPE(sn);
|
||||
if (type == SRC_SETLINE) {
|
||||
lineno = (uintN) js_GetSrcNoteOffset(sn, 0);
|
||||
} else if (type == SRC_NEWLINE) {
|
||||
lineno++;
|
||||
}
|
||||
}
|
||||
return script->code + offset;
|
||||
}
|
||||
|
||||
uintN
|
||||
js_GetScriptLineExtent(JSScript *script)
|
||||
{
|
||||
jssrcnote *sn;
|
||||
uintN lineno;
|
||||
JSSrcNoteType type;
|
||||
|
||||
sn = script->notes;
|
||||
if (!sn)
|
||||
return 0;
|
||||
lineno = script->lineno;
|
||||
for (; !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) {
|
||||
type = SN_TYPE(sn);
|
||||
if (type == SRC_SETLINE) {
|
||||
lineno = (uintN) js_GetSrcNoteOffset(sn, 0);
|
||||
} else if (type == SRC_NEWLINE) {
|
||||
lineno++;
|
||||
}
|
||||
}
|
||||
return 1 + lineno - script->lineno;
|
||||
}
|
282
js/ref/jsstr.c
282
js/ref/jsstr.c
|
@ -53,7 +53,7 @@
|
|||
|
||||
/* Contributions from the String class to the set of methods defined for the
|
||||
* global object. escape and unescape used to be defined in the Mocha library,
|
||||
* but as ECMA decided to spec them. So they've been moved to the core engine
|
||||
* but as ECMA decided to spec them, they've been moved to the core engine
|
||||
* and made ECMA-compliant. (Incomplete escapes are interpreted as literal
|
||||
* characters by unescape.)
|
||||
*/
|
||||
|
@ -75,13 +75,13 @@ static const unsigned char netCharType[256] =
|
|||
*/
|
||||
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
|
||||
{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x */
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1x */
|
||||
0,0,0,0,0,0,0,0,0,0,7,4,0,7,7,4, /* 2x !"#$%&'()*+,-./ */
|
||||
7,7,7,7,7,7,7,7,7,7,0,0,0,0,0,0, /* 3x 0123456789:;<=>? */
|
||||
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, /* 4x @ABCDEFGHIJKLMNO */
|
||||
7,7,7,7,7,7,7,7,7,7,7,0,0,0,0,7, /* 5X PQRSTUVWXYZ[\]^_ */
|
||||
0,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, /* 6x `abcdefghijklmno */
|
||||
7,7,7,7,7,7,7,7,7,7,7,0,0,0,0,0, /* 7X pqrstuvwxyz{\}~ DEL */
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1x */
|
||||
0,0,0,0,0,0,0,0,0,0,7,4,0,7,7,4, /* 2x !"#$%&'()*+,-./ */
|
||||
7,7,7,7,7,7,7,7,7,7,0,0,0,0,0,0, /* 3x 0123456789:;<=>? */
|
||||
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, /* 4x @ABCDEFGHIJKLMNO */
|
||||
7,7,7,7,7,7,7,7,7,7,7,0,0,0,0,7, /* 5X PQRSTUVWXYZ[\]^_ */
|
||||
0,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, /* 6x `abcdefghijklmno */
|
||||
7,7,7,7,7,7,7,7,7,7,7,0,0,0,0,0, /* 7X pqrstuvwxyz{\}~ DEL */
|
||||
0, };
|
||||
|
||||
/* This matches the ECMA escape set when mask is 7 (default.) */
|
||||
|
@ -100,74 +100,74 @@ str_escape(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
jsint mask;
|
||||
jsdouble d;
|
||||
const char digits[] = {'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
|
||||
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
|
||||
|
||||
if (argc > 1) {
|
||||
if (!js_ValueToNumber(cx, argv[1], &d))
|
||||
return JS_FALSE;
|
||||
if (!JSDOUBLE_IS_FINITE(d) ||
|
||||
(mask = (jsint)d) != d ||
|
||||
mask & ~(URL_XALPHAS | URL_XPALPHAS | URL_PATH))
|
||||
{
|
||||
if (!js_ValueToNumber(cx, argv[1], &d))
|
||||
return JS_FALSE;
|
||||
if (!JSDOUBLE_IS_FINITE(d) ||
|
||||
(mask = (jsint)d) != d ||
|
||||
mask & ~(URL_XALPHAS | URL_XPALPHAS | URL_PATH))
|
||||
{
|
||||
char numBuf[12];
|
||||
sprintf(numBuf, "%x", mask);
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_BAD_STRING_MASK, numBuf);
|
||||
return JS_FALSE;
|
||||
}
|
||||
PR_snprintf(numBuf, sizeof numBuf, "%lx", (unsigned long) mask);
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_BAD_STRING_MASK, numBuf);
|
||||
return JS_FALSE;
|
||||
}
|
||||
} else {
|
||||
mask = URL_XALPHAS | URL_XPALPHAS | URL_PATH;
|
||||
mask = URL_XALPHAS | URL_XPALPHAS | URL_PATH;
|
||||
}
|
||||
|
||||
str = js_ValueToString(cx, argv[0]);
|
||||
if (!str)
|
||||
return JS_FALSE;
|
||||
return JS_FALSE;
|
||||
argv[0] = STRING_TO_JSVAL(str);
|
||||
|
||||
chars = str->chars;
|
||||
newlength = str->length;
|
||||
/* Take a first pass and see how big the result string will need to be. */
|
||||
for (i = 0; i < str->length; i++) {
|
||||
if ((ch = chars[i]) < 128 && IS_OK(ch, mask)) {
|
||||
continue;
|
||||
} else if (ch < 256) {
|
||||
if (mask == URL_XPALPHAS && ch == ' ')
|
||||
continue; /* The character will be encoded as '+' */
|
||||
else
|
||||
newlength += 2; /* The character will be encoded as %XX */
|
||||
} else {
|
||||
newlength += 5; /* The character will be encoded as %uXXXX */
|
||||
}
|
||||
if ((ch = chars[i]) < 128 && IS_OK(ch, mask)) {
|
||||
continue;
|
||||
} else if (ch < 256) {
|
||||
if (mask == URL_XPALPHAS && ch == ' ')
|
||||
continue; /* The character will be encoded as '+' */
|
||||
else
|
||||
newlength += 2; /* The character will be encoded as %XX */
|
||||
} else {
|
||||
newlength += 5; /* The character will be encoded as %uXXXX */
|
||||
}
|
||||
}
|
||||
|
||||
newchars = (jschar *) JS_malloc(cx, (newlength + 1) * sizeof(jschar));
|
||||
for (i = 0, ni = 0; i < str->length; i++) {
|
||||
if ((ch = chars[i]) < 128 && IS_OK(ch, mask)) {
|
||||
newchars[ni++] = ch;
|
||||
} else if (ch < 256) {
|
||||
if (mask == URL_XPALPHAS && ch == ' ') {
|
||||
newchars[ni++] = '+'; /* convert spaces to pluses */
|
||||
} else {
|
||||
newchars[ni++] = '%';
|
||||
newchars[ni++] = digits[ch >> 4];
|
||||
newchars[ni++] = digits[ch & 0xF];
|
||||
}
|
||||
} else {
|
||||
newchars[ni++] = '%';
|
||||
newchars[ni++] = 'u';
|
||||
newchars[ni++] = digits[ch >> 12];
|
||||
newchars[ni++] = digits[(ch & 0xF00) >> 8];
|
||||
newchars[ni++] = digits[(ch & 0xF0) >> 4];
|
||||
newchars[ni++] = digits[ch & 0xF];
|
||||
}
|
||||
if ((ch = chars[i]) < 128 && IS_OK(ch, mask)) {
|
||||
newchars[ni++] = ch;
|
||||
} else if (ch < 256) {
|
||||
if (mask == URL_XPALPHAS && ch == ' ') {
|
||||
newchars[ni++] = '+'; /* convert spaces to pluses */
|
||||
} else {
|
||||
newchars[ni++] = '%';
|
||||
newchars[ni++] = digits[ch >> 4];
|
||||
newchars[ni++] = digits[ch & 0xF];
|
||||
}
|
||||
} else {
|
||||
newchars[ni++] = '%';
|
||||
newchars[ni++] = 'u';
|
||||
newchars[ni++] = digits[ch >> 12];
|
||||
newchars[ni++] = digits[(ch & 0xF00) >> 8];
|
||||
newchars[ni++] = digits[(ch & 0xF0) >> 4];
|
||||
newchars[ni++] = digits[ch & 0xF];
|
||||
}
|
||||
}
|
||||
PR_ASSERT(ni == newlength);
|
||||
newchars[newlength] = 0;
|
||||
|
||||
str = js_NewString(cx, newchars, newlength, 0);
|
||||
if (!str) {
|
||||
JS_free(cx, newchars);
|
||||
return JS_FALSE;
|
||||
JS_free(cx, newchars);
|
||||
return JS_FALSE;
|
||||
}
|
||||
*rval = STRING_TO_JSVAL(str);
|
||||
return JS_TRUE;
|
||||
|
@ -186,7 +186,7 @@ str_unescape(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
|
||||
str = js_ValueToString(cx, argv[0]);
|
||||
if (!str)
|
||||
return JS_FALSE;
|
||||
return JS_FALSE;
|
||||
argv[0] = STRING_TO_JSVAL(str);
|
||||
|
||||
chars = str->chars;
|
||||
|
@ -194,32 +194,32 @@ str_unescape(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
newchars = (jschar *) JS_malloc(cx, (str->length + 1) * sizeof(jschar));
|
||||
ni = i = 0;
|
||||
while (i < str->length) {
|
||||
ch = chars[i++];
|
||||
if (ch == '%') {
|
||||
if (i + 1 < str->length &&
|
||||
JS7_ISHEX(chars[i]) && JS7_ISHEX(chars[i + 1]))
|
||||
{
|
||||
ch = JS7_UNHEX(chars[i]) * 16 + JS7_UNHEX(chars[i + 1]);
|
||||
i += 2;
|
||||
} else if (i + 4 < str->length && chars[i] == 'u' &&
|
||||
JS7_ISHEX(chars[i + 1]) && JS7_ISHEX(chars[i + 2]) &&
|
||||
JS7_ISHEX(chars[i + 3]) && JS7_ISHEX(chars[i + 4]))
|
||||
{
|
||||
ch = (((((JS7_UNHEX(chars[i + 1]) << 4)
|
||||
+ JS7_UNHEX(chars[i + 2])) << 4)
|
||||
+ JS7_UNHEX(chars[i + 3])) << 4)
|
||||
+ JS7_UNHEX(chars[i + 4]);
|
||||
i += 5;
|
||||
}
|
||||
}
|
||||
newchars[ni++] = ch;
|
||||
ch = chars[i++];
|
||||
if (ch == '%') {
|
||||
if (i + 1 < str->length &&
|
||||
JS7_ISHEX(chars[i]) && JS7_ISHEX(chars[i + 1]))
|
||||
{
|
||||
ch = JS7_UNHEX(chars[i]) * 16 + JS7_UNHEX(chars[i + 1]);
|
||||
i += 2;
|
||||
} else if (i + 4 < str->length && chars[i] == 'u' &&
|
||||
JS7_ISHEX(chars[i + 1]) && JS7_ISHEX(chars[i + 2]) &&
|
||||
JS7_ISHEX(chars[i + 3]) && JS7_ISHEX(chars[i + 4]))
|
||||
{
|
||||
ch = (((((JS7_UNHEX(chars[i + 1]) << 4)
|
||||
+ JS7_UNHEX(chars[i + 2])) << 4)
|
||||
+ JS7_UNHEX(chars[i + 3])) << 4)
|
||||
+ JS7_UNHEX(chars[i + 4]);
|
||||
i += 5;
|
||||
}
|
||||
}
|
||||
newchars[ni++] = ch;
|
||||
}
|
||||
newchars[ni] = 0;
|
||||
|
||||
str = js_NewString(cx, newchars, ni, 0);
|
||||
if (!str) {
|
||||
JS_free(cx, newchars);
|
||||
return JS_FALSE;
|
||||
JS_free(cx, newchars);
|
||||
return JS_FALSE;
|
||||
}
|
||||
*rval = STRING_TO_JSVAL(str);
|
||||
return JS_TRUE;
|
||||
|
@ -344,7 +344,7 @@ str_quote(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
return JS_FALSE;
|
||||
str = js_QuoteString(cx, str, '"');
|
||||
if (!str)
|
||||
return JS_FALSE;
|
||||
return JS_FALSE;
|
||||
*rval = STRING_TO_JSVAL(str);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
@ -365,25 +365,25 @@ str_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
return js_obj_toSource(cx, obj, argc, argv, rval);
|
||||
str = js_QuoteString(cx, JSVAL_TO_STRING(v), '"');
|
||||
if (!str)
|
||||
return JS_FALSE;
|
||||
return JS_FALSE;
|
||||
j = PR_snprintf(buf, sizeof buf, "(new %s(", string_class.name);
|
||||
s = str->chars;
|
||||
k = str->length;
|
||||
n = j + k + 2;
|
||||
t = JS_malloc(cx, (n + 1) * sizeof(jschar));
|
||||
if (!t)
|
||||
return JS_FALSE;
|
||||
return JS_FALSE;
|
||||
for (i = 0; i < j; i++)
|
||||
t[i] = buf[i];
|
||||
t[i] = buf[i];
|
||||
for (j = 0; j < k; i++, j++)
|
||||
t[i] = s[j];
|
||||
t[i] = s[j];
|
||||
t[i++] = ')';
|
||||
t[i++] = ')';
|
||||
t[i] = 0;
|
||||
str = js_NewString(cx, t, n, 0);
|
||||
if (!str) {
|
||||
JS_free(cx, t);
|
||||
return JS_FALSE;
|
||||
JS_free(cx, t);
|
||||
return JS_FALSE;
|
||||
}
|
||||
*rval = STRING_TO_JSVAL(str);
|
||||
return JS_TRUE;
|
||||
|
@ -463,7 +463,7 @@ str_substring(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
|||
}
|
||||
|
||||
str = js_NewStringCopyN(cx, str->chars + (size_t)begin,
|
||||
(size_t)(end - begin), 0);
|
||||
(size_t)(end - begin), 0);
|
||||
if (!str)
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
@ -546,7 +546,7 @@ str_charAt(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
if (d < 0 || str->length <= d) {
|
||||
*rval = JS_GetEmptyStringValue(cx);
|
||||
} else {
|
||||
index = (size_t)d;
|
||||
index = (size_t)d;
|
||||
buf[0] = str->chars[index];
|
||||
buf[1] = 0;
|
||||
str = js_NewStringCopyN(cx, buf, 1, 0);
|
||||
|
@ -574,10 +574,10 @@ str_charCodeAt(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
|||
return JS_FALSE;
|
||||
d = js_DoubleToInteger(d);
|
||||
if (d < 0 || str->length <= d) {
|
||||
*rval = JS_GetNaNValue(cx);
|
||||
*rval = JS_GetNaNValue(cx);
|
||||
} else {
|
||||
index = (size_t)d;
|
||||
*rval = INT_TO_JSVAL((jsint)str->chars[index]);
|
||||
index = (size_t)d;
|
||||
*rval = INT_TO_JSVAL((jsint)str->chars[index]);
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
@ -639,13 +639,13 @@ str_indexOf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
if (argc > 1) {
|
||||
if (!js_ValueToNumber(cx, argv[1], &d))
|
||||
return JS_FALSE;
|
||||
d = js_DoubleToInteger(d);
|
||||
d = js_DoubleToInteger(d);
|
||||
if (d < 0)
|
||||
i = 0;
|
||||
else if (d > textlen)
|
||||
i = textlen;
|
||||
else
|
||||
i = (jsint)d;
|
||||
else
|
||||
i = (jsint)d;
|
||||
} else {
|
||||
i = 0;
|
||||
}
|
||||
|
@ -706,19 +706,19 @@ str_lastIndexOf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
|||
if (argc > 1) {
|
||||
if (!js_ValueToNumber(cx, argv[1], &d))
|
||||
return JS_FALSE;
|
||||
if (JSDOUBLE_IS_NaN(d)) {
|
||||
i = textlen;
|
||||
} else {
|
||||
d = js_DoubleToInteger(d);
|
||||
if (d < 0)
|
||||
i = 0;
|
||||
else if (d > textlen - patlen)
|
||||
i = textlen - patlen;
|
||||
else
|
||||
i = (jsint)d;
|
||||
}
|
||||
if (JSDOUBLE_IS_NaN(d)) {
|
||||
i = textlen;
|
||||
} else {
|
||||
d = js_DoubleToInteger(d);
|
||||
if (d < 0)
|
||||
i = 0;
|
||||
else if (d > textlen - patlen)
|
||||
i = textlen - patlen;
|
||||
else
|
||||
i = (jsint)d;
|
||||
}
|
||||
} else {
|
||||
i = textlen;
|
||||
i = textlen;
|
||||
}
|
||||
|
||||
if (patlen == 0) {
|
||||
|
@ -748,7 +748,7 @@ static JSBool
|
|||
str_nyi(JSContext *cx, const char *what)
|
||||
{
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_NO_STRING_PROTO, what);
|
||||
JSMSG_NO_STRING_PROTO, what);
|
||||
return JS_FALSE;
|
||||
}
|
||||
#endif
|
||||
|
@ -790,7 +790,7 @@ match_or_replace(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
|||
reobj = JSVAL_TO_OBJECT(argv[0]);
|
||||
re = JS_GetPrivate(cx, reobj);
|
||||
} else {
|
||||
src = js_ValueToString(cx, argv[0]);
|
||||
src = js_ValueToString(cx, argv[0]);
|
||||
if (!src)
|
||||
return JS_FALSE;
|
||||
if (data->optarg < argc) {
|
||||
|
@ -831,7 +831,7 @@ match_or_replace(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
|||
if (!ok)
|
||||
break;
|
||||
if (cx->regExpStatics.lastMatch.length == 0) {
|
||||
if (index == str->length)
|
||||
if (index == str->length)
|
||||
break;
|
||||
index++;
|
||||
}
|
||||
|
@ -866,7 +866,7 @@ match_glob(JSContext *cx, jsint count, GlobData *data)
|
|||
mdata = (MatchData *)data;
|
||||
arrayobj = mdata->arrayobj;
|
||||
if (!arrayobj) {
|
||||
arrayobj = js_ConstructObject(cx, &js_ArrayClass, NULL, NULL);
|
||||
arrayobj = js_ConstructObject(cx, &js_ArrayClass, NULL, NULL);
|
||||
if (!arrayobj)
|
||||
return JS_FALSE;
|
||||
mdata->arrayobj = arrayobj;
|
||||
|
@ -1002,11 +1002,11 @@ find_replen(JSContext *cx, ReplaceData *rdata, size_t *sizep)
|
|||
|
||||
lambda = rdata->lambda;
|
||||
if (lambda) {
|
||||
uintN argc, i, j, m, n, p;
|
||||
jsval *sp, *oldsp, rval;
|
||||
void *mark;
|
||||
uintN argc, i, j, m, n, p;
|
||||
jsval *sp, *oldsp, rval;
|
||||
void *mark;
|
||||
JSStackFrame *fp;
|
||||
JSBool ok;
|
||||
JSBool ok;
|
||||
|
||||
/*
|
||||
* In the lambda case, not only do we find the replacement string's
|
||||
|
@ -1016,8 +1016,8 @@ find_replen(JSContext *cx, ReplaceData *rdata, size_t *sizep)
|
|||
* For $&, etc., we must create string jsvals from cx->regExpStatics.
|
||||
* We grab up stack space to keep the newborn strings GC-rooted.
|
||||
*/
|
||||
p = rdata->base.regexp->parenCount;
|
||||
argc = 1 + p + 2;
|
||||
p = rdata->base.regexp->parenCount;
|
||||
argc = 1 + p + 2;
|
||||
sp = js_AllocStack(cx, 2 + argc, &mark);
|
||||
if (!sp)
|
||||
return JS_FALSE;
|
||||
|
@ -1039,14 +1039,14 @@ find_replen(JSContext *cx, ReplaceData *rdata, size_t *sizep)
|
|||
*sp++ = STRING_TO_JSVAL(str); \
|
||||
PR_END_MACRO
|
||||
|
||||
/* Push $&, $1, $2, ... */
|
||||
/* Push $&, $1, $2, ... */
|
||||
PUSH_REGEXP_STATIC(lastMatch);
|
||||
i = 0;
|
||||
m = cx->regExpStatics.parenCount;
|
||||
n = PR_MIN(m, 9);
|
||||
for (j = 0; i < n; i++, j++)
|
||||
m = cx->regExpStatics.parenCount;
|
||||
n = PR_MIN(m, 9);
|
||||
for (j = 0; i < n; i++, j++)
|
||||
PUSH_REGEXP_STATIC(parens[j]);
|
||||
for (j = 0; i < m; i++, j++)
|
||||
for (j = 0; i < m; i++, j++)
|
||||
PUSH_REGEXP_STATIC(moreParens[j]);
|
||||
|
||||
#undef PUSH_REGEXP_STATIC
|
||||
|
@ -1063,7 +1063,7 @@ find_replen(JSContext *cx, ReplaceData *rdata, size_t *sizep)
|
|||
fp = cx->fp;
|
||||
oldsp = fp->sp;
|
||||
fp->sp = sp;
|
||||
ok = js_Invoke(cx, argc, JS_FALSE);
|
||||
ok = js_Invoke(cx, argc, JS_FALSE);
|
||||
rval = fp->sp[-1];
|
||||
fp->sp = oldsp;
|
||||
|
||||
|
@ -1075,7 +1075,7 @@ find_replen(JSContext *cx, ReplaceData *rdata, size_t *sizep)
|
|||
*/
|
||||
repstr = js_ValueToString(cx, rval);
|
||||
if (!repstr) {
|
||||
ok = JS_FALSE;
|
||||
ok = JS_FALSE;
|
||||
} else {
|
||||
rdata->repstr = repstr;
|
||||
*sizep = repstr->length;
|
||||
|
@ -1084,7 +1084,7 @@ find_replen(JSContext *cx, ReplaceData *rdata, size_t *sizep)
|
|||
|
||||
lambda_out:
|
||||
js_FreeStack(cx, mark);
|
||||
return ok;
|
||||
return ok;
|
||||
}
|
||||
#endif /* JS_HAS_REPLACE_LAMBDA */
|
||||
|
||||
|
@ -1144,7 +1144,7 @@ replace_glob(JSContext *cx, jsint count, GlobData *data)
|
|||
rdata->leftIndex = cx->regExpStatics.lastMatch.chars - str->chars;
|
||||
rdata->leftIndex += cx->regExpStatics.lastMatch.length;
|
||||
if (!find_replen(cx, rdata, &replen))
|
||||
return JS_FALSE;
|
||||
return JS_FALSE;
|
||||
growth = leftlen + replen;
|
||||
chars = rdata->chars
|
||||
? JS_realloc(cx, rdata->chars, (rdata->length + growth + 1)
|
||||
|
@ -1178,8 +1178,8 @@ str_replace(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
|
||||
#if JS_HAS_REPLACE_LAMBDA
|
||||
if (JS_TypeOfValue(cx, argv[1]) == JSTYPE_FUNCTION) {
|
||||
lambda = JSVAL_TO_OBJECT(argv[1]);
|
||||
repstr = NULL;
|
||||
lambda = JSVAL_TO_OBJECT(argv[1]);
|
||||
repstr = NULL;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
|
@ -1339,17 +1339,17 @@ find_split(JSContext *cx, JSString *str, JSRegExp *re, jsint *ip,
|
|||
* in match_or_replace.
|
||||
*/
|
||||
if (i == *ip) {
|
||||
/*
|
||||
* "Bump-along" to avoid sticking at an empty match, but don't
|
||||
* bump past end of string -- our caller must do that by adding
|
||||
* sep->length to our return value.
|
||||
*/
|
||||
if ((size_t)i == str->length) {
|
||||
/*
|
||||
* "Bump-along" to avoid sticking at an empty match, but don't
|
||||
* bump past end of string -- our caller must do that by adding
|
||||
* sep->length to our return value.
|
||||
*/
|
||||
if ((size_t)i == str->length) {
|
||||
sep->length = 1;
|
||||
return i;
|
||||
}
|
||||
i++;
|
||||
goto again;
|
||||
i++;
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
PR_ASSERT((size_t)i >= sep->length);
|
||||
|
@ -1437,19 +1437,19 @@ str_split(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
re = NULL;
|
||||
}
|
||||
|
||||
/* Use the second argument as the split limit, if given. */
|
||||
/* XXX our v2 ecma spec checks against given, undefined. */
|
||||
/* Use the second argument as the split limit, if given. */
|
||||
/* XXX our v2 ecma spec checks against given, undefined. */
|
||||
limited = (argc > 1);
|
||||
if (limited) {
|
||||
if (!js_ValueToNumber(cx, argv[1], &d))
|
||||
return JS_FALSE;
|
||||
|
||||
/* Clamp limit between 0 and 1 + string length. */
|
||||
d = js_DoubleToInteger(d);
|
||||
if (d < 0)
|
||||
d = 0;
|
||||
else if (d > str->length)
|
||||
d = 1 + str->length;
|
||||
/* Clamp limit between 0 and 1 + string length. */
|
||||
d = js_DoubleToInteger(d);
|
||||
if (d < 0)
|
||||
d = 0;
|
||||
else if (d > str->length)
|
||||
d = 1 + str->length;
|
||||
limit = (jsint)d;
|
||||
}
|
||||
|
||||
|
@ -1560,7 +1560,7 @@ str_substr(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
}
|
||||
|
||||
str = js_NewStringCopyN(cx, str->chars + (size_t)begin,
|
||||
(size_t)(end - begin), 0);
|
||||
(size_t)(end - begin), 0);
|
||||
if (!str)
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
@ -1713,7 +1713,7 @@ str_slice(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|||
}
|
||||
|
||||
str = js_NewStringCopyN(cx, str->chars + (size_t)begin,
|
||||
(size_t)(end - begin), 0);
|
||||
(size_t)(end - begin), 0);
|
||||
if (!str)
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
@ -2246,7 +2246,7 @@ js_SkipWhiteSpace(const jschar *s)
|
|||
{
|
||||
/* JS_ISSPACE is false on a null. */
|
||||
while (JS_ISSPACE(*s))
|
||||
s++;
|
||||
s++;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <string.h>
|
||||
#include "prtypes.h"
|
||||
#include "prassert.h"
|
||||
#include "prprintf.h"
|
||||
#include "jsapi.h"
|
||||
#include "jscntxt.h"
|
||||
#include "jsobj.h" /* js_XDRObject */
|
||||
|
@ -47,10 +48,10 @@ typedef struct JSXDRMemState {
|
|||
|
||||
#define MEM_LEFT(xdr, bytes) \
|
||||
PR_BEGIN_MACRO \
|
||||
if ((xdr)->mode == JSXDR_DECODE && \
|
||||
if ((xdr)->mode == JSXDR_DECODE && \
|
||||
MEM_COUNT(xdr) + bytes > MEM_LIMIT(xdr)) { \
|
||||
JS_ReportErrorNumber((xdr)->cx, js_GetErrorMessage, NULL, \
|
||||
JSMSG_END_OF_DATA); \
|
||||
JSMSG_END_OF_DATA); \
|
||||
return 0; \
|
||||
} \
|
||||
PR_END_MACRO
|
||||
|
@ -58,7 +59,7 @@ typedef struct JSXDRMemState {
|
|||
/* XXXbe why does NEED even allow or cope with non-ENCODE mode? */
|
||||
#define MEM_NEED(xdr, bytes) \
|
||||
PR_BEGIN_MACRO \
|
||||
if ((xdr)->mode == JSXDR_ENCODE) { \
|
||||
if ((xdr)->mode == JSXDR_ENCODE) { \
|
||||
if (MEM_LIMIT(xdr) && \
|
||||
MEM_COUNT(xdr) + bytes > MEM_LIMIT(xdr)) { \
|
||||
void *_data = JS_realloc((xdr)->cx, \
|
||||
|
@ -72,7 +73,7 @@ typedef struct JSXDRMemState {
|
|||
} else { \
|
||||
if (MEM_LIMIT(xdr) < MEM_COUNT(xdr) + bytes) { \
|
||||
JS_ReportErrorNumber((xdr)->cx, js_GetErrorMessage, NULL, \
|
||||
JSMSG_END_OF_DATA); \
|
||||
JSMSG_END_OF_DATA); \
|
||||
return 0; \
|
||||
} \
|
||||
} \
|
||||
|
@ -122,9 +123,9 @@ mem_raw(JSXDRState *xdr, uint32 len)
|
|||
{
|
||||
void *data;
|
||||
if (xdr->mode == JSXDR_ENCODE) {
|
||||
MEM_NEED(xdr, len);
|
||||
MEM_NEED(xdr, len);
|
||||
} else if (xdr->mode == JSXDR_DECODE) {
|
||||
MEM_LEFT(xdr, len);
|
||||
MEM_LEFT(xdr, len);
|
||||
}
|
||||
data = MEM_DATA(xdr);
|
||||
MEM_INCR(xdr, len);
|
||||
|
@ -138,7 +139,7 @@ mem_seek(JSXDRState *xdr, int32 offset, JSXDRWhence whence)
|
|||
case JSXDR_SEEK_CUR:
|
||||
if ((int32)MEM_COUNT(xdr) + offset < 0) {
|
||||
JS_ReportErrorNumber(xdr->cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_SEEK_BEYOND_START);
|
||||
JSMSG_SEEK_BEYOND_START);
|
||||
return JS_FALSE;
|
||||
}
|
||||
if (offset > 0)
|
||||
|
@ -148,7 +149,7 @@ mem_seek(JSXDRState *xdr, int32 offset, JSXDRWhence whence)
|
|||
case JSXDR_SEEK_SET:
|
||||
if (offset < 0) {
|
||||
JS_ReportErrorNumber(xdr->cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_SEEK_BEYOND_START);
|
||||
JSMSG_SEEK_BEYOND_START);
|
||||
return JS_FALSE;
|
||||
}
|
||||
if (xdr->mode == JSXDR_ENCODE) {
|
||||
|
@ -158,7 +159,7 @@ mem_seek(JSXDRState *xdr, int32 offset, JSXDRWhence whence)
|
|||
} else {
|
||||
if ((uint32)offset > MEM_LIMIT(xdr)) {
|
||||
JS_ReportErrorNumber(xdr->cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_SEEK_BEYOND_END);
|
||||
JSMSG_SEEK_BEYOND_END);
|
||||
return JS_FALSE;
|
||||
}
|
||||
MEM_COUNT(xdr) = offset;
|
||||
|
@ -169,18 +170,18 @@ mem_seek(JSXDRState *xdr, int32 offset, JSXDRWhence whence)
|
|||
xdr->mode == JSXDR_ENCODE ||
|
||||
(int32)MEM_LIMIT(xdr) + offset < 0) {
|
||||
JS_ReportErrorNumber(xdr->cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_END_SEEK);
|
||||
JSMSG_END_SEEK);
|
||||
return JS_FALSE;
|
||||
}
|
||||
MEM_COUNT(xdr) = MEM_LIMIT(xdr) + offset;
|
||||
return JS_TRUE;
|
||||
default: {
|
||||
char numBuf[12];
|
||||
sprintf(numBuf, "%d", whence);
|
||||
PR_snprintf(numBuf, sizeof numBuf, "%d", whence);
|
||||
JS_ReportErrorNumber(xdr->cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_WHITHER_WHENCE, numBuf);
|
||||
}
|
||||
JSMSG_WHITHER_WHENCE, numBuf);
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -331,8 +332,8 @@ JS_XDRCString(JSXDRState *xdr, char **sp)
|
|||
if (xdr->mode == JSXDR_DECODE) {
|
||||
(*sp)[len] = '\0';
|
||||
} else if (xdr->mode == JSXDR_FREE) {
|
||||
JS_free(xdr->cx, *sp);
|
||||
*sp = NULL;
|
||||
JS_free(xdr->cx, *sp);
|
||||
*sp = NULL;
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
@ -373,7 +374,7 @@ JS_XDRString(JSXDRState *xdr, JSString **strp)
|
|||
}
|
||||
|
||||
if (nbytes % JSXDR_ALIGN)
|
||||
nbytes += JSXDR_ALIGN - (nbytes % JSXDR_ALIGN);
|
||||
nbytes += JSXDR_ALIGN - (nbytes % JSXDR_ALIGN);
|
||||
if (!(raw = xdr->ops->raw(xdr, nbytes)))
|
||||
goto bad;
|
||||
if (xdr->mode == JSXDR_ENCODE) {
|
||||
|
@ -465,7 +466,7 @@ JS_XDRValue(JSXDRState *xdr, jsval *vp)
|
|||
break;
|
||||
}
|
||||
case JSVAL_BOOLEAN: {
|
||||
uint32 b;
|
||||
uint32 b;
|
||||
if (xdr->mode == JSXDR_ENCODE)
|
||||
b = (uint32)JSVAL_TO_BOOLEAN(*vp);
|
||||
if (!JS_XDRUint32(xdr, &b))
|
||||
|
@ -490,11 +491,11 @@ JS_XDRValue(JSXDRState *xdr, jsval *vp)
|
|||
*vp = INT_TO_JSVAL(i);
|
||||
break;
|
||||
}
|
||||
sprintf(numBuf, "%#lx", type);
|
||||
PR_snprintf(numBuf, sizeof numBuf, "%#lx", type);
|
||||
JS_ReportErrorNumber(xdr->cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_BAD_JVAL_TYPE, type);
|
||||
}
|
||||
JSMSG_BAD_JVAL_TYPE, type);
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче