Bug 613457 - clean up string interfaces (r=njn)

--HG--
extra : rebase_source : 3e77b67fa9fe2cc31312ad99951cf92258a98e64
This commit is contained in:
Luke Wagner 2011-03-14 13:59:53 -07:00
parent 7b695c0de6
commit 7c96945e3c
60 changed files with 1546 additions and 1428 deletions

View File

@ -50,9 +50,6 @@
#include "nsServiceManagerUtils.h"
#include "nsDOMError.h"
#include "nsGlobalWindow.h"
#include "jsobj.h"
#include "jsatom.h"
#include "jsfun.h"
#include "nsIContentSecurityPolicy.h"
static const char kSetIntervalStr[] = "setInterval";
@ -134,10 +131,11 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsJSScriptTimeoutHandler)
else if (tmp->mFunObj) {
JSFunction* fun = (JSFunction*)tmp->mFunObj->getPrivate();
if (fun->atom) {
size_t size = 1 + JS_PutEscapedFlatString(NULL, 0, ATOM_TO_STRING(fun->atom), 0);
JSFlatString *funId = JS_ASSERT_STRING_IS_FLAT(JS_GetFunctionId(fun));
size_t size = 1 + JS_PutEscapedFlatString(NULL, 0, funId, 0);
char *name = new char[size];
if (name) {
JS_PutEscapedFlatString(name, size, ATOM_TO_STRING(fun->atom), 0);
JS_PutEscapedFlatString(name, size, funId, 0);
foo.AppendLiteral(" [");
foo.Append(name);
delete[] name;

View File

@ -71,7 +71,7 @@ void JSD_ASSERT_VALID_CONTEXT(JSDContext* jsdc)
static JSClass global_class = {
"JSDGlobal", JSCLASS_GLOBAL_FLAGS,
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
JSCLASS_NO_OPTIONAL_MEMBERS
};

View File

@ -11,28 +11,28 @@ BEGIN_TEST(testIntString_bug515273)
EVAL("'1';", v.addr());
JSString *str = JSVAL_TO_STRING(v.value());
CHECK(JSString::isGCThingStatic(str) && str->isStaticAtom());
CHECK(str->isStaticAtom());
CHECK(JS_FlatStringEqualsAscii(JS_ASSERT_STRING_IS_FLAT(str), "1"));
EVAL("'42';", v.addr());
str = JSVAL_TO_STRING(v.value());
CHECK(JSString::isGCThingStatic(str) && str->isStaticAtom());
CHECK(str->isStaticAtom());
CHECK(JS_FlatStringEqualsAscii(JS_ASSERT_STRING_IS_FLAT(str), "42"));
EVAL("'111';", v.addr());
str = JSVAL_TO_STRING(v.value());
CHECK(JSString::isGCThingStatic(str) && str->isStaticAtom());
CHECK(str->isStaticAtom());
CHECK(JS_FlatStringEqualsAscii(JS_ASSERT_STRING_IS_FLAT(str), "111"));
/* Test other types of static strings. */
EVAL("'a';", v.addr());
str = JSVAL_TO_STRING(v.value());
CHECK(JSString::isGCThingStatic(str) && str->isStaticAtom());
CHECK(str->isStaticAtom());
CHECK(JS_FlatStringEqualsAscii(JS_ASSERT_STRING_IS_FLAT(str), "a"));
EVAL("'bc';", v.addr());
str = JSVAL_TO_STRING(v.value());
CHECK(JSString::isGCThingStatic(str) && str->isStaticAtom());
CHECK(str->isStaticAtom());
CHECK(JS_FlatStringEqualsAscii(JS_ASSERT_STRING_IS_FLAT(str), "bc"));
return true;

View File

@ -328,10 +328,10 @@ JS_ConvertArgumentsVA(JSContext *cx, uintN argc, jsval *argv, const char *format
return JS_FALSE;
*sp = STRING_TO_JSVAL(str);
if (c == 'W') {
const jschar *chars = js_GetStringChars(cx, str);
if (!chars)
JSFixedString *fixed = str->ensureFixed(cx);
if (!fixed)
return JS_FALSE;
*va_arg(ap, const jschar **) = chars;
*va_arg(ap, const jschar **) = fixed->chars();
} else {
*va_arg(ap, JSString **) = str;
}
@ -1769,7 +1769,7 @@ JS_ResolveStandardClass(JSContext *cx, JSObject *obj, jsid id, JSBool *resolved)
/* Check whether we're resolving 'undefined', and define it if so. */
atom = rt->atomState.typeAtoms[JSTYPE_VOID];
if (idstr == ATOM_TO_STRING(atom)) {
if (idstr == atom) {
*resolved = JS_TRUE;
return obj->defineProperty(cx, ATOM_TO_JSID(atom), UndefinedValue(),
PropertyStub, StrictPropertyStub,
@ -1781,7 +1781,7 @@ JS_ResolveStandardClass(JSContext *cx, JSObject *obj, jsid id, JSBool *resolved)
for (i = 0; standard_class_atoms[i].init; i++) {
JS_ASSERT(standard_class_atoms[i].clasp);
atom = OFFSET_TO_ATOM(rt, standard_class_atoms[i].atomOffset);
if (idstr == ATOM_TO_STRING(atom)) {
if (idstr == atom) {
stdnm = &standard_class_atoms[i];
break;
}
@ -1794,7 +1794,7 @@ JS_ResolveStandardClass(JSContext *cx, JSObject *obj, jsid id, JSBool *resolved)
atom = StdNameToAtom(cx, &standard_class_names[i]);
if (!atom)
return JS_FALSE;
if (idstr == ATOM_TO_STRING(atom)) {
if (idstr == atom) {
stdnm = &standard_class_names[i];
break;
}
@ -1811,7 +1811,7 @@ JS_ResolveStandardClass(JSContext *cx, JSObject *obj, jsid id, JSBool *resolved)
atom = StdNameToAtom(cx, &object_prototype_names[i]);
if (!atom)
return JS_FALSE;
if (idstr == ATOM_TO_STRING(atom)) {
if (idstr == atom) {
stdnm = &object_prototype_names[i];
break;
}
@ -2321,7 +2321,7 @@ JS_PrintTraceThingInfo(char *buf, size_t bufsize, JSTracer *trc, void *thing, ui
JS_snprintf(buf, bufsize, "%p", fun);
} else {
if (fun->atom)
PutEscapedString(buf, bufsize, ATOM_TO_STRING(fun->atom), 0);
PutEscapedString(buf, bufsize, fun->atom, 0);
}
} else if (clasp->flags & JSCLASS_HAS_PRIVATE) {
JS_snprintf(buf, bufsize, "%p", obj->getPrivate());
@ -2335,7 +2335,7 @@ JS_PrintTraceThingInfo(char *buf, size_t bufsize, JSTracer *trc, void *thing, ui
{
JSString *str = (JSString *)thing;
if (str->isLinear())
PutEscapedString(buf, bufsize, str->assertIsLinear(), 0);
PutEscapedString(buf, bufsize, &str->asLinear(), 0);
else
JS_snprintf(buf, bufsize, "<rope: length %d>", (int)str->length());
break;
@ -2763,15 +2763,7 @@ JS_PUBLIC_API(JSString *)
JS_NewExternalString(JSContext *cx, jschar *chars, size_t length, intN type)
{
CHECK_REQUEST(cx);
JS_ASSERT(uintN(type) < JSExternalString::TYPE_LIMIT);
JSExternalString *str = js_NewGCExternalString(cx, uintN(type));
if (!str)
return NULL;
str->initFlat(chars, length);
str->externalStringType = type;
cx->runtime->updateMallocCounter((length + 1) * sizeof(jschar));
return str;
return JSExternalString::new_(cx, chars, length, type);
}
JS_PUBLIC_API(void)
@ -4322,7 +4314,7 @@ JS_GetFunctionObject(JSFunction *fun)
JS_PUBLIC_API(JSString *)
JS_GetFunctionId(JSFunction *fun)
{
return fun->atom ? ATOM_TO_STRING(fun->atom) : NULL;
return fun->atom;
}
JS_PUBLIC_API(uintN)
@ -5291,22 +5283,14 @@ JS_PUBLIC_API(JSString *)
JS_InternJSString(JSContext *cx, JSString *str)
{
CHECK_REQUEST(cx);
JSAtom *atom = js_AtomizeString(cx, str, 0);
if (!atom)
return NULL;
return ATOM_TO_STRING(atom);
return js_AtomizeString(cx, str, 0);
}
JS_PUBLIC_API(JSString *)
JS_InternString(JSContext *cx, const char *s)
{
JSAtom *atom;
CHECK_REQUEST(cx);
atom = js_Atomize(cx, s, strlen(s), ATOM_INTERNED);
if (!atom)
return NULL;
return ATOM_TO_STRING(atom);
return js_Atomize(cx, s, strlen(s), ATOM_INTERNED);
}
JS_PUBLIC_API(JSString *)
@ -5335,13 +5319,8 @@ JS_NewUCStringCopyZ(JSContext *cx, const jschar *s)
JS_PUBLIC_API(JSString *)
JS_InternUCStringN(JSContext *cx, const jschar *s, size_t length)
{
JSAtom *atom;
CHECK_REQUEST(cx);
atom = js_AtomizeChars(cx, s, length, ATOM_INTERNED);
if (!atom)
return NULL;
return ATOM_TO_STRING(atom);
return js_AtomizeChars(cx, s, length, ATOM_INTERNED);
}
JS_PUBLIC_API(JSString *)
@ -5385,16 +5364,15 @@ JS_GetStringCharsAndLength(JSContext *cx, JSString *str, size_t *plength)
JS_PUBLIC_API(const jschar *)
JS_GetInternedStringChars(JSString *str)
{
JS_ASSERT(str->isAtom());
return str->flatChars();
return str->asAtom().chars();
}
JS_PUBLIC_API(const jschar *)
JS_GetInternedStringCharsAndLength(JSString *str, size_t *plength)
{
JS_ASSERT(str->isAtom());
*plength = str->flatLength();
return str->flatChars();
JSAtom &atom = str->asAtom();
*plength = atom.length();
return atom.chars();
}
extern JS_PUBLIC_API(JSFlatString *)
@ -5487,7 +5465,7 @@ JS_PUBLIC_API(JSBool)
JS_MakeStringImmutable(JSContext *cx, JSString *str)
{
CHECK_REQUEST(cx);
return js_MakeStringImmutable(cx, str);
return !!str->ensureFixed(cx);
}
JS_PUBLIC_API(JSBool)

View File

@ -108,6 +108,7 @@
#include "jscntxtinlines.h"
#include "jsinterpinlines.h"
#include "jsobjinlines.h"
#include "jsstrinlines.h"
using namespace js;
using namespace js::gc;
@ -1250,7 +1251,7 @@ array_toString_sub(JSContext *cx, JSObject *obj, JSBool locale,
genBefore = cx->busyArrays.generation();
} else {
/* Cycle, so return empty string. */
rval->setString(ATOM_TO_STRING(cx->runtime->atomState.emptyAtom));
rval->setString(cx->runtime->atomState.emptyAtom);
return true;
}
@ -3265,7 +3266,7 @@ js_CloneDensePrimitiveArray(JSContext *cx, JSObject *obj, JSObject **clone)
if (val.isString()) {
// Strings must be made immutable before being copied to a clone.
if (!js_MakeStringImmutable(cx, val.toString()))
if (!val.toString()->ensureFixed(cx))
return JS_FALSE;
} else if (val.isObject()) {
/*

View File

@ -109,35 +109,6 @@ js_IdIsIndex(jsid id, jsuint *indexp)
return js_StringIsIndex(JSID_TO_ATOM(id), indexp);
}
/* XML really wants to pretend jsvals are jsids. */
inline bool
js_IdValIsIndex(JSContext *cx, jsval id, jsuint *indexp, bool *isIndex)
{
if (JSVAL_IS_INT(id)) {
jsint i;
i = JSVAL_TO_INT(id);
if (i < 0) {
*isIndex = false;
return true;
}
*indexp = (jsuint)i;
*isIndex = true;
return true;
}
if (!JSVAL_IS_STRING(id)) {
*isIndex = false;
return true;
}
JSLinearString *str = JSVAL_TO_STRING(id)->ensureLinear(cx);
if (!str)
return false;
*isIndex = js_StringIsIndex(str, indexp);
return true;
}
extern js::Class js_ArrayClass, js_SlowArrayClass;
inline bool

View File

@ -91,7 +91,7 @@ JS_STATIC_ASSERT((1 + 2) * sizeof(JSAtom *) ==
const char *
js_AtomToPrintableString(JSContext *cx, JSAtom *atom, JSAutoByteString *bytes)
{
return js_ValueToPrintable(cx, StringValue(ATOM_TO_STRING(atom)), bytes);
return js_ValueToPrintable(cx, StringValue(atom), bytes);
}
#define JS_PROTO(name,code,init) const char js_##name##_str[] = #name;
@ -390,7 +390,7 @@ js_InitCommonAtoms(JSContext *cx)
JS_ASSERT((uint8 *)atoms - (uint8 *)state == LAZY_ATOM_OFFSET_START);
memset(atoms, 0, ATOM_OFFSET_LIMIT - LAZY_ATOM_OFFSET_START);
cx->runtime->emptyString = ATOM_TO_STRING(state->emptyAtom);
cx->runtime->emptyString = state->emptyAtom;
return JS_TRUE;
}
@ -456,79 +456,84 @@ js_SweepAtomState(JSContext *cx)
}
}
JSAtom *
js_AtomizeString(JSContext *cx, JSString *strArg, uintN flags)
/*
* This call takes ownership of 'chars' if ATOM_NOCOPY is set.
*/
static JSAtom *
Atomize(JSContext *cx, const jschar *chars, size_t length, uintN flags)
{
JS_ASSERT(!(flags & ~(ATOM_PINNED|ATOM_INTERNED|ATOM_TMPSTR|ATOM_NOCOPY)));
JS_ASSERT_IF(flags & ATOM_NOCOPY, flags & ATOM_TMPSTR);
JS_ASSERT(!(flags & ~(ATOM_PINNED|ATOM_INTERNED|ATOM_NOCOPY)));
if (strArg->isAtom())
return STRING_TO_ATOM(strArg);
JSLinearString *str = strArg->ensureLinear(cx);
if (!str)
return NULL;
const jschar *chars = str->chars();
size_t length = str->length();
JSString *staticStr = JSString::lookupStaticString(chars, length);
if (staticStr)
return STRING_TO_ATOM(staticStr);
if (JSAtom *s = JSAtom::lookupStatic(chars, length))
return s;
AutoLockAtomsCompartment lock(cx);
AtomSet &atoms = cx->runtime->atomState.atoms;
AtomSet::AddPtr p = atoms.lookupForAdd(str);
AtomSet::AddPtr p = atoms.lookupForAdd(AtomHasher::Lookup(chars, length));
/* Hashing the string should have flattened it if it was a rope. */
JS_ASSERT(str->isFlat() || str->isDependent());
JSLinearString *key;
JSAtom *atom;
if (p) {
key = AtomEntryToKey(*p);
atom = AtomEntryToKey(*p);
} else {
/*
* We have to relookup the key as the last ditch GC invoked from the
* string allocation or OOM handling may unlock the atomsCompartment.
*/
SwitchToCompartment sc(cx, cx->runtime->atomsCompartment);
if (flags & ATOM_NOCOPY) {
key = js_NewString(cx, const_cast<jschar *>(str->flatChars()), length);
if (!key)
return NULL;
/* Finish handing off chars to the GC'ed key string. */
JS_ASSERT(flags & ATOM_TMPSTR);
str->u.chars = NULL;
JSFixedString *key;
if (flags & ATOM_NOCOPY) {
key = js_NewString(cx, const_cast<jschar *>(chars), length);
if (!key) {
cx->free(const_cast<jschar *>(chars));
return NULL;
}
} else {
key = js_NewStringCopyN(cx, chars, length);
if (!key)
return NULL;
}
if (!atoms.relookupOrAdd(p, key, StringToInitialAtomEntry(key))) {
/*
* We have to relookup the key as the last ditch GC invoked from the
* string allocation or OOM handling may unlock the atomsCompartment.
*/
AtomHasher::Lookup lookup(chars, length);
if (!atoms.relookupOrAdd(p, lookup, StringToInitialAtomEntry(key))) {
JS_ReportOutOfMemory(cx); /* SystemAllocPolicy does not report */
return NULL;
}
key->flatSetAtomized();
atom = key->morphInternedStringIntoAtom();
}
AddAtomEntryFlags(*p, flags & (ATOM_PINNED | ATOM_INTERNED));
JSAtom *atom = STRING_TO_ATOM(key);
return atom;
}
JSAtom *
js_AtomizeString(JSContext *cx, JSString *str, uintN flags)
{
JS_ASSERT(!(flags & ATOM_NOCOPY));
if (str->isAtom())
return &str->asAtom();
size_t length = str->length();
const jschar *chars = str->getChars(cx);
if (!chars)
return NULL;
JS_ASSERT(length <= JSString::MAX_LENGTH);
return Atomize(cx, chars, length, flags);
}
JSAtom *
js_Atomize(JSContext *cx, const char *bytes, size_t length, uintN flags, bool useCESU8)
{
jschar *chars;
JSString str;
JSAtom *atom;
JS_ASSERT(!(flags & ATOM_NOCOPY));
CHECK_REQUEST(cx);
if (!CheckStringLength(cx, length))
return NULL;
/*
* Avoiding the malloc in js_InflateString on shorter strings saves us
* over 20,000 malloc calls on mozilla browser startup. This compares to
@ -536,10 +541,11 @@ js_Atomize(JSContext *cx, const char *bytes, size_t length, uintN flags, bool us
* The vast majority of atomized strings are already in the hashtable. So
* js_AtomizeString rarely has to copy the temp string we make.
*/
#define ATOMIZE_BUF_MAX 32
static const unsigned ATOMIZE_BUF_MAX = 32;
jschar inflated[ATOMIZE_BUF_MAX];
size_t inflatedLength = ATOMIZE_BUF_MAX - 1;
const jschar *chars;
if (length < ATOMIZE_BUF_MAX) {
if (useCESU8)
js_InflateUTF8StringToBuffer(cx, bytes, length, inflated, &inflatedLength, true);
@ -555,48 +561,29 @@ js_Atomize(JSContext *cx, const char *bytes, size_t length, uintN flags, bool us
flags |= ATOM_NOCOPY;
}
str.initFlat(chars, inflatedLength);
atom = js_AtomizeString(cx, &str, ATOM_TMPSTR | flags);
if (chars != inflated && str.flatChars())
cx->free(chars);
return atom;
return Atomize(cx, chars, inflatedLength, flags);
}
JSAtom *
js_AtomizeChars(JSContext *cx, const jschar *chars, size_t length, uintN flags)
{
JSString str;
JS_ASSERT(!(flags & ATOM_NOCOPY));
CHECK_REQUEST(cx);
if (!CheckStringLength(cx, length))
return NULL;
str.initFlatNotTerminated((jschar *)chars, length);
return js_AtomizeString(cx, &str, ATOM_TMPSTR | flags);
return Atomize(cx, chars, length, flags);
}
JSAtom *
js_GetExistingStringAtom(JSContext *cx, const jschar *chars, size_t length)
{
JSString str, *str2;
JSAtomState *state;
if (length == 1) {
jschar c = *chars;
if (c < UNIT_STRING_LIMIT)
return STRING_TO_ATOM(JSString::unitString(c));
}
str.initFlatNotTerminated((jschar *)chars, length);
state = &cx->runtime->atomState;
JS_LOCK(cx, &state->lock);
AtomSet::Ptr p = state->atoms.lookup(str.assertIsFlat());
str2 = p ? AtomEntryToKey(*p) : NULL;
JS_UNLOCK(cx, &state->lock);
return str2 ? STRING_TO_ATOM(str2) : NULL;
if (JSAtom *atom = JSAtom::lookupStatic(chars, length))
return atom;
AutoLockAtomsCompartment lock(cx);
AtomSet::Ptr p = cx->runtime->atomState.atoms.lookup(AtomHasher::Lookup(chars, length));
return p ? AtomEntryToKey(*p) : NULL;
}
#ifdef DEBUG

View File

@ -56,12 +56,6 @@
#define ATOM_PINNED 0x1 /* atom is pinned against GC */
#define ATOM_INTERNED 0x2 /* pinned variant for JS_Intern* API */
#define ATOM_NOCOPY 0x4 /* don't copy atom string bytes */
#define ATOM_TMPSTR 0x8 /* internal, to avoid extra string */
#define STRING_TO_ATOM(str) (JS_ASSERT(str->isAtom()), \
(JSAtom *)str)
#define ATOM_TO_STRING(atom) (atom)
#define ATOM_TO_JSVAL(atom) STRING_TO_JSVAL(ATOM_TO_STRING(atom))
/* Engine-internal extensions of jsid */
@ -274,14 +268,23 @@ AtomEntryToKey(AtomEntryType entry)
struct AtomHasher
{
typedef JSLinearString *Lookup;
struct Lookup
{
const jschar *chars;
size_t length;
Lookup(const jschar *chars, size_t length) : chars(chars), length(length) {}
};
static HashNumber hash(JSLinearString *str) {
return js_HashString(str);
static HashNumber hash(const Lookup &l) {
return HashChars(l.chars, l.length);
}
static bool match(AtomEntryType entry, JSLinearString *lookup) {
return entry ? EqualStrings(AtomEntryToKey(entry), lookup) : false;
static bool match(AtomEntryType entry, const Lookup &lookup) {
JS_ASSERT(entry);
JSAtom *key = AtomEntryToKey(entry);
if (key->length() != lookup.length)
return false;
return PodEqual(key->chars(), lookup.chars, lookup.length);
}
};

View File

@ -43,38 +43,26 @@
#include "jsatom.h"
#include "jsnum.h"
/*
* Convert v to an atomized string and wrap it as an id.
*/
inline bool
js_ValueToAtom(JSContext *cx, const js::Value &v, JSAtom **atomp)
{
JSString *str;
JSAtom *atom;
/*
* Optimize for the common case where v is an already-atomized string. The
* comment in jsstr.h before JSString::flatSetAtomized explains why this is
* thread-safe. The extra rooting via lastAtom (which would otherwise be
* done in js_js_AtomizeString) ensures the caller that the resulting id at
* is least weakly rooted.
*/
if (v.isString()) {
str = v.toString();
if (str->isAtom()) {
*atomp = STRING_TO_ATOM(str);
return true;
}
} else {
str = js_ValueToString(cx, v);
if (!v.isString()) {
JSString *str = js_ValueToString(cx, v);
if (!str)
return false;
JS::Anchor<JSString *> anchor(str);
*atomp = js_AtomizeString(cx, str, 0);
return !!*atomp;
}
atom = js_AtomizeString(cx, str, 0);
if (!atom)
return false;
*atomp = atom;
return true;
JSString *str = v.toString();
if (str->isAtom()) {
*atomp = &str->asAtom();
return true;
}
*atomp = js_AtomizeString(cx, str, 0);
return !!*atomp;
}
inline bool
@ -121,7 +109,7 @@ js_InternNonIntElementId(JSContext *cx, JSObject *obj, const js::Value &idval,
JSAtom *atom;
if (js_ValueToAtom(cx, idval, &atom)) {
*idp = ATOM_TO_JSID(atom);
vp->setString(ATOM_TO_STRING(atom));
vp->setString(atom);
return true;
}
return false;

View File

@ -56,6 +56,7 @@
#include "jsinterpinlines.h"
#include "jsobjinlines.h"
#include "jsstrinlines.h"
using namespace js;
@ -100,7 +101,7 @@ bool_toString(JSContext *cx, uintN argc, Value *vp)
return false;
JSAtom *atom = cx->runtime->atomState.booleanAtoms[b ? 1 : 0];
JSString *str = ATOM_TO_STRING(atom);
JSString *str = atom;
if (!str)
return JS_FALSE;
vp->setString(str);
@ -162,7 +163,7 @@ js_InitBooleanClass(JSContext *cx, JSObject *obj)
JSString *
js_BooleanToString(JSContext *cx, JSBool b)
{
return ATOM_TO_STRING(cx->runtime->atomState.booleanAtoms[b ? 1 : 0]);
return cx->runtime->atomState.booleanAtoms[b ? 1 : 0];
}
/* This function implements E-262-3 section 9.8, toString. */

View File

@ -285,7 +285,7 @@ JSString* FASTCALL
js_TypeOfObject(JSContext* cx, JSObject* obj)
{
JS_ASSERT(obj);
return ATOM_TO_STRING(cx->runtime->atomState.typeAtoms[obj->typeOf(cx)]);
return cx->runtime->atomState.typeAtoms[obj->typeOf(cx)];
}
JS_DEFINE_CALLINFO_2(extern, STRING, js_TypeOfObject, CONTEXT, OBJECT, 1, ACCSET_NONE)
@ -293,7 +293,7 @@ JSString* FASTCALL
js_BooleanIntToString(JSContext *cx, int32 unboxed)
{
JS_ASSERT(uint32(unboxed) <= 1);
return ATOM_TO_STRING(cx->runtime->atomState.booleanAtoms[unboxed]);
return cx->runtime->atomState.booleanAtoms[unboxed];
}
JS_DEFINE_CALLINFO_2(extern, STRING, js_BooleanIntToString, CONTEXT, INT32, 1, ACCSET_NONE)

View File

@ -627,7 +627,7 @@ JS_DECLARE_CALLINFO(js_String_tn)
JS_DECLARE_CALLINFO(js_CompareStringsOnTrace)
JS_DECLARE_CALLINFO(js_ConcatStrings)
JS_DECLARE_CALLINFO(js_EqualStringsOnTrace)
JS_DECLARE_CALLINFO(js_Flatten)
JS_DECLARE_CALLINFO(js_FlattenOnTrace)
/* Defined in jstypedarray.cpp. */
JS_DECLARE_CALLINFO(js_TypedArray_uint8_clamp_double)

View File

@ -75,9 +75,6 @@ struct Cell {
inline JSCompartment *compartment() const;
/* Needed for compatibility reasons because Cell can't be a base class of JSString */
JS_ALWAYS_INLINE js::gc::Cell *asCell() { return this; }
JS_ALWAYS_INLINE js::gc::FreeCell *asFreeCell() {
return reinterpret_cast<FreeCell *>(this);
}

View File

@ -1664,7 +1664,7 @@ js_ReportMissingArg(JSContext *cx, const Value &v, uintN arg)
if (IsFunctionObject(v)) {
atom = GET_FUNCTION_PRIVATE(cx, &v.toObject())->atom;
bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK,
v, ATOM_TO_STRING(atom));
v, atom);
if (!bytes)
return;
}

View File

@ -556,7 +556,7 @@ class CompartmentChecker
void check(JSString *str) {
if (!str->isAtom())
check(str->asCell()->compartment());
check(str->compartment());
}
void check(const js::Value &v) {

View File

@ -205,12 +205,12 @@ JSCompartment::wrap(JSContext *cx, Value *vp)
return true;
/* If the string is already in this compartment, we are done. */
if (str->asCell()->compartment() == this)
if (str->compartment() == this)
return true;
/* If the string is an atom, we don't have to copy. */
if (str->isAtom()) {
JS_ASSERT(str->asCell()->compartment() == cx->runtime->atomsCompartment);
JS_ASSERT(str->compartment() == cx->runtime->atomsCompartment);
return true;
}
}

View File

@ -348,18 +348,18 @@ class NativeIterCache {
* is erroneously included in the measurement; see bug 562553.
*/
class DtoaCache {
double d;
jsint base;
JSString *s; // if s==NULL, d and base are not valid
double d;
jsint base;
JSFixedString *s; // if s==NULL, d and base are not valid
public:
DtoaCache() : s(NULL) {}
void purge() { s = NULL; }
JSString *lookup(jsint base, double d) {
JSFixedString *lookup(jsint base, double d) {
return this->s && base == this->base && d == this->d ? this->s : NULL;
}
void cache(jsint base, double d, JSString *s) {
void cache(jsint base, double d, JSFixedString *s) {
this->base = base;
this->d = d;
this->s = s;

View File

@ -1287,7 +1287,7 @@ JS_LocalNameToAtom(jsuword w)
extern JS_PUBLIC_API(JSString *)
JS_AtomKey(JSAtom *atom)
{
return ATOM_TO_STRING(atom);
return atom;
}
extern JS_PUBLIC_API(void)
@ -1871,7 +1871,7 @@ GetAtomTotalSize(JSContext *cx, JSAtom *atom)
nbytes = sizeof(JSAtom *) + sizeof(JSDHashEntryStub);
nbytes += sizeof(JSString);
nbytes += (ATOM_TO_STRING(atom)->flatLength() + 1) * sizeof(jschar);
nbytes += (atom->length() + 1) * sizeof(jschar);
return nbytes;
}

View File

@ -2979,7 +2979,7 @@ EmitElemOp(JSContext *cx, JSParseNode *pn, JSOp op, JSCodeGenerator *cg)
}
right = &rtmp;
right->pn_type = TOK_STRING;
right->pn_op = js_IsIdentifier(ATOM_TO_STRING(pn->pn_atom))
right->pn_op = js_IsIdentifier(pn->pn_atom)
? JSOP_QNAMEPART
: JSOP_STRING;
right->pn_arity = PN_NULLARY;
@ -3211,7 +3211,7 @@ EmitSwitch(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn,
constVal.setNumber(pn4->pn_dval);
break;
case TOK_STRING:
constVal.setString(ATOM_TO_STRING(pn4->pn_atom));
constVal.setString(pn4->pn_atom);
break;
case TOK_NAME:
if (!pn4->maybeExpr()) {
@ -4426,7 +4426,7 @@ JSParseNode::getConstantValue(JSContext *cx, bool strictChecks, Value *vp)
vp->setNumber(pn_dval);
return true;
case TOK_STRING:
vp->setString(ATOM_TO_STRING(pn_atom));
vp->setString(pn_atom);
return true;
case TOK_PRIMARY:
switch (pn_op) {

View File

@ -341,7 +341,7 @@ InitExnPrivate(JSContext *cx, JSObject *exnObject, JSString *message,
elem->argc = 0;
} else {
elem->funName = fp->fun()->atom
? ATOM_TO_STRING(fp->fun()->atom)
? fp->fun()->atom
: cx->runtime->emptyString;
elem->argc = fp->numActualArgs();
fp->forEachCanonicalActualArg(CopyTo(Valueify(values)));
@ -471,7 +471,7 @@ exn_resolve(JSContext *cx, JSObject *obj, jsid id, uintN flags,
str = JSID_TO_STRING(id);
atom = cx->runtime->atomState.messageAtom;
if (str == ATOM_TO_STRING(atom)) {
if (str == atom) {
prop = js_message_str;
/*
@ -487,21 +487,21 @@ exn_resolve(JSContext *cx, JSObject *obj, jsid id, uintN flags,
}
atom = cx->runtime->atomState.fileNameAtom;
if (str == ATOM_TO_STRING(atom)) {
if (str == atom) {
prop = js_fileName_str;
v = STRING_TO_JSVAL(priv->filename);
goto define;
}
atom = cx->runtime->atomState.lineNumberAtom;
if (str == ATOM_TO_STRING(atom)) {
if (str == atom) {
prop = js_lineNumber_str;
v = INT_TO_JSVAL(priv->lineno);
goto define;
}
atom = cx->runtime->atomState.stackAtom;
if (str == ATOM_TO_STRING(atom)) {
if (str == atom) {
stack = StackTraceToString(cx, priv);
if (!stack)
return false;
@ -1284,9 +1284,10 @@ js_ReportUncaughtException(JSContext *cx)
report.filename = filename.ptr();
report.lineno = (uintN) lineno;
if (JSVAL_IS_STRING(roots[2])) {
report.ucmessage = js_GetStringChars(cx, JSVAL_TO_STRING(roots[2]));
if (!report.ucmessage)
JSFixedString *fixed = JSVAL_TO_STRING(roots[2])->ensureFixed(cx);
if (!fixed)
return false;
report.ucmessage = fixed->chars();
}
}

View File

@ -44,5 +44,5 @@ JS_FRIEND_API(JSString *)
JS_GetAnonymousString(JSRuntime *rt)
{
JS_ASSERT(rt->state == JSRTS_UP);
return ATOM_TO_STRING(rt->atomState.anonymousAtom);
return rt->atomState.anonymousAtom;
}

View File

@ -1617,7 +1617,7 @@ fun_getProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp)
break;
case FUN_NAME:
vp->setString(fun->atom ? ATOM_TO_STRING(fun->atom)
vp->setString(fun->atom ? fun->atom
: cx->runtime->emptyString);
break;
@ -1977,7 +1977,7 @@ fun_trace(JSTracer *trc, JSObject *obj)
}
if (fun->atom)
MarkString(trc, ATOM_TO_STRING(fun->atom), "atom");
MarkString(trc, fun->atom, "atom");
if (fun->isInterpreted() && fun->script())
js_TraceScript(trc, fun->script());

View File

@ -206,13 +206,13 @@ struct JSFunction : public JSObject_Slots2
*/
JSAtom *methodAtom() const {
return (joinable() && getSlot(METHOD_ATOM_SLOT).isString())
? STRING_TO_ATOM(getSlot(METHOD_ATOM_SLOT).toString())
? &getSlot(METHOD_ATOM_SLOT).toString()->asAtom()
: NULL;
}
void setMethodAtom(JSAtom *atom) {
JS_ASSERT(joinable());
getSlotRef(METHOD_ATOM_SLOT).setString(ATOM_TO_STRING(atom));
getSlotRef(METHOD_ATOM_SLOT).setString(atom);
}
js::Native maybeNative() const {
@ -425,7 +425,7 @@ inline const char *
GetFunctionNameBytes(JSContext *cx, JSFunction *fun, JSAutoByteString *bytes)
{
if (fun->atom)
return bytes->encode(cx, ATOM_TO_STRING(fun->atom));
return bytes->encode(cx, fun->atom);
return js_anonymous_str;
}

View File

@ -496,7 +496,7 @@ AllocateArena(JSContext *cx, unsigned thingKind)
JS_FRIEND_API(bool)
IsAboutToBeFinalized(JSContext *cx, void *thing)
{
if (JSString::isGCThingStatic(thing))
if (JSAtom::isStatic(thing))
return false;
JS_ASSERT(cx);
@ -1068,8 +1068,6 @@ FreeLists::purge()
*p = NULL;
}
class JSShortString;
ArenaList *
GetFinalizableArenaList(JSCompartment *c, unsigned thingKind) {
JS_ASSERT(thingKind < FINALIZE_LIMIT);
@ -1210,7 +1208,8 @@ RefillFinalizableFreeList(JSContext *cx, unsigned thingKind)
}
uint32
js_GetGCThingTraceKind(void *thing) {
js_GetGCThingTraceKind(void *thing)
{
return GetGCThingTraceKind(thing);
}
@ -1351,7 +1350,7 @@ Arena<T>::markDelayedChildren(JSTracer *trc)
T *thingsEnd = &t.things[ThingsPerArena-1].t;
JS_ASSERT(thing == getAlignedThing(thing));
while (thing <= thingsEnd) {
if (thing->asCell()->isMarked())
if (thing->isMarked())
js::gc::MarkChildren(trc, thing);
thing++;
@ -1436,7 +1435,7 @@ gc_root_traversal(JSTracer *trc, const RootEntry &entry)
}
if (ptr) {
if (!JSString::isGCThingStatic(ptr)) {
if (!JSAtom::isStatic(ptr)) {
bool root_points_to_gcArenaList = false;
JSCompartment **c = trc->context->runtime->compartments.begin();
for (; c != trc->context->runtime->compartments.end(); ++c) {
@ -1854,23 +1853,19 @@ void
js_FinalizeStringRT(JSRuntime *rt, JSString *str)
{
JS_RUNTIME_UNMETER(rt, liveStrings);
JS_ASSERT(!str->isStaticAtom());
JS_ASSERT(!str->isRope());
JS_ASSERT(str->isLinear() && !str->isStaticAtom());
if (str->isDependent()) {
/* A dependent string can not be external and must be valid. */
JS_ASSERT(str->asCell()->arena()->header()->thingKind == FINALIZE_STRING);
JS_ASSERT(str->dependentBase());
JS_ASSERT(str->arena()->header()->thingKind == FINALIZE_STRING);
JS_ASSERT(str->asDependent().base());
JS_RUNTIME_UNMETER(rt, liveDependentStrings);
} else {
unsigned thingKind = str->asCell()->arena()->header()->thingKind;
unsigned thingKind = str->arena()->header()->thingKind;
JS_ASSERT(unsigned(FINALIZE_SHORT_STRING) <= thingKind &&
thingKind <= unsigned(FINALIZE_EXTERNAL_STRING));
/* A stillborn string has null chars, so is not valid. */
jschar *chars = const_cast<jschar *>(str->flatChars());
if (!chars)
return;
jschar *chars = const_cast<jschar *>(str->asFlat().chars());
if (thingKind == FINALIZE_STRING) {
rt->stringMemoryUsed -= str->length() * 2;
rt->free(chars);
@ -1915,22 +1910,22 @@ FinalizeArenaList(JSCompartment *comp, JSContext *cx, unsigned thingKind)
if (!nextFree) {
nextFree = thingsEnd->asFreeCell();
} else {
JS_ASSERT(thing->asCell() <= nextFree);
JS_ASSERT(nextFree < thingsEnd->asCell());
JS_ASSERT(thing->asFreeCell() <= nextFree);
JS_ASSERT(nextFree < thingsEnd->asFreeCell());
}
for (;; thing++) {
if (thing->asCell() == nextFree) {
if (thing->asFreeCell() == nextFree) {
if (thing == thingsEnd)
break;
nextFree = nextFree->link;
if (!nextFree) {
nextFree = thingsEnd->asFreeCell();
} else {
JS_ASSERT(thing->asCell() < nextFree);
JS_ASSERT(thing->asFreeCell() < nextFree);
JS_ASSERT(nextFree < thingsEnd->asFreeCell());
}
} else if (thing->asCell()->isMarked()) {
} else if (thing->isMarked()) {
allClear = false;
METER(nthings++);
continue;

View File

@ -532,15 +532,8 @@ GetFinalizableTraceKind(size_t thingKind)
return map[thingKind];
}
static inline uint32
GetGCThingTraceKind(void *thing)
{
JS_ASSERT(thing);
if (JSString::isGCThingStatic(thing))
return JSTRACE_STRING;
Cell *cell = reinterpret_cast<Cell *>(thing);
return GetFinalizableTraceKind(cell->arena()->header()->thingKind);
}
inline uint32
GetGCThingTraceKind(void *thing);
static inline JSRuntime *
GetGCThingRuntime(void *thing)

View File

@ -43,6 +43,7 @@
#include "jsgc.h"
#include "jscntxt.h"
#include "jscompartment.h"
#include "jsscope.h"
#include "jslock.h"
#include "jstl.h"
@ -55,9 +56,64 @@
# define METER_IF(condition, x) ((void) 0)
#endif
inline bool
JSAtom::isUnitString(void *ptr)
{
jsuword delta = reinterpret_cast<jsuword>(ptr) -
reinterpret_cast<jsuword>(unitStaticTable);
if (delta >= UNIT_STATIC_LIMIT * sizeof(JSString))
return false;
/* If ptr points inside the static array, it must be well-aligned. */
JS_ASSERT(delta % sizeof(JSString) == 0);
return true;
}
inline bool
JSAtom::isLength2String(void *ptr)
{
jsuword delta = reinterpret_cast<jsuword>(ptr) -
reinterpret_cast<jsuword>(length2StaticTable);
if (delta >= NUM_SMALL_CHARS * NUM_SMALL_CHARS * sizeof(JSString))
return false;
/* If ptr points inside the static array, it must be well-aligned. */
JS_ASSERT(delta % sizeof(JSString) == 0);
return true;
}
inline bool
JSAtom::isHundredString(void *ptr)
{
jsuword delta = reinterpret_cast<jsuword>(ptr) -
reinterpret_cast<jsuword>(hundredStaticTable);
if (delta >= NUM_HUNDRED_STATICS * sizeof(JSString))
return false;
/* If ptr points inside the static array, it must be well-aligned. */
JS_ASSERT(delta % sizeof(JSString) == 0);
return true;
}
inline bool
JSAtom::isStatic(void *ptr)
{
return isUnitString(ptr) || isLength2String(ptr) || isHundredString(ptr);
}
namespace js {
namespace gc {
inline uint32
GetGCThingTraceKind(void *thing)
{
JS_ASSERT(thing);
if (JSAtom::isStatic(thing))
return JSTRACE_STRING;
Cell *cell = reinterpret_cast<Cell *>(thing);
return GetFinalizableTraceKind(cell->arena()->header()->thingKind);
}
/* Capacity for slotsToThingKind */
const size_t SLOTS_TO_THING_KIND_LIMIT = 17;
@ -194,7 +250,7 @@ TypedMarker(JSTracer *trc, JSFunction *thing);
static JS_ALWAYS_INLINE void
TypedMarker(JSTracer *trc, JSShortString *thing);
static JS_ALWAYS_INLINE void
extern void
TypedMarker(JSTracer *trc, JSString *thing);
template<typename T>
@ -210,7 +266,7 @@ Mark(JSTracer *trc, T *thing)
JSRuntime *rt = trc->context->runtime;
/* Don't mark things outside a compartment if we are in a per-compartment GC */
if (rt->gcCurrentCompartment && thing->asCell()->compartment() != rt->gcCurrentCompartment)
if (rt->gcCurrentCompartment && thing->compartment() != rt->gcCurrentCompartment)
goto out;
if (!IS_GC_MARKING_TRACER(trc)) {
@ -307,10 +363,11 @@ static inline void
MarkChildren(JSTracer *trc, JSString *str)
{
if (str->isDependent())
MarkString(trc, str->dependentBase(), "base");
MarkString(trc, str->asDependent().base(), "base");
else if (str->isRope()) {
MarkString(trc, str->ropeLeft(), "left child");
MarkString(trc, str->ropeRight(), "right child");
JSRope &rope = str->asRope();
MarkString(trc, rope.leftChild(), "left child");
MarkString(trc, rope.rightChild(), "right child");
}
}
@ -349,7 +406,7 @@ static JS_ALWAYS_INLINE void
TypedMarker(JSTracer *trc, JSObject *thing)
{
JS_ASSERT(thing);
JS_ASSERT(JSTRACE_OBJECT == GetFinalizableTraceKind(thing->asCell()->arena()->header()->thingKind));
JS_ASSERT(JSTRACE_OBJECT == GetFinalizableTraceKind(thing->arena()->header()->thingKind));
GCMarker *gcmarker = static_cast<GCMarker *>(trc);
if (!thing->markIfUnmarked(gcmarker->getMarkColor()))
@ -366,7 +423,7 @@ static JS_ALWAYS_INLINE void
TypedMarker(JSTracer *trc, JSFunction *thing)
{
JS_ASSERT(thing);
JS_ASSERT(JSTRACE_OBJECT == GetFinalizableTraceKind(thing->asCell()->arena()->header()->thingKind));
JS_ASSERT(JSTRACE_OBJECT == GetFinalizableTraceKind(thing->arena()->header()->thingKind));
GCMarker *gcmarker = static_cast<GCMarker *>(trc);
if (!thing->markIfUnmarked(gcmarker->getMarkColor()))
@ -387,111 +444,7 @@ TypedMarker(JSTracer *trc, JSShortString *thing)
* anything to mark if the string was unmarked and ignore the
* markIfUnmarked result.
*/
(void) thing->asCell()->markIfUnmarked();
}
} /* namespace gc */
namespace detail {
static JS_ALWAYS_INLINE JSString *
Tag(JSString *str)
{
JS_ASSERT(!(size_t(str) & 1));
return (JSString *)(size_t(str) | 1);
}
static JS_ALWAYS_INLINE bool
Tagged(JSString *str)
{
return (size_t(str) & 1) != 0;
}
static JS_ALWAYS_INLINE JSString *
Untag(JSString *str)
{
JS_ASSERT((size_t(str) & 1) == 1);
return (JSString *)(size_t(str) & ~size_t(1));
}
static JS_ALWAYS_INLINE void
NonRopeTypedMarker(JSString *str)
{
/* N.B. The base of a dependent string is not necessarily flat. */
JS_ASSERT(!str->isRope());
while (!str->isStaticAtom() &&
str->asCell()->markIfUnmarked() &&
str->isDependent()) {
str = str->dependentBase();
}
}
} /* namespace detail */
namespace gc {
static JS_ALWAYS_INLINE void
TypedMarker(JSTracer *trc, JSString *str)
{
using namespace detail;
JS_ASSERT(!str->isStaticAtom());
if (!str->isRope()) {
NonRopeTypedMarker(str);
return;
}
/*
* This function must not fail, so a simple stack-based traversal must not
* be used (since it may oom if the stack grows large). Instead, strings
* are temporarily mutated to embed parent pointers as they are traversed.
* This algorithm is homomorphic to JSString::flatten.
*/
JSString *parent = NULL;
first_visit_node: {
JS_ASSERT(!str->isStaticAtom());
if (!str->asCell()->markIfUnmarked())
goto finish_node;
JSString *left = str->ropeLeft();
if (left->isRope()) {
JS_ASSERT(!Tagged(str->u.left) && !Tagged(str->s.right));
str->u.left = Tag(parent);
parent = str;
str = left;
goto first_visit_node;
}
NonRopeTypedMarker(left);
}
visit_right_child: {
JSString *right = str->ropeRight();
if (right->isRope()) {
JS_ASSERT(!Tagged(str->u.left) && !Tagged(str->s.right));
str->s.right = Tag(parent);
parent = str;
str = right;
goto first_visit_node;
}
NonRopeTypedMarker(right);
}
finish_node: {
if (!parent)
return;
if (Tagged(parent->u.left)) {
JS_ASSERT(!Tagged(parent->s.right));
JSString *nextParent = Untag(parent->u.left);
parent->u.left = str;
str = parent;
parent = nextParent;
goto visit_right_child;
}
JS_ASSERT(Tagged(parent->s.right));
JSString *nextParent = Untag(parent->s.right);
parent->s.right = str;
str = parent;
parent = nextParent;
goto finish_node;
}
(void) thing->markIfUnmarked();
}
static inline void
@ -500,9 +453,8 @@ MarkAtomRange(JSTracer *trc, size_t len, JSAtom **vec, const char *name)
for (uint32 i = 0; i < len; i++) {
if (JSAtom *atom = vec[i]) {
JS_SET_TRACING_INDEX(trc, name, i);
JSString *str = ATOM_TO_STRING(atom);
if (!str->isStaticAtom())
Mark(trc, str);
if (!atom->isStaticAtom())
Mark(trc, atom);
}
}
}

View File

@ -364,7 +364,7 @@ GCMarker::dumpConservativeRoots()
JSString *str = (JSString *) i->thing;
if (str->isLinear()) {
char buf[50];
PutEscapedString(buf, sizeof buf, str->assertIsLinear(), '"');
PutEscapedString(buf, sizeof buf, &str->asLinear(), '"');
fprintf(fp, "string %s", buf);
} else {
fprintf(fp, "rope: length %d", (int)str->length());

View File

@ -3906,7 +3906,7 @@ BEGIN_CASE(JSOP_TYPEOF)
const Value &ref = regs.sp[-1];
JSType type = JS_TypeOfValue(cx, Jsvalify(ref));
JSAtom *atom = rt->atomState.typeAtoms[type];
regs.sp[-1].setString(ATOM_TO_STRING(atom));
regs.sp[-1].setString(atom);
}
END_CASE(JSOP_TYPEOF)
@ -4325,7 +4325,7 @@ BEGIN_CASE(JSOP_CALLPROP)
#if JS_HAS_NO_SUCH_METHOD
if (JS_UNLIKELY(rval.isUndefined()) && regs.sp[-1].isObject()) {
LOAD_ATOM(0, atom);
regs.sp[-2].setString(ATOM_TO_STRING(atom));
regs.sp[-2].setString(atom);
if (!js_OnUnknownMethod(cx, regs.sp - 2))
goto error;
}
@ -4502,7 +4502,7 @@ BEGIN_CASE(JSOP_GETELEM)
JSString *str = lref.toString();
int32_t i = rref.toInt32();
if (size_t(i) < str->length()) {
str = JSString::getUnitString(cx, str, size_t(i));
str = JSAtom::getUnitStringForElement(cx, str, size_t(i));
if (!str)
goto error;
regs.sp--;
@ -4945,7 +4945,7 @@ BEGIN_CASE(JSOP_STRING)
{
JSAtom *atom;
LOAD_ATOM(0, atom);
PUSH_STRING(ATOM_TO_STRING(atom));
PUSH_STRING(atom);
}
END_CASE(JSOP_STRING)
@ -5128,7 +5128,7 @@ BEGIN_CASE(JSOP_LOOKUPSWITCH)
JSLinearString *str2;
SEARCH_PAIRS(
match = (rval.isString() &&
((str2 = rval.toString()->assertIsLinear()) == str ||
((str2 = &rval.toString()->asLinear()) == str ||
EqualStrings(str2, str)));
)
} else if (lval.isNumber()) {
@ -6290,7 +6290,7 @@ BEGIN_CASE(JSOP_QNAMEPART)
{
JSAtom *atom;
LOAD_ATOM(0, atom);
PUSH_STRING(ATOM_TO_STRING(atom));
PUSH_STRING(atom);
}
END_CASE(JSOP_QNAMEPART)
@ -6298,7 +6298,7 @@ BEGIN_CASE(JSOP_QNAMECONST)
{
JSAtom *atom;
LOAD_ATOM(0, atom);
Value rval = StringValue(ATOM_TO_STRING(atom));
Value rval = StringValue(atom);
Value lval = regs.sp[-1];
JSObject *obj = js_ConstructXMLQNameObject(cx, lval, rval);
if (!obj)
@ -6511,7 +6511,7 @@ BEGIN_CASE(JSOP_XMLCDATA)
{
JSAtom *atom;
LOAD_ATOM(0, atom);
JSString *str = ATOM_TO_STRING(atom);
JSString *str = atom;
JSObject *obj = js_NewXMLSpecialObject(cx, JSXML_CLASS_TEXT, NULL, str);
if (!obj)
goto error;
@ -6523,7 +6523,7 @@ BEGIN_CASE(JSOP_XMLCOMMENT)
{
JSAtom *atom;
LOAD_ATOM(0, atom);
JSString *str = ATOM_TO_STRING(atom);
JSString *str = atom;
JSObject *obj = js_NewXMLSpecialObject(cx, JSXML_CLASS_COMMENT, NULL, str);
if (!obj)
goto error;
@ -6535,7 +6535,7 @@ BEGIN_CASE(JSOP_XMLPI)
{
JSAtom *atom;
LOAD_ATOM(0, atom);
JSString *str = ATOM_TO_STRING(atom);
JSString *str = atom;
Value rval = regs.sp[-1];
JSString *str2 = rval.toString();
JSObject *obj = js_NewXMLSpecialObject(cx, JSXML_CLASS_PROCESSING_INSTRUCTION, str, str2);

View File

@ -1006,8 +1006,8 @@ js_IteratorNext(JSContext *cx, JSObject *iterobj, Value *rval)
JSString *str;
jsint i;
if (rval->isInt32() && (jsuint(i = rval->toInt32()) < INT_STRING_LIMIT)) {
str = JSString::intString(i);
if (rval->isInt32() && JSAtom::hasIntStatic(i = rval->toInt32())) {
str = &JSAtom::intStatic(i);
} else {
str = js_ValueToString(cx, *rval);
if (!str)

View File

@ -663,7 +663,7 @@ math_tan(JSContext *cx, uintN argc, Value *vp)
static JSBool
math_toSource(JSContext *cx, uintN argc, Value *vp)
{
vp->setString(ATOM_TO_STRING(CLASS_ATOM(cx, Math)));
vp->setString(CLASS_ATOM(cx, Math));
return JS_TRUE;
}
#endif

View File

@ -605,8 +605,8 @@ js_IntToString(JSContext *cx, int32 si)
{
uint32 ui;
if (si >= 0) {
if (si < INT_STRING_LIMIT)
return JSString::intString(si);
if (JSAtom::hasIntStatic(si))
return &JSAtom::intStatic(si);
ui = si;
} else {
ui = uint32(-si);
@ -621,10 +621,10 @@ js_IntToString(JSContext *cx, int32 si)
if (!str)
return NULL;
/* +1, since MAX_SHORT_STRING_LENGTH does not count the null char. */
JS_STATIC_ASSERT(JSShortString::MAX_SHORT_STRING_LENGTH + 1 >= sizeof("-2147483648"));
/* +1, since MAX_LENGTH does not count the null char. */
JS_STATIC_ASSERT(JSShortString::MAX_LENGTH + 1 >= sizeof("-2147483648"));
jschar *end = str->getInlineStorageBeforeInit() + JSShortString::MAX_SHORT_STRING_LENGTH;
jschar *end = str->inlineStorageBeforeInit() + JSShortString::MAX_SHORT_LENGTH;
jschar *cp = end;
*cp = 0;
@ -639,9 +639,8 @@ js_IntToString(JSContext *cx, int32 si)
str->initAtOffsetInBuffer(cp, end - cp);
JSString *ret = str->header();
c->dtoaCache.cache(10, si, ret);
return ret;
c->dtoaCache.cache(10, si, str);
return str;
}
/* Returns a non-NULL pointer to inside cbuf. */
@ -1154,7 +1153,6 @@ js_NumberToStringWithBase(JSContext *cx, jsdouble d, jsint base)
{
ToCStringBuf cbuf;
char *numStr;
JSString *s;
/*
* Caller is responsible for error reporting. When called from trace,
@ -1168,21 +1166,23 @@ js_NumberToStringWithBase(JSContext *cx, jsdouble d, jsint base)
int32_t i;
if (JSDOUBLE_IS_INT32(d, &i)) {
if (base == 10 && jsuint(i) < INT_STRING_LIMIT)
return JSString::intString(i);
if (base == 10 && JSAtom::hasIntStatic(i))
return &JSAtom::intStatic(i);
if (jsuint(i) < jsuint(base)) {
if (i < 10)
return JSString::intString(i);
return JSString::unitString(jschar('a' + i - 10));
return &JSAtom::intStatic(i);
jschar c = 'a' + i - 10;
JS_ASSERT(JSAtom::hasUnitStatic(c));
return &JSAtom::unitStatic(c);
}
if (JSString *str = c->dtoaCache.lookup(base, d))
if (JSFlatString *str = c->dtoaCache.lookup(base, d))
return str;
numStr = IntToCString(&cbuf, i, base);
JS_ASSERT(!cbuf.dbuf && numStr >= cbuf.sbuf && numStr < cbuf.sbuf + cbuf.sbufSize);
} else {
if (JSString *str = c->dtoaCache.lookup(base, d))
if (JSFlatString *str = c->dtoaCache.lookup(base, d))
return str;
numStr = FracNumberToCString(cx, &cbuf, d, base);
@ -1196,8 +1196,7 @@ js_NumberToStringWithBase(JSContext *cx, jsdouble d, jsint base)
cbuf.dbuf && cbuf.dbuf == numStr);
}
s = js_NewStringCopyZ(cx, numStr);
JSFixedString *s = js_NewStringCopyZ(cx, numStr);
c->dtoaCache.cache(base, d, s);
return s;
}
@ -1210,11 +1209,11 @@ js_NumberToString(JSContext *cx, jsdouble d)
namespace js {
JSFlatString *
JSFixedString *
NumberToString(JSContext *cx, jsdouble d)
{
if (JSString *str = js_NumberToStringWithBase(cx, d, 10))
return str->assertIsFlat();
return &str->asFixed();
return NULL;
}

View File

@ -207,7 +207,7 @@ extern bool JS_FASTCALL
NumberValueToStringBuffer(JSContext *cx, const Value &v, StringBuffer &sb);
/* Same as js_NumberToString, different signature. */
extern JSFlatString *
extern JSFixedString *
NumberToString(JSContext *cx, jsdouble d);
/*

View File

@ -590,13 +590,13 @@ obj_toSource(JSContext *cx, uintN argc, Value *vp)
if (attrs & JSPROP_GETTER) {
doGet = false;
val[valcnt] = shape->getterValue();
gsop[valcnt] = ATOM_TO_STRING(cx->runtime->atomState.getAtom);
gsop[valcnt] = cx->runtime->atomState.getAtom;
valcnt++;
}
if (attrs & JSPROP_SETTER) {
doGet = false;
val[valcnt] = shape->setterValue();
gsop[valcnt] = ATOM_TO_STRING(cx->runtime->atomState.setAtom);
gsop[valcnt] = cx->runtime->atomState.setAtom;
valcnt++;
}
}
@ -855,13 +855,13 @@ obj_toString(JSContext *cx, uintN argc, Value *vp)
/* Step 1. */
if (thisv.isUndefined()) {
vp->setString(ATOM_TO_STRING(cx->runtime->atomState.objectUndefinedAtom));
vp->setString(cx->runtime->atomState.objectUndefinedAtom);
return true;
}
/* Step 2. */
if (thisv.isNull()) {
vp->setString(ATOM_TO_STRING(cx->runtime->atomState.objectNullAtom));
vp->setString(cx->runtime->atomState.objectNullAtom);
return true;
}
@ -4420,8 +4420,7 @@ js_CheckForStringIndex(jsid id)
return id;
JSAtom *atom = JSID_TO_ATOM(id);
JSString *str = ATOM_TO_STRING(atom);
const jschar *s = str->flatChars();
const jschar *s = atom->chars();
jschar ch = *s;
JSBool negative = (ch == '-');
@ -4431,7 +4430,7 @@ js_CheckForStringIndex(jsid id)
if (!JS7_ISDEC(ch))
return id;
size_t n = str->flatLength() - negative;
size_t n = atom->length() - negative;
if (n > sizeof(JSBOXEDWORD_INT_MAX_STRING) - 1)
return id;
@ -6246,7 +6245,7 @@ js_TryValueOf(JSContext *cx, JSObject *obj, JSType type, Value *rval)
{
Value argv[1];
argv[0].setString(ATOM_TO_STRING(cx->runtime->atomState.typeAtoms[type]));
argv[0].setString(cx->runtime->atomState.typeAtoms[type]);
return js_TryMethod(cx, obj, cx->runtime->atomState.valueOfAtom,
1, argv, rval);
}
@ -6589,7 +6588,7 @@ JS_FRIEND_API(void)
js_DumpAtom(JSAtom *atom)
{
fprintf(stderr, "JSAtom* (%p) = ", (void *) atom);
js_DumpString(ATOM_TO_STRING(atom));
js_DumpString(atom);
}
void
@ -6610,7 +6609,7 @@ dumpValue(const Value &v)
JSFunction *fun = GET_FUNCTION_PRIVATE(cx, funobj);
if (fun->atom) {
fputs("<function ", stderr);
FileEscapedString(stderr, ATOM_TO_STRING(fun->atom), 0);
FileEscapedString(stderr, fun->atom, 0);
} else {
fputs("<unnamed function", stderr);
}

View File

@ -58,13 +58,13 @@
#include "jsbool.h"
#include "jscntxt.h"
#include "jsnum.h"
#include "jsscopeinlines.h"
#include "jsscriptinlines.h"
#include "jsstr.h"
#include "jsfuninlines.h"
#include "jsgcinlines.h"
#include "jsprobes.h"
#include "jsscopeinlines.h"
inline bool
JSObject::preventExtensions(JSContext *cx, js::AutoIdVector *props)
@ -125,6 +125,39 @@ JSObject::syncSpecialEquality()
flags |= JSObject::HAS_EQUALITY;
}
inline void
JSObject::trace(JSTracer *trc)
{
if (!isNative())
return;
JSContext *cx = trc->context;
js::Shape *shape = lastProp;
if (IS_GC_MARKING_TRACER(trc) && cx->runtime->gcRegenShapes) {
/*
* Either this object has its own shape, which must be regenerated, or
* it must have the same shape as lastProp.
*/
if (!shape->hasRegenFlag()) {
shape->shape = js_RegenerateShapeForGC(cx->runtime);
shape->setRegenFlag();
}
uint32 newShape = shape->shape;
if (hasOwnShape()) {
newShape = js_RegenerateShapeForGC(cx->runtime);
JS_ASSERT(newShape != shape->shape);
}
objShape = newShape;
}
/* Trace our property tree or dictionary ancestor line. */
do {
shape->trace(trc);
} while ((shape = shape->parent) != NULL && !shape->marked());
}
inline void
JSObject::finalize(JSContext *cx)
{
@ -670,7 +703,7 @@ JSObject::getNamePrefix() const
{
JS_ASSERT(isNamespace() || isQName());
const js::Value &v = getSlot(JSSLOT_NAME_PREFIX);
return !v.isUndefined() ? v.toString()->assertIsLinear() : NULL;
return !v.isUndefined() ? &v.toString()->asLinear() : NULL;
}
inline jsval
@ -699,7 +732,7 @@ JSObject::getNameURI() const
{
JS_ASSERT(isNamespace() || isQName());
const js::Value &v = getSlot(JSSLOT_NAME_URI);
return !v.isUndefined() ? v.toString()->assertIsLinear() : NULL;
return !v.isUndefined() ? &v.toString()->asLinear() : NULL;
}
inline jsval
@ -735,7 +768,7 @@ JSObject::getQNameLocalName() const
{
JS_ASSERT(isQName());
const js::Value &v = getSlot(JSSLOT_QNAME_LOCAL_NAME);
return !v.isUndefined() ? v.toString()->assertIsLinear() : NULL;
return !v.isUndefined() ? &v.toString()->asLinear() : NULL;
}
inline jsval

View File

@ -64,6 +64,7 @@
#include "jsatominlines.h"
#include "jsobjinlines.h"
#include "jsstrinlines.h"
using namespace js;
using namespace js::gc;
@ -1262,7 +1263,7 @@ js_ConsumeJSONText(JSContext *cx, JSONParser *jp, const jschar *data, uint32 len
static JSBool
json_toSource(JSContext *cx, uintN argc, Value *vp)
{
vp->setString(ATOM_TO_STRING(CLASS_ATOM(cx, JSON)));
vp->setString(CLASS_ATOM(cx, JSON));
return JS_TRUE;
}
#endif

View File

@ -421,7 +421,7 @@ js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc,
v = Jsvalify(script->getConst(index));
} else {
JS_GET_SCRIPT_ATOM(script, pc, index, atom);
v = ATOM_TO_JSVAL(atom);
v = STRING_TO_JSVAL(atom);
}
} else {
if (type == JOF_OBJECT)
@ -440,7 +440,7 @@ js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc,
case JOF_GLOBAL:
atom = script->getGlobalAtom(GET_SLOTNO(pc));
v = ATOM_TO_JSVAL(atom);
v = STRING_TO_JSVAL(atom);
{
JSAutoByteString bytes;
if (!ToDisassemblySource(cx, v, &bytes))
@ -528,7 +528,7 @@ js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc,
index = js_GetIndexFromBytecode(cx, script, pc, SLOTNO_LEN);
if (type == JOF_SLOTATOM) {
JS_GET_SCRIPT_ATOM(script, pc, index, atom);
v = ATOM_TO_JSVAL(atom);
v = STRING_TO_JSVAL(atom);
} else {
obj = script->getObject(index);
v = OBJECT_TO_JSVAL(obj);
@ -1263,7 +1263,7 @@ DecompileSwitch(SprintStack *ss, TableEntry *table, uintN tableLength,
*/
todo = -1;
if (table[i].label) {
str = ATOM_TO_STRING(table[i].label);
str = table[i].label;
key = JSVAL_VOID;
} else if (JSVAL_IS_DOUBLE(key)) {
JSOp junk;
@ -1385,7 +1385,7 @@ GetLocal(SprintStack *ss, jsint i)
LOCAL_ASSERT(JSID_IS_ATOM(shape.id));
JSAtom *atom = JSID_TO_ATOM(shape.id);
const char *rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
const char *rval = QuoteString(&ss->sprinter, atom, 0);
if (!rval)
return NULL;
@ -1925,7 +1925,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
quote_ = 0; \
fmt = ufmt; \
} \
rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), quote_); \
rval = QuoteString(&ss->sprinter, atom, quote_); \
if (!rval) \
return NULL; \
JS_END_MACRO
@ -2285,7 +2285,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
case SRC_LABEL:
GET_SOURCE_NOTE_ATOM(sn, atom);
jp->indent -= 4;
rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
rval = QuoteString(&ss->sprinter, atom, 0);
if (!rval)
return NULL;
RETRACT(&ss->sprinter, rval);
@ -2295,7 +2295,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
case SRC_LABELBRACE:
GET_SOURCE_NOTE_ATOM(sn, atom);
rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
rval = QuoteString(&ss->sprinter, atom, 0);
if (!rval)
return NULL;
RETRACT(&ss->sprinter, rval);
@ -2707,7 +2707,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
ok = JS_TRUE;
for (i = 0; i < argc; i++) {
atom = atomv[i];
rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
rval = QuoteString(&ss->sprinter, atom, 0);
if (!rval ||
!PushOff(ss, STR2OFF(&ss->sprinter, rval), op)) {
ok = JS_FALSE;
@ -2781,7 +2781,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
i = GET_SLOTNO(pc) - jp->script->nfixed;
pc += JSOP_SETLOCALPOP_LENGTH;
atom = atomv[i - OBJ_BLOCK_DEPTH(cx, obj)];
str = ATOM_TO_STRING(atom);
str = atom;
if (!QuoteString(&jp->sprinter, str, 0)) {
ok = JS_FALSE;
goto enterblock_out;
@ -3243,7 +3243,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
case SRC_CONT2LABEL:
GET_SOURCE_NOTE_ATOM(sn, atom);
rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
rval = QuoteString(&ss->sprinter, atom, 0);
if (!rval)
return NULL;
RETRACT(&ss->sprinter, rval);
@ -3256,7 +3256,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
case SRC_BREAK2LABEL:
GET_SOURCE_NOTE_ATOM(sn, atom);
rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
rval = QuoteString(&ss->sprinter, atom, 0);
if (!rval)
return NULL;
RETRACT(&ss->sprinter, rval);
@ -3434,7 +3434,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
atom = GetArgOrVarAtom(jp, i);
LOCAL_ASSERT(atom);
todo = SprintCString(&ss->sprinter, VarPrefix(sn));
if (todo < 0 || !QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0))
if (todo < 0 || !QuoteString(&ss->sprinter, atom, 0))
return NULL;
break;
@ -3444,7 +3444,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
sn = js_GetSrcNote(jp->script, pc);
todo = SprintCString(&ss->sprinter, VarPrefix(sn));
if (todo < 0 || !QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0))
if (todo < 0 || !QuoteString(&ss->sprinter, atom, 0))
return NULL;
break;
@ -3452,7 +3452,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
xval = NULL;
LOAD_ATOM(0);
if (!ATOM_IS_IDENTIFIER(atom)) {
xval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom),
xval = QuoteString(&ss->sprinter, atom,
(jschar)'\'');
if (!xval)
return NULL;
@ -3465,7 +3465,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
todo = Sprint(&ss->sprinter, ss_format, lval, *lval ? "." : "");
if (todo < 0)
return NULL;
if (!QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0))
if (!QuoteString(&ss->sprinter, atom, 0))
return NULL;
}
break;
@ -3560,7 +3560,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
LOAD_ATOM(0);
do_setname:
lval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
lval = QuoteString(&ss->sprinter, atom, 0);
if (!lval)
return NULL;
rval = POP_STR();
@ -3671,7 +3671,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
case JSOP_DELNAME:
LOAD_ATOM(0);
lval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
lval = QuoteString(&ss->sprinter, atom, 0);
if (!lval)
return NULL;
RETRACT(&ss->sprinter, lval);
@ -3731,7 +3731,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
case JSOP_DECGNAME:
LOAD_ATOM(0);
do_incatom:
lval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
lval = QuoteString(&ss->sprinter, atom, 0);
if (!lval)
return NULL;
RETRACT(&ss->sprinter, lval);
@ -3787,7 +3787,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
case JSOP_GNAMEDEC:
LOAD_ATOM(0);
do_atominc:
lval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
lval = QuoteString(&ss->sprinter, atom, 0);
if (!lval)
return NULL;
RETRACT(&ss->sprinter, lval);
@ -3866,7 +3866,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
do_getarg_prop:
atom = GetArgOrVarAtom(ss->printer, i);
LOCAL_ASSERT(atom);
lval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
lval = QuoteString(&ss->sprinter, atom, 0);
if (!lval || !PushOff(ss, STR2OFF(&ss->sprinter, lval), op))
return NULL;
@ -4002,8 +4002,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
do_qname:
#endif
sn = js_GetSrcNote(jp->script, pc);
rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom),
inXML ? DONT_ESCAPE : 0);
rval = QuoteString(&ss->sprinter, atom, inXML ? DONT_ESCAPE : 0);
if (!rval)
return NULL;
RETRACT(&ss->sprinter, rval);
@ -4040,8 +4039,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
case JSOP_STRING:
LOAD_ATOM(0);
rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom),
inXML ? DONT_ESCAPE : '"');
rval = QuoteString(&ss->sprinter, atom, inXML ? DONT_ESCAPE : '"');
if (!rval)
return NULL;
todo = STR2OFF(&ss->sprinter, rval);
@ -4214,7 +4212,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
case JSOP_CALLEE:
JS_ASSERT(jp->fun && jp->fun->atom);
todo = SprintString(&ss->sprinter, ATOM_TO_STRING(jp->fun->atom));
todo = SprintString(&ss->sprinter, jp->fun->atom);
break;
case JSOP_OBJECT:
@ -4556,7 +4554,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
case JSOP_INITPROP:
case JSOP_INITMETHOD:
LOAD_ATOM(0);
xval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom),
xval = QuoteString(&ss->sprinter, atom,
jschar(ATOM_IS_IDENTIFIER(atom) ? 0 : '\''));
if (!xval)
return NULL;
@ -4644,7 +4642,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
case JSOP_QNAMECONST:
LOAD_ATOM(0);
rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
rval = QuoteString(&ss->sprinter, atom, 0);
if (!rval)
return NULL;
RETRACT(&ss->sprinter, rval);
@ -4737,8 +4735,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
case JSOP_XMLCDATA:
LOAD_ATOM(0);
todo = SprintPut(&ss->sprinter, "<![CDATA[", 9);
if (!QuoteString(&ss->sprinter, ATOM_TO_STRING(atom),
DONT_ESCAPE))
if (!QuoteString(&ss->sprinter, atom, DONT_ESCAPE))
return NULL;
SprintPut(&ss->sprinter, "]]>", 3);
break;
@ -4746,8 +4743,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
case JSOP_XMLCOMMENT:
LOAD_ATOM(0);
todo = SprintPut(&ss->sprinter, "<!--", 4);
if (!QuoteString(&ss->sprinter, ATOM_TO_STRING(atom),
DONT_ESCAPE))
if (!QuoteString(&ss->sprinter, atom, DONT_ESCAPE))
return NULL;
SprintPut(&ss->sprinter, "-->", 3);
break;
@ -4758,7 +4754,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
if (!rval)
return NULL;
todo = SprintPut(&ss->sprinter, "<?", 2);
ok = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0) &&
ok = QuoteString(&ss->sprinter, atom, 0) &&
(*rval == '\0' ||
(SprintPut(&ss->sprinter, " ", 1) >= 0 &&
SprintCString(&ss->sprinter, rval)));
@ -4972,7 +4968,7 @@ js_DecompileFunction(JSPrinter *jp)
}
js_printf(jp, "%s ", js_function_str);
if (fun->atom && !QuoteString(&jp->sprinter, ATOM_TO_STRING(fun->atom), 0))
if (fun->atom && !QuoteString(&jp->sprinter, fun->atom, 0))
return JS_FALSE;
js_puts(jp, "(");
@ -5041,7 +5037,7 @@ js_DecompileFunction(JSPrinter *jp)
#undef LOCAL_ASSERT
#endif
if (!QuoteString(&jp->sprinter, ATOM_TO_STRING(param), 0)) {
if (!QuoteString(&jp->sprinter, param, 0)) {
ok = JS_FALSE;
break;
}

View File

@ -9136,7 +9136,7 @@ FoldType(JSContext *cx, JSParseNode *pn, TokenKind type)
case TOK_NUMBER:
if (pn->pn_type == TOK_STRING) {
jsdouble d;
if (!ValueToNumber(cx, StringValue(ATOM_TO_STRING(pn->pn_atom)), &d))
if (!ValueToNumber(cx, StringValue(pn->pn_atom), &d))
return JS_FALSE;
pn->pn_dval = d;
pn->pn_type = TOK_NUMBER;
@ -9265,9 +9265,9 @@ FoldXMLConstants(JSContext *cx, JSParseNode *pn, JSTreeContext *tc)
str = NULL;
if ((pn->pn_xflags & PNX_CANTFOLD) == 0) {
if (tt == TOK_XMLETAGO)
accum = ATOM_TO_STRING(cx->runtime->atomState.etagoAtom);
accum = cx->runtime->atomState.etagoAtom;
else if (tt == TOK_XMLSTAGO || tt == TOK_XMLPTAGC)
accum = ATOM_TO_STRING(cx->runtime->atomState.stagoAtom);
accum = cx->runtime->atomState.stagoAtom;
}
/*
@ -9291,24 +9291,23 @@ FoldXMLConstants(JSContext *cx, JSParseNode *pn, JSTreeContext *tc)
case TOK_STRING:
if (pn2->pn_arity == PN_LIST)
goto cantfold;
str = ATOM_TO_STRING(pn2->pn_atom);
str = pn2->pn_atom;
break;
case TOK_XMLCDATA:
str = js_MakeXMLCDATAString(cx, ATOM_TO_STRING(pn2->pn_atom));
str = js_MakeXMLCDATAString(cx, pn2->pn_atom);
if (!str)
return JS_FALSE;
break;
case TOK_XMLCOMMENT:
str = js_MakeXMLCommentString(cx, ATOM_TO_STRING(pn2->pn_atom));
str = js_MakeXMLCommentString(cx, pn2->pn_atom);
if (!str)
return JS_FALSE;
break;
case TOK_XMLPI:
str = js_MakeXMLPIString(cx, ATOM_TO_STRING(pn2->pn_atom),
ATOM_TO_STRING(pn2->pn_atom2));
str = js_MakeXMLPIString(cx, pn2->pn_atom, pn2->pn_atom2);
if (!str)
return JS_FALSE;
break;
@ -9369,9 +9368,9 @@ FoldXMLConstants(JSContext *cx, JSParseNode *pn, JSTreeContext *tc)
str = NULL;
if ((pn->pn_xflags & PNX_CANTFOLD) == 0) {
if (tt == TOK_XMLPTAGC)
str = ATOM_TO_STRING(cx->runtime->atomState.ptagcAtom);
str = cx->runtime->atomState.ptagcAtom;
else if (tt == TOK_XMLSTAGO || tt == TOK_XMLETAGO)
str = ATOM_TO_STRING(cx->runtime->atomState.tagcAtom);
str = cx->runtime->atomState.tagcAtom;
}
if (str) {
accum = js_ConcatStrings(cx, accum, str);
@ -9422,7 +9421,7 @@ Boolish(JSParseNode *pn)
return pn->pn_dval != 0 && !JSDOUBLE_IS_NaN(pn->pn_dval);
case JSOP_STRING:
return ATOM_TO_STRING(pn->pn_atom)->length() != 0;
return pn->pn_atom->length() != 0;
#if JS_HAS_GENERATOR_EXPRS
case JSOP_CALL:
@ -9596,7 +9595,7 @@ js_FoldConstants(JSContext *cx, JSParseNode *pn, JSTreeContext *tc, bool inCond)
pn2 = pn3;
break;
case TOK_STRING:
if (ATOM_TO_STRING(pn1->pn_atom)->length() == 0)
if (pn1->pn_atom->length() == 0)
pn2 = pn3;
break;
case TOK_PRIMARY:
@ -9708,10 +9707,6 @@ js_FoldConstants(JSContext *cx, JSParseNode *pn, JSTreeContext *tc, bool inCond)
case TOK_PLUS:
if (pn->pn_arity == PN_LIST) {
size_t length, length2;
jschar *chars;
JSString *str, *str2;
/*
* Any string literal term with all others number or string means
* this is a concatenation. If any term is not a string or number
@ -9724,22 +9719,22 @@ js_FoldConstants(JSContext *cx, JSParseNode *pn, JSTreeContext *tc, bool inCond)
goto do_binary_op;
/* Ok, we're concatenating: convert non-string constant operands. */
length = 0;
size_t length = 0;
for (pn2 = pn1; pn2; pn2 = pn2->pn_next) {
if (!FoldType(cx, pn2, TOK_STRING))
return JS_FALSE;
/* XXX fold only if all operands convert to string */
if (pn2->pn_type != TOK_STRING)
return JS_TRUE;
length += ATOM_TO_STRING(pn2->pn_atom)->flatLength();
length += pn2->pn_atom->length();
}
/* Allocate a new buffer and string descriptor for the result. */
chars = (jschar *) cx->malloc((length + 1) * sizeof(jschar));
jschar *chars = (jschar *) cx->malloc((length + 1) * sizeof(jschar));
if (!chars)
return JS_FALSE;
chars[length] = 0;
str = js_NewString(cx, chars, length);
JSString *str = js_NewString(cx, chars, length);
if (!str) {
cx->free(chars);
return JS_FALSE;
@ -9747,9 +9742,9 @@ js_FoldConstants(JSContext *cx, JSParseNode *pn, JSTreeContext *tc, bool inCond)
/* Fill the buffer, advancing chars and recycling kids as we go. */
for (pn2 = pn1; pn2; pn2 = RecycleTree(pn2, tc)) {
str2 = ATOM_TO_STRING(pn2->pn_atom);
length2 = str2->flatLength();
js_strncpy(chars, str2->flatChars(), length2);
JSAtom *atom = pn2->pn_atom;
size_t length2 = atom->length();
js_strncpy(chars, atom->chars(), length2);
chars += length2;
}
JS_ASSERT(*chars == 0);
@ -9775,8 +9770,8 @@ js_FoldConstants(JSContext *cx, JSParseNode *pn, JSTreeContext *tc, bool inCond)
}
if (pn1->pn_type != TOK_STRING || pn2->pn_type != TOK_STRING)
return JS_TRUE;
left = ATOM_TO_STRING(pn1->pn_atom);
right = ATOM_TO_STRING(pn2->pn_atom);
left = pn1->pn_atom;
right = pn2->pn_atom;
str = js_ConcatStrings(cx, left, right);
if (!str)
return JS_FALSE;
@ -9898,7 +9893,7 @@ js_FoldConstants(JSContext *cx, JSParseNode *pn, JSTreeContext *tc, bool inCond)
if (pn1->pn_type == TOK_XMLNAME) {
JSObjectBox *xmlbox;
Value v = StringValue(ATOM_TO_STRING(pn1->pn_atom));
Value v = StringValue(pn1->pn_atom);
if (!js_ToAttributeName(cx, &v))
return JS_FALSE;
JS_ASSERT(v.isObject());

View File

@ -601,7 +601,7 @@ public:
*/
bool isEscapeFreeStringLiteral() const {
JS_ASSERT(pn_type == js::TOK_STRING && !pn_parens);
JSString *str = ATOM_TO_STRING(pn_atom);
JSString *str = pn_atom;
/*
* If the string's length in the source code is its length as a value,

View File

@ -140,7 +140,7 @@ Probes::FunctionName(JSContext *cx, const JSFunction *fun, JSAutoByteString *byt
return nullName;
}
return bytes->encode(cx, ATOM_TO_STRING(atom)) ? bytes->ptr() : nullName;
return bytes->encode(cx, atom) ? bytes->ptr() : nullName;
}
#ifdef INCLUDE_MOZILLA_DTRACE

View File

@ -93,8 +93,6 @@ typedef struct JSTreeContext JSTreeContext;
typedef struct JSTryNote JSTryNote;
/* Friend "Advanced API" typedefs. */
typedef struct JSLinearString JSLinearString;
typedef struct JSAtom JSAtom;
typedef struct JSAtomList JSAtomList;
typedef struct JSAtomListElement JSAtomListElement;
typedef struct JSAtomMap JSAtomMap;
@ -118,8 +116,17 @@ typedef struct JSXMLArrayCursor JSXMLArrayCursor;
* templates.
*/
#ifdef __cplusplus
extern "C++" {
class JSDependentString;
class JSExtensibleString;
class JSLinearString;
class JSFixedString;
class JSStaticAtom;
class JSRope;
class JSAtom;
namespace js {
struct ArgumentsData;
@ -177,6 +184,11 @@ class Bindings;
} /* namespace js */
} /* export "C++" */
#else
typedef struct JSAtom JSAtom;
#endif /* __cplusplus */
/* "Friend" types used by jscntxt.h and jsdbgapi.h. */

View File

@ -317,7 +317,7 @@ class NodeBuilder
if (!atom)
return false;
*dst = Valueify(ATOM_TO_JSVAL(atom));
dst->setString(atom);
return true;
}
@ -1613,7 +1613,7 @@ class ASTSerializer
uint32 lineno;
Value atomContents(JSAtom *atom) {
return Valueify(ATOM_TO_JSVAL(atom ? atom : cx->runtime->atomState.emptyAtom));
return StringValue(atom ? atom : cx->runtime->atomState.emptyAtom);
}
BinaryOperator binop(TokenKind tk, JSOp op);
@ -2886,7 +2886,7 @@ ASTSerializer::literal(JSParseNode *pn, Value *dst)
Value val;
switch (PN_TYPE(pn)) {
case TOK_STRING:
val = Valueify(ATOM_TO_JSVAL(pn->pn_atom));
val.setString(pn->pn_atom);
break;
case TOK_REGEXP:

View File

@ -42,7 +42,10 @@
#include "jsregexp.h"
#include "jscntxt.h"
#include "jsobjinlines.h"
#include "jsstrinlines.h"
#include "assembler/wtf/Platform.h"
#if ENABLE_YARR_JIT

View File

@ -57,7 +57,6 @@
#include "jsprvtd.h"
#include "jspubtd.h"
#include "jspropertytree.h"
#include "jsstrinlines.h"
#ifdef _MSC_VER
#pragma warning(push)

View File

@ -132,39 +132,6 @@ JSObject::extend(JSContext *cx, const js::Shape *shape, bool isDefinitelyAtom)
updateShape(cx);
}
inline void
JSObject::trace(JSTracer *trc)
{
if (!isNative())
return;
JSContext *cx = trc->context;
js::Shape *shape = lastProp;
if (IS_GC_MARKING_TRACER(trc) && cx->runtime->gcRegenShapes) {
/*
* Either this object has its own shape, which must be regenerated, or
* it must have the same shape as lastProp.
*/
if (!shape->hasRegenFlag()) {
shape->shape = js_RegenerateShapeForGC(cx->runtime);
shape->setRegenFlag();
}
uint32 newShape = shape->shape;
if (hasOwnShape()) {
newShape = js_RegenerateShapeForGC(cx->runtime);
JS_ASSERT(newShape != shape->shape);
}
objShape = newShape;
}
/* Trace our property tree or dictionary ancestor line. */
do {
shape->trace(trc);
} while ((shape = shape->parent) != NULL && !shape->marked());
}
namespace js {
inline

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -41,7 +41,9 @@
#define jsstrinlines_h___
#include "jsstr.h"
#include "jscntxtinlines.h"
#include "jsgcinlines.h"
namespace js {
@ -49,6 +51,16 @@ static inline bool
CheckStringLength(JSContext *cx, size_t length)
{
if (JS_UNLIKELY(length > JSString::MAX_LENGTH)) {
if (JS_ON_TRACE(cx)) {
/*
* If we can't leave the trace, signal OOM condition, otherwise
* exit from trace before throwing.
*/
if (!CanLeaveTrace(cx))
return NULL;
LeaveTrace(cx);
}
js_ReportAllocationOverflow(cx);
return false;
}
@ -116,7 +128,7 @@ class StringBuffer
* This method takes responsibility for adding the terminating '\0'
* required by js_NewString.
*/
JSFlatString *finishString();
JSFixedString *finishString();
template <size_t ArrayLength>
bool append(const char (&array)[ArrayLength]) {
@ -227,73 +239,206 @@ StringBuffer::checkLength(size_t length)
} /* namespace js */
inline JSFlatString *
JSString::unitString(jschar c)
JS_ALWAYS_INLINE void
JSRope::init(JSString *left, JSString *right, size_t length)
{
JS_ASSERT(c < UNIT_STRING_LIMIT);
return const_cast<JSString *>(&unitStringTable[c])->assertIsFlat();
d.lengthAndFlags = buildLengthAndFlags(length, ROPE_BIT);
d.u1.left = left;
d.s.u2.right = right;
}
JS_ALWAYS_INLINE JSRope *
JSRope::new_(JSContext *cx, JSString *left, JSString *right, size_t length)
{
JSRope *str = (JSRope *)js_NewGCString(cx);
if (!str)
return NULL;
str->init(left, right, length);
return str;
}
JS_ALWAYS_INLINE void
JSDependentString::init(JSLinearString *base, const jschar *chars, size_t length)
{
d.lengthAndFlags = buildLengthAndFlags(length, DEPENDENT_BIT);
d.u1.chars = chars;
d.s.u2.base = base;
}
JS_ALWAYS_INLINE JSDependentString *
JSDependentString::new_(JSContext *cx, JSLinearString *base, const jschar *chars, size_t length)
{
/* Try to avoid long chains of dependent strings. */
while (base->isDependent())
base = base->asDependent().base();
JS_ASSERT(base->isFlat());
JS_ASSERT(chars >= base->chars() && chars < base->chars() + base->length());
JS_ASSERT(length <= base->length() - (chars - base->chars()));
JSDependentString *str = (JSDependentString *)js_NewGCString(cx);
if (!str)
return NULL;
str->init(base, chars, length);
#ifdef DEBUG
JSRuntime *rt = cx->runtime;
JS_RUNTIME_METER(rt, liveDependentStrings);
JS_RUNTIME_METER(rt, totalDependentStrings);
JS_RUNTIME_METER(rt, liveStrings);
JS_RUNTIME_METER(rt, totalStrings);
JS_LOCK_RUNTIME_VOID(rt,
(rt->strdepLengthSum += (double)length,
rt->strdepLengthSquaredSum += (double)length * (double)length));
JS_LOCK_RUNTIME_VOID(rt,
(rt->lengthSum += (double)length,
rt->lengthSquaredSum += (double)length * (double)length));
#endif
return str;
}
JS_ALWAYS_INLINE void
JSFixedString::init(const jschar *chars, size_t length)
{
d.lengthAndFlags = buildLengthAndFlags(length, FIXED_FLAGS);
d.u1.chars = chars;
}
JS_ALWAYS_INLINE JSFixedString *
JSFixedString::new_(JSContext *cx, const jschar *chars, size_t length)
{
JS_ASSERT(length <= MAX_LENGTH);
JS_ASSERT(chars[length] == jschar(0));
JSFixedString *str = (JSFixedString *)js_NewGCString(cx);
if (!str)
return NULL;
str->init(chars, length);
cx->runtime->stringMemoryUsed += length * 2;
#ifdef DEBUG
JSRuntime *rt = cx->runtime;
JS_RUNTIME_METER(rt, liveStrings);
JS_RUNTIME_METER(rt, totalStrings);
JS_LOCK_RUNTIME_VOID(rt,
(rt->lengthSum += (double)length,
rt->lengthSquaredSum += (double)length * (double)length));
#endif
return str;
}
JS_ALWAYS_INLINE JSAtom *
JSFixedString::morphInternedStringIntoAtom()
{
JS_ASSERT((d.lengthAndFlags & FLAGS_MASK) == JS_BIT(2));
JS_STATIC_ASSERT(NON_STATIC_ATOM == JS_BIT(3));
d.lengthAndFlags ^= (JS_BIT(2) | JS_BIT(3));
return &asAtom();
}
JS_ALWAYS_INLINE void
JSExternalString::init(const jschar *chars, size_t length, intN type)
{
d.lengthAndFlags = buildLengthAndFlags(length, FIXED_FLAGS);
d.u1.chars = chars;
d.s.u2.externalStringType = type;
}
JS_ALWAYS_INLINE JSExternalString *
JSExternalString::new_(JSContext *cx, const jschar *chars, size_t length, intN type)
{
JS_ASSERT(uintN(type) < JSExternalString::TYPE_LIMIT);
JS_ASSERT(chars[length] == 0);
JSExternalString *str = (JSExternalString *)js_NewGCExternalString(cx, type);
if (!str)
return NULL;
str->init(chars, length, type);
cx->runtime->updateMallocCounter((length + 1) * sizeof(jschar));
return str;
}
inline bool
JSAtom::fitsInSmallChar(jschar c)
{
return c < SMALL_CHAR_LIMIT && toSmallChar[c] != INVALID_SMALL_CHAR;
}
inline bool
JSAtom::hasUnitStatic(jschar c)
{
return c < UNIT_STATIC_LIMIT;
}
inline JSStaticAtom &
JSAtom::unitStatic(jschar c)
{
JS_ASSERT(hasUnitStatic(c));
return (JSStaticAtom &)unitStaticTable[c];
}
inline bool
JSAtom::hasIntStatic(int32 i)
{
return uint32(i) < INT_STATIC_LIMIT;
}
inline JSStaticAtom &
JSAtom::intStatic(jsint i)
{
JS_ASSERT(hasIntStatic(i));
return (JSStaticAtom &)*intStaticTable[i];
}
inline JSLinearString *
JSString::getUnitString(JSContext *cx, JSString *str, size_t index)
JSAtom::getUnitStringForElement(JSContext *cx, JSString *str, size_t index)
{
JS_ASSERT(index < str->length());
const jschar *chars = str->getChars(cx);
if (!chars)
return NULL;
jschar c = chars[index];
if (c < UNIT_STRING_LIMIT)
return unitString(c);
if (c < UNIT_STATIC_LIMIT)
return &unitStatic(c);
return js_NewDependentString(cx, str, index, 1);
}
inline JSFlatString *
JSString::length2String(jschar c1, jschar c2)
inline JSStaticAtom &
JSAtom::length2Static(jschar c1, jschar c2)
{
JS_ASSERT(fitsInSmallChar(c1));
JS_ASSERT(fitsInSmallChar(c2));
return const_cast<JSString *> (
&length2StringTable[(((size_t)toSmallChar[c1]) << 6) + toSmallChar[c2]]
)->assertIsFlat();
size_t index = (((size_t)toSmallChar[c1]) << 6) + toSmallChar[c2];
return (JSStaticAtom &)length2StaticTable[index];
}
inline JSFlatString *
JSString::length2String(uint32 i)
inline JSStaticAtom &
JSAtom::length2Static(uint32 i)
{
JS_ASSERT(i < 100);
return length2String('0' + i / 10, '0' + i % 10);
}
inline JSFlatString *
JSString::intString(jsint i)
{
jsuint u = jsuint(i);
JS_ASSERT(u < INT_STRING_LIMIT);
return const_cast<JSString *>(JSString::intStringTable[u])->assertIsFlat();
return length2Static('0' + i / 10, '0' + i % 10);
}
/* Get a static atomized string for chars if possible. */
inline JSFlatString *
JSString::lookupStaticString(const jschar *chars, size_t length)
inline JSStaticAtom *
JSAtom::lookupStatic(const jschar *chars, size_t length)
{
if (length == 1) {
if (chars[0] < UNIT_STRING_LIMIT)
return unitString(chars[0]);
}
if (length == 2) {
switch (length) {
case 1:
if (chars[0] < UNIT_STATIC_LIMIT)
return &unitStatic(chars[0]);
return NULL;
case 2:
if (fitsInSmallChar(chars[0]) && fitsInSmallChar(chars[1]))
return length2String(chars[0], chars[1]);
}
/*
* Here we know that JSString::intStringTable covers only 256 (or at least
* not 1000 or more) chars. We rely on order here to resolve the unit vs.
* int string/length-2 string atom identity issue by giving priority to unit
* strings for "0" through "9" and length-2 strings for "10" through "99".
*/
JS_STATIC_ASSERT(INT_STRING_LIMIT <= 999);
if (length == 3) {
return &length2Static(chars[0], chars[1]);
return NULL;
case 3:
/*
* Here we know that JSString::intStringTable covers only 256 (or at least
* not 1000 or more) chars. We rely on order here to resolve the unit vs.
* int string/length-2 string atom identity issue by giving priority to unit
* strings for "0" through "9" and length-2 strings for "10" through "99".
*/
JS_STATIC_ASSERT(INT_STATIC_LIMIT <= 999);
if ('1' <= chars[0] && chars[0] <= '9' &&
'0' <= chars[1] && chars[1] <= '9' &&
'0' <= chars[2] && chars[2] <= '9') {
@ -301,60 +446,51 @@ JSString::lookupStaticString(const jschar *chars, size_t length)
(chars[1] - '0') * 10 +
(chars[2] - '0');
if (jsuint(i) < INT_STRING_LIMIT)
return intString(i);
if (jsuint(i) < INT_STATIC_LIMIT)
return &intStatic(i);
}
return NULL;
}
return NULL;
}
inline void
JSString::finalize(JSContext *cx) {
JS_ASSERT(!isStaticAtom());
JS_ALWAYS_INLINE void
JSString::finalize(JSContext *cx)
{
JS_ASSERT(!isStaticAtom() && !isShort());
JS_RUNTIME_UNMETER(cx->runtime, liveStrings);
if (isDependent()) {
JS_RUNTIME_UNMETER(cx->runtime, liveDependentStrings);
} else if (isFlat()) {
/*
* flatChars for stillborn string is null, but cx->free checks
* for a null pointer on its own.
*/
cx->runtime->stringMemoryUsed -= length() * 2;
cx->free(const_cast<jschar *>(flatChars()));
cx->free(const_cast<jschar *>(asFlat().chars()));
} else {
JS_ASSERT(isRope());
}
}
inline void
JSShortString::finalize(JSContext *cx)
{
JS_ASSERT(!mHeader.isStaticAtom());
JS_ASSERT(mHeader.isFlat());
JS_ASSERT(isShort());
JS_RUNTIME_UNMETER(cx->runtime, liveStrings);
}
inline void
JSExternalString::finalize(JSContext *cx)
{
JS_ASSERT(unsigned(externalStringType) < JS_ARRAY_LENGTH(str_finalizers));
JS_ASSERT(!isStaticAtom());
JS_ASSERT(isFlat());
JS_RUNTIME_UNMETER(cx->runtime, liveStrings);
/* A stillborn string has null chars. */
jschar *chars = const_cast<jschar *>(flatChars());
if (!chars)
return;
JSStringFinalizeOp finalizer = str_finalizers[externalStringType];
if (finalizer)
if (JSStringFinalizeOp finalizer = str_finalizers[externalStringType()])
finalizer(cx, this);
}
inline void
JSExternalString::finalize()
{
JS_ASSERT(unsigned(externalStringType) < JS_ARRAY_LENGTH(str_finalizers));
JSStringFinalizeOp finalizer = str_finalizers[externalStringType];
JSStringFinalizeOp finalizer = str_finalizers[externalStringType()];
if (finalizer) {
/*
* Assume that the finalizer for the permanently interned
@ -392,15 +528,16 @@ class StringSegmentRange
* StackAllocPolicy which stashes a reusable freed-at-gc buffer in the cx.
*/
Vector<JSString *, 32> stack;
JSString *cur;
JSLinearString *cur;
bool settle(JSString *str) {
while (str->isRope()) {
if (!stack.append(str->ropeRight()))
JSRope &rope = str->asRope();
if (!stack.append(rope.rightChild()))
return false;
str = str->ropeLeft();
str = rope.leftChild();
}
cur = str;
cur = &str->asLinear();
return true;
}
@ -418,7 +555,7 @@ class StringSegmentRange
return cur == NULL;
}
JSString *front() const {
JSLinearString *front() const {
JS_ASSERT(!cur->isRope());
return cur;
}

View File

@ -902,7 +902,7 @@ FragProfiling_showResults(TraceMonitor* tm)
/* ----------------------------------------------------------------- */
#ifdef DEBUG
static JSBool FASTCALL
JSBool FASTCALL
PrintOnTrace(char* format, uint32 argc, double *argv)
{
union {
@ -974,15 +974,19 @@ PrintOnTrace(char* format, uint32 argc, double *argv)
fprintf(out, "<rope>");
break;
}
const jschar *chars = u.s->nonRopeChars();
for (unsigned i = 0; i < length; ++i) {
jschar co = chars[i];
if (co < 128)
putc(co, out);
else if (co < 256)
fprintf(out, "\\u%02x", co);
else
fprintf(out, "\\u%04x", co);
if (u.s->isRope()) {
fprintf(out, "<rope: length %d>", (int)u.s->asRope().length());
} else {
const jschar *chars = u.s->asLinear().chars();
for (unsigned i = 0; i < length; ++i) {
jschar co = chars[i];
if (co < 128)
putc(co, out);
else if (co < 256)
fprintf(out, "\\u%02x", co);
else
fprintf(out, "\\u%04x", co);
}
}
}
break;
@ -2750,7 +2754,7 @@ ValueToNative(const Value &v, JSValueType type, double* slot)
if (LogController.lcbits & LC_TMTracer) {
char funName[40];
if (fun->atom)
JS_PutEscapedFlatString(funName, sizeof funName, ATOM_TO_STRING(fun->atom), 0);
JS_PutEscapedFlatString(funName, sizeof funName, fun->atom, 0);
else
strcpy(funName, "unnamed");
LogController.printf("function<%p:%s> ", (void*)*(JSObject **)slot, funName);
@ -2979,7 +2983,7 @@ NativeToValue(JSContext* cx, Value& v, JSValueType type, double* slot)
JSFunction* fun = GET_FUNCTION_PRIVATE(cx, &v.toObject());
char funName[40];
if (fun->atom)
JS_PutEscapedFlatString(funName, sizeof funName, ATOM_TO_STRING(fun->atom), 0);
JS_PutEscapedFlatString(funName, sizeof funName, fun->atom, 0);
else
strcpy(funName, "unnamed");
LogController.printf("function<%p:%s> ", (void*) &v.toObject(), funName);
@ -11601,7 +11605,7 @@ TraceRecorder::callNative(uintN argc, JSOp mode)
#ifdef DEBUG
ci->_name = js_anonymous_str;
if (fun->atom) {
JSAutoByteString bytes(cx, ATOM_TO_STRING(fun->atom));
JSAutoByteString bytes(cx, fun->atom);
if (!!bytes) {
size_t n = strlen(bytes.ptr()) + 1;
char *buffer = new (traceAlloc()) char[n];
@ -12523,7 +12527,7 @@ RootedStringToId(JSContext* cx, JSString** namep, jsid* idp)
JSAtom* atom = js_AtomizeString(cx, name, 0);
if (!atom)
return false;
*namep = ATOM_TO_STRING(atom); /* write back to GC root */
*namep = atom; /* write back to GC root */
*idp = ATOM_TO_JSID(atom);
return true;
}
@ -12850,7 +12854,7 @@ TraceRecorder::getCharCodeAt(JSString *str, LIns* str_ins, LIns* idx_ins, LIns**
if (MaybeBranch mbr = w.jt(w.eqp0(w.andp(lengthAndFlags_ins, w.nameImmw(JSString::ROPE_BIT)))))
{
LIns *args[] = { str_ins, cx_ins };
LIns *ok_ins = w.call(&js_Flatten_ci, args);
LIns *ok_ins = w.call(&js_FlattenOnTrace_ci, args);
guard(false, w.eqi0(ok_ins), OOM_EXIT);
w.label(mbr);
}
@ -12869,8 +12873,9 @@ JS_REQUIRES_STACK LIns*
TraceRecorder::getUnitString(LIns* str_ins, LIns* idx_ins)
{
LIns *ch_ins = w.getStringChar(str_ins, idx_ins);
guard(true, w.ltuiN(ch_ins, UNIT_STRING_LIMIT), MISMATCH_EXIT);
return w.addp(w.nameImmpNonGC(JSString::unitStringTable),
guard(true, w.ltuiN(ch_ins, JSAtom::UNIT_STATIC_LIMIT), MISMATCH_EXIT);
JS_STATIC_ASSERT(sizeof(JSString) == 16 || sizeof(JSString) == 32);
return w.addp(w.nameImmpNonGC(JSAtom::unitStaticTable),
w.lshpN(w.ui2p(ch_ins), (sizeof(JSString) == 16) ? 4 : 5));
}
@ -12884,7 +12889,7 @@ TraceRecorder::getCharAt(JSString *str, LIns* str_ins, LIns* idx_ins, JSOp mode,
w.nameImmw(JSString::ROPE_BIT)))))
{
LIns *args[] = { str_ins, cx_ins };
LIns *ok_ins = w.call(&js_Flatten_ci, args);
LIns *ok_ins = w.call(&js_FlattenOnTrace_ci, args);
guard(false, w.eqi0(ok_ins), OOM_EXIT);
w.label(mbr);
}

View File

@ -1138,7 +1138,7 @@ class TraceRecorder
#define immpObjGC(obj) name(w_immpObjGC(obj), #obj)
#define immpFunGC(fun) name(w_immpFunGC(fun), #fun)
#define immpStrGC(str) name(w_immpStrGC(str), #str)
#define immpAtomGC(atom) name(w_immpStrGC(ATOM_TO_STRING(atom)), "ATOM_TO_STRING(" #atom ")")
#define immpAtomGC(atom) name(w_immpStrGC(atom), "ATOM(" #atom ")")
#define immpShapeGC(shape) name(w_immpShapeGC(shape), #shape)
#define immpIdGC(id) name(w_immpIdGC(id), #id)

View File

@ -488,6 +488,22 @@ PodCopy(T *dst, const T *src, size_t nelem)
}
}
template <class T>
JS_ALWAYS_INLINE static bool
PodEqual(T *one, T *two, size_t len)
{
if (len < 128) {
T *p1end = one + len;
for (T *p1 = one, *p2 = two; p1 != p1end; ++p1, ++p2) {
if (*p1 != *p2)
return false;
}
return true;
}
return !memcmp(one, two, len * sizeof(T));
}
} /* namespace js */
#endif /* defined(__cplusplus) */

View File

@ -267,8 +267,13 @@ typedef enum JSWhyMagic
JS_GENERIC_MAGIC /* for local use */
} JSWhyMagic;
#ifdef __cplusplus
class JSString;
class JSFlatString;
#else
typedef struct JSString JSString;
typedef struct JSFlatString JSFlatString;
#endif
typedef struct JSObject JSObject;
#if defined(IS_LITTLE_ENDIAN)

View File

@ -670,7 +670,7 @@ js_XDRAtom(JSXDRState *xdr, JSAtom **atomp)
}
} else {
if (idx == uint32(-1)) {
JSString *str = ATOM_TO_STRING(*atomp);
JSString *str = *atomp;
return JS_XDRString(xdr, &str);
}
}

View File

@ -412,12 +412,12 @@ ConvertQNameToString(JSContext *cx, JSObject *obj)
JSString *str;
if (!uri) {
/* No uri means wildcard qualifier. */
str = ATOM_TO_STRING(cx->runtime->atomState.starQualifierAtom);
str = cx->runtime->atomState.starQualifierAtom;
} else if (uri->empty()) {
/* Empty string for uri means localName is in no namespace. */
str = cx->runtime->emptyString;
} else {
JSString *qualstr = ATOM_TO_STRING(cx->runtime->atomState.qualifierAtom);
JSString *qualstr = cx->runtime->atomState.qualifierAtom;
str = js_ConcatStrings(cx, uri, qualstr);
if (!str)
return NULL;
@ -758,7 +758,7 @@ QNameHelper(JSContext *cx, JSObject *obj, intN argc, jsval *argv, jsval *rval)
if (argc == 0) {
name = cx->runtime->emptyString;
} else if (argc < 0) {
name = ATOM_TO_STRING(cx->runtime->atomState.typeAtoms[JSTYPE_VOID]);
name = cx->runtime->atomState.typeAtoms[JSTYPE_VOID];
} else {
JSString *str = js_ValueToString(cx, Valueify(nameval));
if (!str)
@ -1430,7 +1430,7 @@ ParseNodeToXML(Parser *parser, JSParseNode *pn,
/* Enforce "Well-formedness constraint: Unique Att Spec". */
for (pn3 = head; pn3 != pn2; pn3 = pn3->pn_next->pn_next) {
if (pn3->pn_atom == pn2->pn_atom) {
Value v = StringValue(ATOM_TO_STRING(pn2->pn_atom));
Value v = StringValue(pn2->pn_atom);
JSAutoByteString bytes;
if (js_ValueToPrintable(cx, v, &bytes)) {
ReportCompileErrorNumber(cx, &parser->tokenStream, pn2,
@ -1454,7 +1454,7 @@ ParseNodeToXML(Parser *parser, JSParseNode *pn,
(length == 5 || chars[5] == ':')) {
JSLinearString *uri, *prefix;
uri = ATOM_TO_STRING(pn2->pn_atom);
uri = pn2->pn_atom;
if (length == 5) {
/* 10.3.2.1. Step 6(h)(i)(1)(a). */
prefix = cx->runtime->emptyString;
@ -1528,7 +1528,7 @@ ParseNodeToXML(Parser *parser, JSParseNode *pn,
attrjqn = attrj->name;
if (EqualStrings(attrjqn->getNameURI(), qn->getNameURI()) &&
EqualStrings(attrjqn->getQNameLocalName(), qn->getQNameLocalName())) {
Value v = StringValue(ATOM_TO_STRING(pn2->pn_atom));
Value v = StringValue(pn2->pn_atom);
JSAutoByteString bytes;
if (js_ValueToPrintable(cx, v, &bytes)) {
ReportCompileErrorNumber(cx, &parser->tokenStream, pn2,
@ -1550,7 +1550,7 @@ ParseNodeToXML(Parser *parser, JSParseNode *pn,
XMLARRAY_SET_MEMBER(&xml->xml_attrs, i, attr);
attr->parent = xml;
attr->name = qn;
attr->xml_value = ATOM_TO_STRING(pn2->pn_atom);
attr->xml_value = pn2->pn_atom;
}
/* Point tag closes its own namespace scope. */
@ -1563,7 +1563,7 @@ ParseNodeToXML(Parser *parser, JSParseNode *pn,
case TOK_XMLCDATA:
case TOK_XMLCOMMENT:
case TOK_XMLPI:
str = ATOM_TO_STRING(pn->pn_atom);
str = pn->pn_atom;
qn = NULL;
if (pn->pn_type == TOK_XMLCOMMENT) {
if (flags & XSF_IGNORE_COMMENTS)
@ -1587,9 +1587,7 @@ ParseNodeToXML(Parser *parser, JSParseNode *pn,
if (!qn)
goto fail;
str = pn->pn_atom2
? ATOM_TO_STRING(pn->pn_atom2)
: cx->runtime->emptyString;
str = pn->pn_atom2 ? pn->pn_atom2 : cx->runtime->emptyString;
xml_class = JSXML_CLASS_PROCESSING_INSTRUCTION;
} else {
/* CDATA section content, or element text. */
@ -2792,7 +2790,7 @@ ToAttributeName(JSContext *cx, jsval v)
name = qn->getQNameLocalName();
} else {
if (clasp == &js_AnyNameClass) {
name = ATOM_TO_STRING(cx->runtime->atomState.starAtom);
name = cx->runtime->atomState.starAtom;
} else {
JSString *str = js_ValueToString(cx, Valueify(v));
if (!str)
@ -2825,11 +2823,8 @@ IsFunctionQName(JSContext *cx, JSObject *qn, jsid *funidp)
atom = cx->runtime->atomState.functionNamespaceURIAtom;
uri = qn->getNameURI();
if (uri &&
(uri == ATOM_TO_STRING(atom) ||
EqualStrings(uri, ATOM_TO_STRING(atom)))) {
if (uri && (uri == atom || EqualStrings(uri, atom)))
return JS_ValueToId(cx, STRING_TO_JSVAL(qn->getQNameLocalName()), funidp);
}
*funidp = JSID_VOID;
return JS_TRUE;
}
@ -2865,7 +2860,7 @@ ToXMLName(JSContext *cx, jsval v, jsid *funidp)
if (clasp == &js_AttributeNameClass || clasp == &js_QNameClass)
goto out;
if (clasp == &js_AnyNameClass) {
name = ATOM_TO_STRING(cx->runtime->atomState.starAtom);
name = cx->runtime->atomState.starAtom;
goto construct;
}
name = js_ValueToString(cx, Valueify(v));
@ -4622,6 +4617,34 @@ HasFunctionProperty(JSContext *cx, JSObject *obj, jsid funid, JSBool *found)
return true;
}
static bool
IdValIsIndex(JSContext *cx, jsval id, jsuint *indexp, bool *isIndex)
{
if (JSVAL_IS_INT(id)) {
jsint i;
i = JSVAL_TO_INT(id);
if (i < 0) {
*isIndex = false;
return true;
}
*indexp = (jsuint)i;
*isIndex = true;
return true;
}
if (!JSVAL_IS_STRING(id)) {
*isIndex = false;
return true;
}
JSLinearString *str = JSVAL_TO_STRING(id)->ensureLinear(cx);
if (!str)
return false;
*isIndex = js_StringIsIndex(str, indexp);
return true;
}
/* ECMA-357 9.1.1.6 XML [[HasProperty]] and 9.2.1.5 XMLList [[HasProperty]]. */
static JSBool
HasProperty(JSContext *cx, JSObject *obj, jsval id, JSBool *found)
@ -4633,7 +4656,7 @@ HasProperty(JSContext *cx, JSObject *obj, jsval id, JSBool *found)
jsid funid;
xml = (JSXML *) obj->getPrivate();
if (!js_IdValIsIndex(cx, id, &i, &isIndex))
if (!IdValIsIndex(cx, id, &i, &isIndex))
return JS_FALSE;
if (isIndex) {
@ -5291,7 +5314,7 @@ xml_attribute(JSContext *cx, uintN argc, jsval *vp)
static JSBool
xml_attributes(JSContext *cx, uintN argc, jsval *vp)
{
jsval name = ATOM_TO_JSVAL(cx->runtime->atomState.starAtom);
jsval name = STRING_TO_JSVAL(cx->runtime->atomState.starAtom);
JSObject *qn = ToAttributeName(cx, name);
if (!qn)
return JS_FALSE;
@ -5355,7 +5378,7 @@ xml_child_helper(JSContext *cx, JSObject *obj, JSXML *xml, jsval name,
/* ECMA-357 13.4.4.6 */
JS_ASSERT(xml->xml_class != JSXML_CLASS_LIST);
if (!js_IdValIsIndex(cx, name, &index, &isIndex))
if (!IdValIsIndex(cx, name, &index, &isIndex))
return JS_FALSE;
if (isIndex) {
@ -5577,7 +5600,7 @@ xml_descendants(JSContext *cx, uintN argc, jsval *vp)
JSXML *list;
XML_METHOD_PROLOG;
name = argc == 0 ? ATOM_TO_JSVAL(cx->runtime->atomState.starAtom) : vp[2];
name = argc == 0 ? STRING_TO_JSVAL(cx->runtime->atomState.starAtom) : vp[2];
list = Descendants(cx, xml, name);
if (!list)
return JS_FALSE;
@ -5653,7 +5676,7 @@ xml_elements(JSContext *cx, uintN argc, jsval *vp)
XML_METHOD_PROLOG;
name = (argc == 0) ? ATOM_TO_JSVAL(cx->runtime->atomState.starAtom) : vp[2];
name = (argc == 0) ? STRING_TO_JSVAL(cx->runtime->atomState.starAtom) : vp[2];
nameqn = ToXMLName(cx, name, &funid);
if (!nameqn)
return JS_FALSE;
@ -6201,7 +6224,7 @@ xml_processingInstructions(JSContext *cx, uintN argc, jsval *vp)
XML_METHOD_PROLOG;
name = (argc == 0) ? ATOM_TO_JSVAL(cx->runtime->atomState.starAtom) : vp[2];
name = (argc == 0) ? STRING_TO_JSVAL(cx->runtime->atomState.starAtom) : vp[2];
nameqn = ToXMLName(cx, name, &funid);
if (!nameqn)
return JS_FALSE;
@ -6234,7 +6257,7 @@ xml_propertyIsEnumerable(JSContext *cx, uintN argc, jsval *vp)
XML_METHOD_PROLOG;
*vp = JSVAL_FALSE;
if (argc != 0) {
if (!js_IdValIsIndex(cx, vp[2], &index, &isIndex))
if (!IdValIsIndex(cx, vp[2], &index, &isIndex))
return JS_FALSE;
if (isIndex) {
@ -6340,7 +6363,7 @@ xml_replace(JSContext *cx, uintN argc, jsval *vp)
goto done;
if (argc <= 1) {
value = ATOM_TO_JSVAL(cx->runtime->atomState.typeAtoms[JSTYPE_VOID]);
value = STRING_TO_JSVAL(cx->runtime->atomState.typeAtoms[JSTYPE_VOID]);
} else {
value = vp[3];
vxml = VALUE_IS_XML(value)
@ -6366,7 +6389,7 @@ xml_replace(JSContext *cx, uintN argc, jsval *vp)
if (argc == 0) {
haveIndex = false;
} else {
if (!js_IdValIsIndex(cx, vp[2], &index, &haveIndex))
if (!IdValIsIndex(cx, vp[2], &index, &haveIndex))
return JS_FALSE;
}
@ -6432,7 +6455,7 @@ xml_setLocalName(JSContext *cx, uintN argc, jsval *vp)
return JS_TRUE;
if (argc == 0) {
namestr = ATOM_TO_STRING(cx->runtime->atomState.typeAtoms[JSTYPE_VOID]);
namestr = cx->runtime->atomState.typeAtoms[JSTYPE_VOID];
} else {
name = vp[2];
if (!JSVAL_IS_PRIMITIVE(name) &&
@ -6472,7 +6495,7 @@ xml_setName(JSContext *cx, uintN argc, jsval *vp)
return JS_TRUE;
if (argc == 0) {
name = ATOM_TO_JSVAL(cx->runtime->atomState.typeAtoms[JSTYPE_VOID]);
name = STRING_TO_JSVAL(cx->runtime->atomState.typeAtoms[JSTYPE_VOID]);
} else {
name = vp[2];
if (!JSVAL_IS_PRIMITIVE(name) &&
@ -7358,8 +7381,7 @@ js_GetAnyName(JSContext *cx, jsid *idp)
JS_ASSERT(!obj->getProto());
JSRuntime *rt = cx->runtime;
InitXMLQName(obj, rt->emptyString, rt->emptyString,
ATOM_TO_STRING(rt->atomState.starAtom));
InitXMLQName(obj, rt->emptyString, rt->emptyString, rt->atomState.starAtom);
METER(xml_stats.qname);
v.setObject(*obj);
@ -7385,7 +7407,7 @@ js_FindXMLProperty(JSContext *cx, const Value &nameval, JSObject **objp, jsid *i
JS_ASSERT(nameval.isObject());
nameobj = &nameval.toObject();
if (nameobj->getClass() == &js_AnyNameClass) {
v = ATOM_TO_JSVAL(cx->runtime->atomState.starAtom);
v = STRING_TO_JSVAL(cx->runtime->atomState.starAtom);
nameobj = js_ConstructObject(cx, &js_QNameClass, NULL, NULL, 1,
Valueify(&v));
if (!nameobj)

View File

@ -1412,11 +1412,7 @@ mjit::Compiler::generateMethod()
END_CASE(JSOP_DOUBLE)
BEGIN_CASE(JSOP_STRING)
{
JSAtom *atom = script->getAtom(fullAtomIndex(PC));
JSString *str = ATOM_TO_STRING(atom);
frame.push(Value(StringValue(str)));
}
frame.push(StringValue(script->getAtom(fullAtomIndex(PC))));
END_CASE(JSOP_STRING)
BEGIN_CASE(JSOP_ZERO)

View File

@ -851,7 +851,7 @@ mjit::Compiler::jsop_typeof()
if (atom) {
frame.pop();
frame.push(StringValue(ATOM_TO_STRING(atom)));
frame.push(StringValue(atom));
return;
}
}

View File

@ -1851,7 +1851,7 @@ ic::CallProp(VMFrame &f, ic::PICInfo *pic)
#if JS_HAS_NO_SUCH_METHOD
if (JS_UNLIKELY(rval.isUndefined()) && regs.sp[-1].isObject()) {
regs.sp[-2].setString(ATOM_TO_STRING(pic->atom));
regs.sp[-2].setString(pic->atom);
if (!js_OnUnknownMethod(cx, regs.sp - 2))
THROW();
}
@ -2131,7 +2131,7 @@ GetElementIC::attachGetProp(JSContext *cx, JSObject *obj, const Value &v, jsid i
CodeLocationLabel cs = buffer.finalize();
#if DEBUG
char *chars = js_DeflateString(cx, v.toString()->nonRopeChars(), v.toString()->length());
char *chars = js_DeflateString(cx, v.toString()->getChars(cx), v.toString()->length());
JaegerSpew(JSpew_PICs, "generated %s stub at %p for atom 0x%x (\"%s\") shape 0x%x (%s: %d)\n",
js_CodeName[op], cs.executableAddress(), id, chars, holder->shape(),
cx->fp()->script()->filename, js_FramePCToLineNumber(cx, cx->fp()));

View File

@ -419,7 +419,7 @@ stubs::GetElem(VMFrame &f)
JSString *str = lref.toString();
int32_t i = rref.toInt32();
if ((size_t)i < str->length()) {
str = JSString::getUnitString(cx, str, (size_t)i);
str = JSAtom::getUnitStringForElement(cx, str, (size_t)i);
if (!str)
THROW();
f.regs.sp[-2].setString(str);
@ -2002,7 +2002,7 @@ stubs::CallProp(VMFrame &f, JSAtom *origAtom)
}
#if JS_HAS_NO_SUCH_METHOD
if (JS_UNLIKELY(rval.isUndefined()) && regs.sp[-1].isObject()) {
regs.sp[-2].setString(ATOM_TO_STRING(origAtom));
regs.sp[-2].setString(origAtom);
if (!js_OnUnknownMethod(cx, regs.sp - 2))
THROW();
}
@ -2173,7 +2173,7 @@ stubs::TypeOf(VMFrame &f)
const Value &ref = f.regs.sp[-1];
JSType type = JS_TypeOfValue(f.cx, Jsvalify(ref));
JSAtom *atom = f.cx->runtime->atomState.typeAtoms[type];
return ATOM_TO_STRING(atom);
return atom;
}
void JS_FASTCALL
@ -2376,7 +2376,7 @@ stubs::LookupSwitch(VMFrame &f, jsbytecode *pc)
Value rval = script->getConst(GET_INDEX(pc));
pc += INDEX_LEN;
if (rval.isString()) {
JSLinearString *rhs = rval.toString()->assertIsLinear();
JSLinearString *rhs = &rval.toString()->asLinear();
if (rhs == str || EqualStrings(str, rhs)) {
void* native = script->nativeCodeForPC(ctor,
jpc + GET_JUMP_OFFSET(pc));

View File

@ -2058,9 +2058,8 @@ SrcNotes(JSContext *cx, JSScript *script)
case SRC_CONT2LABEL:
index = js_GetSrcNoteOffset(sn, 0);
JS_GET_SCRIPT_ATOM(script, NULL, index, atom);
str = ATOM_TO_STRING(atom);
fprintf(gOutFile, " atom %u (", index);
JS_FileEscapedString(gOutFile, str, 0);
JS_FileEscapedString(gOutFile, atom, 0);
putc(')', gOutFile);
break;
case SRC_FUNCDEF: {
@ -4815,7 +4814,7 @@ Help(JSContext *cx, uintN argc, jsval *vp)
type = JS_TypeOfValue(cx, argv[i]);
if (type == JSTYPE_FUNCTION) {
fun = JS_ValueToFunction(cx, argv[i]);
str = fun->atom ? ATOM_TO_STRING(fun->atom) : NULL;
str = fun->atom;
} else if (type == JSTYPE_STRING) {
str = JSVAL_TO_STRING(argv[i]);
} else {
@ -5314,7 +5313,7 @@ Exec(JSContext *cx, uintN argc, jsval *vp)
nargv[0] = name;
jsval *argv = JS_ARGV(cx, vp);
for (i = 0; i < nargc; i++) {
str = (i == 0) ? ATOM_TO_STRING(fun->atom) : JS_ValueToString(cx, argv[i-1]);
str = (i == 0) ? fun->atom : JS_ValueToString(cx, argv[i-1]);
if (!str) {
ok = false;
goto done;

View File

@ -248,9 +248,9 @@ couldBeObjectOrString(LIns *ins)
#endif
} else if (ins->isop(LIR_addp) &&
((ins->oprnd1()->isImmP() &&
(void *)ins->oprnd1()->immP() == JSString::unitStringTable) ||
(void *)ins->oprnd1()->immP() == JSAtom::unitStaticTable) ||
(ins->oprnd2()->isImmP() &&
(void *)ins->oprnd2()->immP() == JSString::unitStringTable)))
(void *)ins->oprnd2()->immP() == JSAtom::unitStaticTable)))
{
// (String only)
// ins = addp ..., JSString::unitStringTable

View File

@ -90,7 +90,7 @@ XPCStringConvert::ReadableToJSVal(JSContext *cx,
JSAtom *atom;
if (length == 0 && (atom = cx->runtime->atomState.emptyAtom))
{
return ATOM_TO_JSVAL(atom);
return STRING_TO_JSVAL(atom);
}
nsStringBuffer *buf = nsStringBuffer::FromString(readable);