jbarnette-johnson 1.0.0.20090326161333 → 1.0.0.20090402144841
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +8 -3
- data/Rakefile +1 -0
- data/ext/spidermonkey/runtime.c +36 -12
- data/johnson.gemspec +5 -5
- data/lib/johnson/runtime.rb +1 -1
- data/lib/johnson/spidermonkey/runtime.rb +9 -0
- data/lib/tasks/testing.rake +8 -8
- data/vendor/spidermonkey/Makefile.in +0 -13
- data/vendor/spidermonkey/Makefile.ref +1 -0
- data/vendor/spidermonkey/config.mk +0 -4
- data/vendor/spidermonkey/fdlibm/fdlibm.mak +1453 -1453
- data/vendor/spidermonkey/js.msg +1 -0
- data/vendor/spidermonkey/jsapi.c +1 -1
- data/vendor/spidermonkey/jsarray.c +38 -30
- data/vendor/spidermonkey/jsarray.h +3 -0
- data/vendor/spidermonkey/jscpucfg.c +14 -1
- data/vendor/spidermonkey/jsdate.c +17 -25
- data/vendor/spidermonkey/jsdbgapi.c +6 -3
- data/vendor/spidermonkey/jsgc.c +10 -2
- data/vendor/spidermonkey/jsinterp.c +77 -51
- data/vendor/spidermonkey/jsinterp.h +5 -1
- data/vendor/spidermonkey/jsmath.c +1 -2
- data/vendor/spidermonkey/jsnum.c +19 -8
- data/vendor/spidermonkey/jsobj.c +27 -11
- data/vendor/spidermonkey/jsopcode.c +1 -1
- data/vendor/spidermonkey/jsparse.c +33 -9
- data/vendor/spidermonkey/jsregexp.c +15 -3
- data/vendor/spidermonkey/jsscan.c +142 -133
- data/vendor/spidermonkey/jsscope.c +12 -3
- data/vendor/spidermonkey/jsscope.h +2 -2
- data/vendor/spidermonkey/jsstr.c +5 -4
- data/vendor/spidermonkey/jsxml.c +82 -77
- metadata +3 -3
- data/MINGW32.mk +0 -124
- data/vendor/spidermonkey/config/FreeBSD.mk +0 -103
- data/vendor/spidermonkey/js.mak +0 -4438
data/vendor/spidermonkey/jsobj.c
CHANGED
@@ -299,8 +299,13 @@ js_SetProtoOrParent(JSContext *cx, JSObject *obj, uint32 slot, JSObject *pobj)
|
|
299
299
|
JS_LOCK_GC(rt);
|
300
300
|
ssr.next = rt->setSlotRequests;
|
301
301
|
rt->setSlotRequests = &ssr;
|
302
|
-
|
303
|
-
|
302
|
+
for (;;) {
|
303
|
+
js_GC(cx, GC_SET_SLOT_REQUEST);
|
304
|
+
JS_UNLOCK_GC(rt);
|
305
|
+
if (!rt->setSlotRequests)
|
306
|
+
break;
|
307
|
+
JS_LOCK_GC(rt);
|
308
|
+
}
|
304
309
|
|
305
310
|
if (ssr.errnum != JSMSG_NOT_AN_ERROR) {
|
306
311
|
if (ssr.errnum == JSMSG_OUT_OF_MEMORY) {
|
@@ -1140,8 +1145,10 @@ js_ComputeFilename(JSContext *cx, JSStackFrame *caller,
|
|
1140
1145
|
{
|
1141
1146
|
uint32 flags;
|
1142
1147
|
|
1148
|
+
JS_ASSERT(principals || !cx->runtime->findObjectPrincipals);
|
1143
1149
|
flags = JS_GetScriptFilenameFlags(caller->script);
|
1144
1150
|
if ((flags & JSFILENAME_PROTECTED) &&
|
1151
|
+
principals &&
|
1145
1152
|
strcmp(principals->codebase, "[System Principal]")) {
|
1146
1153
|
*linenop = 0;
|
1147
1154
|
return principals->codebase;
|
@@ -1214,13 +1221,16 @@ obj_eval(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|
1214
1221
|
return JS_FALSE;
|
1215
1222
|
|
1216
1223
|
/*
|
1217
|
-
* Script.prototype.compile/exec and Object.prototype.eval
|
1218
|
-
* optional trailing argument
|
1224
|
+
* Script.prototype.compile/exec and Object.prototype.eval no longer take
|
1225
|
+
* an optional trailing argument.
|
1219
1226
|
*/
|
1220
1227
|
if (argc >= 2) {
|
1221
|
-
if (!
|
1228
|
+
if (!JS_ReportErrorFlagsAndNumber(cx,
|
1229
|
+
JSREPORT_WARNING | JSREPORT_STRICT,
|
1230
|
+
js_GetErrorMessage, NULL,
|
1231
|
+
JSMSG_EVAL_ARITY)) {
|
1222
1232
|
return JS_FALSE;
|
1223
|
-
|
1233
|
+
}
|
1224
1234
|
}
|
1225
1235
|
|
1226
1236
|
/* From here on, control must exit through label out with ok set. */
|
@@ -1242,7 +1252,7 @@ obj_eval(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
|
1242
1252
|
}
|
1243
1253
|
if (obj != callerScopeChain) {
|
1244
1254
|
ok = js_CheckPrincipalsAccess(cx, obj,
|
1245
|
-
caller
|
1255
|
+
JS_StackFramePrincipals(cx, caller),
|
1246
1256
|
cx->runtime->atomState.evalAtom);
|
1247
1257
|
if (!ok)
|
1248
1258
|
goto out;
|
@@ -1432,6 +1442,9 @@ obj_watch(JSContext *cx, uintN argc, jsval *vp)
|
|
1432
1442
|
if (attrs & JSPROP_READONLY)
|
1433
1443
|
return JS_TRUE;
|
1434
1444
|
*vp = JSVAL_VOID;
|
1445
|
+
|
1446
|
+
if (OBJ_IS_DENSE_ARRAY(cx, obj) && !js_MakeArraySlow(cx, obj))
|
1447
|
+
return JS_FALSE;
|
1435
1448
|
return JS_SetWatchPoint(cx, obj, userid, obj_watch_handler, callable);
|
1436
1449
|
}
|
1437
1450
|
|
@@ -3341,7 +3354,8 @@ js_LookupPropertyWithFlags(JSContext *cx, JSObject *obj, jsid id, uintN flags,
|
|
3341
3354
|
/* Resolved: juggle locks and lookup id again. */
|
3342
3355
|
if (obj2 != obj) {
|
3343
3356
|
JS_UNLOCK_OBJ(cx, obj);
|
3344
|
-
|
3357
|
+
if (OBJ_IS_NATIVE(obj2))
|
3358
|
+
JS_LOCK_OBJ(cx, obj2);
|
3345
3359
|
}
|
3346
3360
|
protoIndex = 0;
|
3347
3361
|
for (proto = start; proto && proto != obj2;
|
@@ -3352,7 +3366,6 @@ js_LookupPropertyWithFlags(JSContext *cx, JSObject *obj, jsid id, uintN flags,
|
|
3352
3366
|
if (!MAP_IS_NATIVE(&scope->map)) {
|
3353
3367
|
/* Whoops, newresolve handed back a foreign obj2. */
|
3354
3368
|
JS_ASSERT(obj2 != obj);
|
3355
|
-
JS_UNLOCK_OBJ(cx, obj2);
|
3356
3369
|
ok = OBJ_LOOKUP_PROPERTY(cx, obj2, id, objp, propp);
|
3357
3370
|
if (!ok || *propp)
|
3358
3371
|
goto cleanup;
|
@@ -3373,7 +3386,8 @@ js_LookupPropertyWithFlags(JSContext *cx, JSObject *obj, jsid id, uintN flags,
|
|
3373
3386
|
JS_ASSERT(obj2 == scope->object);
|
3374
3387
|
obj = obj2;
|
3375
3388
|
} else if (obj2 != obj) {
|
3376
|
-
|
3389
|
+
if (OBJ_IS_NATIVE(obj2))
|
3390
|
+
JS_UNLOCK_OBJ(cx, obj2);
|
3377
3391
|
JS_LOCK_OBJ(cx, obj);
|
3378
3392
|
}
|
3379
3393
|
}
|
@@ -4359,8 +4373,10 @@ js_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode,
|
|
4359
4373
|
|
4360
4374
|
/* Avoid diverging for non-natives that reuse js_CheckAccess. */
|
4361
4375
|
if (pobj->map->ops->checkAccess == js_CheckAccess) {
|
4362
|
-
if (!writing)
|
4376
|
+
if (!writing) {
|
4363
4377
|
*vp = JSVAL_VOID;
|
4378
|
+
*attrsp = 0;
|
4379
|
+
}
|
4364
4380
|
break;
|
4365
4381
|
}
|
4366
4382
|
return OBJ_CHECK_ACCESS(cx, pobj, id, mode, vp, attrsp);
|
@@ -4824,7 +4824,7 @@ js_DecompileValueGenerator(JSContext *cx, intN spindex, jsval v,
|
|
4824
4824
|
|
4825
4825
|
for (fp = cx->fp; fp && !fp->script; fp = fp->down)
|
4826
4826
|
continue;
|
4827
|
-
if (!fp || !fp->regs)
|
4827
|
+
if (!fp || !fp->regs || !fp->regs->sp)
|
4828
4828
|
goto do_fallback;
|
4829
4829
|
|
4830
4830
|
script = fp->script;
|
@@ -2029,6 +2029,16 @@ CheckDestructuring(JSContext *cx, BindData *data,
|
|
2029
2029
|
return JS_FALSE;
|
2030
2030
|
}
|
2031
2031
|
|
2032
|
+
#if JS_HAS_DESTRUCTURING_SHORTHAND
|
2033
|
+
if (right &&
|
2034
|
+
right->pn_arity == PN_LIST &&
|
2035
|
+
(right->pn_extra & PNX_SHORTHAND)) {
|
2036
|
+
js_ReportCompileErrorNumber(cx, TS(tc->parseContext), right,
|
2037
|
+
JSREPORT_ERROR, JSMSG_BAD_OBJECT_INIT);
|
2038
|
+
return JS_FALSE;
|
2039
|
+
}
|
2040
|
+
#endif
|
2041
|
+
|
2032
2042
|
fpvd.table.ops = NULL;
|
2033
2043
|
lhs = left->pn_head;
|
2034
2044
|
if (lhs && lhs->pn_type == TOK_DEFSHARP) {
|
@@ -4555,18 +4565,32 @@ MemberExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc,
|
|
4555
4565
|
pn2->pn_pos.begin = pn->pn_pos.begin;
|
4556
4566
|
pn2->pn_pos.end = CURRENT_TOKEN(ts).pos.end;
|
4557
4567
|
|
4558
|
-
/*
|
4559
|
-
|
4560
|
-
|
4561
|
-
|
4562
|
-
|
4563
|
-
|
4564
|
-
|
4565
|
-
|
4568
|
+
/*
|
4569
|
+
* Optimize o['p'] to o.p by rewriting pn2, but avoid rewriting
|
4570
|
+
* o['0'] to use JSOP_GETPROP, to keep fast indexing disjoint in
|
4571
|
+
* the interpreter from fast property access. However, if the
|
4572
|
+
* bracketed string is a uint32, we rewrite pn3 to be a number
|
4573
|
+
* instead of a string.
|
4574
|
+
*/
|
4575
|
+
do {
|
4576
|
+
if (pn3->pn_type == TOK_STRING) {
|
4577
|
+
jsuint index;
|
4578
|
+
|
4579
|
+
if (!js_IdIsIndex(ATOM_TO_JSID(pn3->pn_atom), &index)) {
|
4580
|
+
pn2->pn_type = TOK_DOT;
|
4581
|
+
pn2->pn_op = JSOP_GETPROP;
|
4582
|
+
pn2->pn_arity = PN_NAME;
|
4583
|
+
pn2->pn_expr = pn;
|
4584
|
+
pn2->pn_atom = pn3->pn_atom;
|
4585
|
+
break;
|
4586
|
+
}
|
4587
|
+
pn3->pn_type = TOK_NUMBER;
|
4588
|
+
pn3->pn_dval = index;
|
4589
|
+
}
|
4566
4590
|
pn2->pn_op = JSOP_GETELEM;
|
4567
4591
|
pn2->pn_left = pn;
|
4568
4592
|
pn2->pn_right = pn3;
|
4569
|
-
}
|
4593
|
+
} while (0);
|
4570
4594
|
} else if (allowCallSyntax && tt == TOK_LP) {
|
4571
4595
|
pn2 = NewParseNode(cx, ts, PN_LIST, tc);
|
4572
4596
|
if (!pn2)
|
@@ -3622,12 +3622,17 @@ regexp_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
|
3622
3622
|
|
3623
3623
|
if (!JSVAL_IS_INT(id))
|
3624
3624
|
return JS_TRUE;
|
3625
|
+
while (OBJ_GET_CLASS(cx, obj) != &js_RegExpClass) {
|
3626
|
+
obj = OBJ_GET_PROTO(cx, obj);
|
3627
|
+
if (!obj)
|
3628
|
+
return JS_TRUE;
|
3629
|
+
}
|
3625
3630
|
slot = JSVAL_TO_INT(id);
|
3626
3631
|
if (slot == REGEXP_LAST_INDEX)
|
3627
3632
|
return JS_GetReservedSlot(cx, obj, 0, vp);
|
3628
3633
|
|
3629
3634
|
JS_LOCK_OBJ(cx, obj);
|
3630
|
-
re = (JSRegExp *)
|
3635
|
+
re = (JSRegExp *) JS_GetPrivate(cx, obj);
|
3631
3636
|
if (re) {
|
3632
3637
|
switch (slot) {
|
3633
3638
|
case REGEXP_SOURCE:
|
@@ -3661,6 +3666,11 @@ regexp_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
|
3661
3666
|
ok = JS_TRUE;
|
3662
3667
|
if (!JSVAL_IS_INT(id))
|
3663
3668
|
return ok;
|
3669
|
+
while (OBJ_GET_CLASS(cx, obj) != &js_RegExpClass) {
|
3670
|
+
obj = OBJ_GET_PROTO(cx, obj);
|
3671
|
+
if (!obj)
|
3672
|
+
return JS_TRUE;
|
3673
|
+
}
|
3664
3674
|
slot = JSVAL_TO_INT(id);
|
3665
3675
|
if (slot == REGEXP_LAST_INDEX) {
|
3666
3676
|
if (!JS_ValueToNumber(cx, *vp, &lastIndex))
|
@@ -4298,10 +4308,12 @@ js_NewRegExpObject(JSContext *cx, JSTokenStream *ts,
|
|
4298
4308
|
str = js_NewStringCopyN(cx, chars, length);
|
4299
4309
|
if (!str)
|
4300
4310
|
return NULL;
|
4311
|
+
JS_PUSH_TEMP_ROOT_STRING(cx, str, &tvr);
|
4301
4312
|
re = js_NewRegExp(cx, ts, str, flags, JS_FALSE);
|
4302
|
-
if (!re)
|
4313
|
+
if (!re) {
|
4314
|
+
JS_POP_TEMP_ROOT(cx, &tvr);
|
4303
4315
|
return NULL;
|
4304
|
-
|
4316
|
+
}
|
4305
4317
|
obj = js_NewObject(cx, &js_RegExpClass, NULL, NULL, 0);
|
4306
4318
|
if (!obj || !JS_SetPrivate(cx, obj, re)) {
|
4307
4319
|
js_DestroyRegExp(cx, re);
|
@@ -298,150 +298,144 @@ GetChar(JSTokenStream *ts)
|
|
298
298
|
if (ts->ungetpos != 0) {
|
299
299
|
c = ts->ungetbuf[--ts->ungetpos];
|
300
300
|
} else {
|
301
|
-
|
302
|
-
|
303
|
-
|
301
|
+
if (ts->linebuf.ptr == ts->linebuf.limit) {
|
302
|
+
len = PTRDIFF(ts->userbuf.limit, ts->userbuf.ptr, jschar);
|
303
|
+
if (len <= 0) {
|
304
|
+
if (!ts->file) {
|
305
|
+
ts->flags |= TSF_EOF;
|
306
|
+
return EOF;
|
307
|
+
}
|
308
|
+
|
309
|
+
/* Fill ts->userbuf so that \r and \r\n convert to \n. */
|
310
|
+
crflag = (ts->flags & TSF_CRFLAG) != 0;
|
311
|
+
len = js_fgets(cbuf, JS_LINE_LIMIT - crflag, ts->file);
|
304
312
|
if (len <= 0) {
|
305
|
-
|
306
|
-
|
307
|
-
return EOF;
|
308
|
-
}
|
309
|
-
|
310
|
-
/* Fill ts->userbuf so that \r and \r\n convert to \n. */
|
311
|
-
crflag = (ts->flags & TSF_CRFLAG) != 0;
|
312
|
-
len = js_fgets(cbuf, JS_LINE_LIMIT - crflag, ts->file);
|
313
|
-
if (len <= 0) {
|
314
|
-
ts->flags |= TSF_EOF;
|
315
|
-
return EOF;
|
316
|
-
}
|
317
|
-
olen = len;
|
318
|
-
ubuf = ts->userbuf.base;
|
319
|
-
i = 0;
|
320
|
-
if (crflag) {
|
321
|
-
ts->flags &= ~TSF_CRFLAG;
|
322
|
-
if (cbuf[0] != '\n') {
|
323
|
-
ubuf[i++] = '\n';
|
324
|
-
len++;
|
325
|
-
ts->linepos--;
|
326
|
-
}
|
327
|
-
}
|
328
|
-
for (j = 0; i < len; i++, j++)
|
329
|
-
ubuf[i] = (jschar) (unsigned char) cbuf[j];
|
330
|
-
ts->userbuf.limit = ubuf + len;
|
331
|
-
ts->userbuf.ptr = ubuf;
|
313
|
+
ts->flags |= TSF_EOF;
|
314
|
+
return EOF;
|
332
315
|
}
|
333
|
-
|
334
|
-
|
335
|
-
|
316
|
+
olen = len;
|
317
|
+
ubuf = ts->userbuf.base;
|
318
|
+
i = 0;
|
319
|
+
if (crflag) {
|
320
|
+
ts->flags &= ~TSF_CRFLAG;
|
321
|
+
if (cbuf[0] != '\n') {
|
322
|
+
ubuf[i++] = '\n';
|
323
|
+
len++;
|
324
|
+
ts->linepos--;
|
325
|
+
}
|
336
326
|
}
|
337
|
-
|
338
|
-
|
339
|
-
|
327
|
+
for (j = 0; i < len; i++, j++)
|
328
|
+
ubuf[i] = (jschar) (unsigned char) cbuf[j];
|
329
|
+
ts->userbuf.limit = ubuf + len;
|
330
|
+
ts->userbuf.ptr = ubuf;
|
331
|
+
}
|
332
|
+
if (ts->listener) {
|
333
|
+
ts->listener(ts->filename, ts->lineno, ts->userbuf.ptr, len,
|
334
|
+
&ts->listenerTSData, ts->listenerData);
|
335
|
+
}
|
336
|
+
|
337
|
+
nl = ts->saveEOL;
|
338
|
+
if (!nl) {
|
339
|
+
/*
|
340
|
+
* Any one of \n, \r, or \r\n ends a line (the longest
|
341
|
+
* match wins). Also allow the Unicode line and paragraph
|
342
|
+
* separators.
|
343
|
+
*/
|
344
|
+
for (nl = ts->userbuf.ptr; nl < ts->userbuf.limit; nl++) {
|
340
345
|
/*
|
341
|
-
*
|
342
|
-
*
|
343
|
-
* separators.
|
346
|
+
* Try to prevent value-testing on most characters by
|
347
|
+
* filtering out characters that aren't 000x or 202x.
|
344
348
|
*/
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
break;
|
353
|
-
if (*nl == '\r') {
|
354
|
-
if (nl + 1 < ts->userbuf.limit && nl[1] == '\n')
|
355
|
-
nl++;
|
356
|
-
break;
|
357
|
-
}
|
358
|
-
if (*nl == LINE_SEPARATOR || *nl == PARA_SEPARATOR)
|
359
|
-
break;
|
349
|
+
if ((*nl & 0xDFD0) == 0) {
|
350
|
+
if (*nl == '\n')
|
351
|
+
break;
|
352
|
+
if (*nl == '\r') {
|
353
|
+
if (nl + 1 < ts->userbuf.limit && nl[1] == '\n')
|
354
|
+
nl++;
|
355
|
+
break;
|
360
356
|
}
|
357
|
+
if (*nl == LINE_SEPARATOR || *nl == PARA_SEPARATOR)
|
358
|
+
break;
|
361
359
|
}
|
362
360
|
}
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
ts->flags |= TSF_CRFLAG; /* clear NLFLAG? */
|
396
|
-
if (len == 0) {
|
397
|
-
/*
|
398
|
-
* This can happen when a segment ends in
|
399
|
-
* \r\r. Start over. ptr == limit in this
|
400
|
-
* case, so we'll fall into buffer-filling
|
401
|
-
* code.
|
402
|
-
*/
|
403
|
-
return GetChar(ts);
|
404
|
-
}
|
405
|
-
} else {
|
406
|
-
ts->linebuf.base[len-1] = '\n';
|
407
|
-
}
|
408
|
-
}
|
409
|
-
} else if (*nl == '\n') {
|
410
|
-
if (nl > ts->userbuf.base &&
|
411
|
-
nl[-1] == '\r' &&
|
412
|
-
ts->linebuf.base[len-2] == '\r') {
|
361
|
+
}
|
362
|
+
|
363
|
+
/*
|
364
|
+
* If there was a line terminator, copy thru it into linebuf.
|
365
|
+
* Else copy JS_LINE_LIMIT-1 bytes into linebuf.
|
366
|
+
*/
|
367
|
+
if (nl < ts->userbuf.limit)
|
368
|
+
len = PTRDIFF(nl, ts->userbuf.ptr, jschar) + 1;
|
369
|
+
if (len >= JS_LINE_LIMIT) {
|
370
|
+
len = JS_LINE_LIMIT - 1;
|
371
|
+
ts->saveEOL = nl;
|
372
|
+
} else {
|
373
|
+
ts->saveEOL = NULL;
|
374
|
+
}
|
375
|
+
js_strncpy(ts->linebuf.base, ts->userbuf.ptr, len);
|
376
|
+
ts->userbuf.ptr += len;
|
377
|
+
olen = len;
|
378
|
+
|
379
|
+
/*
|
380
|
+
* Make sure linebuf contains \n for EOL (don't do this in
|
381
|
+
* userbuf because the user's string might be readonly).
|
382
|
+
*/
|
383
|
+
if (nl < ts->userbuf.limit) {
|
384
|
+
if (*nl == '\r') {
|
385
|
+
if (ts->linebuf.base[len-1] == '\r') {
|
386
|
+
/*
|
387
|
+
* Does the line segment end in \r? We must check
|
388
|
+
* for a \n at the front of the next segment before
|
389
|
+
* storing a \n into linebuf. This case matters
|
390
|
+
* only when we're reading from a file.
|
391
|
+
*/
|
392
|
+
if (nl + 1 == ts->userbuf.limit && ts->file) {
|
413
393
|
len--;
|
414
|
-
|
394
|
+
ts->flags |= TSF_CRFLAG; /* clear NLFLAG? */
|
395
|
+
if (len == 0) {
|
396
|
+
/*
|
397
|
+
* This can happen when a segment ends in
|
398
|
+
* \r\r. Start over. ptr == limit in this
|
399
|
+
* case, so we'll fall into buffer-filling
|
400
|
+
* code.
|
401
|
+
*/
|
402
|
+
return GetChar(ts);
|
403
|
+
}
|
404
|
+
} else {
|
415
405
|
ts->linebuf.base[len-1] = '\n';
|
416
406
|
}
|
417
|
-
}
|
407
|
+
}
|
408
|
+
} else if (*nl == '\n') {
|
409
|
+
if (nl > ts->userbuf.base &&
|
410
|
+
nl[-1] == '\r' &&
|
411
|
+
ts->linebuf.base[len-2] == '\r') {
|
412
|
+
len--;
|
413
|
+
JS_ASSERT(ts->linebuf.base[len] == '\n');
|
418
414
|
ts->linebuf.base[len-1] = '\n';
|
419
415
|
}
|
416
|
+
} else if (*nl == LINE_SEPARATOR || *nl == PARA_SEPARATOR) {
|
417
|
+
ts->linebuf.base[len-1] = '\n';
|
420
418
|
}
|
421
|
-
|
422
|
-
/* Reset linebuf based on adjusted segment length. */
|
423
|
-
ts->linebuf.limit = ts->linebuf.base + len;
|
424
|
-
ts->linebuf.ptr = ts->linebuf.base;
|
425
|
-
|
426
|
-
/* Update position of linebuf within physical userbuf line. */
|
427
|
-
if (!(ts->flags & TSF_NLFLAG))
|
428
|
-
ts->linepos += ts->linelen;
|
429
|
-
else
|
430
|
-
ts->linepos = 0;
|
431
|
-
if (ts->linebuf.limit[-1] == '\n')
|
432
|
-
ts->flags |= TSF_NLFLAG;
|
433
|
-
else
|
434
|
-
ts->flags &= ~TSF_NLFLAG;
|
435
|
-
|
436
|
-
/* Update linelen from original segment length. */
|
437
|
-
ts->linelen = olen;
|
438
419
|
}
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
420
|
+
|
421
|
+
/* Reset linebuf based on adjusted segment length. */
|
422
|
+
ts->linebuf.limit = ts->linebuf.base + len;
|
423
|
+
ts->linebuf.ptr = ts->linebuf.base;
|
424
|
+
|
425
|
+
/* Update position of linebuf within physical userbuf line. */
|
426
|
+
if (!(ts->flags & TSF_NLFLAG))
|
427
|
+
ts->linepos += ts->linelen;
|
428
|
+
else
|
429
|
+
ts->linepos = 0;
|
430
|
+
if (ts->linebuf.limit[-1] == '\n')
|
431
|
+
ts->flags |= TSF_NLFLAG;
|
432
|
+
else
|
433
|
+
ts->flags &= ~TSF_NLFLAG;
|
434
|
+
|
435
|
+
/* Update linelen from original segment length. */
|
436
|
+
ts->linelen = olen;
|
437
|
+
}
|
438
|
+
c = *ts->linebuf.ptr++;
|
445
439
|
}
|
446
440
|
if (c == '\n')
|
447
441
|
ts->lineno++;
|
@@ -819,6 +813,8 @@ GetXMLEntity(JSContext *cx, JSTokenStream *ts)
|
|
819
813
|
/* Put the entity, including the '&' already scanned, in ts->tokenbuf. */
|
820
814
|
offset = PTRDIFF(ts->tokenbuf.ptr, ts->tokenbuf.base, jschar);
|
821
815
|
FastAppendChar(&ts->tokenbuf, '&');
|
816
|
+
if (!STRING_BUFFER_OK(&ts->tokenbuf))
|
817
|
+
return JS_FALSE;
|
822
818
|
while ((c = GetChar(ts)) != ';') {
|
823
819
|
if (c == EOF || c == '\n') {
|
824
820
|
js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR,
|
@@ -826,6 +822,8 @@ GetXMLEntity(JSContext *cx, JSTokenStream *ts)
|
|
826
822
|
return JS_FALSE;
|
827
823
|
}
|
828
824
|
FastAppendChar(&ts->tokenbuf, (jschar) c);
|
825
|
+
if (!STRING_BUFFER_OK(&ts->tokenbuf))
|
826
|
+
return JS_FALSE;
|
829
827
|
}
|
830
828
|
|
831
829
|
/* Let length be the number of jschars after the '&', including the ';'. */
|
@@ -911,6 +909,8 @@ badncr:
|
|
911
909
|
msg = JSMSG_BAD_XML_NCR;
|
912
910
|
bad:
|
913
911
|
/* No match: throw a TypeError per ECMA-357 10.3.2.1 step 8(a). */
|
912
|
+
JS_ASSERT(STRING_BUFFER_OK(&ts->tokenbuf));
|
913
|
+
JS_ASSERT(PTRDIFF(ts->tokenbuf.ptr, bp, jschar) >= 1);
|
914
914
|
bytes = js_DeflateString(cx, bp + 1,
|
915
915
|
PTRDIFF(ts->tokenbuf.ptr, bp, jschar) - 1);
|
916
916
|
if (bytes) {
|
@@ -990,6 +990,15 @@ NewToken(JSTokenStream *ts, ptrdiff_t adjust)
|
|
990
990
|
return tp;
|
991
991
|
}
|
992
992
|
|
993
|
+
static JS_INLINE JSBool
|
994
|
+
ScanAsSpace(jschar c)
|
995
|
+
{
|
996
|
+
/* Treat little- and big-endian BOMs as whitespace for compatibility. */
|
997
|
+
if (JS_ISSPACE(c) || c == 0xfffe || c == 0xfeff)
|
998
|
+
return JS_TRUE;
|
999
|
+
return JS_FALSE;
|
1000
|
+
}
|
1001
|
+
|
993
1002
|
JSTokenType
|
994
1003
|
js_GetToken(JSContext *cx, JSTokenStream *ts)
|
995
1004
|
{
|
@@ -1200,7 +1209,7 @@ retry:
|
|
1200
1209
|
if (ts->flags & TSF_NEWLINES)
|
1201
1210
|
break;
|
1202
1211
|
}
|
1203
|
-
} while (
|
1212
|
+
} while (ScanAsSpace(c));
|
1204
1213
|
|
1205
1214
|
tp = NewToken(ts, -1);
|
1206
1215
|
if (c == EOF) {
|
@@ -1722,7 +1731,7 @@ retry:
|
|
1722
1731
|
cp[3] == 'n' &&
|
1723
1732
|
cp[4] == 'e') {
|
1724
1733
|
SkipChars(ts, 5);
|
1725
|
-
while ((c = GetChar(ts)) != '\n' &&
|
1734
|
+
while ((c = GetChar(ts)) != '\n' && ScanAsSpace(c))
|
1726
1735
|
continue;
|
1727
1736
|
if (JS7_ISDEC(c)) {
|
1728
1737
|
line = JS7_UNDEC(c);
|
@@ -1734,7 +1743,7 @@ retry:
|
|
1734
1743
|
}
|
1735
1744
|
line = temp;
|
1736
1745
|
}
|
1737
|
-
while (c != '\n' &&
|
1746
|
+
while (c != '\n' && ScanAsSpace(c))
|
1738
1747
|
c = GetChar(ts);
|
1739
1748
|
i = 0;
|
1740
1749
|
if (c == '"') {
|
@@ -1749,7 +1758,7 @@ retry:
|
|
1749
1758
|
}
|
1750
1759
|
if (c == '"') {
|
1751
1760
|
while ((c = GetChar(ts)) != '\n' &&
|
1752
|
-
|
1761
|
+
ScanAsSpace(c)) {
|
1753
1762
|
continue;
|
1754
1763
|
}
|
1755
1764
|
}
|
@@ -809,6 +809,7 @@ GetPropertyTreeChild(JSContext *cx, JSScopeProperty *parent,
|
|
809
809
|
JSScopeProperty *sprop;
|
810
810
|
PropTreeKidsChunk *chunk;
|
811
811
|
uintN i, n;
|
812
|
+
uint32 shape;
|
812
813
|
|
813
814
|
rt = cx->runtime;
|
814
815
|
if (!parent) {
|
@@ -895,6 +896,12 @@ GetPropertyTreeChild(JSContext *cx, JSScopeProperty *parent,
|
|
895
896
|
}
|
896
897
|
|
897
898
|
locked_not_found:
|
899
|
+
/*
|
900
|
+
* Call js_GenerateShape before the allocation to prevent collecting the
|
901
|
+
* new property when the shape generation triggers the GC.
|
902
|
+
*/
|
903
|
+
shape = js_GenerateShape(cx, JS_TRUE, NULL);
|
904
|
+
|
898
905
|
sprop = NewScopeProperty(rt);
|
899
906
|
if (!sprop)
|
900
907
|
goto out_of_memory;
|
@@ -907,7 +914,7 @@ locked_not_found:
|
|
907
914
|
sprop->flags = child->flags;
|
908
915
|
sprop->shortid = child->shortid;
|
909
916
|
sprop->parent = sprop->kids = NULL;
|
910
|
-
sprop->shape =
|
917
|
+
sprop->shape = shape;
|
911
918
|
|
912
919
|
if (!parent) {
|
913
920
|
entry->child = sprop;
|
@@ -1256,9 +1263,11 @@ js_AddScopeProperty(JSContext *cx, JSScope *scope, jsid id,
|
|
1256
1263
|
*/
|
1257
1264
|
if (!JS_CLIST_IS_EMPTY(&cx->runtime->watchPointList) &&
|
1258
1265
|
js_FindWatchPoint(cx->runtime, scope, id)) {
|
1259
|
-
|
1266
|
+
if (overwriting)
|
1267
|
+
JS_PUSH_TEMP_ROOT_SPROP(cx, overwriting, &tvr);
|
1260
1268
|
setter = js_WrapWatchedSetter(cx, id, attrs, setter);
|
1261
|
-
|
1269
|
+
if (overwriting)
|
1270
|
+
JS_POP_TEMP_ROOT(cx, &tvr);
|
1262
1271
|
if (!setter)
|
1263
1272
|
goto fail_overwrite;
|
1264
1273
|
}
|
@@ -220,7 +220,7 @@ JS_STATIC_ASSERT(offsetof(JSScope, title) == sizeof(JSObjectMap));
|
|
220
220
|
#define OBJ_SCOPE(obj) ((JSScope *)(obj)->map)
|
221
221
|
|
222
222
|
#define SCOPE_MAKE_UNIQUE_SHAPE(cx,scope) \
|
223
|
-
((scope)->shape = js_GenerateShape((cx), JS_FALSE))
|
223
|
+
((scope)->shape = js_GenerateShape((cx), JS_FALSE, NULL))
|
224
224
|
|
225
225
|
#define SCOPE_EXTEND_SHAPE(cx,scope,sprop) \
|
226
226
|
JS_BEGIN_MACRO \
|
@@ -228,7 +228,7 @@ JS_STATIC_ASSERT(offsetof(JSScope, title) == sizeof(JSObjectMap));
|
|
228
228
|
(scope)->shape == (scope)->lastProp->shape) { \
|
229
229
|
(scope)->shape = (sprop)->shape; \
|
230
230
|
} else { \
|
231
|
-
(scope)->shape = js_GenerateShape((cx), JS_FALSE);
|
231
|
+
(scope)->shape = js_GenerateShape((cx), JS_FALSE, sprop); \
|
232
232
|
} \
|
233
233
|
JS_END_MACRO
|
234
234
|
|
data/vendor/spidermonkey/jsstr.c
CHANGED
@@ -1216,9 +1216,7 @@ match_or_replace(JSContext *cx,
|
|
1216
1216
|
|
1217
1217
|
/* Assume a full array result is required, then prove otherwise. */
|
1218
1218
|
test = JS_FALSE;
|
1219
|
-
if (fp) {
|
1220
|
-
JS_ASSERT(*fp->regs->pc == JSOP_CALL ||
|
1221
|
-
*fp->regs->pc == JSOP_NEW);
|
1219
|
+
if (fp && (*fp->regs->pc == JSOP_CALL || *fp->regs->pc == JSOP_NEW)) {
|
1222
1220
|
JS_ASSERT(js_CodeSpec[*fp->regs->pc].length == 3);
|
1223
1221
|
switch (fp->regs->pc[3]) {
|
1224
1222
|
case JSOP_POP:
|
@@ -1949,6 +1947,9 @@ str_concat(JSContext *cx, uintN argc, jsval *vp)
|
|
1949
1947
|
|
1950
1948
|
NORMALIZE_THIS(cx, vp, str);
|
1951
1949
|
|
1950
|
+
/* Set vp (aka rval) early to handle the argc == 0 case. */
|
1951
|
+
*vp = STRING_TO_JSVAL(str);
|
1952
|
+
|
1952
1953
|
for (i = 0, argv = vp + 2; i < argc; i++) {
|
1953
1954
|
str2 = js_ValueToString(cx, argv[i]);
|
1954
1955
|
if (!str2)
|
@@ -1958,9 +1959,9 @@ str_concat(JSContext *cx, uintN argc, jsval *vp)
|
|
1958
1959
|
str = js_ConcatStrings(cx, str, str2);
|
1959
1960
|
if (!str)
|
1960
1961
|
return JS_FALSE;
|
1962
|
+
*vp = STRING_TO_JSVAL(str);
|
1961
1963
|
}
|
1962
1964
|
|
1963
|
-
*vp = STRING_TO_JSVAL(str);
|
1964
1965
|
return JS_TRUE;
|
1965
1966
|
}
|
1966
1967
|
|