This commit is contained in:
Andreas Gal 2009-04-16 15:56:46 -07:00
commit 34e554c496
4 changed files with 35 additions and 10 deletions

View File

@ -622,15 +622,17 @@ js_GetCallObject(JSContext *cx, JSStackFrame *fp)
* expression Call's parent points to an environment object holding
* function's name.
*/
JSObject *parent = fp->scopeChain;
JSAtom *lambdaName = (fp->fun->flags & JSFUN_LAMBDA) ? fp->fun->atom : NULL;
if (lambdaName) {
parent = js_NewObjectWithGivenProto(cx, &js_DeclEnvClass, NULL,
parent, 0);
if (!parent)
JSObject *env = js_NewObjectWithGivenProto(cx, &js_DeclEnvClass, NULL,
fp->scopeChain, 0);
if (!env)
return JS_FALSE;
/* Root env. */
fp->scopeChain = env;
}
callobj = js_NewObject(cx, &js_CallClass, NULL, parent, 0);
callobj = js_NewObject(cx, &js_CallClass, NULL, fp->scopeChain, 0);
if (!callobj)
return NULL;
@ -638,7 +640,7 @@ js_GetCallObject(JSContext *cx, JSStackFrame *fp)
JS_ASSERT(fp->fun == GET_FUNCTION_PRIVATE(cx, fp->callee));
STOBJ_SET_SLOT(callobj, JSSLOT_CALLEE, OBJECT_TO_JSVAL(fp->callee));
if (lambdaName &&
!js_DefineNativeProperty(cx, parent, ATOM_TO_JSID(lambdaName),
!js_DefineNativeProperty(cx, fp->scopeChain, ATOM_TO_JSID(lambdaName),
OBJECT_TO_JSVAL(fp->callee), NULL, NULL,
JSPROP_PERMANENT | JSPROP_READONLY,
0, 0, NULL)) {

View File

@ -316,6 +316,17 @@ js_CompareAndSwap(jsword *w, jsword ov, jsword nv)
#endif
static inline void
js_AtomicSetMask(jsword *w, jsword mask)
{
jsword ov, nv;
do {
ov = *w;
nv = ov | mask;
} while (!js_CompareAndSwap(w, ov, nv));
}
JS_END_EXTERN_C
#endif /* jslock_h___ */

View File

@ -2935,7 +2935,7 @@ js_FinalizeStringRT(JSRuntime *rt, JSString *str, intN type, JSContext *cx)
}
}
}
if (valid)
if (valid && JSSTRING_IS_DEFLATED(str))
js_PurgeDeflatedStringCache(rt, str);
}
@ -3454,6 +3454,7 @@ js_SetStringBytes(JSContext *cx, JSString *str, char *bytes, size_t length)
if (ok)
rt->deflatedStringCacheBytes += length;
#endif
JSSTRING_SET_DEFLATED(str);
JS_RELEASE_LOCK(rt->deflatedStringCacheLock);
return ok;
@ -3508,6 +3509,7 @@ js_GetStringBytes(JSContext *cx, JSString *str)
#ifdef DEBUG
rt->deflatedStringCacheBytes += JSSTRING_LENGTH(str);
#endif
JSSTRING_SET_DEFLATED(str);
} else {
if (cx)
JS_free(cx, bytes);

View File

@ -108,8 +108,9 @@ struct JSString {
#define JSSTRFLAG_PREFIX JSSTRING_BIT(JS_BITS_PER_WORD - 2)
#define JSSTRFLAG_MUTABLE JSSTRFLAG_PREFIX
#define JSSTRFLAG_ATOMIZED JSSTRING_BIT(JS_BITS_PER_WORD - 3)
#define JSSTRFLAG_DEFLATED JSSTRING_BIT(JS_BITS_PER_WORD - 4)
#define JSSTRING_LENGTH_BITS (JS_BITS_PER_WORD - 3)
#define JSSTRING_LENGTH_BITS (JS_BITS_PER_WORD - 4)
#define JSSTRING_LENGTH_MASK JSSTRING_BITMASK(JSSTRING_LENGTH_BITS)
/* Universal JSString type inquiry and accessor macros. */
@ -132,6 +133,13 @@ struct JSString {
? JSSTRDEP_LENGTH(str) \
: JSFLATSTR_LENGTH(str))
JS_STATIC_ASSERT(sizeof(size_t) == sizeof(jsword));
#define JSSTRING_IS_DEFLATED(str) ((str)->length & JSSTRFLAG_DEFLATED)
#define JSSTRING_SET_DEFLATED(str) js_AtomicSetMask((jsword*)&(str)->length, \
JSSTRFLAG_DEFLATED);
#define JSSTRING_CHARS_AND_LENGTH(str, chars_, length_) \
((void)(JSSTRING_IS_DEPENDENT(str) \
? ((length_) = JSSTRDEP_LENGTH(str), \
@ -182,8 +190,10 @@ struct JSString {
* with the atomized bit set.
*/
#define JSFLATSTR_SET_ATOMIZED(str) \
((void)(JS_ASSERT(JSSTRING_IS_FLAT(str) && !JSSTRING_IS_MUTABLE(str)), \
(str)->length |= JSSTRFLAG_ATOMIZED))
JS_BEGIN_MACRO \
JS_ASSERT(JSSTRING_IS_FLAT(str) && !JSSTRING_IS_MUTABLE(str)); \
js_AtomicSetMask((jsword*) &(str)->length, JSSTRFLAG_ATOMIZED); \
JS_END_MACRO
#define JSFLATSTR_SET_MUTABLE(str) \
((void)(JS_ASSERT(JSSTRING_IS_FLAT(str) && !JSSTRING_IS_ATOMIZED(str)), \