mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 613457 - clean up string interfaces (r=njn)
--HG-- extra : rebase_source : 3e77b67fa9fe2cc31312ad99951cf92258a98e64
This commit is contained in:
parent
7b695c0de6
commit
7c96945e3c
@ -50,9 +50,6 @@
|
|||||||
#include "nsServiceManagerUtils.h"
|
#include "nsServiceManagerUtils.h"
|
||||||
#include "nsDOMError.h"
|
#include "nsDOMError.h"
|
||||||
#include "nsGlobalWindow.h"
|
#include "nsGlobalWindow.h"
|
||||||
#include "jsobj.h"
|
|
||||||
#include "jsatom.h"
|
|
||||||
#include "jsfun.h"
|
|
||||||
#include "nsIContentSecurityPolicy.h"
|
#include "nsIContentSecurityPolicy.h"
|
||||||
|
|
||||||
static const char kSetIntervalStr[] = "setInterval";
|
static const char kSetIntervalStr[] = "setInterval";
|
||||||
@ -134,10 +131,11 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsJSScriptTimeoutHandler)
|
|||||||
else if (tmp->mFunObj) {
|
else if (tmp->mFunObj) {
|
||||||
JSFunction* fun = (JSFunction*)tmp->mFunObj->getPrivate();
|
JSFunction* fun = (JSFunction*)tmp->mFunObj->getPrivate();
|
||||||
if (fun->atom) {
|
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];
|
char *name = new char[size];
|
||||||
if (name) {
|
if (name) {
|
||||||
JS_PutEscapedFlatString(name, size, ATOM_TO_STRING(fun->atom), 0);
|
JS_PutEscapedFlatString(name, size, funId, 0);
|
||||||
foo.AppendLiteral(" [");
|
foo.AppendLiteral(" [");
|
||||||
foo.Append(name);
|
foo.Append(name);
|
||||||
delete[] name;
|
delete[] name;
|
||||||
|
@ -71,7 +71,7 @@ void JSD_ASSERT_VALID_CONTEXT(JSDContext* jsdc)
|
|||||||
|
|
||||||
static JSClass global_class = {
|
static JSClass global_class = {
|
||||||
"JSDGlobal", JSCLASS_GLOBAL_FLAGS,
|
"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,
|
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
|
||||||
JSCLASS_NO_OPTIONAL_MEMBERS
|
JSCLASS_NO_OPTIONAL_MEMBERS
|
||||||
};
|
};
|
||||||
|
@ -11,28 +11,28 @@ BEGIN_TEST(testIntString_bug515273)
|
|||||||
|
|
||||||
EVAL("'1';", v.addr());
|
EVAL("'1';", v.addr());
|
||||||
JSString *str = JSVAL_TO_STRING(v.value());
|
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"));
|
CHECK(JS_FlatStringEqualsAscii(JS_ASSERT_STRING_IS_FLAT(str), "1"));
|
||||||
|
|
||||||
EVAL("'42';", v.addr());
|
EVAL("'42';", v.addr());
|
||||||
str = JSVAL_TO_STRING(v.value());
|
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"));
|
CHECK(JS_FlatStringEqualsAscii(JS_ASSERT_STRING_IS_FLAT(str), "42"));
|
||||||
|
|
||||||
EVAL("'111';", v.addr());
|
EVAL("'111';", v.addr());
|
||||||
str = JSVAL_TO_STRING(v.value());
|
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"));
|
CHECK(JS_FlatStringEqualsAscii(JS_ASSERT_STRING_IS_FLAT(str), "111"));
|
||||||
|
|
||||||
/* Test other types of static strings. */
|
/* Test other types of static strings. */
|
||||||
EVAL("'a';", v.addr());
|
EVAL("'a';", v.addr());
|
||||||
str = JSVAL_TO_STRING(v.value());
|
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"));
|
CHECK(JS_FlatStringEqualsAscii(JS_ASSERT_STRING_IS_FLAT(str), "a"));
|
||||||
|
|
||||||
EVAL("'bc';", v.addr());
|
EVAL("'bc';", v.addr());
|
||||||
str = JSVAL_TO_STRING(v.value());
|
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"));
|
CHECK(JS_FlatStringEqualsAscii(JS_ASSERT_STRING_IS_FLAT(str), "bc"));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -328,10 +328,10 @@ JS_ConvertArgumentsVA(JSContext *cx, uintN argc, jsval *argv, const char *format
|
|||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
*sp = STRING_TO_JSVAL(str);
|
*sp = STRING_TO_JSVAL(str);
|
||||||
if (c == 'W') {
|
if (c == 'W') {
|
||||||
const jschar *chars = js_GetStringChars(cx, str);
|
JSFixedString *fixed = str->ensureFixed(cx);
|
||||||
if (!chars)
|
if (!fixed)
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
*va_arg(ap, const jschar **) = chars;
|
*va_arg(ap, const jschar **) = fixed->chars();
|
||||||
} else {
|
} else {
|
||||||
*va_arg(ap, JSString **) = str;
|
*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. */
|
/* Check whether we're resolving 'undefined', and define it if so. */
|
||||||
atom = rt->atomState.typeAtoms[JSTYPE_VOID];
|
atom = rt->atomState.typeAtoms[JSTYPE_VOID];
|
||||||
if (idstr == ATOM_TO_STRING(atom)) {
|
if (idstr == atom) {
|
||||||
*resolved = JS_TRUE;
|
*resolved = JS_TRUE;
|
||||||
return obj->defineProperty(cx, ATOM_TO_JSID(atom), UndefinedValue(),
|
return obj->defineProperty(cx, ATOM_TO_JSID(atom), UndefinedValue(),
|
||||||
PropertyStub, StrictPropertyStub,
|
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++) {
|
for (i = 0; standard_class_atoms[i].init; i++) {
|
||||||
JS_ASSERT(standard_class_atoms[i].clasp);
|
JS_ASSERT(standard_class_atoms[i].clasp);
|
||||||
atom = OFFSET_TO_ATOM(rt, standard_class_atoms[i].atomOffset);
|
atom = OFFSET_TO_ATOM(rt, standard_class_atoms[i].atomOffset);
|
||||||
if (idstr == ATOM_TO_STRING(atom)) {
|
if (idstr == atom) {
|
||||||
stdnm = &standard_class_atoms[i];
|
stdnm = &standard_class_atoms[i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1794,7 +1794,7 @@ JS_ResolveStandardClass(JSContext *cx, JSObject *obj, jsid id, JSBool *resolved)
|
|||||||
atom = StdNameToAtom(cx, &standard_class_names[i]);
|
atom = StdNameToAtom(cx, &standard_class_names[i]);
|
||||||
if (!atom)
|
if (!atom)
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
if (idstr == ATOM_TO_STRING(atom)) {
|
if (idstr == atom) {
|
||||||
stdnm = &standard_class_names[i];
|
stdnm = &standard_class_names[i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1811,7 +1811,7 @@ JS_ResolveStandardClass(JSContext *cx, JSObject *obj, jsid id, JSBool *resolved)
|
|||||||
atom = StdNameToAtom(cx, &object_prototype_names[i]);
|
atom = StdNameToAtom(cx, &object_prototype_names[i]);
|
||||||
if (!atom)
|
if (!atom)
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
if (idstr == ATOM_TO_STRING(atom)) {
|
if (idstr == atom) {
|
||||||
stdnm = &object_prototype_names[i];
|
stdnm = &object_prototype_names[i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2321,7 +2321,7 @@ JS_PrintTraceThingInfo(char *buf, size_t bufsize, JSTracer *trc, void *thing, ui
|
|||||||
JS_snprintf(buf, bufsize, "%p", fun);
|
JS_snprintf(buf, bufsize, "%p", fun);
|
||||||
} else {
|
} else {
|
||||||
if (fun->atom)
|
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) {
|
} else if (clasp->flags & JSCLASS_HAS_PRIVATE) {
|
||||||
JS_snprintf(buf, bufsize, "%p", obj->getPrivate());
|
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;
|
JSString *str = (JSString *)thing;
|
||||||
if (str->isLinear())
|
if (str->isLinear())
|
||||||
PutEscapedString(buf, bufsize, str->assertIsLinear(), 0);
|
PutEscapedString(buf, bufsize, &str->asLinear(), 0);
|
||||||
else
|
else
|
||||||
JS_snprintf(buf, bufsize, "<rope: length %d>", (int)str->length());
|
JS_snprintf(buf, bufsize, "<rope: length %d>", (int)str->length());
|
||||||
break;
|
break;
|
||||||
@ -2763,15 +2763,7 @@ JS_PUBLIC_API(JSString *)
|
|||||||
JS_NewExternalString(JSContext *cx, jschar *chars, size_t length, intN type)
|
JS_NewExternalString(JSContext *cx, jschar *chars, size_t length, intN type)
|
||||||
{
|
{
|
||||||
CHECK_REQUEST(cx);
|
CHECK_REQUEST(cx);
|
||||||
JS_ASSERT(uintN(type) < JSExternalString::TYPE_LIMIT);
|
return JSExternalString::new_(cx, chars, length, type);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_PUBLIC_API(void)
|
JS_PUBLIC_API(void)
|
||||||
@ -4322,7 +4314,7 @@ JS_GetFunctionObject(JSFunction *fun)
|
|||||||
JS_PUBLIC_API(JSString *)
|
JS_PUBLIC_API(JSString *)
|
||||||
JS_GetFunctionId(JSFunction *fun)
|
JS_GetFunctionId(JSFunction *fun)
|
||||||
{
|
{
|
||||||
return fun->atom ? ATOM_TO_STRING(fun->atom) : NULL;
|
return fun->atom;
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_PUBLIC_API(uintN)
|
JS_PUBLIC_API(uintN)
|
||||||
@ -5291,22 +5283,14 @@ JS_PUBLIC_API(JSString *)
|
|||||||
JS_InternJSString(JSContext *cx, JSString *str)
|
JS_InternJSString(JSContext *cx, JSString *str)
|
||||||
{
|
{
|
||||||
CHECK_REQUEST(cx);
|
CHECK_REQUEST(cx);
|
||||||
JSAtom *atom = js_AtomizeString(cx, str, 0);
|
return js_AtomizeString(cx, str, 0);
|
||||||
if (!atom)
|
|
||||||
return NULL;
|
|
||||||
return ATOM_TO_STRING(atom);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_PUBLIC_API(JSString *)
|
JS_PUBLIC_API(JSString *)
|
||||||
JS_InternString(JSContext *cx, const char *s)
|
JS_InternString(JSContext *cx, const char *s)
|
||||||
{
|
{
|
||||||
JSAtom *atom;
|
|
||||||
|
|
||||||
CHECK_REQUEST(cx);
|
CHECK_REQUEST(cx);
|
||||||
atom = js_Atomize(cx, s, strlen(s), ATOM_INTERNED);
|
return js_Atomize(cx, s, strlen(s), ATOM_INTERNED);
|
||||||
if (!atom)
|
|
||||||
return NULL;
|
|
||||||
return ATOM_TO_STRING(atom);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_PUBLIC_API(JSString *)
|
JS_PUBLIC_API(JSString *)
|
||||||
@ -5335,13 +5319,8 @@ JS_NewUCStringCopyZ(JSContext *cx, const jschar *s)
|
|||||||
JS_PUBLIC_API(JSString *)
|
JS_PUBLIC_API(JSString *)
|
||||||
JS_InternUCStringN(JSContext *cx, const jschar *s, size_t length)
|
JS_InternUCStringN(JSContext *cx, const jschar *s, size_t length)
|
||||||
{
|
{
|
||||||
JSAtom *atom;
|
|
||||||
|
|
||||||
CHECK_REQUEST(cx);
|
CHECK_REQUEST(cx);
|
||||||
atom = js_AtomizeChars(cx, s, length, ATOM_INTERNED);
|
return js_AtomizeChars(cx, s, length, ATOM_INTERNED);
|
||||||
if (!atom)
|
|
||||||
return NULL;
|
|
||||||
return ATOM_TO_STRING(atom);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_PUBLIC_API(JSString *)
|
JS_PUBLIC_API(JSString *)
|
||||||
@ -5385,16 +5364,15 @@ JS_GetStringCharsAndLength(JSContext *cx, JSString *str, size_t *plength)
|
|||||||
JS_PUBLIC_API(const jschar *)
|
JS_PUBLIC_API(const jschar *)
|
||||||
JS_GetInternedStringChars(JSString *str)
|
JS_GetInternedStringChars(JSString *str)
|
||||||
{
|
{
|
||||||
JS_ASSERT(str->isAtom());
|
return str->asAtom().chars();
|
||||||
return str->flatChars();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_PUBLIC_API(const jschar *)
|
JS_PUBLIC_API(const jschar *)
|
||||||
JS_GetInternedStringCharsAndLength(JSString *str, size_t *plength)
|
JS_GetInternedStringCharsAndLength(JSString *str, size_t *plength)
|
||||||
{
|
{
|
||||||
JS_ASSERT(str->isAtom());
|
JSAtom &atom = str->asAtom();
|
||||||
*plength = str->flatLength();
|
*plength = atom.length();
|
||||||
return str->flatChars();
|
return atom.chars();
|
||||||
}
|
}
|
||||||
|
|
||||||
extern JS_PUBLIC_API(JSFlatString *)
|
extern JS_PUBLIC_API(JSFlatString *)
|
||||||
@ -5487,7 +5465,7 @@ JS_PUBLIC_API(JSBool)
|
|||||||
JS_MakeStringImmutable(JSContext *cx, JSString *str)
|
JS_MakeStringImmutable(JSContext *cx, JSString *str)
|
||||||
{
|
{
|
||||||
CHECK_REQUEST(cx);
|
CHECK_REQUEST(cx);
|
||||||
return js_MakeStringImmutable(cx, str);
|
return !!str->ensureFixed(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_PUBLIC_API(JSBool)
|
JS_PUBLIC_API(JSBool)
|
||||||
|
@ -108,6 +108,7 @@
|
|||||||
#include "jscntxtinlines.h"
|
#include "jscntxtinlines.h"
|
||||||
#include "jsinterpinlines.h"
|
#include "jsinterpinlines.h"
|
||||||
#include "jsobjinlines.h"
|
#include "jsobjinlines.h"
|
||||||
|
#include "jsstrinlines.h"
|
||||||
|
|
||||||
using namespace js;
|
using namespace js;
|
||||||
using namespace js::gc;
|
using namespace js::gc;
|
||||||
@ -1250,7 +1251,7 @@ array_toString_sub(JSContext *cx, JSObject *obj, JSBool locale,
|
|||||||
genBefore = cx->busyArrays.generation();
|
genBefore = cx->busyArrays.generation();
|
||||||
} else {
|
} else {
|
||||||
/* Cycle, so return empty string. */
|
/* Cycle, so return empty string. */
|
||||||
rval->setString(ATOM_TO_STRING(cx->runtime->atomState.emptyAtom));
|
rval->setString(cx->runtime->atomState.emptyAtom);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3265,7 +3266,7 @@ js_CloneDensePrimitiveArray(JSContext *cx, JSObject *obj, JSObject **clone)
|
|||||||
|
|
||||||
if (val.isString()) {
|
if (val.isString()) {
|
||||||
// Strings must be made immutable before being copied to a clone.
|
// 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;
|
return JS_FALSE;
|
||||||
} else if (val.isObject()) {
|
} else if (val.isObject()) {
|
||||||
/*
|
/*
|
||||||
|
@ -109,35 +109,6 @@ js_IdIsIndex(jsid id, jsuint *indexp)
|
|||||||
return js_StringIsIndex(JSID_TO_ATOM(id), 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;
|
extern js::Class js_ArrayClass, js_SlowArrayClass;
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
|
@ -91,7 +91,7 @@ JS_STATIC_ASSERT((1 + 2) * sizeof(JSAtom *) ==
|
|||||||
const char *
|
const char *
|
||||||
js_AtomToPrintableString(JSContext *cx, JSAtom *atom, JSAutoByteString *bytes)
|
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;
|
#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);
|
JS_ASSERT((uint8 *)atoms - (uint8 *)state == LAZY_ATOM_OFFSET_START);
|
||||||
memset(atoms, 0, ATOM_OFFSET_LIMIT - 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;
|
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(!(flags & ~(ATOM_PINNED|ATOM_INTERNED|ATOM_NOCOPY)));
|
||||||
JS_ASSERT_IF(flags & ATOM_NOCOPY, flags & ATOM_TMPSTR);
|
|
||||||
|
|
||||||
if (strArg->isAtom())
|
if (JSAtom *s = JSAtom::lookupStatic(chars, length))
|
||||||
return STRING_TO_ATOM(strArg);
|
return s;
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
AutoLockAtomsCompartment lock(cx);
|
AutoLockAtomsCompartment lock(cx);
|
||||||
|
|
||||||
AtomSet &atoms = cx->runtime->atomState.atoms;
|
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. */
|
JSAtom *atom;
|
||||||
JS_ASSERT(str->isFlat() || str->isDependent());
|
|
||||||
|
|
||||||
JSLinearString *key;
|
|
||||||
if (p) {
|
if (p) {
|
||||||
key = AtomEntryToKey(*p);
|
atom = AtomEntryToKey(*p);
|
||||||
} else {
|
} 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);
|
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. */
|
JSFixedString *key;
|
||||||
JS_ASSERT(flags & ATOM_TMPSTR);
|
if (flags & ATOM_NOCOPY) {
|
||||||
str->u.chars = NULL;
|
key = js_NewString(cx, const_cast<jschar *>(chars), length);
|
||||||
|
if (!key) {
|
||||||
|
cx->free(const_cast<jschar *>(chars));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
key = js_NewStringCopyN(cx, chars, length);
|
key = js_NewStringCopyN(cx, chars, length);
|
||||||
if (!key)
|
if (!key)
|
||||||
return NULL;
|
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 */
|
JS_ReportOutOfMemory(cx); /* SystemAllocPolicy does not report */
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
key->flatSetAtomized();
|
|
||||||
|
atom = key->morphInternedStringIntoAtom();
|
||||||
}
|
}
|
||||||
|
|
||||||
AddAtomEntryFlags(*p, flags & (ATOM_PINNED | ATOM_INTERNED));
|
AddAtomEntryFlags(*p, flags & (ATOM_PINNED | ATOM_INTERNED));
|
||||||
|
|
||||||
JSAtom *atom = STRING_TO_ATOM(key);
|
|
||||||
return atom;
|
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 *
|
JSAtom *
|
||||||
js_Atomize(JSContext *cx, const char *bytes, size_t length, uintN flags, bool useCESU8)
|
js_Atomize(JSContext *cx, const char *bytes, size_t length, uintN flags, bool useCESU8)
|
||||||
{
|
{
|
||||||
jschar *chars;
|
JS_ASSERT(!(flags & ATOM_NOCOPY));
|
||||||
JSString str;
|
|
||||||
JSAtom *atom;
|
|
||||||
|
|
||||||
CHECK_REQUEST(cx);
|
CHECK_REQUEST(cx);
|
||||||
|
|
||||||
|
if (!CheckStringLength(cx, length))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Avoiding the malloc in js_InflateString on shorter strings saves us
|
* Avoiding the malloc in js_InflateString on shorter strings saves us
|
||||||
* over 20,000 malloc calls on mozilla browser startup. This compares to
|
* 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
|
* The vast majority of atomized strings are already in the hashtable. So
|
||||||
* js_AtomizeString rarely has to copy the temp string we make.
|
* 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];
|
jschar inflated[ATOMIZE_BUF_MAX];
|
||||||
size_t inflatedLength = ATOMIZE_BUF_MAX - 1;
|
size_t inflatedLength = ATOMIZE_BUF_MAX - 1;
|
||||||
|
|
||||||
|
const jschar *chars;
|
||||||
if (length < ATOMIZE_BUF_MAX) {
|
if (length < ATOMIZE_BUF_MAX) {
|
||||||
if (useCESU8)
|
if (useCESU8)
|
||||||
js_InflateUTF8StringToBuffer(cx, bytes, length, inflated, &inflatedLength, true);
|
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;
|
flags |= ATOM_NOCOPY;
|
||||||
}
|
}
|
||||||
|
|
||||||
str.initFlat(chars, inflatedLength);
|
return Atomize(cx, chars, inflatedLength, flags);
|
||||||
atom = js_AtomizeString(cx, &str, ATOM_TMPSTR | flags);
|
|
||||||
if (chars != inflated && str.flatChars())
|
|
||||||
cx->free(chars);
|
|
||||||
return atom;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JSAtom *
|
JSAtom *
|
||||||
js_AtomizeChars(JSContext *cx, const jschar *chars, size_t length, uintN flags)
|
js_AtomizeChars(JSContext *cx, const jschar *chars, size_t length, uintN flags)
|
||||||
{
|
{
|
||||||
JSString str;
|
JS_ASSERT(!(flags & ATOM_NOCOPY));
|
||||||
|
|
||||||
CHECK_REQUEST(cx);
|
CHECK_REQUEST(cx);
|
||||||
|
|
||||||
if (!CheckStringLength(cx, length))
|
if (!CheckStringLength(cx, length))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
str.initFlatNotTerminated((jschar *)chars, length);
|
return Atomize(cx, chars, length, flags);
|
||||||
return js_AtomizeString(cx, &str, ATOM_TMPSTR | flags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JSAtom *
|
JSAtom *
|
||||||
js_GetExistingStringAtom(JSContext *cx, const jschar *chars, size_t length)
|
js_GetExistingStringAtom(JSContext *cx, const jschar *chars, size_t length)
|
||||||
{
|
{
|
||||||
JSString str, *str2;
|
if (JSAtom *atom = JSAtom::lookupStatic(chars, length))
|
||||||
JSAtomState *state;
|
return atom;
|
||||||
|
AutoLockAtomsCompartment lock(cx);
|
||||||
if (length == 1) {
|
AtomSet::Ptr p = cx->runtime->atomState.atoms.lookup(AtomHasher::Lookup(chars, length));
|
||||||
jschar c = *chars;
|
return p ? AtomEntryToKey(*p) : NULL;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
@ -56,12 +56,6 @@
|
|||||||
#define ATOM_PINNED 0x1 /* atom is pinned against GC */
|
#define ATOM_PINNED 0x1 /* atom is pinned against GC */
|
||||||
#define ATOM_INTERNED 0x2 /* pinned variant for JS_Intern* API */
|
#define ATOM_INTERNED 0x2 /* pinned variant for JS_Intern* API */
|
||||||
#define ATOM_NOCOPY 0x4 /* don't copy atom string bytes */
|
#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 */
|
/* Engine-internal extensions of jsid */
|
||||||
|
|
||||||
@ -274,14 +268,23 @@ AtomEntryToKey(AtomEntryType entry)
|
|||||||
|
|
||||||
struct AtomHasher
|
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) {
|
static HashNumber hash(const Lookup &l) {
|
||||||
return js_HashString(str);
|
return HashChars(l.chars, l.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool match(AtomEntryType entry, JSLinearString *lookup) {
|
static bool match(AtomEntryType entry, const Lookup &lookup) {
|
||||||
return entry ? EqualStrings(AtomEntryToKey(entry), lookup) : false;
|
JS_ASSERT(entry);
|
||||||
|
JSAtom *key = AtomEntryToKey(entry);
|
||||||
|
if (key->length() != lookup.length)
|
||||||
|
return false;
|
||||||
|
return PodEqual(key->chars(), lookup.chars, lookup.length);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -43,40 +43,28 @@
|
|||||||
#include "jsatom.h"
|
#include "jsatom.h"
|
||||||
#include "jsnum.h"
|
#include "jsnum.h"
|
||||||
|
|
||||||
/*
|
|
||||||
* Convert v to an atomized string and wrap it as an id.
|
|
||||||
*/
|
|
||||||
inline bool
|
inline bool
|
||||||
js_ValueToAtom(JSContext *cx, const js::Value &v, JSAtom **atomp)
|
js_ValueToAtom(JSContext *cx, const js::Value &v, JSAtom **atomp)
|
||||||
{
|
{
|
||||||
JSString *str;
|
if (!v.isString()) {
|
||||||
JSAtom *atom;
|
JSString *str = js_ValueToString(cx, v);
|
||||||
|
|
||||||
/*
|
|
||||||
* 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 (!str)
|
if (!str)
|
||||||
return false;
|
return false;
|
||||||
|
JS::Anchor<JSString *> anchor(str);
|
||||||
|
*atomp = js_AtomizeString(cx, str, 0);
|
||||||
|
return !!*atomp;
|
||||||
}
|
}
|
||||||
atom = js_AtomizeString(cx, str, 0);
|
|
||||||
if (!atom)
|
JSString *str = v.toString();
|
||||||
return false;
|
if (str->isAtom()) {
|
||||||
*atomp = atom;
|
*atomp = &str->asAtom();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*atomp = js_AtomizeString(cx, str, 0);
|
||||||
|
return !!*atomp;
|
||||||
|
}
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
js_ValueToStringId(JSContext *cx, const js::Value &v, jsid *idp)
|
js_ValueToStringId(JSContext *cx, const js::Value &v, jsid *idp)
|
||||||
{
|
{
|
||||||
@ -121,7 +109,7 @@ js_InternNonIntElementId(JSContext *cx, JSObject *obj, const js::Value &idval,
|
|||||||
JSAtom *atom;
|
JSAtom *atom;
|
||||||
if (js_ValueToAtom(cx, idval, &atom)) {
|
if (js_ValueToAtom(cx, idval, &atom)) {
|
||||||
*idp = ATOM_TO_JSID(atom);
|
*idp = ATOM_TO_JSID(atom);
|
||||||
vp->setString(ATOM_TO_STRING(atom));
|
vp->setString(atom);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -56,6 +56,7 @@
|
|||||||
|
|
||||||
#include "jsinterpinlines.h"
|
#include "jsinterpinlines.h"
|
||||||
#include "jsobjinlines.h"
|
#include "jsobjinlines.h"
|
||||||
|
#include "jsstrinlines.h"
|
||||||
|
|
||||||
using namespace js;
|
using namespace js;
|
||||||
|
|
||||||
@ -100,7 +101,7 @@ bool_toString(JSContext *cx, uintN argc, Value *vp)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
JSAtom *atom = cx->runtime->atomState.booleanAtoms[b ? 1 : 0];
|
JSAtom *atom = cx->runtime->atomState.booleanAtoms[b ? 1 : 0];
|
||||||
JSString *str = ATOM_TO_STRING(atom);
|
JSString *str = atom;
|
||||||
if (!str)
|
if (!str)
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
vp->setString(str);
|
vp->setString(str);
|
||||||
@ -162,7 +163,7 @@ js_InitBooleanClass(JSContext *cx, JSObject *obj)
|
|||||||
JSString *
|
JSString *
|
||||||
js_BooleanToString(JSContext *cx, JSBool b)
|
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. */
|
/* This function implements E-262-3 section 9.8, toString. */
|
||||||
|
@ -285,7 +285,7 @@ JSString* FASTCALL
|
|||||||
js_TypeOfObject(JSContext* cx, JSObject* obj)
|
js_TypeOfObject(JSContext* cx, JSObject* obj)
|
||||||
{
|
{
|
||||||
JS_ASSERT(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)
|
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_BooleanIntToString(JSContext *cx, int32 unboxed)
|
||||||
{
|
{
|
||||||
JS_ASSERT(uint32(unboxed) <= 1);
|
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)
|
JS_DEFINE_CALLINFO_2(extern, STRING, js_BooleanIntToString, CONTEXT, INT32, 1, ACCSET_NONE)
|
||||||
|
|
||||||
|
@ -627,7 +627,7 @@ JS_DECLARE_CALLINFO(js_String_tn)
|
|||||||
JS_DECLARE_CALLINFO(js_CompareStringsOnTrace)
|
JS_DECLARE_CALLINFO(js_CompareStringsOnTrace)
|
||||||
JS_DECLARE_CALLINFO(js_ConcatStrings)
|
JS_DECLARE_CALLINFO(js_ConcatStrings)
|
||||||
JS_DECLARE_CALLINFO(js_EqualStringsOnTrace)
|
JS_DECLARE_CALLINFO(js_EqualStringsOnTrace)
|
||||||
JS_DECLARE_CALLINFO(js_Flatten)
|
JS_DECLARE_CALLINFO(js_FlattenOnTrace)
|
||||||
|
|
||||||
/* Defined in jstypedarray.cpp. */
|
/* Defined in jstypedarray.cpp. */
|
||||||
JS_DECLARE_CALLINFO(js_TypedArray_uint8_clamp_double)
|
JS_DECLARE_CALLINFO(js_TypedArray_uint8_clamp_double)
|
||||||
|
@ -75,9 +75,6 @@ struct Cell {
|
|||||||
|
|
||||||
inline JSCompartment *compartment() const;
|
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() {
|
JS_ALWAYS_INLINE js::gc::FreeCell *asFreeCell() {
|
||||||
return reinterpret_cast<FreeCell *>(this);
|
return reinterpret_cast<FreeCell *>(this);
|
||||||
}
|
}
|
||||||
|
@ -1664,7 +1664,7 @@ js_ReportMissingArg(JSContext *cx, const Value &v, uintN arg)
|
|||||||
if (IsFunctionObject(v)) {
|
if (IsFunctionObject(v)) {
|
||||||
atom = GET_FUNCTION_PRIVATE(cx, &v.toObject())->atom;
|
atom = GET_FUNCTION_PRIVATE(cx, &v.toObject())->atom;
|
||||||
bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK,
|
bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK,
|
||||||
v, ATOM_TO_STRING(atom));
|
v, atom);
|
||||||
if (!bytes)
|
if (!bytes)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -556,7 +556,7 @@ class CompartmentChecker
|
|||||||
|
|
||||||
void check(JSString *str) {
|
void check(JSString *str) {
|
||||||
if (!str->isAtom())
|
if (!str->isAtom())
|
||||||
check(str->asCell()->compartment());
|
check(str->compartment());
|
||||||
}
|
}
|
||||||
|
|
||||||
void check(const js::Value &v) {
|
void check(const js::Value &v) {
|
||||||
|
@ -205,12 +205,12 @@ JSCompartment::wrap(JSContext *cx, Value *vp)
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
/* If the string is already in this compartment, we are done. */
|
/* If the string is already in this compartment, we are done. */
|
||||||
if (str->asCell()->compartment() == this)
|
if (str->compartment() == this)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
/* If the string is an atom, we don't have to copy. */
|
/* If the string is an atom, we don't have to copy. */
|
||||||
if (str->isAtom()) {
|
if (str->isAtom()) {
|
||||||
JS_ASSERT(str->asCell()->compartment() == cx->runtime->atomsCompartment);
|
JS_ASSERT(str->compartment() == cx->runtime->atomsCompartment);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -350,16 +350,16 @@ class NativeIterCache {
|
|||||||
class DtoaCache {
|
class DtoaCache {
|
||||||
double d;
|
double d;
|
||||||
jsint base;
|
jsint base;
|
||||||
JSString *s; // if s==NULL, d and base are not valid
|
JSFixedString *s; // if s==NULL, d and base are not valid
|
||||||
public:
|
public:
|
||||||
DtoaCache() : s(NULL) {}
|
DtoaCache() : s(NULL) {}
|
||||||
void purge() { 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;
|
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->base = base;
|
||||||
this->d = d;
|
this->d = d;
|
||||||
this->s = s;
|
this->s = s;
|
||||||
|
@ -1287,7 +1287,7 @@ JS_LocalNameToAtom(jsuword w)
|
|||||||
extern JS_PUBLIC_API(JSString *)
|
extern JS_PUBLIC_API(JSString *)
|
||||||
JS_AtomKey(JSAtom *atom)
|
JS_AtomKey(JSAtom *atom)
|
||||||
{
|
{
|
||||||
return ATOM_TO_STRING(atom);
|
return atom;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern JS_PUBLIC_API(void)
|
extern JS_PUBLIC_API(void)
|
||||||
@ -1871,7 +1871,7 @@ GetAtomTotalSize(JSContext *cx, JSAtom *atom)
|
|||||||
|
|
||||||
nbytes = sizeof(JSAtom *) + sizeof(JSDHashEntryStub);
|
nbytes = sizeof(JSAtom *) + sizeof(JSDHashEntryStub);
|
||||||
nbytes += sizeof(JSString);
|
nbytes += sizeof(JSString);
|
||||||
nbytes += (ATOM_TO_STRING(atom)->flatLength() + 1) * sizeof(jschar);
|
nbytes += (atom->length() + 1) * sizeof(jschar);
|
||||||
return nbytes;
|
return nbytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2979,7 +2979,7 @@ EmitElemOp(JSContext *cx, JSParseNode *pn, JSOp op, JSCodeGenerator *cg)
|
|||||||
}
|
}
|
||||||
right = &rtmp;
|
right = &rtmp;
|
||||||
right->pn_type = TOK_STRING;
|
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_QNAMEPART
|
||||||
: JSOP_STRING;
|
: JSOP_STRING;
|
||||||
right->pn_arity = PN_NULLARY;
|
right->pn_arity = PN_NULLARY;
|
||||||
@ -3211,7 +3211,7 @@ EmitSwitch(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn,
|
|||||||
constVal.setNumber(pn4->pn_dval);
|
constVal.setNumber(pn4->pn_dval);
|
||||||
break;
|
break;
|
||||||
case TOK_STRING:
|
case TOK_STRING:
|
||||||
constVal.setString(ATOM_TO_STRING(pn4->pn_atom));
|
constVal.setString(pn4->pn_atom);
|
||||||
break;
|
break;
|
||||||
case TOK_NAME:
|
case TOK_NAME:
|
||||||
if (!pn4->maybeExpr()) {
|
if (!pn4->maybeExpr()) {
|
||||||
@ -4426,7 +4426,7 @@ JSParseNode::getConstantValue(JSContext *cx, bool strictChecks, Value *vp)
|
|||||||
vp->setNumber(pn_dval);
|
vp->setNumber(pn_dval);
|
||||||
return true;
|
return true;
|
||||||
case TOK_STRING:
|
case TOK_STRING:
|
||||||
vp->setString(ATOM_TO_STRING(pn_atom));
|
vp->setString(pn_atom);
|
||||||
return true;
|
return true;
|
||||||
case TOK_PRIMARY:
|
case TOK_PRIMARY:
|
||||||
switch (pn_op) {
|
switch (pn_op) {
|
||||||
|
@ -341,7 +341,7 @@ InitExnPrivate(JSContext *cx, JSObject *exnObject, JSString *message,
|
|||||||
elem->argc = 0;
|
elem->argc = 0;
|
||||||
} else {
|
} else {
|
||||||
elem->funName = fp->fun()->atom
|
elem->funName = fp->fun()->atom
|
||||||
? ATOM_TO_STRING(fp->fun()->atom)
|
? fp->fun()->atom
|
||||||
: cx->runtime->emptyString;
|
: cx->runtime->emptyString;
|
||||||
elem->argc = fp->numActualArgs();
|
elem->argc = fp->numActualArgs();
|
||||||
fp->forEachCanonicalActualArg(CopyTo(Valueify(values)));
|
fp->forEachCanonicalActualArg(CopyTo(Valueify(values)));
|
||||||
@ -471,7 +471,7 @@ exn_resolve(JSContext *cx, JSObject *obj, jsid id, uintN flags,
|
|||||||
str = JSID_TO_STRING(id);
|
str = JSID_TO_STRING(id);
|
||||||
|
|
||||||
atom = cx->runtime->atomState.messageAtom;
|
atom = cx->runtime->atomState.messageAtom;
|
||||||
if (str == ATOM_TO_STRING(atom)) {
|
if (str == atom) {
|
||||||
prop = js_message_str;
|
prop = js_message_str;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -487,21 +487,21 @@ exn_resolve(JSContext *cx, JSObject *obj, jsid id, uintN flags,
|
|||||||
}
|
}
|
||||||
|
|
||||||
atom = cx->runtime->atomState.fileNameAtom;
|
atom = cx->runtime->atomState.fileNameAtom;
|
||||||
if (str == ATOM_TO_STRING(atom)) {
|
if (str == atom) {
|
||||||
prop = js_fileName_str;
|
prop = js_fileName_str;
|
||||||
v = STRING_TO_JSVAL(priv->filename);
|
v = STRING_TO_JSVAL(priv->filename);
|
||||||
goto define;
|
goto define;
|
||||||
}
|
}
|
||||||
|
|
||||||
atom = cx->runtime->atomState.lineNumberAtom;
|
atom = cx->runtime->atomState.lineNumberAtom;
|
||||||
if (str == ATOM_TO_STRING(atom)) {
|
if (str == atom) {
|
||||||
prop = js_lineNumber_str;
|
prop = js_lineNumber_str;
|
||||||
v = INT_TO_JSVAL(priv->lineno);
|
v = INT_TO_JSVAL(priv->lineno);
|
||||||
goto define;
|
goto define;
|
||||||
}
|
}
|
||||||
|
|
||||||
atom = cx->runtime->atomState.stackAtom;
|
atom = cx->runtime->atomState.stackAtom;
|
||||||
if (str == ATOM_TO_STRING(atom)) {
|
if (str == atom) {
|
||||||
stack = StackTraceToString(cx, priv);
|
stack = StackTraceToString(cx, priv);
|
||||||
if (!stack)
|
if (!stack)
|
||||||
return false;
|
return false;
|
||||||
@ -1284,9 +1284,10 @@ js_ReportUncaughtException(JSContext *cx)
|
|||||||
report.filename = filename.ptr();
|
report.filename = filename.ptr();
|
||||||
report.lineno = (uintN) lineno;
|
report.lineno = (uintN) lineno;
|
||||||
if (JSVAL_IS_STRING(roots[2])) {
|
if (JSVAL_IS_STRING(roots[2])) {
|
||||||
report.ucmessage = js_GetStringChars(cx, JSVAL_TO_STRING(roots[2]));
|
JSFixedString *fixed = JSVAL_TO_STRING(roots[2])->ensureFixed(cx);
|
||||||
if (!report.ucmessage)
|
if (!fixed)
|
||||||
return false;
|
return false;
|
||||||
|
report.ucmessage = fixed->chars();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,5 +44,5 @@ JS_FRIEND_API(JSString *)
|
|||||||
JS_GetAnonymousString(JSRuntime *rt)
|
JS_GetAnonymousString(JSRuntime *rt)
|
||||||
{
|
{
|
||||||
JS_ASSERT(rt->state == JSRTS_UP);
|
JS_ASSERT(rt->state == JSRTS_UP);
|
||||||
return ATOM_TO_STRING(rt->atomState.anonymousAtom);
|
return rt->atomState.anonymousAtom;
|
||||||
}
|
}
|
||||||
|
@ -1617,7 +1617,7 @@ fun_getProperty(JSContext *cx, JSObject *obj, jsid id, Value *vp)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case FUN_NAME:
|
case FUN_NAME:
|
||||||
vp->setString(fun->atom ? ATOM_TO_STRING(fun->atom)
|
vp->setString(fun->atom ? fun->atom
|
||||||
: cx->runtime->emptyString);
|
: cx->runtime->emptyString);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1977,7 +1977,7 @@ fun_trace(JSTracer *trc, JSObject *obj)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (fun->atom)
|
if (fun->atom)
|
||||||
MarkString(trc, ATOM_TO_STRING(fun->atom), "atom");
|
MarkString(trc, fun->atom, "atom");
|
||||||
|
|
||||||
if (fun->isInterpreted() && fun->script())
|
if (fun->isInterpreted() && fun->script())
|
||||||
js_TraceScript(trc, fun->script());
|
js_TraceScript(trc, fun->script());
|
||||||
|
@ -206,13 +206,13 @@ struct JSFunction : public JSObject_Slots2
|
|||||||
*/
|
*/
|
||||||
JSAtom *methodAtom() const {
|
JSAtom *methodAtom() const {
|
||||||
return (joinable() && getSlot(METHOD_ATOM_SLOT).isString())
|
return (joinable() && getSlot(METHOD_ATOM_SLOT).isString())
|
||||||
? STRING_TO_ATOM(getSlot(METHOD_ATOM_SLOT).toString())
|
? &getSlot(METHOD_ATOM_SLOT).toString()->asAtom()
|
||||||
: NULL;
|
: NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setMethodAtom(JSAtom *atom) {
|
void setMethodAtom(JSAtom *atom) {
|
||||||
JS_ASSERT(joinable());
|
JS_ASSERT(joinable());
|
||||||
getSlotRef(METHOD_ATOM_SLOT).setString(ATOM_TO_STRING(atom));
|
getSlotRef(METHOD_ATOM_SLOT).setString(atom);
|
||||||
}
|
}
|
||||||
|
|
||||||
js::Native maybeNative() const {
|
js::Native maybeNative() const {
|
||||||
@ -425,7 +425,7 @@ inline const char *
|
|||||||
GetFunctionNameBytes(JSContext *cx, JSFunction *fun, JSAutoByteString *bytes)
|
GetFunctionNameBytes(JSContext *cx, JSFunction *fun, JSAutoByteString *bytes)
|
||||||
{
|
{
|
||||||
if (fun->atom)
|
if (fun->atom)
|
||||||
return bytes->encode(cx, ATOM_TO_STRING(fun->atom));
|
return bytes->encode(cx, fun->atom);
|
||||||
return js_anonymous_str;
|
return js_anonymous_str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -496,7 +496,7 @@ AllocateArena(JSContext *cx, unsigned thingKind)
|
|||||||
JS_FRIEND_API(bool)
|
JS_FRIEND_API(bool)
|
||||||
IsAboutToBeFinalized(JSContext *cx, void *thing)
|
IsAboutToBeFinalized(JSContext *cx, void *thing)
|
||||||
{
|
{
|
||||||
if (JSString::isGCThingStatic(thing))
|
if (JSAtom::isStatic(thing))
|
||||||
return false;
|
return false;
|
||||||
JS_ASSERT(cx);
|
JS_ASSERT(cx);
|
||||||
|
|
||||||
@ -1068,8 +1068,6 @@ FreeLists::purge()
|
|||||||
*p = NULL;
|
*p = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
class JSShortString;
|
|
||||||
|
|
||||||
ArenaList *
|
ArenaList *
|
||||||
GetFinalizableArenaList(JSCompartment *c, unsigned thingKind) {
|
GetFinalizableArenaList(JSCompartment *c, unsigned thingKind) {
|
||||||
JS_ASSERT(thingKind < FINALIZE_LIMIT);
|
JS_ASSERT(thingKind < FINALIZE_LIMIT);
|
||||||
@ -1210,7 +1208,8 @@ RefillFinalizableFreeList(JSContext *cx, unsigned thingKind)
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32
|
uint32
|
||||||
js_GetGCThingTraceKind(void *thing) {
|
js_GetGCThingTraceKind(void *thing)
|
||||||
|
{
|
||||||
return GetGCThingTraceKind(thing);
|
return GetGCThingTraceKind(thing);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1351,7 +1350,7 @@ Arena<T>::markDelayedChildren(JSTracer *trc)
|
|||||||
T *thingsEnd = &t.things[ThingsPerArena-1].t;
|
T *thingsEnd = &t.things[ThingsPerArena-1].t;
|
||||||
JS_ASSERT(thing == getAlignedThing(thing));
|
JS_ASSERT(thing == getAlignedThing(thing));
|
||||||
while (thing <= thingsEnd) {
|
while (thing <= thingsEnd) {
|
||||||
if (thing->asCell()->isMarked())
|
if (thing->isMarked())
|
||||||
js::gc::MarkChildren(trc, thing);
|
js::gc::MarkChildren(trc, thing);
|
||||||
|
|
||||||
thing++;
|
thing++;
|
||||||
@ -1436,7 +1435,7 @@ gc_root_traversal(JSTracer *trc, const RootEntry &entry)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ptr) {
|
if (ptr) {
|
||||||
if (!JSString::isGCThingStatic(ptr)) {
|
if (!JSAtom::isStatic(ptr)) {
|
||||||
bool root_points_to_gcArenaList = false;
|
bool root_points_to_gcArenaList = false;
|
||||||
JSCompartment **c = trc->context->runtime->compartments.begin();
|
JSCompartment **c = trc->context->runtime->compartments.begin();
|
||||||
for (; c != trc->context->runtime->compartments.end(); ++c) {
|
for (; c != trc->context->runtime->compartments.end(); ++c) {
|
||||||
@ -1854,23 +1853,19 @@ void
|
|||||||
js_FinalizeStringRT(JSRuntime *rt, JSString *str)
|
js_FinalizeStringRT(JSRuntime *rt, JSString *str)
|
||||||
{
|
{
|
||||||
JS_RUNTIME_UNMETER(rt, liveStrings);
|
JS_RUNTIME_UNMETER(rt, liveStrings);
|
||||||
JS_ASSERT(!str->isStaticAtom());
|
JS_ASSERT(str->isLinear() && !str->isStaticAtom());
|
||||||
JS_ASSERT(!str->isRope());
|
|
||||||
|
|
||||||
if (str->isDependent()) {
|
if (str->isDependent()) {
|
||||||
/* A dependent string can not be external and must be valid. */
|
/* A dependent string can not be external and must be valid. */
|
||||||
JS_ASSERT(str->asCell()->arena()->header()->thingKind == FINALIZE_STRING);
|
JS_ASSERT(str->arena()->header()->thingKind == FINALIZE_STRING);
|
||||||
JS_ASSERT(str->dependentBase());
|
JS_ASSERT(str->asDependent().base());
|
||||||
JS_RUNTIME_UNMETER(rt, liveDependentStrings);
|
JS_RUNTIME_UNMETER(rt, liveDependentStrings);
|
||||||
} else {
|
} else {
|
||||||
unsigned thingKind = str->asCell()->arena()->header()->thingKind;
|
unsigned thingKind = str->arena()->header()->thingKind;
|
||||||
JS_ASSERT(unsigned(FINALIZE_SHORT_STRING) <= thingKind &&
|
JS_ASSERT(unsigned(FINALIZE_SHORT_STRING) <= thingKind &&
|
||||||
thingKind <= unsigned(FINALIZE_EXTERNAL_STRING));
|
thingKind <= unsigned(FINALIZE_EXTERNAL_STRING));
|
||||||
|
|
||||||
/* A stillborn string has null chars, so is not valid. */
|
jschar *chars = const_cast<jschar *>(str->asFlat().chars());
|
||||||
jschar *chars = const_cast<jschar *>(str->flatChars());
|
|
||||||
if (!chars)
|
|
||||||
return;
|
|
||||||
if (thingKind == FINALIZE_STRING) {
|
if (thingKind == FINALIZE_STRING) {
|
||||||
rt->stringMemoryUsed -= str->length() * 2;
|
rt->stringMemoryUsed -= str->length() * 2;
|
||||||
rt->free(chars);
|
rt->free(chars);
|
||||||
@ -1915,22 +1910,22 @@ FinalizeArenaList(JSCompartment *comp, JSContext *cx, unsigned thingKind)
|
|||||||
if (!nextFree) {
|
if (!nextFree) {
|
||||||
nextFree = thingsEnd->asFreeCell();
|
nextFree = thingsEnd->asFreeCell();
|
||||||
} else {
|
} else {
|
||||||
JS_ASSERT(thing->asCell() <= nextFree);
|
JS_ASSERT(thing->asFreeCell() <= nextFree);
|
||||||
JS_ASSERT(nextFree < thingsEnd->asCell());
|
JS_ASSERT(nextFree < thingsEnd->asFreeCell());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (;; thing++) {
|
for (;; thing++) {
|
||||||
if (thing->asCell() == nextFree) {
|
if (thing->asFreeCell() == nextFree) {
|
||||||
if (thing == thingsEnd)
|
if (thing == thingsEnd)
|
||||||
break;
|
break;
|
||||||
nextFree = nextFree->link;
|
nextFree = nextFree->link;
|
||||||
if (!nextFree) {
|
if (!nextFree) {
|
||||||
nextFree = thingsEnd->asFreeCell();
|
nextFree = thingsEnd->asFreeCell();
|
||||||
} else {
|
} else {
|
||||||
JS_ASSERT(thing->asCell() < nextFree);
|
JS_ASSERT(thing->asFreeCell() < nextFree);
|
||||||
JS_ASSERT(nextFree < thingsEnd->asFreeCell());
|
JS_ASSERT(nextFree < thingsEnd->asFreeCell());
|
||||||
}
|
}
|
||||||
} else if (thing->asCell()->isMarked()) {
|
} else if (thing->isMarked()) {
|
||||||
allClear = false;
|
allClear = false;
|
||||||
METER(nthings++);
|
METER(nthings++);
|
||||||
continue;
|
continue;
|
||||||
|
@ -532,15 +532,8 @@ GetFinalizableTraceKind(size_t thingKind)
|
|||||||
return map[thingKind];
|
return map[thingKind];
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32
|
inline uint32
|
||||||
GetGCThingTraceKind(void *thing)
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline JSRuntime *
|
static inline JSRuntime *
|
||||||
GetGCThingRuntime(void *thing)
|
GetGCThingRuntime(void *thing)
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
#include "jsgc.h"
|
#include "jsgc.h"
|
||||||
#include "jscntxt.h"
|
#include "jscntxt.h"
|
||||||
#include "jscompartment.h"
|
#include "jscompartment.h"
|
||||||
|
#include "jsscope.h"
|
||||||
|
|
||||||
#include "jslock.h"
|
#include "jslock.h"
|
||||||
#include "jstl.h"
|
#include "jstl.h"
|
||||||
@ -55,9 +56,64 @@
|
|||||||
# define METER_IF(condition, x) ((void) 0)
|
# define METER_IF(condition, x) ((void) 0)
|
||||||
#endif
|
#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 js {
|
||||||
namespace gc {
|
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 */
|
/* Capacity for slotsToThingKind */
|
||||||
const size_t SLOTS_TO_THING_KIND_LIMIT = 17;
|
const size_t SLOTS_TO_THING_KIND_LIMIT = 17;
|
||||||
|
|
||||||
@ -194,7 +250,7 @@ TypedMarker(JSTracer *trc, JSFunction *thing);
|
|||||||
static JS_ALWAYS_INLINE void
|
static JS_ALWAYS_INLINE void
|
||||||
TypedMarker(JSTracer *trc, JSShortString *thing);
|
TypedMarker(JSTracer *trc, JSShortString *thing);
|
||||||
|
|
||||||
static JS_ALWAYS_INLINE void
|
extern void
|
||||||
TypedMarker(JSTracer *trc, JSString *thing);
|
TypedMarker(JSTracer *trc, JSString *thing);
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@ -210,7 +266,7 @@ Mark(JSTracer *trc, T *thing)
|
|||||||
|
|
||||||
JSRuntime *rt = trc->context->runtime;
|
JSRuntime *rt = trc->context->runtime;
|
||||||
/* Don't mark things outside a compartment if we are in a per-compartment GC */
|
/* 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;
|
goto out;
|
||||||
|
|
||||||
if (!IS_GC_MARKING_TRACER(trc)) {
|
if (!IS_GC_MARKING_TRACER(trc)) {
|
||||||
@ -307,10 +363,11 @@ static inline void
|
|||||||
MarkChildren(JSTracer *trc, JSString *str)
|
MarkChildren(JSTracer *trc, JSString *str)
|
||||||
{
|
{
|
||||||
if (str->isDependent())
|
if (str->isDependent())
|
||||||
MarkString(trc, str->dependentBase(), "base");
|
MarkString(trc, str->asDependent().base(), "base");
|
||||||
else if (str->isRope()) {
|
else if (str->isRope()) {
|
||||||
MarkString(trc, str->ropeLeft(), "left child");
|
JSRope &rope = str->asRope();
|
||||||
MarkString(trc, str->ropeRight(), "right child");
|
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)
|
TypedMarker(JSTracer *trc, JSObject *thing)
|
||||||
{
|
{
|
||||||
JS_ASSERT(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);
|
GCMarker *gcmarker = static_cast<GCMarker *>(trc);
|
||||||
if (!thing->markIfUnmarked(gcmarker->getMarkColor()))
|
if (!thing->markIfUnmarked(gcmarker->getMarkColor()))
|
||||||
@ -366,7 +423,7 @@ static JS_ALWAYS_INLINE void
|
|||||||
TypedMarker(JSTracer *trc, JSFunction *thing)
|
TypedMarker(JSTracer *trc, JSFunction *thing)
|
||||||
{
|
{
|
||||||
JS_ASSERT(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);
|
GCMarker *gcmarker = static_cast<GCMarker *>(trc);
|
||||||
if (!thing->markIfUnmarked(gcmarker->getMarkColor()))
|
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
|
* anything to mark if the string was unmarked and ignore the
|
||||||
* markIfUnmarked result.
|
* markIfUnmarked result.
|
||||||
*/
|
*/
|
||||||
(void) thing->asCell()->markIfUnmarked();
|
(void) thing->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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
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++) {
|
for (uint32 i = 0; i < len; i++) {
|
||||||
if (JSAtom *atom = vec[i]) {
|
if (JSAtom *atom = vec[i]) {
|
||||||
JS_SET_TRACING_INDEX(trc, name, i);
|
JS_SET_TRACING_INDEX(trc, name, i);
|
||||||
JSString *str = ATOM_TO_STRING(atom);
|
if (!atom->isStaticAtom())
|
||||||
if (!str->isStaticAtom())
|
Mark(trc, atom);
|
||||||
Mark(trc, str);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -364,7 +364,7 @@ GCMarker::dumpConservativeRoots()
|
|||||||
JSString *str = (JSString *) i->thing;
|
JSString *str = (JSString *) i->thing;
|
||||||
if (str->isLinear()) {
|
if (str->isLinear()) {
|
||||||
char buf[50];
|
char buf[50];
|
||||||
PutEscapedString(buf, sizeof buf, str->assertIsLinear(), '"');
|
PutEscapedString(buf, sizeof buf, &str->asLinear(), '"');
|
||||||
fprintf(fp, "string %s", buf);
|
fprintf(fp, "string %s", buf);
|
||||||
} else {
|
} else {
|
||||||
fprintf(fp, "rope: length %d", (int)str->length());
|
fprintf(fp, "rope: length %d", (int)str->length());
|
||||||
|
@ -3906,7 +3906,7 @@ BEGIN_CASE(JSOP_TYPEOF)
|
|||||||
const Value &ref = regs.sp[-1];
|
const Value &ref = regs.sp[-1];
|
||||||
JSType type = JS_TypeOfValue(cx, Jsvalify(ref));
|
JSType type = JS_TypeOfValue(cx, Jsvalify(ref));
|
||||||
JSAtom *atom = rt->atomState.typeAtoms[type];
|
JSAtom *atom = rt->atomState.typeAtoms[type];
|
||||||
regs.sp[-1].setString(ATOM_TO_STRING(atom));
|
regs.sp[-1].setString(atom);
|
||||||
}
|
}
|
||||||
END_CASE(JSOP_TYPEOF)
|
END_CASE(JSOP_TYPEOF)
|
||||||
|
|
||||||
@ -4325,7 +4325,7 @@ BEGIN_CASE(JSOP_CALLPROP)
|
|||||||
#if JS_HAS_NO_SUCH_METHOD
|
#if JS_HAS_NO_SUCH_METHOD
|
||||||
if (JS_UNLIKELY(rval.isUndefined()) && regs.sp[-1].isObject()) {
|
if (JS_UNLIKELY(rval.isUndefined()) && regs.sp[-1].isObject()) {
|
||||||
LOAD_ATOM(0, atom);
|
LOAD_ATOM(0, atom);
|
||||||
regs.sp[-2].setString(ATOM_TO_STRING(atom));
|
regs.sp[-2].setString(atom);
|
||||||
if (!js_OnUnknownMethod(cx, regs.sp - 2))
|
if (!js_OnUnknownMethod(cx, regs.sp - 2))
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
@ -4502,7 +4502,7 @@ BEGIN_CASE(JSOP_GETELEM)
|
|||||||
JSString *str = lref.toString();
|
JSString *str = lref.toString();
|
||||||
int32_t i = rref.toInt32();
|
int32_t i = rref.toInt32();
|
||||||
if (size_t(i) < str->length()) {
|
if (size_t(i) < str->length()) {
|
||||||
str = JSString::getUnitString(cx, str, size_t(i));
|
str = JSAtom::getUnitStringForElement(cx, str, size_t(i));
|
||||||
if (!str)
|
if (!str)
|
||||||
goto error;
|
goto error;
|
||||||
regs.sp--;
|
regs.sp--;
|
||||||
@ -4945,7 +4945,7 @@ BEGIN_CASE(JSOP_STRING)
|
|||||||
{
|
{
|
||||||
JSAtom *atom;
|
JSAtom *atom;
|
||||||
LOAD_ATOM(0, atom);
|
LOAD_ATOM(0, atom);
|
||||||
PUSH_STRING(ATOM_TO_STRING(atom));
|
PUSH_STRING(atom);
|
||||||
}
|
}
|
||||||
END_CASE(JSOP_STRING)
|
END_CASE(JSOP_STRING)
|
||||||
|
|
||||||
@ -5128,7 +5128,7 @@ BEGIN_CASE(JSOP_LOOKUPSWITCH)
|
|||||||
JSLinearString *str2;
|
JSLinearString *str2;
|
||||||
SEARCH_PAIRS(
|
SEARCH_PAIRS(
|
||||||
match = (rval.isString() &&
|
match = (rval.isString() &&
|
||||||
((str2 = rval.toString()->assertIsLinear()) == str ||
|
((str2 = &rval.toString()->asLinear()) == str ||
|
||||||
EqualStrings(str2, str)));
|
EqualStrings(str2, str)));
|
||||||
)
|
)
|
||||||
} else if (lval.isNumber()) {
|
} else if (lval.isNumber()) {
|
||||||
@ -6290,7 +6290,7 @@ BEGIN_CASE(JSOP_QNAMEPART)
|
|||||||
{
|
{
|
||||||
JSAtom *atom;
|
JSAtom *atom;
|
||||||
LOAD_ATOM(0, atom);
|
LOAD_ATOM(0, atom);
|
||||||
PUSH_STRING(ATOM_TO_STRING(atom));
|
PUSH_STRING(atom);
|
||||||
}
|
}
|
||||||
END_CASE(JSOP_QNAMEPART)
|
END_CASE(JSOP_QNAMEPART)
|
||||||
|
|
||||||
@ -6298,7 +6298,7 @@ BEGIN_CASE(JSOP_QNAMECONST)
|
|||||||
{
|
{
|
||||||
JSAtom *atom;
|
JSAtom *atom;
|
||||||
LOAD_ATOM(0, atom);
|
LOAD_ATOM(0, atom);
|
||||||
Value rval = StringValue(ATOM_TO_STRING(atom));
|
Value rval = StringValue(atom);
|
||||||
Value lval = regs.sp[-1];
|
Value lval = regs.sp[-1];
|
||||||
JSObject *obj = js_ConstructXMLQNameObject(cx, lval, rval);
|
JSObject *obj = js_ConstructXMLQNameObject(cx, lval, rval);
|
||||||
if (!obj)
|
if (!obj)
|
||||||
@ -6511,7 +6511,7 @@ BEGIN_CASE(JSOP_XMLCDATA)
|
|||||||
{
|
{
|
||||||
JSAtom *atom;
|
JSAtom *atom;
|
||||||
LOAD_ATOM(0, atom);
|
LOAD_ATOM(0, atom);
|
||||||
JSString *str = ATOM_TO_STRING(atom);
|
JSString *str = atom;
|
||||||
JSObject *obj = js_NewXMLSpecialObject(cx, JSXML_CLASS_TEXT, NULL, str);
|
JSObject *obj = js_NewXMLSpecialObject(cx, JSXML_CLASS_TEXT, NULL, str);
|
||||||
if (!obj)
|
if (!obj)
|
||||||
goto error;
|
goto error;
|
||||||
@ -6523,7 +6523,7 @@ BEGIN_CASE(JSOP_XMLCOMMENT)
|
|||||||
{
|
{
|
||||||
JSAtom *atom;
|
JSAtom *atom;
|
||||||
LOAD_ATOM(0, atom);
|
LOAD_ATOM(0, atom);
|
||||||
JSString *str = ATOM_TO_STRING(atom);
|
JSString *str = atom;
|
||||||
JSObject *obj = js_NewXMLSpecialObject(cx, JSXML_CLASS_COMMENT, NULL, str);
|
JSObject *obj = js_NewXMLSpecialObject(cx, JSXML_CLASS_COMMENT, NULL, str);
|
||||||
if (!obj)
|
if (!obj)
|
||||||
goto error;
|
goto error;
|
||||||
@ -6535,7 +6535,7 @@ BEGIN_CASE(JSOP_XMLPI)
|
|||||||
{
|
{
|
||||||
JSAtom *atom;
|
JSAtom *atom;
|
||||||
LOAD_ATOM(0, atom);
|
LOAD_ATOM(0, atom);
|
||||||
JSString *str = ATOM_TO_STRING(atom);
|
JSString *str = atom;
|
||||||
Value rval = regs.sp[-1];
|
Value rval = regs.sp[-1];
|
||||||
JSString *str2 = rval.toString();
|
JSString *str2 = rval.toString();
|
||||||
JSObject *obj = js_NewXMLSpecialObject(cx, JSXML_CLASS_PROCESSING_INSTRUCTION, str, str2);
|
JSObject *obj = js_NewXMLSpecialObject(cx, JSXML_CLASS_PROCESSING_INSTRUCTION, str, str2);
|
||||||
|
@ -1006,8 +1006,8 @@ js_IteratorNext(JSContext *cx, JSObject *iterobj, Value *rval)
|
|||||||
|
|
||||||
JSString *str;
|
JSString *str;
|
||||||
jsint i;
|
jsint i;
|
||||||
if (rval->isInt32() && (jsuint(i = rval->toInt32()) < INT_STRING_LIMIT)) {
|
if (rval->isInt32() && JSAtom::hasIntStatic(i = rval->toInt32())) {
|
||||||
str = JSString::intString(i);
|
str = &JSAtom::intStatic(i);
|
||||||
} else {
|
} else {
|
||||||
str = js_ValueToString(cx, *rval);
|
str = js_ValueToString(cx, *rval);
|
||||||
if (!str)
|
if (!str)
|
||||||
|
@ -663,7 +663,7 @@ math_tan(JSContext *cx, uintN argc, Value *vp)
|
|||||||
static JSBool
|
static JSBool
|
||||||
math_toSource(JSContext *cx, uintN argc, Value *vp)
|
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;
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -605,8 +605,8 @@ js_IntToString(JSContext *cx, int32 si)
|
|||||||
{
|
{
|
||||||
uint32 ui;
|
uint32 ui;
|
||||||
if (si >= 0) {
|
if (si >= 0) {
|
||||||
if (si < INT_STRING_LIMIT)
|
if (JSAtom::hasIntStatic(si))
|
||||||
return JSString::intString(si);
|
return &JSAtom::intStatic(si);
|
||||||
ui = si;
|
ui = si;
|
||||||
} else {
|
} else {
|
||||||
ui = uint32(-si);
|
ui = uint32(-si);
|
||||||
@ -621,10 +621,10 @@ js_IntToString(JSContext *cx, int32 si)
|
|||||||
if (!str)
|
if (!str)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* +1, since MAX_SHORT_STRING_LENGTH does not count the null char. */
|
/* +1, since MAX_LENGTH does not count the null char. */
|
||||||
JS_STATIC_ASSERT(JSShortString::MAX_SHORT_STRING_LENGTH + 1 >= sizeof("-2147483648"));
|
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;
|
jschar *cp = end;
|
||||||
*cp = 0;
|
*cp = 0;
|
||||||
|
|
||||||
@ -639,9 +639,8 @@ js_IntToString(JSContext *cx, int32 si)
|
|||||||
|
|
||||||
str->initAtOffsetInBuffer(cp, end - cp);
|
str->initAtOffsetInBuffer(cp, end - cp);
|
||||||
|
|
||||||
JSString *ret = str->header();
|
c->dtoaCache.cache(10, si, str);
|
||||||
c->dtoaCache.cache(10, si, ret);
|
return str;
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns a non-NULL pointer to inside cbuf. */
|
/* Returns a non-NULL pointer to inside cbuf. */
|
||||||
@ -1154,7 +1153,6 @@ js_NumberToStringWithBase(JSContext *cx, jsdouble d, jsint base)
|
|||||||
{
|
{
|
||||||
ToCStringBuf cbuf;
|
ToCStringBuf cbuf;
|
||||||
char *numStr;
|
char *numStr;
|
||||||
JSString *s;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Caller is responsible for error reporting. When called from trace,
|
* 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;
|
int32_t i;
|
||||||
if (JSDOUBLE_IS_INT32(d, &i)) {
|
if (JSDOUBLE_IS_INT32(d, &i)) {
|
||||||
if (base == 10 && jsuint(i) < INT_STRING_LIMIT)
|
if (base == 10 && JSAtom::hasIntStatic(i))
|
||||||
return JSString::intString(i);
|
return &JSAtom::intStatic(i);
|
||||||
if (jsuint(i) < jsuint(base)) {
|
if (jsuint(i) < jsuint(base)) {
|
||||||
if (i < 10)
|
if (i < 10)
|
||||||
return JSString::intString(i);
|
return &JSAtom::intStatic(i);
|
||||||
return JSString::unitString(jschar('a' + i - 10));
|
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;
|
return str;
|
||||||
|
|
||||||
numStr = IntToCString(&cbuf, i, base);
|
numStr = IntToCString(&cbuf, i, base);
|
||||||
JS_ASSERT(!cbuf.dbuf && numStr >= cbuf.sbuf && numStr < cbuf.sbuf + cbuf.sbufSize);
|
JS_ASSERT(!cbuf.dbuf && numStr >= cbuf.sbuf && numStr < cbuf.sbuf + cbuf.sbufSize);
|
||||||
} else {
|
} else {
|
||||||
if (JSString *str = c->dtoaCache.lookup(base, d))
|
if (JSFlatString *str = c->dtoaCache.lookup(base, d))
|
||||||
return str;
|
return str;
|
||||||
|
|
||||||
numStr = FracNumberToCString(cx, &cbuf, d, base);
|
numStr = FracNumberToCString(cx, &cbuf, d, base);
|
||||||
@ -1196,8 +1196,7 @@ js_NumberToStringWithBase(JSContext *cx, jsdouble d, jsint base)
|
|||||||
cbuf.dbuf && cbuf.dbuf == numStr);
|
cbuf.dbuf && cbuf.dbuf == numStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
s = js_NewStringCopyZ(cx, numStr);
|
JSFixedString *s = js_NewStringCopyZ(cx, numStr);
|
||||||
|
|
||||||
c->dtoaCache.cache(base, d, s);
|
c->dtoaCache.cache(base, d, s);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -1210,11 +1209,11 @@ js_NumberToString(JSContext *cx, jsdouble d)
|
|||||||
|
|
||||||
namespace js {
|
namespace js {
|
||||||
|
|
||||||
JSFlatString *
|
JSFixedString *
|
||||||
NumberToString(JSContext *cx, jsdouble d)
|
NumberToString(JSContext *cx, jsdouble d)
|
||||||
{
|
{
|
||||||
if (JSString *str = js_NumberToStringWithBase(cx, d, 10))
|
if (JSString *str = js_NumberToStringWithBase(cx, d, 10))
|
||||||
return str->assertIsFlat();
|
return &str->asFixed();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,7 +207,7 @@ extern bool JS_FASTCALL
|
|||||||
NumberValueToStringBuffer(JSContext *cx, const Value &v, StringBuffer &sb);
|
NumberValueToStringBuffer(JSContext *cx, const Value &v, StringBuffer &sb);
|
||||||
|
|
||||||
/* Same as js_NumberToString, different signature. */
|
/* Same as js_NumberToString, different signature. */
|
||||||
extern JSFlatString *
|
extern JSFixedString *
|
||||||
NumberToString(JSContext *cx, jsdouble d);
|
NumberToString(JSContext *cx, jsdouble d);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -590,13 +590,13 @@ obj_toSource(JSContext *cx, uintN argc, Value *vp)
|
|||||||
if (attrs & JSPROP_GETTER) {
|
if (attrs & JSPROP_GETTER) {
|
||||||
doGet = false;
|
doGet = false;
|
||||||
val[valcnt] = shape->getterValue();
|
val[valcnt] = shape->getterValue();
|
||||||
gsop[valcnt] = ATOM_TO_STRING(cx->runtime->atomState.getAtom);
|
gsop[valcnt] = cx->runtime->atomState.getAtom;
|
||||||
valcnt++;
|
valcnt++;
|
||||||
}
|
}
|
||||||
if (attrs & JSPROP_SETTER) {
|
if (attrs & JSPROP_SETTER) {
|
||||||
doGet = false;
|
doGet = false;
|
||||||
val[valcnt] = shape->setterValue();
|
val[valcnt] = shape->setterValue();
|
||||||
gsop[valcnt] = ATOM_TO_STRING(cx->runtime->atomState.setAtom);
|
gsop[valcnt] = cx->runtime->atomState.setAtom;
|
||||||
valcnt++;
|
valcnt++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -855,13 +855,13 @@ obj_toString(JSContext *cx, uintN argc, Value *vp)
|
|||||||
|
|
||||||
/* Step 1. */
|
/* Step 1. */
|
||||||
if (thisv.isUndefined()) {
|
if (thisv.isUndefined()) {
|
||||||
vp->setString(ATOM_TO_STRING(cx->runtime->atomState.objectUndefinedAtom));
|
vp->setString(cx->runtime->atomState.objectUndefinedAtom);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Step 2. */
|
/* Step 2. */
|
||||||
if (thisv.isNull()) {
|
if (thisv.isNull()) {
|
||||||
vp->setString(ATOM_TO_STRING(cx->runtime->atomState.objectNullAtom));
|
vp->setString(cx->runtime->atomState.objectNullAtom);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4420,8 +4420,7 @@ js_CheckForStringIndex(jsid id)
|
|||||||
return id;
|
return id;
|
||||||
|
|
||||||
JSAtom *atom = JSID_TO_ATOM(id);
|
JSAtom *atom = JSID_TO_ATOM(id);
|
||||||
JSString *str = ATOM_TO_STRING(atom);
|
const jschar *s = atom->chars();
|
||||||
const jschar *s = str->flatChars();
|
|
||||||
jschar ch = *s;
|
jschar ch = *s;
|
||||||
|
|
||||||
JSBool negative = (ch == '-');
|
JSBool negative = (ch == '-');
|
||||||
@ -4431,7 +4430,7 @@ js_CheckForStringIndex(jsid id)
|
|||||||
if (!JS7_ISDEC(ch))
|
if (!JS7_ISDEC(ch))
|
||||||
return id;
|
return id;
|
||||||
|
|
||||||
size_t n = str->flatLength() - negative;
|
size_t n = atom->length() - negative;
|
||||||
if (n > sizeof(JSBOXEDWORD_INT_MAX_STRING) - 1)
|
if (n > sizeof(JSBOXEDWORD_INT_MAX_STRING) - 1)
|
||||||
return id;
|
return id;
|
||||||
|
|
||||||
@ -6246,7 +6245,7 @@ js_TryValueOf(JSContext *cx, JSObject *obj, JSType type, Value *rval)
|
|||||||
{
|
{
|
||||||
Value argv[1];
|
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,
|
return js_TryMethod(cx, obj, cx->runtime->atomState.valueOfAtom,
|
||||||
1, argv, rval);
|
1, argv, rval);
|
||||||
}
|
}
|
||||||
@ -6589,7 +6588,7 @@ JS_FRIEND_API(void)
|
|||||||
js_DumpAtom(JSAtom *atom)
|
js_DumpAtom(JSAtom *atom)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "JSAtom* (%p) = ", (void *) atom);
|
fprintf(stderr, "JSAtom* (%p) = ", (void *) atom);
|
||||||
js_DumpString(ATOM_TO_STRING(atom));
|
js_DumpString(atom);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -6610,7 +6609,7 @@ dumpValue(const Value &v)
|
|||||||
JSFunction *fun = GET_FUNCTION_PRIVATE(cx, funobj);
|
JSFunction *fun = GET_FUNCTION_PRIVATE(cx, funobj);
|
||||||
if (fun->atom) {
|
if (fun->atom) {
|
||||||
fputs("<function ", stderr);
|
fputs("<function ", stderr);
|
||||||
FileEscapedString(stderr, ATOM_TO_STRING(fun->atom), 0);
|
FileEscapedString(stderr, fun->atom, 0);
|
||||||
} else {
|
} else {
|
||||||
fputs("<unnamed function", stderr);
|
fputs("<unnamed function", stderr);
|
||||||
}
|
}
|
||||||
|
@ -58,13 +58,13 @@
|
|||||||
#include "jsbool.h"
|
#include "jsbool.h"
|
||||||
#include "jscntxt.h"
|
#include "jscntxt.h"
|
||||||
#include "jsnum.h"
|
#include "jsnum.h"
|
||||||
#include "jsscopeinlines.h"
|
|
||||||
#include "jsscriptinlines.h"
|
#include "jsscriptinlines.h"
|
||||||
#include "jsstr.h"
|
#include "jsstr.h"
|
||||||
|
|
||||||
#include "jsfuninlines.h"
|
#include "jsfuninlines.h"
|
||||||
#include "jsgcinlines.h"
|
#include "jsgcinlines.h"
|
||||||
#include "jsprobes.h"
|
#include "jsprobes.h"
|
||||||
|
#include "jsscopeinlines.h"
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
JSObject::preventExtensions(JSContext *cx, js::AutoIdVector *props)
|
JSObject::preventExtensions(JSContext *cx, js::AutoIdVector *props)
|
||||||
@ -125,6 +125,39 @@ JSObject::syncSpecialEquality()
|
|||||||
flags |= JSObject::HAS_EQUALITY;
|
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
|
inline void
|
||||||
JSObject::finalize(JSContext *cx)
|
JSObject::finalize(JSContext *cx)
|
||||||
{
|
{
|
||||||
@ -670,7 +703,7 @@ JSObject::getNamePrefix() const
|
|||||||
{
|
{
|
||||||
JS_ASSERT(isNamespace() || isQName());
|
JS_ASSERT(isNamespace() || isQName());
|
||||||
const js::Value &v = getSlot(JSSLOT_NAME_PREFIX);
|
const js::Value &v = getSlot(JSSLOT_NAME_PREFIX);
|
||||||
return !v.isUndefined() ? v.toString()->assertIsLinear() : NULL;
|
return !v.isUndefined() ? &v.toString()->asLinear() : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline jsval
|
inline jsval
|
||||||
@ -699,7 +732,7 @@ JSObject::getNameURI() const
|
|||||||
{
|
{
|
||||||
JS_ASSERT(isNamespace() || isQName());
|
JS_ASSERT(isNamespace() || isQName());
|
||||||
const js::Value &v = getSlot(JSSLOT_NAME_URI);
|
const js::Value &v = getSlot(JSSLOT_NAME_URI);
|
||||||
return !v.isUndefined() ? v.toString()->assertIsLinear() : NULL;
|
return !v.isUndefined() ? &v.toString()->asLinear() : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline jsval
|
inline jsval
|
||||||
@ -735,7 +768,7 @@ JSObject::getQNameLocalName() const
|
|||||||
{
|
{
|
||||||
JS_ASSERT(isQName());
|
JS_ASSERT(isQName());
|
||||||
const js::Value &v = getSlot(JSSLOT_QNAME_LOCAL_NAME);
|
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
|
inline jsval
|
||||||
|
@ -64,6 +64,7 @@
|
|||||||
|
|
||||||
#include "jsatominlines.h"
|
#include "jsatominlines.h"
|
||||||
#include "jsobjinlines.h"
|
#include "jsobjinlines.h"
|
||||||
|
#include "jsstrinlines.h"
|
||||||
|
|
||||||
using namespace js;
|
using namespace js;
|
||||||
using namespace js::gc;
|
using namespace js::gc;
|
||||||
@ -1262,7 +1263,7 @@ js_ConsumeJSONText(JSContext *cx, JSONParser *jp, const jschar *data, uint32 len
|
|||||||
static JSBool
|
static JSBool
|
||||||
json_toSource(JSContext *cx, uintN argc, Value *vp)
|
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;
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -421,7 +421,7 @@ js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc,
|
|||||||
v = Jsvalify(script->getConst(index));
|
v = Jsvalify(script->getConst(index));
|
||||||
} else {
|
} else {
|
||||||
JS_GET_SCRIPT_ATOM(script, pc, index, atom);
|
JS_GET_SCRIPT_ATOM(script, pc, index, atom);
|
||||||
v = ATOM_TO_JSVAL(atom);
|
v = STRING_TO_JSVAL(atom);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (type == JOF_OBJECT)
|
if (type == JOF_OBJECT)
|
||||||
@ -440,7 +440,7 @@ js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc,
|
|||||||
|
|
||||||
case JOF_GLOBAL:
|
case JOF_GLOBAL:
|
||||||
atom = script->getGlobalAtom(GET_SLOTNO(pc));
|
atom = script->getGlobalAtom(GET_SLOTNO(pc));
|
||||||
v = ATOM_TO_JSVAL(atom);
|
v = STRING_TO_JSVAL(atom);
|
||||||
{
|
{
|
||||||
JSAutoByteString bytes;
|
JSAutoByteString bytes;
|
||||||
if (!ToDisassemblySource(cx, v, &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);
|
index = js_GetIndexFromBytecode(cx, script, pc, SLOTNO_LEN);
|
||||||
if (type == JOF_SLOTATOM) {
|
if (type == JOF_SLOTATOM) {
|
||||||
JS_GET_SCRIPT_ATOM(script, pc, index, atom);
|
JS_GET_SCRIPT_ATOM(script, pc, index, atom);
|
||||||
v = ATOM_TO_JSVAL(atom);
|
v = STRING_TO_JSVAL(atom);
|
||||||
} else {
|
} else {
|
||||||
obj = script->getObject(index);
|
obj = script->getObject(index);
|
||||||
v = OBJECT_TO_JSVAL(obj);
|
v = OBJECT_TO_JSVAL(obj);
|
||||||
@ -1263,7 +1263,7 @@ DecompileSwitch(SprintStack *ss, TableEntry *table, uintN tableLength,
|
|||||||
*/
|
*/
|
||||||
todo = -1;
|
todo = -1;
|
||||||
if (table[i].label) {
|
if (table[i].label) {
|
||||||
str = ATOM_TO_STRING(table[i].label);
|
str = table[i].label;
|
||||||
key = JSVAL_VOID;
|
key = JSVAL_VOID;
|
||||||
} else if (JSVAL_IS_DOUBLE(key)) {
|
} else if (JSVAL_IS_DOUBLE(key)) {
|
||||||
JSOp junk;
|
JSOp junk;
|
||||||
@ -1385,7 +1385,7 @@ GetLocal(SprintStack *ss, jsint i)
|
|||||||
LOCAL_ASSERT(JSID_IS_ATOM(shape.id));
|
LOCAL_ASSERT(JSID_IS_ATOM(shape.id));
|
||||||
|
|
||||||
JSAtom *atom = JSID_TO_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)
|
if (!rval)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -1925,7 +1925,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
|||||||
quote_ = 0; \
|
quote_ = 0; \
|
||||||
fmt = ufmt; \
|
fmt = ufmt; \
|
||||||
} \
|
} \
|
||||||
rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), quote_); \
|
rval = QuoteString(&ss->sprinter, atom, quote_); \
|
||||||
if (!rval) \
|
if (!rval) \
|
||||||
return NULL; \
|
return NULL; \
|
||||||
JS_END_MACRO
|
JS_END_MACRO
|
||||||
@ -2285,7 +2285,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
|||||||
case SRC_LABEL:
|
case SRC_LABEL:
|
||||||
GET_SOURCE_NOTE_ATOM(sn, atom);
|
GET_SOURCE_NOTE_ATOM(sn, atom);
|
||||||
jp->indent -= 4;
|
jp->indent -= 4;
|
||||||
rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
|
rval = QuoteString(&ss->sprinter, atom, 0);
|
||||||
if (!rval)
|
if (!rval)
|
||||||
return NULL;
|
return NULL;
|
||||||
RETRACT(&ss->sprinter, rval);
|
RETRACT(&ss->sprinter, rval);
|
||||||
@ -2295,7 +2295,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
|||||||
|
|
||||||
case SRC_LABELBRACE:
|
case SRC_LABELBRACE:
|
||||||
GET_SOURCE_NOTE_ATOM(sn, atom);
|
GET_SOURCE_NOTE_ATOM(sn, atom);
|
||||||
rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
|
rval = QuoteString(&ss->sprinter, atom, 0);
|
||||||
if (!rval)
|
if (!rval)
|
||||||
return NULL;
|
return NULL;
|
||||||
RETRACT(&ss->sprinter, rval);
|
RETRACT(&ss->sprinter, rval);
|
||||||
@ -2707,7 +2707,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
|||||||
ok = JS_TRUE;
|
ok = JS_TRUE;
|
||||||
for (i = 0; i < argc; i++) {
|
for (i = 0; i < argc; i++) {
|
||||||
atom = atomv[i];
|
atom = atomv[i];
|
||||||
rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
|
rval = QuoteString(&ss->sprinter, atom, 0);
|
||||||
if (!rval ||
|
if (!rval ||
|
||||||
!PushOff(ss, STR2OFF(&ss->sprinter, rval), op)) {
|
!PushOff(ss, STR2OFF(&ss->sprinter, rval), op)) {
|
||||||
ok = JS_FALSE;
|
ok = JS_FALSE;
|
||||||
@ -2781,7 +2781,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
|||||||
i = GET_SLOTNO(pc) - jp->script->nfixed;
|
i = GET_SLOTNO(pc) - jp->script->nfixed;
|
||||||
pc += JSOP_SETLOCALPOP_LENGTH;
|
pc += JSOP_SETLOCALPOP_LENGTH;
|
||||||
atom = atomv[i - OBJ_BLOCK_DEPTH(cx, obj)];
|
atom = atomv[i - OBJ_BLOCK_DEPTH(cx, obj)];
|
||||||
str = ATOM_TO_STRING(atom);
|
str = atom;
|
||||||
if (!QuoteString(&jp->sprinter, str, 0)) {
|
if (!QuoteString(&jp->sprinter, str, 0)) {
|
||||||
ok = JS_FALSE;
|
ok = JS_FALSE;
|
||||||
goto enterblock_out;
|
goto enterblock_out;
|
||||||
@ -3243,7 +3243,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
|||||||
|
|
||||||
case SRC_CONT2LABEL:
|
case SRC_CONT2LABEL:
|
||||||
GET_SOURCE_NOTE_ATOM(sn, atom);
|
GET_SOURCE_NOTE_ATOM(sn, atom);
|
||||||
rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
|
rval = QuoteString(&ss->sprinter, atom, 0);
|
||||||
if (!rval)
|
if (!rval)
|
||||||
return NULL;
|
return NULL;
|
||||||
RETRACT(&ss->sprinter, rval);
|
RETRACT(&ss->sprinter, rval);
|
||||||
@ -3256,7 +3256,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
|||||||
|
|
||||||
case SRC_BREAK2LABEL:
|
case SRC_BREAK2LABEL:
|
||||||
GET_SOURCE_NOTE_ATOM(sn, atom);
|
GET_SOURCE_NOTE_ATOM(sn, atom);
|
||||||
rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
|
rval = QuoteString(&ss->sprinter, atom, 0);
|
||||||
if (!rval)
|
if (!rval)
|
||||||
return NULL;
|
return NULL;
|
||||||
RETRACT(&ss->sprinter, rval);
|
RETRACT(&ss->sprinter, rval);
|
||||||
@ -3434,7 +3434,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
|||||||
atom = GetArgOrVarAtom(jp, i);
|
atom = GetArgOrVarAtom(jp, i);
|
||||||
LOCAL_ASSERT(atom);
|
LOCAL_ASSERT(atom);
|
||||||
todo = SprintCString(&ss->sprinter, VarPrefix(sn));
|
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;
|
return NULL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -3444,7 +3444,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
|||||||
|
|
||||||
sn = js_GetSrcNote(jp->script, pc);
|
sn = js_GetSrcNote(jp->script, pc);
|
||||||
todo = SprintCString(&ss->sprinter, VarPrefix(sn));
|
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;
|
return NULL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -3452,7 +3452,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
|||||||
xval = NULL;
|
xval = NULL;
|
||||||
LOAD_ATOM(0);
|
LOAD_ATOM(0);
|
||||||
if (!ATOM_IS_IDENTIFIER(atom)) {
|
if (!ATOM_IS_IDENTIFIER(atom)) {
|
||||||
xval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom),
|
xval = QuoteString(&ss->sprinter, atom,
|
||||||
(jschar)'\'');
|
(jschar)'\'');
|
||||||
if (!xval)
|
if (!xval)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -3465,7 +3465,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
|||||||
todo = Sprint(&ss->sprinter, ss_format, lval, *lval ? "." : "");
|
todo = Sprint(&ss->sprinter, ss_format, lval, *lval ? "." : "");
|
||||||
if (todo < 0)
|
if (todo < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (!QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0))
|
if (!QuoteString(&ss->sprinter, atom, 0))
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -3560,7 +3560,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
|||||||
LOAD_ATOM(0);
|
LOAD_ATOM(0);
|
||||||
|
|
||||||
do_setname:
|
do_setname:
|
||||||
lval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
|
lval = QuoteString(&ss->sprinter, atom, 0);
|
||||||
if (!lval)
|
if (!lval)
|
||||||
return NULL;
|
return NULL;
|
||||||
rval = POP_STR();
|
rval = POP_STR();
|
||||||
@ -3671,7 +3671,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
|||||||
|
|
||||||
case JSOP_DELNAME:
|
case JSOP_DELNAME:
|
||||||
LOAD_ATOM(0);
|
LOAD_ATOM(0);
|
||||||
lval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
|
lval = QuoteString(&ss->sprinter, atom, 0);
|
||||||
if (!lval)
|
if (!lval)
|
||||||
return NULL;
|
return NULL;
|
||||||
RETRACT(&ss->sprinter, lval);
|
RETRACT(&ss->sprinter, lval);
|
||||||
@ -3731,7 +3731,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
|||||||
case JSOP_DECGNAME:
|
case JSOP_DECGNAME:
|
||||||
LOAD_ATOM(0);
|
LOAD_ATOM(0);
|
||||||
do_incatom:
|
do_incatom:
|
||||||
lval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
|
lval = QuoteString(&ss->sprinter, atom, 0);
|
||||||
if (!lval)
|
if (!lval)
|
||||||
return NULL;
|
return NULL;
|
||||||
RETRACT(&ss->sprinter, lval);
|
RETRACT(&ss->sprinter, lval);
|
||||||
@ -3787,7 +3787,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
|||||||
case JSOP_GNAMEDEC:
|
case JSOP_GNAMEDEC:
|
||||||
LOAD_ATOM(0);
|
LOAD_ATOM(0);
|
||||||
do_atominc:
|
do_atominc:
|
||||||
lval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
|
lval = QuoteString(&ss->sprinter, atom, 0);
|
||||||
if (!lval)
|
if (!lval)
|
||||||
return NULL;
|
return NULL;
|
||||||
RETRACT(&ss->sprinter, lval);
|
RETRACT(&ss->sprinter, lval);
|
||||||
@ -3866,7 +3866,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
|||||||
do_getarg_prop:
|
do_getarg_prop:
|
||||||
atom = GetArgOrVarAtom(ss->printer, i);
|
atom = GetArgOrVarAtom(ss->printer, i);
|
||||||
LOCAL_ASSERT(atom);
|
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))
|
if (!lval || !PushOff(ss, STR2OFF(&ss->sprinter, lval), op))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -4002,8 +4002,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
|||||||
do_qname:
|
do_qname:
|
||||||
#endif
|
#endif
|
||||||
sn = js_GetSrcNote(jp->script, pc);
|
sn = js_GetSrcNote(jp->script, pc);
|
||||||
rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom),
|
rval = QuoteString(&ss->sprinter, atom, inXML ? DONT_ESCAPE : 0);
|
||||||
inXML ? DONT_ESCAPE : 0);
|
|
||||||
if (!rval)
|
if (!rval)
|
||||||
return NULL;
|
return NULL;
|
||||||
RETRACT(&ss->sprinter, rval);
|
RETRACT(&ss->sprinter, rval);
|
||||||
@ -4040,8 +4039,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
|||||||
|
|
||||||
case JSOP_STRING:
|
case JSOP_STRING:
|
||||||
LOAD_ATOM(0);
|
LOAD_ATOM(0);
|
||||||
rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom),
|
rval = QuoteString(&ss->sprinter, atom, inXML ? DONT_ESCAPE : '"');
|
||||||
inXML ? DONT_ESCAPE : '"');
|
|
||||||
if (!rval)
|
if (!rval)
|
||||||
return NULL;
|
return NULL;
|
||||||
todo = STR2OFF(&ss->sprinter, rval);
|
todo = STR2OFF(&ss->sprinter, rval);
|
||||||
@ -4214,7 +4212,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
|||||||
|
|
||||||
case JSOP_CALLEE:
|
case JSOP_CALLEE:
|
||||||
JS_ASSERT(jp->fun && jp->fun->atom);
|
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;
|
break;
|
||||||
|
|
||||||
case JSOP_OBJECT:
|
case JSOP_OBJECT:
|
||||||
@ -4556,7 +4554,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
|||||||
case JSOP_INITPROP:
|
case JSOP_INITPROP:
|
||||||
case JSOP_INITMETHOD:
|
case JSOP_INITMETHOD:
|
||||||
LOAD_ATOM(0);
|
LOAD_ATOM(0);
|
||||||
xval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom),
|
xval = QuoteString(&ss->sprinter, atom,
|
||||||
jschar(ATOM_IS_IDENTIFIER(atom) ? 0 : '\''));
|
jschar(ATOM_IS_IDENTIFIER(atom) ? 0 : '\''));
|
||||||
if (!xval)
|
if (!xval)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -4644,7 +4642,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
|||||||
|
|
||||||
case JSOP_QNAMECONST:
|
case JSOP_QNAMECONST:
|
||||||
LOAD_ATOM(0);
|
LOAD_ATOM(0);
|
||||||
rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0);
|
rval = QuoteString(&ss->sprinter, atom, 0);
|
||||||
if (!rval)
|
if (!rval)
|
||||||
return NULL;
|
return NULL;
|
||||||
RETRACT(&ss->sprinter, rval);
|
RETRACT(&ss->sprinter, rval);
|
||||||
@ -4737,8 +4735,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
|||||||
case JSOP_XMLCDATA:
|
case JSOP_XMLCDATA:
|
||||||
LOAD_ATOM(0);
|
LOAD_ATOM(0);
|
||||||
todo = SprintPut(&ss->sprinter, "<![CDATA[", 9);
|
todo = SprintPut(&ss->sprinter, "<![CDATA[", 9);
|
||||||
if (!QuoteString(&ss->sprinter, ATOM_TO_STRING(atom),
|
if (!QuoteString(&ss->sprinter, atom, DONT_ESCAPE))
|
||||||
DONT_ESCAPE))
|
|
||||||
return NULL;
|
return NULL;
|
||||||
SprintPut(&ss->sprinter, "]]>", 3);
|
SprintPut(&ss->sprinter, "]]>", 3);
|
||||||
break;
|
break;
|
||||||
@ -4746,8 +4743,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
|||||||
case JSOP_XMLCOMMENT:
|
case JSOP_XMLCOMMENT:
|
||||||
LOAD_ATOM(0);
|
LOAD_ATOM(0);
|
||||||
todo = SprintPut(&ss->sprinter, "<!--", 4);
|
todo = SprintPut(&ss->sprinter, "<!--", 4);
|
||||||
if (!QuoteString(&ss->sprinter, ATOM_TO_STRING(atom),
|
if (!QuoteString(&ss->sprinter, atom, DONT_ESCAPE))
|
||||||
DONT_ESCAPE))
|
|
||||||
return NULL;
|
return NULL;
|
||||||
SprintPut(&ss->sprinter, "-->", 3);
|
SprintPut(&ss->sprinter, "-->", 3);
|
||||||
break;
|
break;
|
||||||
@ -4758,7 +4754,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
|
|||||||
if (!rval)
|
if (!rval)
|
||||||
return NULL;
|
return NULL;
|
||||||
todo = SprintPut(&ss->sprinter, "<?", 2);
|
todo = SprintPut(&ss->sprinter, "<?", 2);
|
||||||
ok = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0) &&
|
ok = QuoteString(&ss->sprinter, atom, 0) &&
|
||||||
(*rval == '\0' ||
|
(*rval == '\0' ||
|
||||||
(SprintPut(&ss->sprinter, " ", 1) >= 0 &&
|
(SprintPut(&ss->sprinter, " ", 1) >= 0 &&
|
||||||
SprintCString(&ss->sprinter, rval)));
|
SprintCString(&ss->sprinter, rval)));
|
||||||
@ -4972,7 +4968,7 @@ js_DecompileFunction(JSPrinter *jp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
js_printf(jp, "%s ", js_function_str);
|
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;
|
return JS_FALSE;
|
||||||
js_puts(jp, "(");
|
js_puts(jp, "(");
|
||||||
|
|
||||||
@ -5041,7 +5037,7 @@ js_DecompileFunction(JSPrinter *jp)
|
|||||||
#undef LOCAL_ASSERT
|
#undef LOCAL_ASSERT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!QuoteString(&jp->sprinter, ATOM_TO_STRING(param), 0)) {
|
if (!QuoteString(&jp->sprinter, param, 0)) {
|
||||||
ok = JS_FALSE;
|
ok = JS_FALSE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -9136,7 +9136,7 @@ FoldType(JSContext *cx, JSParseNode *pn, TokenKind type)
|
|||||||
case TOK_NUMBER:
|
case TOK_NUMBER:
|
||||||
if (pn->pn_type == TOK_STRING) {
|
if (pn->pn_type == TOK_STRING) {
|
||||||
jsdouble d;
|
jsdouble d;
|
||||||
if (!ValueToNumber(cx, StringValue(ATOM_TO_STRING(pn->pn_atom)), &d))
|
if (!ValueToNumber(cx, StringValue(pn->pn_atom), &d))
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
pn->pn_dval = d;
|
pn->pn_dval = d;
|
||||||
pn->pn_type = TOK_NUMBER;
|
pn->pn_type = TOK_NUMBER;
|
||||||
@ -9265,9 +9265,9 @@ FoldXMLConstants(JSContext *cx, JSParseNode *pn, JSTreeContext *tc)
|
|||||||
str = NULL;
|
str = NULL;
|
||||||
if ((pn->pn_xflags & PNX_CANTFOLD) == 0) {
|
if ((pn->pn_xflags & PNX_CANTFOLD) == 0) {
|
||||||
if (tt == TOK_XMLETAGO)
|
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)
|
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:
|
case TOK_STRING:
|
||||||
if (pn2->pn_arity == PN_LIST)
|
if (pn2->pn_arity == PN_LIST)
|
||||||
goto cantfold;
|
goto cantfold;
|
||||||
str = ATOM_TO_STRING(pn2->pn_atom);
|
str = pn2->pn_atom;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_XMLCDATA:
|
case TOK_XMLCDATA:
|
||||||
str = js_MakeXMLCDATAString(cx, ATOM_TO_STRING(pn2->pn_atom));
|
str = js_MakeXMLCDATAString(cx, pn2->pn_atom);
|
||||||
if (!str)
|
if (!str)
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_XMLCOMMENT:
|
case TOK_XMLCOMMENT:
|
||||||
str = js_MakeXMLCommentString(cx, ATOM_TO_STRING(pn2->pn_atom));
|
str = js_MakeXMLCommentString(cx, pn2->pn_atom);
|
||||||
if (!str)
|
if (!str)
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_XMLPI:
|
case TOK_XMLPI:
|
||||||
str = js_MakeXMLPIString(cx, ATOM_TO_STRING(pn2->pn_atom),
|
str = js_MakeXMLPIString(cx, pn2->pn_atom, pn2->pn_atom2);
|
||||||
ATOM_TO_STRING(pn2->pn_atom2));
|
|
||||||
if (!str)
|
if (!str)
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
break;
|
break;
|
||||||
@ -9369,9 +9368,9 @@ FoldXMLConstants(JSContext *cx, JSParseNode *pn, JSTreeContext *tc)
|
|||||||
str = NULL;
|
str = NULL;
|
||||||
if ((pn->pn_xflags & PNX_CANTFOLD) == 0) {
|
if ((pn->pn_xflags & PNX_CANTFOLD) == 0) {
|
||||||
if (tt == TOK_XMLPTAGC)
|
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)
|
else if (tt == TOK_XMLSTAGO || tt == TOK_XMLETAGO)
|
||||||
str = ATOM_TO_STRING(cx->runtime->atomState.tagcAtom);
|
str = cx->runtime->atomState.tagcAtom;
|
||||||
}
|
}
|
||||||
if (str) {
|
if (str) {
|
||||||
accum = js_ConcatStrings(cx, accum, 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);
|
return pn->pn_dval != 0 && !JSDOUBLE_IS_NaN(pn->pn_dval);
|
||||||
|
|
||||||
case JSOP_STRING:
|
case JSOP_STRING:
|
||||||
return ATOM_TO_STRING(pn->pn_atom)->length() != 0;
|
return pn->pn_atom->length() != 0;
|
||||||
|
|
||||||
#if JS_HAS_GENERATOR_EXPRS
|
#if JS_HAS_GENERATOR_EXPRS
|
||||||
case JSOP_CALL:
|
case JSOP_CALL:
|
||||||
@ -9596,7 +9595,7 @@ js_FoldConstants(JSContext *cx, JSParseNode *pn, JSTreeContext *tc, bool inCond)
|
|||||||
pn2 = pn3;
|
pn2 = pn3;
|
||||||
break;
|
break;
|
||||||
case TOK_STRING:
|
case TOK_STRING:
|
||||||
if (ATOM_TO_STRING(pn1->pn_atom)->length() == 0)
|
if (pn1->pn_atom->length() == 0)
|
||||||
pn2 = pn3;
|
pn2 = pn3;
|
||||||
break;
|
break;
|
||||||
case TOK_PRIMARY:
|
case TOK_PRIMARY:
|
||||||
@ -9708,10 +9707,6 @@ js_FoldConstants(JSContext *cx, JSParseNode *pn, JSTreeContext *tc, bool inCond)
|
|||||||
|
|
||||||
case TOK_PLUS:
|
case TOK_PLUS:
|
||||||
if (pn->pn_arity == PN_LIST) {
|
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
|
* Any string literal term with all others number or string means
|
||||||
* this is a concatenation. If any term is not a string or number
|
* 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;
|
goto do_binary_op;
|
||||||
|
|
||||||
/* Ok, we're concatenating: convert non-string constant operands. */
|
/* Ok, we're concatenating: convert non-string constant operands. */
|
||||||
length = 0;
|
size_t length = 0;
|
||||||
for (pn2 = pn1; pn2; pn2 = pn2->pn_next) {
|
for (pn2 = pn1; pn2; pn2 = pn2->pn_next) {
|
||||||
if (!FoldType(cx, pn2, TOK_STRING))
|
if (!FoldType(cx, pn2, TOK_STRING))
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
/* XXX fold only if all operands convert to string */
|
/* XXX fold only if all operands convert to string */
|
||||||
if (pn2->pn_type != TOK_STRING)
|
if (pn2->pn_type != TOK_STRING)
|
||||||
return JS_TRUE;
|
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. */
|
/* 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)
|
if (!chars)
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
chars[length] = 0;
|
chars[length] = 0;
|
||||||
str = js_NewString(cx, chars, length);
|
JSString *str = js_NewString(cx, chars, length);
|
||||||
if (!str) {
|
if (!str) {
|
||||||
cx->free(chars);
|
cx->free(chars);
|
||||||
return JS_FALSE;
|
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. */
|
/* Fill the buffer, advancing chars and recycling kids as we go. */
|
||||||
for (pn2 = pn1; pn2; pn2 = RecycleTree(pn2, tc)) {
|
for (pn2 = pn1; pn2; pn2 = RecycleTree(pn2, tc)) {
|
||||||
str2 = ATOM_TO_STRING(pn2->pn_atom);
|
JSAtom *atom = pn2->pn_atom;
|
||||||
length2 = str2->flatLength();
|
size_t length2 = atom->length();
|
||||||
js_strncpy(chars, str2->flatChars(), length2);
|
js_strncpy(chars, atom->chars(), length2);
|
||||||
chars += length2;
|
chars += length2;
|
||||||
}
|
}
|
||||||
JS_ASSERT(*chars == 0);
|
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)
|
if (pn1->pn_type != TOK_STRING || pn2->pn_type != TOK_STRING)
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
left = ATOM_TO_STRING(pn1->pn_atom);
|
left = pn1->pn_atom;
|
||||||
right = ATOM_TO_STRING(pn2->pn_atom);
|
right = pn2->pn_atom;
|
||||||
str = js_ConcatStrings(cx, left, right);
|
str = js_ConcatStrings(cx, left, right);
|
||||||
if (!str)
|
if (!str)
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
@ -9898,7 +9893,7 @@ js_FoldConstants(JSContext *cx, JSParseNode *pn, JSTreeContext *tc, bool inCond)
|
|||||||
if (pn1->pn_type == TOK_XMLNAME) {
|
if (pn1->pn_type == TOK_XMLNAME) {
|
||||||
JSObjectBox *xmlbox;
|
JSObjectBox *xmlbox;
|
||||||
|
|
||||||
Value v = StringValue(ATOM_TO_STRING(pn1->pn_atom));
|
Value v = StringValue(pn1->pn_atom);
|
||||||
if (!js_ToAttributeName(cx, &v))
|
if (!js_ToAttributeName(cx, &v))
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
JS_ASSERT(v.isObject());
|
JS_ASSERT(v.isObject());
|
||||||
|
@ -601,7 +601,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool isEscapeFreeStringLiteral() const {
|
bool isEscapeFreeStringLiteral() const {
|
||||||
JS_ASSERT(pn_type == js::TOK_STRING && !pn_parens);
|
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,
|
* If the string's length in the source code is its length as a value,
|
||||||
|
@ -140,7 +140,7 @@ Probes::FunctionName(JSContext *cx, const JSFunction *fun, JSAutoByteString *byt
|
|||||||
return nullName;
|
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
|
#ifdef INCLUDE_MOZILLA_DTRACE
|
||||||
|
@ -93,8 +93,6 @@ typedef struct JSTreeContext JSTreeContext;
|
|||||||
typedef struct JSTryNote JSTryNote;
|
typedef struct JSTryNote JSTryNote;
|
||||||
|
|
||||||
/* Friend "Advanced API" typedefs. */
|
/* Friend "Advanced API" typedefs. */
|
||||||
typedef struct JSLinearString JSLinearString;
|
|
||||||
typedef struct JSAtom JSAtom;
|
|
||||||
typedef struct JSAtomList JSAtomList;
|
typedef struct JSAtomList JSAtomList;
|
||||||
typedef struct JSAtomListElement JSAtomListElement;
|
typedef struct JSAtomListElement JSAtomListElement;
|
||||||
typedef struct JSAtomMap JSAtomMap;
|
typedef struct JSAtomMap JSAtomMap;
|
||||||
@ -118,8 +116,17 @@ typedef struct JSXMLArrayCursor JSXMLArrayCursor;
|
|||||||
* templates.
|
* templates.
|
||||||
*/
|
*/
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
extern "C++" {
|
extern "C++" {
|
||||||
|
|
||||||
|
class JSDependentString;
|
||||||
|
class JSExtensibleString;
|
||||||
|
class JSLinearString;
|
||||||
|
class JSFixedString;
|
||||||
|
class JSStaticAtom;
|
||||||
|
class JSRope;
|
||||||
|
class JSAtom;
|
||||||
|
|
||||||
namespace js {
|
namespace js {
|
||||||
|
|
||||||
struct ArgumentsData;
|
struct ArgumentsData;
|
||||||
@ -177,6 +184,11 @@ class Bindings;
|
|||||||
} /* namespace js */
|
} /* namespace js */
|
||||||
|
|
||||||
} /* export "C++" */
|
} /* export "C++" */
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
typedef struct JSAtom JSAtom;
|
||||||
|
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
/* "Friend" types used by jscntxt.h and jsdbgapi.h. */
|
/* "Friend" types used by jscntxt.h and jsdbgapi.h. */
|
||||||
|
@ -317,7 +317,7 @@ class NodeBuilder
|
|||||||
if (!atom)
|
if (!atom)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
*dst = Valueify(ATOM_TO_JSVAL(atom));
|
dst->setString(atom);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1613,7 +1613,7 @@ class ASTSerializer
|
|||||||
uint32 lineno;
|
uint32 lineno;
|
||||||
|
|
||||||
Value atomContents(JSAtom *atom) {
|
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);
|
BinaryOperator binop(TokenKind tk, JSOp op);
|
||||||
@ -2886,7 +2886,7 @@ ASTSerializer::literal(JSParseNode *pn, Value *dst)
|
|||||||
Value val;
|
Value val;
|
||||||
switch (PN_TYPE(pn)) {
|
switch (PN_TYPE(pn)) {
|
||||||
case TOK_STRING:
|
case TOK_STRING:
|
||||||
val = Valueify(ATOM_TO_JSVAL(pn->pn_atom));
|
val.setString(pn->pn_atom);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_REGEXP:
|
case TOK_REGEXP:
|
||||||
|
@ -42,7 +42,10 @@
|
|||||||
|
|
||||||
#include "jsregexp.h"
|
#include "jsregexp.h"
|
||||||
#include "jscntxt.h"
|
#include "jscntxt.h"
|
||||||
|
|
||||||
#include "jsobjinlines.h"
|
#include "jsobjinlines.h"
|
||||||
|
#include "jsstrinlines.h"
|
||||||
|
|
||||||
#include "assembler/wtf/Platform.h"
|
#include "assembler/wtf/Platform.h"
|
||||||
|
|
||||||
#if ENABLE_YARR_JIT
|
#if ENABLE_YARR_JIT
|
||||||
|
@ -57,7 +57,6 @@
|
|||||||
#include "jsprvtd.h"
|
#include "jsprvtd.h"
|
||||||
#include "jspubtd.h"
|
#include "jspubtd.h"
|
||||||
#include "jspropertytree.h"
|
#include "jspropertytree.h"
|
||||||
#include "jsstrinlines.h"
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
|
@ -132,39 +132,6 @@ JSObject::extend(JSContext *cx, const js::Shape *shape, bool isDefinitelyAtom)
|
|||||||
updateShape(cx);
|
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 {
|
namespace js {
|
||||||
|
|
||||||
inline
|
inline
|
||||||
|
558
js/src/jsstr.cpp
558
js/src/jsstr.cpp
File diff suppressed because it is too large
Load Diff
997
js/src/jsstr.h
997
js/src/jsstr.h
File diff suppressed because it is too large
Load Diff
@ -41,7 +41,9 @@
|
|||||||
#define jsstrinlines_h___
|
#define jsstrinlines_h___
|
||||||
|
|
||||||
#include "jsstr.h"
|
#include "jsstr.h"
|
||||||
|
|
||||||
#include "jscntxtinlines.h"
|
#include "jscntxtinlines.h"
|
||||||
|
#include "jsgcinlines.h"
|
||||||
|
|
||||||
namespace js {
|
namespace js {
|
||||||
|
|
||||||
@ -49,6 +51,16 @@ static inline bool
|
|||||||
CheckStringLength(JSContext *cx, size_t length)
|
CheckStringLength(JSContext *cx, size_t length)
|
||||||
{
|
{
|
||||||
if (JS_UNLIKELY(length > JSString::MAX_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);
|
js_ReportAllocationOverflow(cx);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -116,7 +128,7 @@ class StringBuffer
|
|||||||
* This method takes responsibility for adding the terminating '\0'
|
* This method takes responsibility for adding the terminating '\0'
|
||||||
* required by js_NewString.
|
* required by js_NewString.
|
||||||
*/
|
*/
|
||||||
JSFlatString *finishString();
|
JSFixedString *finishString();
|
||||||
|
|
||||||
template <size_t ArrayLength>
|
template <size_t ArrayLength>
|
||||||
bool append(const char (&array)[ArrayLength]) {
|
bool append(const char (&array)[ArrayLength]) {
|
||||||
@ -227,73 +239,206 @@ StringBuffer::checkLength(size_t length)
|
|||||||
|
|
||||||
} /* namespace js */
|
} /* namespace js */
|
||||||
|
|
||||||
inline JSFlatString *
|
JS_ALWAYS_INLINE void
|
||||||
JSString::unitString(jschar c)
|
JSRope::init(JSString *left, JSString *right, size_t length)
|
||||||
{
|
{
|
||||||
JS_ASSERT(c < UNIT_STRING_LIMIT);
|
d.lengthAndFlags = buildLengthAndFlags(length, ROPE_BIT);
|
||||||
return const_cast<JSString *>(&unitStringTable[c])->assertIsFlat();
|
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 *
|
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());
|
JS_ASSERT(index < str->length());
|
||||||
const jschar *chars = str->getChars(cx);
|
const jschar *chars = str->getChars(cx);
|
||||||
if (!chars)
|
if (!chars)
|
||||||
return NULL;
|
return NULL;
|
||||||
jschar c = chars[index];
|
jschar c = chars[index];
|
||||||
if (c < UNIT_STRING_LIMIT)
|
if (c < UNIT_STATIC_LIMIT)
|
||||||
return unitString(c);
|
return &unitStatic(c);
|
||||||
return js_NewDependentString(cx, str, index, 1);
|
return js_NewDependentString(cx, str, index, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline JSFlatString *
|
inline JSStaticAtom &
|
||||||
JSString::length2String(jschar c1, jschar c2)
|
JSAtom::length2Static(jschar c1, jschar c2)
|
||||||
{
|
{
|
||||||
JS_ASSERT(fitsInSmallChar(c1));
|
JS_ASSERT(fitsInSmallChar(c1));
|
||||||
JS_ASSERT(fitsInSmallChar(c2));
|
JS_ASSERT(fitsInSmallChar(c2));
|
||||||
return const_cast<JSString *> (
|
size_t index = (((size_t)toSmallChar[c1]) << 6) + toSmallChar[c2];
|
||||||
&length2StringTable[(((size_t)toSmallChar[c1]) << 6) + toSmallChar[c2]]
|
return (JSStaticAtom &)length2StaticTable[index];
|
||||||
)->assertIsFlat();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline JSFlatString *
|
inline JSStaticAtom &
|
||||||
JSString::length2String(uint32 i)
|
JSAtom::length2Static(uint32 i)
|
||||||
{
|
{
|
||||||
JS_ASSERT(i < 100);
|
JS_ASSERT(i < 100);
|
||||||
return length2String('0' + i / 10, '0' + i % 10);
|
return length2Static('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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get a static atomized string for chars if possible. */
|
/* Get a static atomized string for chars if possible. */
|
||||||
inline JSFlatString *
|
inline JSStaticAtom *
|
||||||
JSString::lookupStaticString(const jschar *chars, size_t length)
|
JSAtom::lookupStatic(const jschar *chars, size_t length)
|
||||||
{
|
{
|
||||||
if (length == 1) {
|
switch (length) {
|
||||||
if (chars[0] < UNIT_STRING_LIMIT)
|
case 1:
|
||||||
return unitString(chars[0]);
|
if (chars[0] < UNIT_STATIC_LIMIT)
|
||||||
}
|
return &unitStatic(chars[0]);
|
||||||
|
return NULL;
|
||||||
if (length == 2) {
|
case 2:
|
||||||
if (fitsInSmallChar(chars[0]) && fitsInSmallChar(chars[1]))
|
if (fitsInSmallChar(chars[0]) && fitsInSmallChar(chars[1]))
|
||||||
return length2String(chars[0], chars[1]);
|
return &length2Static(chars[0], chars[1]);
|
||||||
}
|
return NULL;
|
||||||
|
case 3:
|
||||||
/*
|
/*
|
||||||
* Here we know that JSString::intStringTable covers only 256 (or at least
|
* 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.
|
* 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
|
* 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".
|
* strings for "0" through "9" and length-2 strings for "10" through "99".
|
||||||
*/
|
*/
|
||||||
JS_STATIC_ASSERT(INT_STRING_LIMIT <= 999);
|
JS_STATIC_ASSERT(INT_STATIC_LIMIT <= 999);
|
||||||
if (length == 3) {
|
|
||||||
if ('1' <= chars[0] && chars[0] <= '9' &&
|
if ('1' <= chars[0] && chars[0] <= '9' &&
|
||||||
'0' <= chars[1] && chars[1] <= '9' &&
|
'0' <= chars[1] && chars[1] <= '9' &&
|
||||||
'0' <= chars[2] && chars[2] <= '9') {
|
'0' <= chars[2] && chars[2] <= '9') {
|
||||||
@ -301,60 +446,51 @@ JSString::lookupStaticString(const jschar *chars, size_t length)
|
|||||||
(chars[1] - '0') * 10 +
|
(chars[1] - '0') * 10 +
|
||||||
(chars[2] - '0');
|
(chars[2] - '0');
|
||||||
|
|
||||||
if (jsuint(i) < INT_STRING_LIMIT)
|
if (jsuint(i) < INT_STATIC_LIMIT)
|
||||||
return intString(i);
|
return &intStatic(i);
|
||||||
}
|
}
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
JS_ALWAYS_INLINE void
|
||||||
JSString::finalize(JSContext *cx) {
|
JSString::finalize(JSContext *cx)
|
||||||
JS_ASSERT(!isStaticAtom());
|
{
|
||||||
|
JS_ASSERT(!isStaticAtom() && !isShort());
|
||||||
|
|
||||||
JS_RUNTIME_UNMETER(cx->runtime, liveStrings);
|
JS_RUNTIME_UNMETER(cx->runtime, liveStrings);
|
||||||
|
|
||||||
if (isDependent()) {
|
if (isDependent()) {
|
||||||
JS_RUNTIME_UNMETER(cx->runtime, liveDependentStrings);
|
JS_RUNTIME_UNMETER(cx->runtime, liveDependentStrings);
|
||||||
} else if (isFlat()) {
|
} 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->runtime->stringMemoryUsed -= length() * 2;
|
||||||
cx->free(const_cast<jschar *>(flatChars()));
|
cx->free(const_cast<jschar *>(asFlat().chars()));
|
||||||
|
} else {
|
||||||
|
JS_ASSERT(isRope());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
JSShortString::finalize(JSContext *cx)
|
JSShortString::finalize(JSContext *cx)
|
||||||
{
|
{
|
||||||
JS_ASSERT(!mHeader.isStaticAtom());
|
JS_ASSERT(isShort());
|
||||||
JS_ASSERT(mHeader.isFlat());
|
|
||||||
JS_RUNTIME_UNMETER(cx->runtime, liveStrings);
|
JS_RUNTIME_UNMETER(cx->runtime, liveStrings);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
JSExternalString::finalize(JSContext *cx)
|
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);
|
JS_RUNTIME_UNMETER(cx->runtime, liveStrings);
|
||||||
|
if (JSStringFinalizeOp finalizer = str_finalizers[externalStringType()])
|
||||||
/* A stillborn string has null chars. */
|
|
||||||
jschar *chars = const_cast<jschar *>(flatChars());
|
|
||||||
if (!chars)
|
|
||||||
return;
|
|
||||||
JSStringFinalizeOp finalizer = str_finalizers[externalStringType];
|
|
||||||
if (finalizer)
|
|
||||||
finalizer(cx, this);
|
finalizer(cx, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
JSExternalString::finalize()
|
JSExternalString::finalize()
|
||||||
{
|
{
|
||||||
JS_ASSERT(unsigned(externalStringType) < JS_ARRAY_LENGTH(str_finalizers));
|
JSStringFinalizeOp finalizer = str_finalizers[externalStringType()];
|
||||||
JSStringFinalizeOp finalizer = str_finalizers[externalStringType];
|
|
||||||
if (finalizer) {
|
if (finalizer) {
|
||||||
/*
|
/*
|
||||||
* Assume that the finalizer for the permanently interned
|
* 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.
|
* StackAllocPolicy which stashes a reusable freed-at-gc buffer in the cx.
|
||||||
*/
|
*/
|
||||||
Vector<JSString *, 32> stack;
|
Vector<JSString *, 32> stack;
|
||||||
JSString *cur;
|
JSLinearString *cur;
|
||||||
|
|
||||||
bool settle(JSString *str) {
|
bool settle(JSString *str) {
|
||||||
while (str->isRope()) {
|
while (str->isRope()) {
|
||||||
if (!stack.append(str->ropeRight()))
|
JSRope &rope = str->asRope();
|
||||||
|
if (!stack.append(rope.rightChild()))
|
||||||
return false;
|
return false;
|
||||||
str = str->ropeLeft();
|
str = rope.leftChild();
|
||||||
}
|
}
|
||||||
cur = str;
|
cur = &str->asLinear();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -418,7 +555,7 @@ class StringSegmentRange
|
|||||||
return cur == NULL;
|
return cur == NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
JSString *front() const {
|
JSLinearString *front() const {
|
||||||
JS_ASSERT(!cur->isRope());
|
JS_ASSERT(!cur->isRope());
|
||||||
return cur;
|
return cur;
|
||||||
}
|
}
|
||||||
|
@ -902,7 +902,7 @@ FragProfiling_showResults(TraceMonitor* tm)
|
|||||||
/* ----------------------------------------------------------------- */
|
/* ----------------------------------------------------------------- */
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
static JSBool FASTCALL
|
JSBool FASTCALL
|
||||||
PrintOnTrace(char* format, uint32 argc, double *argv)
|
PrintOnTrace(char* format, uint32 argc, double *argv)
|
||||||
{
|
{
|
||||||
union {
|
union {
|
||||||
@ -974,7 +974,10 @@ PrintOnTrace(char* format, uint32 argc, double *argv)
|
|||||||
fprintf(out, "<rope>");
|
fprintf(out, "<rope>");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
const jschar *chars = u.s->nonRopeChars();
|
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) {
|
for (unsigned i = 0; i < length; ++i) {
|
||||||
jschar co = chars[i];
|
jschar co = chars[i];
|
||||||
if (co < 128)
|
if (co < 128)
|
||||||
@ -985,6 +988,7 @@ PrintOnTrace(char* format, uint32 argc, double *argv)
|
|||||||
fprintf(out, "\\u%04x", co);
|
fprintf(out, "\\u%04x", co);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'S':
|
case 'S':
|
||||||
GET_ARG();
|
GET_ARG();
|
||||||
@ -2750,7 +2754,7 @@ ValueToNative(const Value &v, JSValueType type, double* slot)
|
|||||||
if (LogController.lcbits & LC_TMTracer) {
|
if (LogController.lcbits & LC_TMTracer) {
|
||||||
char funName[40];
|
char funName[40];
|
||||||
if (fun->atom)
|
if (fun->atom)
|
||||||
JS_PutEscapedFlatString(funName, sizeof funName, ATOM_TO_STRING(fun->atom), 0);
|
JS_PutEscapedFlatString(funName, sizeof funName, fun->atom, 0);
|
||||||
else
|
else
|
||||||
strcpy(funName, "unnamed");
|
strcpy(funName, "unnamed");
|
||||||
LogController.printf("function<%p:%s> ", (void*)*(JSObject **)slot, funName);
|
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());
|
JSFunction* fun = GET_FUNCTION_PRIVATE(cx, &v.toObject());
|
||||||
char funName[40];
|
char funName[40];
|
||||||
if (fun->atom)
|
if (fun->atom)
|
||||||
JS_PutEscapedFlatString(funName, sizeof funName, ATOM_TO_STRING(fun->atom), 0);
|
JS_PutEscapedFlatString(funName, sizeof funName, fun->atom, 0);
|
||||||
else
|
else
|
||||||
strcpy(funName, "unnamed");
|
strcpy(funName, "unnamed");
|
||||||
LogController.printf("function<%p:%s> ", (void*) &v.toObject(), funName);
|
LogController.printf("function<%p:%s> ", (void*) &v.toObject(), funName);
|
||||||
@ -11601,7 +11605,7 @@ TraceRecorder::callNative(uintN argc, JSOp mode)
|
|||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
ci->_name = js_anonymous_str;
|
ci->_name = js_anonymous_str;
|
||||||
if (fun->atom) {
|
if (fun->atom) {
|
||||||
JSAutoByteString bytes(cx, ATOM_TO_STRING(fun->atom));
|
JSAutoByteString bytes(cx, fun->atom);
|
||||||
if (!!bytes) {
|
if (!!bytes) {
|
||||||
size_t n = strlen(bytes.ptr()) + 1;
|
size_t n = strlen(bytes.ptr()) + 1;
|
||||||
char *buffer = new (traceAlloc()) char[n];
|
char *buffer = new (traceAlloc()) char[n];
|
||||||
@ -12523,7 +12527,7 @@ RootedStringToId(JSContext* cx, JSString** namep, jsid* idp)
|
|||||||
JSAtom* atom = js_AtomizeString(cx, name, 0);
|
JSAtom* atom = js_AtomizeString(cx, name, 0);
|
||||||
if (!atom)
|
if (!atom)
|
||||||
return false;
|
return false;
|
||||||
*namep = ATOM_TO_STRING(atom); /* write back to GC root */
|
*namep = atom; /* write back to GC root */
|
||||||
*idp = ATOM_TO_JSID(atom);
|
*idp = ATOM_TO_JSID(atom);
|
||||||
return true;
|
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)))))
|
if (MaybeBranch mbr = w.jt(w.eqp0(w.andp(lengthAndFlags_ins, w.nameImmw(JSString::ROPE_BIT)))))
|
||||||
{
|
{
|
||||||
LIns *args[] = { str_ins, cx_ins };
|
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);
|
guard(false, w.eqi0(ok_ins), OOM_EXIT);
|
||||||
w.label(mbr);
|
w.label(mbr);
|
||||||
}
|
}
|
||||||
@ -12869,8 +12873,9 @@ JS_REQUIRES_STACK LIns*
|
|||||||
TraceRecorder::getUnitString(LIns* str_ins, LIns* idx_ins)
|
TraceRecorder::getUnitString(LIns* str_ins, LIns* idx_ins)
|
||||||
{
|
{
|
||||||
LIns *ch_ins = w.getStringChar(str_ins, idx_ins);
|
LIns *ch_ins = w.getStringChar(str_ins, idx_ins);
|
||||||
guard(true, w.ltuiN(ch_ins, UNIT_STRING_LIMIT), MISMATCH_EXIT);
|
guard(true, w.ltuiN(ch_ins, JSAtom::UNIT_STATIC_LIMIT), MISMATCH_EXIT);
|
||||||
return w.addp(w.nameImmpNonGC(JSString::unitStringTable),
|
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));
|
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)))))
|
w.nameImmw(JSString::ROPE_BIT)))))
|
||||||
{
|
{
|
||||||
LIns *args[] = { str_ins, cx_ins };
|
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);
|
guard(false, w.eqi0(ok_ins), OOM_EXIT);
|
||||||
w.label(mbr);
|
w.label(mbr);
|
||||||
}
|
}
|
||||||
|
@ -1138,7 +1138,7 @@ class TraceRecorder
|
|||||||
#define immpObjGC(obj) name(w_immpObjGC(obj), #obj)
|
#define immpObjGC(obj) name(w_immpObjGC(obj), #obj)
|
||||||
#define immpFunGC(fun) name(w_immpFunGC(fun), #fun)
|
#define immpFunGC(fun) name(w_immpFunGC(fun), #fun)
|
||||||
#define immpStrGC(str) name(w_immpStrGC(str), #str)
|
#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 immpShapeGC(shape) name(w_immpShapeGC(shape), #shape)
|
||||||
#define immpIdGC(id) name(w_immpIdGC(id), #id)
|
#define immpIdGC(id) name(w_immpIdGC(id), #id)
|
||||||
|
|
||||||
|
@ -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 */
|
} /* namespace js */
|
||||||
|
|
||||||
#endif /* defined(__cplusplus) */
|
#endif /* defined(__cplusplus) */
|
||||||
|
@ -267,8 +267,13 @@ typedef enum JSWhyMagic
|
|||||||
JS_GENERIC_MAGIC /* for local use */
|
JS_GENERIC_MAGIC /* for local use */
|
||||||
} JSWhyMagic;
|
} JSWhyMagic;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
class JSString;
|
||||||
|
class JSFlatString;
|
||||||
|
#else
|
||||||
typedef struct JSString JSString;
|
typedef struct JSString JSString;
|
||||||
typedef struct JSFlatString JSFlatString;
|
typedef struct JSFlatString JSFlatString;
|
||||||
|
#endif
|
||||||
typedef struct JSObject JSObject;
|
typedef struct JSObject JSObject;
|
||||||
|
|
||||||
#if defined(IS_LITTLE_ENDIAN)
|
#if defined(IS_LITTLE_ENDIAN)
|
||||||
|
@ -670,7 +670,7 @@ js_XDRAtom(JSXDRState *xdr, JSAtom **atomp)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (idx == uint32(-1)) {
|
if (idx == uint32(-1)) {
|
||||||
JSString *str = ATOM_TO_STRING(*atomp);
|
JSString *str = *atomp;
|
||||||
return JS_XDRString(xdr, &str);
|
return JS_XDRString(xdr, &str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -412,12 +412,12 @@ ConvertQNameToString(JSContext *cx, JSObject *obj)
|
|||||||
JSString *str;
|
JSString *str;
|
||||||
if (!uri) {
|
if (!uri) {
|
||||||
/* No uri means wildcard qualifier. */
|
/* No uri means wildcard qualifier. */
|
||||||
str = ATOM_TO_STRING(cx->runtime->atomState.starQualifierAtom);
|
str = cx->runtime->atomState.starQualifierAtom;
|
||||||
} else if (uri->empty()) {
|
} else if (uri->empty()) {
|
||||||
/* Empty string for uri means localName is in no namespace. */
|
/* Empty string for uri means localName is in no namespace. */
|
||||||
str = cx->runtime->emptyString;
|
str = cx->runtime->emptyString;
|
||||||
} else {
|
} else {
|
||||||
JSString *qualstr = ATOM_TO_STRING(cx->runtime->atomState.qualifierAtom);
|
JSString *qualstr = cx->runtime->atomState.qualifierAtom;
|
||||||
str = js_ConcatStrings(cx, uri, qualstr);
|
str = js_ConcatStrings(cx, uri, qualstr);
|
||||||
if (!str)
|
if (!str)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -758,7 +758,7 @@ QNameHelper(JSContext *cx, JSObject *obj, intN argc, jsval *argv, jsval *rval)
|
|||||||
if (argc == 0) {
|
if (argc == 0) {
|
||||||
name = cx->runtime->emptyString;
|
name = cx->runtime->emptyString;
|
||||||
} else if (argc < 0) {
|
} else if (argc < 0) {
|
||||||
name = ATOM_TO_STRING(cx->runtime->atomState.typeAtoms[JSTYPE_VOID]);
|
name = cx->runtime->atomState.typeAtoms[JSTYPE_VOID];
|
||||||
} else {
|
} else {
|
||||||
JSString *str = js_ValueToString(cx, Valueify(nameval));
|
JSString *str = js_ValueToString(cx, Valueify(nameval));
|
||||||
if (!str)
|
if (!str)
|
||||||
@ -1430,7 +1430,7 @@ ParseNodeToXML(Parser *parser, JSParseNode *pn,
|
|||||||
/* Enforce "Well-formedness constraint: Unique Att Spec". */
|
/* Enforce "Well-formedness constraint: Unique Att Spec". */
|
||||||
for (pn3 = head; pn3 != pn2; pn3 = pn3->pn_next->pn_next) {
|
for (pn3 = head; pn3 != pn2; pn3 = pn3->pn_next->pn_next) {
|
||||||
if (pn3->pn_atom == pn2->pn_atom) {
|
if (pn3->pn_atom == pn2->pn_atom) {
|
||||||
Value v = StringValue(ATOM_TO_STRING(pn2->pn_atom));
|
Value v = StringValue(pn2->pn_atom);
|
||||||
JSAutoByteString bytes;
|
JSAutoByteString bytes;
|
||||||
if (js_ValueToPrintable(cx, v, &bytes)) {
|
if (js_ValueToPrintable(cx, v, &bytes)) {
|
||||||
ReportCompileErrorNumber(cx, &parser->tokenStream, pn2,
|
ReportCompileErrorNumber(cx, &parser->tokenStream, pn2,
|
||||||
@ -1454,7 +1454,7 @@ ParseNodeToXML(Parser *parser, JSParseNode *pn,
|
|||||||
(length == 5 || chars[5] == ':')) {
|
(length == 5 || chars[5] == ':')) {
|
||||||
JSLinearString *uri, *prefix;
|
JSLinearString *uri, *prefix;
|
||||||
|
|
||||||
uri = ATOM_TO_STRING(pn2->pn_atom);
|
uri = pn2->pn_atom;
|
||||||
if (length == 5) {
|
if (length == 5) {
|
||||||
/* 10.3.2.1. Step 6(h)(i)(1)(a). */
|
/* 10.3.2.1. Step 6(h)(i)(1)(a). */
|
||||||
prefix = cx->runtime->emptyString;
|
prefix = cx->runtime->emptyString;
|
||||||
@ -1528,7 +1528,7 @@ ParseNodeToXML(Parser *parser, JSParseNode *pn,
|
|||||||
attrjqn = attrj->name;
|
attrjqn = attrj->name;
|
||||||
if (EqualStrings(attrjqn->getNameURI(), qn->getNameURI()) &&
|
if (EqualStrings(attrjqn->getNameURI(), qn->getNameURI()) &&
|
||||||
EqualStrings(attrjqn->getQNameLocalName(), qn->getQNameLocalName())) {
|
EqualStrings(attrjqn->getQNameLocalName(), qn->getQNameLocalName())) {
|
||||||
Value v = StringValue(ATOM_TO_STRING(pn2->pn_atom));
|
Value v = StringValue(pn2->pn_atom);
|
||||||
JSAutoByteString bytes;
|
JSAutoByteString bytes;
|
||||||
if (js_ValueToPrintable(cx, v, &bytes)) {
|
if (js_ValueToPrintable(cx, v, &bytes)) {
|
||||||
ReportCompileErrorNumber(cx, &parser->tokenStream, pn2,
|
ReportCompileErrorNumber(cx, &parser->tokenStream, pn2,
|
||||||
@ -1550,7 +1550,7 @@ ParseNodeToXML(Parser *parser, JSParseNode *pn,
|
|||||||
XMLARRAY_SET_MEMBER(&xml->xml_attrs, i, attr);
|
XMLARRAY_SET_MEMBER(&xml->xml_attrs, i, attr);
|
||||||
attr->parent = xml;
|
attr->parent = xml;
|
||||||
attr->name = qn;
|
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. */
|
/* Point tag closes its own namespace scope. */
|
||||||
@ -1563,7 +1563,7 @@ ParseNodeToXML(Parser *parser, JSParseNode *pn,
|
|||||||
case TOK_XMLCDATA:
|
case TOK_XMLCDATA:
|
||||||
case TOK_XMLCOMMENT:
|
case TOK_XMLCOMMENT:
|
||||||
case TOK_XMLPI:
|
case TOK_XMLPI:
|
||||||
str = ATOM_TO_STRING(pn->pn_atom);
|
str = pn->pn_atom;
|
||||||
qn = NULL;
|
qn = NULL;
|
||||||
if (pn->pn_type == TOK_XMLCOMMENT) {
|
if (pn->pn_type == TOK_XMLCOMMENT) {
|
||||||
if (flags & XSF_IGNORE_COMMENTS)
|
if (flags & XSF_IGNORE_COMMENTS)
|
||||||
@ -1587,9 +1587,7 @@ ParseNodeToXML(Parser *parser, JSParseNode *pn,
|
|||||||
if (!qn)
|
if (!qn)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
str = pn->pn_atom2
|
str = pn->pn_atom2 ? pn->pn_atom2 : cx->runtime->emptyString;
|
||||||
? ATOM_TO_STRING(pn->pn_atom2)
|
|
||||||
: cx->runtime->emptyString;
|
|
||||||
xml_class = JSXML_CLASS_PROCESSING_INSTRUCTION;
|
xml_class = JSXML_CLASS_PROCESSING_INSTRUCTION;
|
||||||
} else {
|
} else {
|
||||||
/* CDATA section content, or element text. */
|
/* CDATA section content, or element text. */
|
||||||
@ -2792,7 +2790,7 @@ ToAttributeName(JSContext *cx, jsval v)
|
|||||||
name = qn->getQNameLocalName();
|
name = qn->getQNameLocalName();
|
||||||
} else {
|
} else {
|
||||||
if (clasp == &js_AnyNameClass) {
|
if (clasp == &js_AnyNameClass) {
|
||||||
name = ATOM_TO_STRING(cx->runtime->atomState.starAtom);
|
name = cx->runtime->atomState.starAtom;
|
||||||
} else {
|
} else {
|
||||||
JSString *str = js_ValueToString(cx, Valueify(v));
|
JSString *str = js_ValueToString(cx, Valueify(v));
|
||||||
if (!str)
|
if (!str)
|
||||||
@ -2825,11 +2823,8 @@ IsFunctionQName(JSContext *cx, JSObject *qn, jsid *funidp)
|
|||||||
|
|
||||||
atom = cx->runtime->atomState.functionNamespaceURIAtom;
|
atom = cx->runtime->atomState.functionNamespaceURIAtom;
|
||||||
uri = qn->getNameURI();
|
uri = qn->getNameURI();
|
||||||
if (uri &&
|
if (uri && (uri == atom || EqualStrings(uri, atom)))
|
||||||
(uri == ATOM_TO_STRING(atom) ||
|
|
||||||
EqualStrings(uri, ATOM_TO_STRING(atom)))) {
|
|
||||||
return JS_ValueToId(cx, STRING_TO_JSVAL(qn->getQNameLocalName()), funidp);
|
return JS_ValueToId(cx, STRING_TO_JSVAL(qn->getQNameLocalName()), funidp);
|
||||||
}
|
|
||||||
*funidp = JSID_VOID;
|
*funidp = JSID_VOID;
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
@ -2865,7 +2860,7 @@ ToXMLName(JSContext *cx, jsval v, jsid *funidp)
|
|||||||
if (clasp == &js_AttributeNameClass || clasp == &js_QNameClass)
|
if (clasp == &js_AttributeNameClass || clasp == &js_QNameClass)
|
||||||
goto out;
|
goto out;
|
||||||
if (clasp == &js_AnyNameClass) {
|
if (clasp == &js_AnyNameClass) {
|
||||||
name = ATOM_TO_STRING(cx->runtime->atomState.starAtom);
|
name = cx->runtime->atomState.starAtom;
|
||||||
goto construct;
|
goto construct;
|
||||||
}
|
}
|
||||||
name = js_ValueToString(cx, Valueify(v));
|
name = js_ValueToString(cx, Valueify(v));
|
||||||
@ -4622,6 +4617,34 @@ HasFunctionProperty(JSContext *cx, JSObject *obj, jsid funid, JSBool *found)
|
|||||||
return true;
|
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]]. */
|
/* ECMA-357 9.1.1.6 XML [[HasProperty]] and 9.2.1.5 XMLList [[HasProperty]]. */
|
||||||
static JSBool
|
static JSBool
|
||||||
HasProperty(JSContext *cx, JSObject *obj, jsval id, JSBool *found)
|
HasProperty(JSContext *cx, JSObject *obj, jsval id, JSBool *found)
|
||||||
@ -4633,7 +4656,7 @@ HasProperty(JSContext *cx, JSObject *obj, jsval id, JSBool *found)
|
|||||||
jsid funid;
|
jsid funid;
|
||||||
|
|
||||||
xml = (JSXML *) obj->getPrivate();
|
xml = (JSXML *) obj->getPrivate();
|
||||||
if (!js_IdValIsIndex(cx, id, &i, &isIndex))
|
if (!IdValIsIndex(cx, id, &i, &isIndex))
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
|
|
||||||
if (isIndex) {
|
if (isIndex) {
|
||||||
@ -5291,7 +5314,7 @@ xml_attribute(JSContext *cx, uintN argc, jsval *vp)
|
|||||||
static JSBool
|
static JSBool
|
||||||
xml_attributes(JSContext *cx, uintN argc, jsval *vp)
|
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);
|
JSObject *qn = ToAttributeName(cx, name);
|
||||||
if (!qn)
|
if (!qn)
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
@ -5355,7 +5378,7 @@ xml_child_helper(JSContext *cx, JSObject *obj, JSXML *xml, jsval name,
|
|||||||
/* ECMA-357 13.4.4.6 */
|
/* ECMA-357 13.4.4.6 */
|
||||||
JS_ASSERT(xml->xml_class != JSXML_CLASS_LIST);
|
JS_ASSERT(xml->xml_class != JSXML_CLASS_LIST);
|
||||||
|
|
||||||
if (!js_IdValIsIndex(cx, name, &index, &isIndex))
|
if (!IdValIsIndex(cx, name, &index, &isIndex))
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
|
|
||||||
if (isIndex) {
|
if (isIndex) {
|
||||||
@ -5577,7 +5600,7 @@ xml_descendants(JSContext *cx, uintN argc, jsval *vp)
|
|||||||
JSXML *list;
|
JSXML *list;
|
||||||
|
|
||||||
XML_METHOD_PROLOG;
|
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);
|
list = Descendants(cx, xml, name);
|
||||||
if (!list)
|
if (!list)
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
@ -5653,7 +5676,7 @@ xml_elements(JSContext *cx, uintN argc, jsval *vp)
|
|||||||
|
|
||||||
XML_METHOD_PROLOG;
|
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);
|
nameqn = ToXMLName(cx, name, &funid);
|
||||||
if (!nameqn)
|
if (!nameqn)
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
@ -6201,7 +6224,7 @@ xml_processingInstructions(JSContext *cx, uintN argc, jsval *vp)
|
|||||||
|
|
||||||
XML_METHOD_PROLOG;
|
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);
|
nameqn = ToXMLName(cx, name, &funid);
|
||||||
if (!nameqn)
|
if (!nameqn)
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
@ -6234,7 +6257,7 @@ xml_propertyIsEnumerable(JSContext *cx, uintN argc, jsval *vp)
|
|||||||
XML_METHOD_PROLOG;
|
XML_METHOD_PROLOG;
|
||||||
*vp = JSVAL_FALSE;
|
*vp = JSVAL_FALSE;
|
||||||
if (argc != 0) {
|
if (argc != 0) {
|
||||||
if (!js_IdValIsIndex(cx, vp[2], &index, &isIndex))
|
if (!IdValIsIndex(cx, vp[2], &index, &isIndex))
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
|
|
||||||
if (isIndex) {
|
if (isIndex) {
|
||||||
@ -6340,7 +6363,7 @@ xml_replace(JSContext *cx, uintN argc, jsval *vp)
|
|||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
if (argc <= 1) {
|
if (argc <= 1) {
|
||||||
value = ATOM_TO_JSVAL(cx->runtime->atomState.typeAtoms[JSTYPE_VOID]);
|
value = STRING_TO_JSVAL(cx->runtime->atomState.typeAtoms[JSTYPE_VOID]);
|
||||||
} else {
|
} else {
|
||||||
value = vp[3];
|
value = vp[3];
|
||||||
vxml = VALUE_IS_XML(value)
|
vxml = VALUE_IS_XML(value)
|
||||||
@ -6366,7 +6389,7 @@ xml_replace(JSContext *cx, uintN argc, jsval *vp)
|
|||||||
if (argc == 0) {
|
if (argc == 0) {
|
||||||
haveIndex = false;
|
haveIndex = false;
|
||||||
} else {
|
} else {
|
||||||
if (!js_IdValIsIndex(cx, vp[2], &index, &haveIndex))
|
if (!IdValIsIndex(cx, vp[2], &index, &haveIndex))
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6432,7 +6455,7 @@ xml_setLocalName(JSContext *cx, uintN argc, jsval *vp)
|
|||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
|
|
||||||
if (argc == 0) {
|
if (argc == 0) {
|
||||||
namestr = ATOM_TO_STRING(cx->runtime->atomState.typeAtoms[JSTYPE_VOID]);
|
namestr = cx->runtime->atomState.typeAtoms[JSTYPE_VOID];
|
||||||
} else {
|
} else {
|
||||||
name = vp[2];
|
name = vp[2];
|
||||||
if (!JSVAL_IS_PRIMITIVE(name) &&
|
if (!JSVAL_IS_PRIMITIVE(name) &&
|
||||||
@ -6472,7 +6495,7 @@ xml_setName(JSContext *cx, uintN argc, jsval *vp)
|
|||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
|
|
||||||
if (argc == 0) {
|
if (argc == 0) {
|
||||||
name = ATOM_TO_JSVAL(cx->runtime->atomState.typeAtoms[JSTYPE_VOID]);
|
name = STRING_TO_JSVAL(cx->runtime->atomState.typeAtoms[JSTYPE_VOID]);
|
||||||
} else {
|
} else {
|
||||||
name = vp[2];
|
name = vp[2];
|
||||||
if (!JSVAL_IS_PRIMITIVE(name) &&
|
if (!JSVAL_IS_PRIMITIVE(name) &&
|
||||||
@ -7358,8 +7381,7 @@ js_GetAnyName(JSContext *cx, jsid *idp)
|
|||||||
JS_ASSERT(!obj->getProto());
|
JS_ASSERT(!obj->getProto());
|
||||||
|
|
||||||
JSRuntime *rt = cx->runtime;
|
JSRuntime *rt = cx->runtime;
|
||||||
InitXMLQName(obj, rt->emptyString, rt->emptyString,
|
InitXMLQName(obj, rt->emptyString, rt->emptyString, rt->atomState.starAtom);
|
||||||
ATOM_TO_STRING(rt->atomState.starAtom));
|
|
||||||
METER(xml_stats.qname);
|
METER(xml_stats.qname);
|
||||||
|
|
||||||
v.setObject(*obj);
|
v.setObject(*obj);
|
||||||
@ -7385,7 +7407,7 @@ js_FindXMLProperty(JSContext *cx, const Value &nameval, JSObject **objp, jsid *i
|
|||||||
JS_ASSERT(nameval.isObject());
|
JS_ASSERT(nameval.isObject());
|
||||||
nameobj = &nameval.toObject();
|
nameobj = &nameval.toObject();
|
||||||
if (nameobj->getClass() == &js_AnyNameClass) {
|
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,
|
nameobj = js_ConstructObject(cx, &js_QNameClass, NULL, NULL, 1,
|
||||||
Valueify(&v));
|
Valueify(&v));
|
||||||
if (!nameobj)
|
if (!nameobj)
|
||||||
|
@ -1412,11 +1412,7 @@ mjit::Compiler::generateMethod()
|
|||||||
END_CASE(JSOP_DOUBLE)
|
END_CASE(JSOP_DOUBLE)
|
||||||
|
|
||||||
BEGIN_CASE(JSOP_STRING)
|
BEGIN_CASE(JSOP_STRING)
|
||||||
{
|
frame.push(StringValue(script->getAtom(fullAtomIndex(PC))));
|
||||||
JSAtom *atom = script->getAtom(fullAtomIndex(PC));
|
|
||||||
JSString *str = ATOM_TO_STRING(atom);
|
|
||||||
frame.push(Value(StringValue(str)));
|
|
||||||
}
|
|
||||||
END_CASE(JSOP_STRING)
|
END_CASE(JSOP_STRING)
|
||||||
|
|
||||||
BEGIN_CASE(JSOP_ZERO)
|
BEGIN_CASE(JSOP_ZERO)
|
||||||
|
@ -851,7 +851,7 @@ mjit::Compiler::jsop_typeof()
|
|||||||
|
|
||||||
if (atom) {
|
if (atom) {
|
||||||
frame.pop();
|
frame.pop();
|
||||||
frame.push(StringValue(ATOM_TO_STRING(atom)));
|
frame.push(StringValue(atom));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1851,7 +1851,7 @@ ic::CallProp(VMFrame &f, ic::PICInfo *pic)
|
|||||||
|
|
||||||
#if JS_HAS_NO_SUCH_METHOD
|
#if JS_HAS_NO_SUCH_METHOD
|
||||||
if (JS_UNLIKELY(rval.isUndefined()) && regs.sp[-1].isObject()) {
|
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))
|
if (!js_OnUnknownMethod(cx, regs.sp - 2))
|
||||||
THROW();
|
THROW();
|
||||||
}
|
}
|
||||||
@ -2131,7 +2131,7 @@ GetElementIC::attachGetProp(JSContext *cx, JSObject *obj, const Value &v, jsid i
|
|||||||
|
|
||||||
CodeLocationLabel cs = buffer.finalize();
|
CodeLocationLabel cs = buffer.finalize();
|
||||||
#if DEBUG
|
#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",
|
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(),
|
js_CodeName[op], cs.executableAddress(), id, chars, holder->shape(),
|
||||||
cx->fp()->script()->filename, js_FramePCToLineNumber(cx, cx->fp()));
|
cx->fp()->script()->filename, js_FramePCToLineNumber(cx, cx->fp()));
|
||||||
|
@ -419,7 +419,7 @@ stubs::GetElem(VMFrame &f)
|
|||||||
JSString *str = lref.toString();
|
JSString *str = lref.toString();
|
||||||
int32_t i = rref.toInt32();
|
int32_t i = rref.toInt32();
|
||||||
if ((size_t)i < str->length()) {
|
if ((size_t)i < str->length()) {
|
||||||
str = JSString::getUnitString(cx, str, (size_t)i);
|
str = JSAtom::getUnitStringForElement(cx, str, (size_t)i);
|
||||||
if (!str)
|
if (!str)
|
||||||
THROW();
|
THROW();
|
||||||
f.regs.sp[-2].setString(str);
|
f.regs.sp[-2].setString(str);
|
||||||
@ -2002,7 +2002,7 @@ stubs::CallProp(VMFrame &f, JSAtom *origAtom)
|
|||||||
}
|
}
|
||||||
#if JS_HAS_NO_SUCH_METHOD
|
#if JS_HAS_NO_SUCH_METHOD
|
||||||
if (JS_UNLIKELY(rval.isUndefined()) && regs.sp[-1].isObject()) {
|
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))
|
if (!js_OnUnknownMethod(cx, regs.sp - 2))
|
||||||
THROW();
|
THROW();
|
||||||
}
|
}
|
||||||
@ -2173,7 +2173,7 @@ stubs::TypeOf(VMFrame &f)
|
|||||||
const Value &ref = f.regs.sp[-1];
|
const Value &ref = f.regs.sp[-1];
|
||||||
JSType type = JS_TypeOfValue(f.cx, Jsvalify(ref));
|
JSType type = JS_TypeOfValue(f.cx, Jsvalify(ref));
|
||||||
JSAtom *atom = f.cx->runtime->atomState.typeAtoms[type];
|
JSAtom *atom = f.cx->runtime->atomState.typeAtoms[type];
|
||||||
return ATOM_TO_STRING(atom);
|
return atom;
|
||||||
}
|
}
|
||||||
|
|
||||||
void JS_FASTCALL
|
void JS_FASTCALL
|
||||||
@ -2376,7 +2376,7 @@ stubs::LookupSwitch(VMFrame &f, jsbytecode *pc)
|
|||||||
Value rval = script->getConst(GET_INDEX(pc));
|
Value rval = script->getConst(GET_INDEX(pc));
|
||||||
pc += INDEX_LEN;
|
pc += INDEX_LEN;
|
||||||
if (rval.isString()) {
|
if (rval.isString()) {
|
||||||
JSLinearString *rhs = rval.toString()->assertIsLinear();
|
JSLinearString *rhs = &rval.toString()->asLinear();
|
||||||
if (rhs == str || EqualStrings(str, rhs)) {
|
if (rhs == str || EqualStrings(str, rhs)) {
|
||||||
void* native = script->nativeCodeForPC(ctor,
|
void* native = script->nativeCodeForPC(ctor,
|
||||||
jpc + GET_JUMP_OFFSET(pc));
|
jpc + GET_JUMP_OFFSET(pc));
|
||||||
|
@ -2058,9 +2058,8 @@ SrcNotes(JSContext *cx, JSScript *script)
|
|||||||
case SRC_CONT2LABEL:
|
case SRC_CONT2LABEL:
|
||||||
index = js_GetSrcNoteOffset(sn, 0);
|
index = js_GetSrcNoteOffset(sn, 0);
|
||||||
JS_GET_SCRIPT_ATOM(script, NULL, index, atom);
|
JS_GET_SCRIPT_ATOM(script, NULL, index, atom);
|
||||||
str = ATOM_TO_STRING(atom);
|
|
||||||
fprintf(gOutFile, " atom %u (", index);
|
fprintf(gOutFile, " atom %u (", index);
|
||||||
JS_FileEscapedString(gOutFile, str, 0);
|
JS_FileEscapedString(gOutFile, atom, 0);
|
||||||
putc(')', gOutFile);
|
putc(')', gOutFile);
|
||||||
break;
|
break;
|
||||||
case SRC_FUNCDEF: {
|
case SRC_FUNCDEF: {
|
||||||
@ -4815,7 +4814,7 @@ Help(JSContext *cx, uintN argc, jsval *vp)
|
|||||||
type = JS_TypeOfValue(cx, argv[i]);
|
type = JS_TypeOfValue(cx, argv[i]);
|
||||||
if (type == JSTYPE_FUNCTION) {
|
if (type == JSTYPE_FUNCTION) {
|
||||||
fun = JS_ValueToFunction(cx, argv[i]);
|
fun = JS_ValueToFunction(cx, argv[i]);
|
||||||
str = fun->atom ? ATOM_TO_STRING(fun->atom) : NULL;
|
str = fun->atom;
|
||||||
} else if (type == JSTYPE_STRING) {
|
} else if (type == JSTYPE_STRING) {
|
||||||
str = JSVAL_TO_STRING(argv[i]);
|
str = JSVAL_TO_STRING(argv[i]);
|
||||||
} else {
|
} else {
|
||||||
@ -5314,7 +5313,7 @@ Exec(JSContext *cx, uintN argc, jsval *vp)
|
|||||||
nargv[0] = name;
|
nargv[0] = name;
|
||||||
jsval *argv = JS_ARGV(cx, vp);
|
jsval *argv = JS_ARGV(cx, vp);
|
||||||
for (i = 0; i < nargc; i++) {
|
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) {
|
if (!str) {
|
||||||
ok = false;
|
ok = false;
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -248,9 +248,9 @@ couldBeObjectOrString(LIns *ins)
|
|||||||
#endif
|
#endif
|
||||||
} else if (ins->isop(LIR_addp) &&
|
} else if (ins->isop(LIR_addp) &&
|
||||||
((ins->oprnd1()->isImmP() &&
|
((ins->oprnd1()->isImmP() &&
|
||||||
(void *)ins->oprnd1()->immP() == JSString::unitStringTable) ||
|
(void *)ins->oprnd1()->immP() == JSAtom::unitStaticTable) ||
|
||||||
(ins->oprnd2()->isImmP() &&
|
(ins->oprnd2()->isImmP() &&
|
||||||
(void *)ins->oprnd2()->immP() == JSString::unitStringTable)))
|
(void *)ins->oprnd2()->immP() == JSAtom::unitStaticTable)))
|
||||||
{
|
{
|
||||||
// (String only)
|
// (String only)
|
||||||
// ins = addp ..., JSString::unitStringTable
|
// ins = addp ..., JSString::unitStringTable
|
||||||
|
@ -90,7 +90,7 @@ XPCStringConvert::ReadableToJSVal(JSContext *cx,
|
|||||||
JSAtom *atom;
|
JSAtom *atom;
|
||||||
if (length == 0 && (atom = cx->runtime->atomState.emptyAtom))
|
if (length == 0 && (atom = cx->runtime->atomState.emptyAtom))
|
||||||
{
|
{
|
||||||
return ATOM_TO_JSVAL(atom);
|
return STRING_TO_JSVAL(atom);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsStringBuffer *buf = nsStringBuffer::FromString(readable);
|
nsStringBuffer *buf = nsStringBuffer::FromString(readable);
|
||||||
|
Loading…
Reference in New Issue
Block a user