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:
brendan%netscape.com 1998-09-08 05:39:51 +00:00
Родитель 97fe5038d8
Коммит f8bbc56e36
36 изменённых файлов: 5125 добавлений и 11471 удалений

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

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

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

@ -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 */

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

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

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

@ -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___ */

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

@ -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
/*

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

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

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

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

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

@ -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.

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

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

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

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

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

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

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

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

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

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

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

@ -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___ */

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

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

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

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

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

@ -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.
*/

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

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

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

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