From 9054b3e0fb93496997d9afaaa4626dda1d69635d Mon Sep 17 00:00:00 2001 From: "rogerl%netscape.com" Date: Mon, 9 Jun 2003 00:59:12 +0000 Subject: [PATCH] Switched to StringAtom throughout --- js2/src/epimetheus.cpp | 28 ++-- js2/src/js2array.cpp | 174 ++++++++++------------ js2/src/js2engine.cpp | 82 ++++++----- js2/src/js2engine.h | 34 +++-- js2/src/js2error.cpp | 14 +- js2/src/js2eval.cpp | 68 +++++---- js2/src/js2function.cpp | 8 +- js2/src/js2math.cpp | 4 +- js2/src/js2metadata.cpp | 276 ++++++++++++++++++----------------- js2/src/js2metadata.h | 93 ++++++------ js2/src/js2number.cpp | 2 +- js2/src/js2op_invocation.cpp | 8 +- js2/src/js2op_literal.cpp | 4 +- js2/src/js2regexp.cpp | 58 ++++---- js2/src/js2string.cpp | 20 +-- js2/src/world.cpp | 1 - js2/src/world.h | 2 + 17 files changed, 434 insertions(+), 442 deletions(-) diff --git a/js2/src/epimetheus.cpp b/js2/src/epimetheus.cpp index 10a50b87470..5813ce64332 100644 --- a/js2/src/epimetheus.cpp +++ b/js2/src/epimetheus.cpp @@ -257,7 +257,7 @@ void printLocalBindings(LocalBindingMap *lMap, ValueList *frameSlots) LocalBindingEntry *lbe = *bi; for (LocalBindingEntry::NS_Iterator i = lbe->begin(), end = lbe->end(); (i != end); i++) { LocalBindingEntry::NamespaceBinding ns = *i; - stdOut << "\t" << *(ns.first->name) << "::" << lbe->name; + stdOut << "\t" << ns.first->name << "::" << lbe->name; LocalMember *m = checked_cast(ns.second->content); switch (m->memberKind) { case Member::ForbiddenMember: @@ -268,13 +268,13 @@ void printLocalBindings(LocalBindingMap *lMap, ValueList *frameSlots) case Member::GetterMember: { Getter *g = checked_cast(m); - stdOut << " get" << ":" << *g->type->name << "\n"; + stdOut << " get" << ":" << g->type->name << "\n"; } break; case Member::SetterMember: { Setter *s = checked_cast(m); - stdOut << " set" << ":" << *s->type->name << "\n"; + stdOut << " set" << ":" << s->type->name << "\n"; } break; case Member::DynamicVariableMember: @@ -296,7 +296,7 @@ void printLocalBindings(LocalBindingMap *lMap, ValueList *frameSlots) case Member::VariableMember: { Variable *v = checked_cast(m); - stdOut << ":" << *v->type->name; + stdOut << ":" << v->type->name; accessAccess(ns.second->accesses); stdOut << ((v->immutable) ? "immutable " : "non-immutable "); stdOut << *metadata->toString(v->value) << "\n"; @@ -318,7 +318,7 @@ void printInstanceVariables(JS2Class *c, Slot *slots) InstanceBindingEntry::NamespaceBinding ns = *i; if (ns.second->content->memberKind == Member::InstanceVariableMember) { InstanceVariable *iv = checked_cast(ns.second->content); - stdOut << "\t" << *(ns.first->name) << "::" << ibe->name << ":" << *iv->type->name; + stdOut << "\t" << ns.first->name << "::" << ibe->name << ":" << iv->type->name; accessAccess(ns.second->accesses); stdOut << *metadata->toString(slots[iv->slotIndex].value) << "\n"; } @@ -347,7 +347,7 @@ js2val dump(JS2Metadata *meta, const js2val /* thisValue */, js2val argv[], uint else stdOut << "super = " << *metadata->toString(s->super) << '\n'; stdOut << ((s->sealed) ? "sealed " : "not-sealed ") << '\n'; - stdOut << "type = " << *s->type->name << '\n'; + stdOut << "type = " << s->type->name << '\n'; printLocalBindings(&s->localBindings, NULL); stdOut << " Instance Bindings:\n"; printInstanceVariables(s->type, s->fixedSlots); @@ -364,9 +364,9 @@ js2val dump(JS2Metadata *meta, const js2val /* thisValue */, js2val argv[], uint case ClassKind: { JS2Class *c = checked_cast(fObj); - stdOut << "class " << *c->name; + stdOut << "class " << c->name; if (c->super) - stdOut << " extends " << *c->super->name; + stdOut << " extends " << c->super->name; stdOut << "\n"; stdOut << ((c->dynamic) ? " dynamic, " : " non-dynamic, ") << ((c->final) ? "final" : "non-final") << "\n"; stdOut << " slotCount = " << c->slotCount << "\n"; @@ -380,7 +380,7 @@ js2val dump(JS2Metadata *meta, const js2val /* thisValue */, js2val argv[], uint case Member::InstanceVariableMember: { InstanceVariable *iv = checked_cast(ns.second->content); - stdOut << "\tVariable " << *(ns.first->name) << "::" << ibe->name << ":" << *iv->type->name; + stdOut << "\tVariable " << ns.first->name << "::" << ibe->name << ":" << iv->type->name; accessAccess(ns.second->accesses); stdOut << ((iv->immutable) ? " immutable, " : " non-immutable, ") << ((iv->final) ? "final, " : "non-final, ") << ((iv->enumerable) ? "enumerable, " : "non-enumerable, ") ; stdOut << "slot:" << iv->slotIndex << ", defaultValue:" << *metadata->toString(iv->defaultValue) << "\n"; @@ -389,7 +389,7 @@ js2val dump(JS2Metadata *meta, const js2val /* thisValue */, js2val argv[], uint case Member::InstanceMethodMember: { InstanceMethod *im = checked_cast(ns.second->content); - stdOut << "\tMethod " << *(ns.first->name) << "::" << ibe->name; // XXX << *iv->type; the signature + stdOut << "\tMethod " << ns.first->name << "::" << ibe->name; // XXX << *iv->type; the signature accessAccess(ns.second->accesses); stdOut << ((im->final) ? "final, " : "non-final, ") << ((im->enumerable) ? "enumerable, " : "non-enumerable, ") ; printFormat(stdOut, "function = 0x%08X\n", im->fInst); @@ -398,15 +398,15 @@ js2val dump(JS2Metadata *meta, const js2val /* thisValue */, js2val argv[], uint case Member::InstanceGetterMember: { InstanceGetter *g = checked_cast(ns.second->content); - stdOut << "\t" << *(ns.first->name) << "::" << ibe->name; - stdOut << " get" << ":" << *g->type->name << "\n"; + stdOut << "\t" << ns.first->name << "::" << ibe->name; + stdOut << " get" << ":" << g->type->name << "\n"; } break; case Member::InstanceSetterMember: { InstanceSetter *s = checked_cast(ns.second->content); - stdOut << "\t" << *(ns.first->name) << "::" << ibe->name; - stdOut << " set" << ":" << *s->type->name << "\n"; + stdOut << "\t" << ns.first->name << "::" << ibe->name; + stdOut << " set" << ":" << s->type->name << "\n"; } break; } diff --git a/js2/src/js2array.cpp b/js2/src/js2array.cpp index 79217d498e5..994f5ad9c5c 100644 --- a/js2/src/js2array.cpp +++ b/js2/src/js2array.cpp @@ -102,14 +102,14 @@ js2val Array_Constructor(JS2Metadata *meta, const js2val /*thisValue*/, js2val * meta->reportError(Exception::rangeError, "Array length too large", meta->engine->errorPos()); } else { - meta->createDynamicProperty(arrInst, meta->engine->numberToString((int32)0), argv[0], ReadWriteAccess, false, true); + meta->createDynamicProperty(arrInst, meta->engine->numberToStringAtom((int32)0), argv[0], ReadWriteAccess, false, true); setLength(meta, arrInst, 1); } } else { uint32 i; for (i = 0; i < argc; i++) { - meta->createDynamicProperty(arrInst, meta->engine->numberToString(i), argv[i], ReadWriteAccess, false, true); + meta->createDynamicProperty(arrInst, meta->engine->numberToStringAtom(i), argv[i], ReadWriteAccess, false, true); } setLength(meta, arrInst, i); } @@ -143,7 +143,7 @@ static js2val Array_toString(JS2Metadata *meta, const js2val thisValue, js2val * else s = new String(); for (uint32 i = 0; i < length; i++) { - if (meta->arrayClass->ReadPublic(meta, &thatValue, meta->engine->numberToString(i), RunPhase, &result) + if (meta->arrayClass->ReadPublic(meta, &thatValue, meta->engine->numberToStringAtom(i), RunPhase, &result) && !JS2VAL_IS_UNDEFINED(result) && !JS2VAL_IS_NULL(result) ) s->append(*meta->toString(result)); @@ -179,7 +179,7 @@ static js2val Array_toSource(JS2Metadata *meta, const js2val thisValue, js2val * js2val result; String *s = new String(widenCString("[")); for (uint32 i = 0; i < length; i++) { - if (meta->arrayClass->ReadPublic(meta, &thatValue, meta->engine->numberToString(i), RunPhase, &result) + if (meta->arrayClass->ReadPublic(meta, &thatValue, meta->engine->numberToStringAtom(i), RunPhase, &result) && !JS2VAL_IS_UNDEFINED(result)) s->append(*meta->toString(result)); if (i < (length - 1)) @@ -201,7 +201,7 @@ static js2val Array_push(JS2Metadata *meta, const js2val thisValue, js2val *argv JS2Class *c = meta->objectType(thisObj); for (uint32 i = 0; i < argc; i++) { - c->WritePublic(meta, thisValue, meta->engine->numberToString(i + length), true, argv[i]); + c->WritePublic(meta, thisValue, meta->engine->numberToStringAtom(i + length), true, argv[i]); } return setLength(meta, thisObj, length + argc); } @@ -217,8 +217,8 @@ static js2val Array_pop(JS2Metadata *meta, const js2val thisValue, js2val * /*ar js2val result = JS2VAL_UNDEFINED; bool deleteResult; JS2Class *c = meta->objectType(thisObj); - c->ReadPublic(meta, &thatValue, meta->engine->numberToString(length - 1), RunPhase, &result); - c->DeletePublic(meta, thatValue, meta->engine->numberToString(length - 1), &deleteResult); + c->ReadPublic(meta, &thatValue, meta->engine->numberToStringAtom(length - 1), RunPhase, &result); + c->DeletePublic(meta, thatValue, meta->engine->numberToStringAtom(length - 1), &deleteResult); setLength(meta, thisObj, length - 1); return result; } @@ -238,7 +238,7 @@ js2val Array_concat(JS2Metadata *meta, const js2val thisValue, js2val *argv, uin do { if (meta->objectType(E) != meta->arrayClass) { - meta->arrayClass->WritePublic(meta, result, meta->engine->numberToString(n++), true, E); + meta->arrayClass->WritePublic(meta, result, meta->engine->numberToStringAtom(n++), true, E); } else { ASSERT(JS2VAL_IS_OBJECT(thisValue)); @@ -247,8 +247,8 @@ js2val Array_concat(JS2Metadata *meta, const js2val thisValue, js2val *argv, uin JS2Class *c = meta->objectType(arrObj); for (uint32 k = 0; k < length; k++) { js2val rval = JS2VAL_UNDEFINED; - c->ReadPublic(meta, &E, meta->engine->numberToString(k), RunPhase, &rval); - meta->arrayClass->WritePublic(meta, result, meta->engine->numberToString(n++), true, rval); + c->ReadPublic(meta, &E, meta->engine->numberToStringAtom(k), RunPhase, &rval); + meta->arrayClass->WritePublic(meta, result, meta->engine->numberToStringAtom(n++), true, rval); } } E = argv[i++]; @@ -276,7 +276,7 @@ static js2val Array_join(JS2Metadata *meta, const js2val thisValue, js2val *argv for (uint32 k = 0; k < length; k++) { js2val result = JS2VAL_UNDEFINED; - c->ReadPublic(meta, &thatValue, meta->engine->numberToString(k), RunPhase, &result); + c->ReadPublic(meta, &thatValue, meta->engine->numberToStringAtom(k), RunPhase, &result); if (!JS2VAL_IS_UNDEFINED(result) && !JS2VAL_IS_NULL(result)) *S += *meta->toString(result); @@ -297,41 +297,35 @@ static js2val Array_reverse(JS2Metadata *meta, const js2val thisValue, js2val * JS2Class *c = meta->objectType(thisObj); - // XXX Need to root the Strings somewhere, this'll do for now.. - Multiname *mn1 = new (meta) Multiname(meta->publicNamespace); - Multiname *mn2 = new (meta) Multiname(meta->publicNamespace); - DEFINE_ROOTKEEPER(meta, rk1, mn1); - DEFINE_ROOTKEEPER(meta, rk2, mn2); - for (uint32 k = 0; k < halfway; k++) { bool deleteResult; js2val result1 = JS2VAL_UNDEFINED; js2val result2 = JS2VAL_UNDEFINED; - mn1->name = meta->engine->numberToString(k); - mn2->name = meta->engine->numberToString(length - k - 1); + const StringAtom &nm1 = meta->engine->numberToStringAtom(k); + const StringAtom &nm2 = meta->engine->numberToStringAtom(length - k - 1); - if (meta->hasOwnProperty(thisObj, mn1->name)) { - if (meta->hasOwnProperty(thisObj, mn2->name)) { - c->ReadPublic(meta, &thatValue, mn1->name, RunPhase, &result1); - c->ReadPublic(meta, &thatValue, mn2->name, RunPhase, &result2); - c->WritePublic(meta, thatValue, mn1->name, true, result2); - c->WritePublic(meta, thatValue, mn2->name, true, result1); + if (meta->hasOwnProperty(thisObj, nm1)) { + if (meta->hasOwnProperty(thisObj, nm2)) { + c->ReadPublic(meta, &thatValue, nm1, RunPhase, &result1); + c->ReadPublic(meta, &thatValue, nm2, RunPhase, &result2); + c->WritePublic(meta, thatValue, nm1, true, result2); + c->WritePublic(meta, thatValue, nm2, true, result1); } else { - c->ReadPublic(meta, &thatValue, mn1->name, RunPhase, &result1); - c->WritePublic(meta, thatValue, mn2->name, true, result1); - c->DeletePublic(meta, thatValue, mn1->name, &deleteResult); + c->ReadPublic(meta, &thatValue, nm1, RunPhase, &result1); + c->WritePublic(meta, thatValue, nm2, true, result1); + c->DeletePublic(meta, thatValue, nm1, &deleteResult); } } else { - if (meta->hasOwnProperty(thisObj, mn2->name)) { - c->ReadPublic(meta, &thatValue, mn2->name, RunPhase, &result2); - c->WritePublic(meta, thatValue, mn1->name, true, result2); - c->DeletePublic(meta, thatValue, mn2->name, &deleteResult); + if (meta->hasOwnProperty(thisObj, nm2)) { + c->ReadPublic(meta, &thatValue, nm2, RunPhase, &result2); + c->WritePublic(meta, thatValue, nm1, true, result2); + c->DeletePublic(meta, thatValue, nm2, &deleteResult); } else { - c->DeletePublic(meta, thatValue, mn1->name, &deleteResult); - c->DeletePublic(meta, thatValue, mn2->name, &deleteResult); + c->DeletePublic(meta, thatValue, nm1, &deleteResult); + c->DeletePublic(meta, thatValue, nm2, &deleteResult); } } } @@ -352,31 +346,26 @@ static js2val Array_shift(JS2Metadata *meta, const js2val thisValue, js2val * /* } JS2Class *c = meta->objectType(thisObj); - // XXX Need to root the Strings somewhere, this'll do for now.. - Multiname *mn1 = new (meta) Multiname(meta->publicNamespace); - Multiname *mn2 = new (meta) Multiname(meta->publicNamespace); - DEFINE_ROOTKEEPER(meta, rk1, mn1); - DEFINE_ROOTKEEPER(meta, rk2, mn2); js2val result; bool deleteResult; - mn1->name = meta->engine->numberToString((int32)0); - c->ReadPublic(meta, &thatValue, mn1->name, RunPhase, &result); + const StringAtom &nm1 = meta->engine->numberToStringAtom((int32)0); + c->ReadPublic(meta, &thatValue, nm1, RunPhase, &result); for (uint32 k = 1; k < length; k++) { - mn1->name = meta->engine->numberToString(k); - mn2->name = meta->engine->numberToString(k - 1); + const StringAtom &nm1 = meta->engine->numberToStringAtom(k); + const StringAtom &nm2 = meta->engine->numberToStringAtom(k - 1); - if (meta->hasOwnProperty(thisObj, mn1->name)) { - c->ReadPublic(meta, &thatValue, mn1->name, RunPhase, &result); - c->WritePublic(meta, thatValue, mn2->name, true, result); + if (meta->hasOwnProperty(thisObj, nm1)) { + c->ReadPublic(meta, &thatValue, nm1, RunPhase, &result); + c->WritePublic(meta, thatValue, nm2, true, result); } else - c->DeletePublic(meta, thatValue, mn2->name, &deleteResult); + c->DeletePublic(meta, thatValue, nm2, &deleteResult); } - mn2->name = meta->engine->numberToString(length - 1); - c->DeletePublic(meta, thatValue, mn2->name, &deleteResult); + const StringAtom &nm2 = meta->engine->numberToStringAtom(length - 1); + c->DeletePublic(meta, thatValue, nm2, &deleteResult); setLength(meta, thisObj, length - 1); return result; } @@ -433,19 +422,14 @@ static js2val Array_slice(JS2Metadata *meta, const js2val thisValue, js2val *arg } JS2Class *c = meta->objectType(thisObj); - // XXX Need to root the Strings somewhere, this'll do for now.. - Multiname *mn1 = new (meta) Multiname(meta->publicNamespace); - Multiname *mn2 = new (meta) Multiname(meta->publicNamespace); - DEFINE_ROOTKEEPER(meta, rk1, mn1); - DEFINE_ROOTKEEPER(meta, rk2, mn2); uint32 n = 0; while (start < end) { - mn1->name = meta->engine->numberToString(start); - if (meta->hasOwnProperty(thisObj, mn1->name)) { + const StringAtom &nm1 = meta->engine->numberToStringAtom(start); + if (meta->hasOwnProperty(thisObj, nm1)) { js2val rval; - mn2->name = meta->engine->numberToString(n); - c->ReadPublic(meta, &thatValue, mn1->name, RunPhase, &rval); - meta->arrayClass->WritePublic(meta, result, mn2->name, true, rval); + const StringAtom &nm2 = meta->engine->numberToStringAtom(n); + c->ReadPublic(meta, &thatValue, nm1, RunPhase, &rval); + meta->arrayClass->WritePublic(meta, result, nm2, true, rval); } n++; start++; @@ -600,13 +584,13 @@ static js2val Array_sort(JS2Metadata *meta, const js2val thisValue, js2val *argv JS2Class *c = meta->objectType(thisObj); for (i = 0; i < length; i++) { - c->ReadPublic(meta, &thatValue, meta->engine->numberToString(i), RunPhase, &vec[i]); + c->ReadPublic(meta, &thatValue, meta->engine->numberToStringAtom(i), RunPhase, &vec[i]); } js_qsort(vec, length, &ca); for (i = 0; i < length; i++) { - c->WritePublic(meta, thatValue, meta->engine->numberToString(i), true, vec[i]); + c->WritePublic(meta, thatValue, meta->engine->numberToStringAtom(i), true, vec[i]); } return thatValue; } @@ -652,19 +636,14 @@ static js2val Array_splice(JS2Metadata *meta, const js2val thisValue, js2val *ar deleteCount = toUInt32(arg1); JS2Class *c = meta->objectType(thisObj); - // XXX Need to root the Strings somewhere, this'll do for now.. - Multiname *mn1 = new (meta) Multiname(meta->publicNamespace); - Multiname *mn2 = new (meta) Multiname(meta->publicNamespace); - DEFINE_ROOTKEEPER(meta, rk1, mn1); - DEFINE_ROOTKEEPER(meta, rk2, mn2); for (k = 0; k < deleteCount; k++) { - mn1->name = meta->engine->numberToString(start + k); - if (meta->hasOwnProperty(thisObj, mn1->name)) { + const StringAtom &nm1 = meta->engine->numberToStringAtom(start + k); + if (meta->hasOwnProperty(thisObj, nm1)) { js2val rval; - mn2->name = meta->engine->numberToString(k); - c->ReadPublic(meta, &thatValue, mn1->name, RunPhase, &rval); - meta->arrayClass->WritePublic(meta, result, mn2->name, true, rval); + const StringAtom &nm2 = meta->engine->numberToStringAtom(k); + c->ReadPublic(meta, &thatValue, nm1, RunPhase, &rval); + meta->arrayClass->WritePublic(meta, result, nm2, true, rval); } } setLength(meta, A, deleteCount); @@ -673,41 +652,41 @@ static js2val Array_splice(JS2Metadata *meta, const js2val thisValue, js2val *ar if (newItemCount < deleteCount) { bool deleteResult; for (k = start; k < (length - deleteCount); k++) { - mn1->name = meta->engine->numberToString(k + deleteCount); - mn2->name = meta->engine->numberToString(k + newItemCount); - if (meta->hasOwnProperty(thisObj, mn1->name)) { + const StringAtom &nm1 = meta->engine->numberToStringAtom(k + deleteCount); + const StringAtom &nm2 = meta->engine->numberToStringAtom(k + newItemCount); + if (meta->hasOwnProperty(thisObj, nm1)) { js2val rval; - c->ReadPublic(meta, &thatValue, mn1->name, RunPhase, &rval); - meta->arrayClass->WritePublic(meta, result, mn2->name, true, rval); + c->ReadPublic(meta, &thatValue, nm1, RunPhase, &rval); + meta->arrayClass->WritePublic(meta, result, nm2, true, rval); } else - c->DeletePublic(meta, thatValue, mn2->name, &deleteResult); + c->DeletePublic(meta, thatValue, nm2, &deleteResult); } for (k = length; k > (length - deleteCount + newItemCount); k--) { - mn1->name = meta->engine->numberToString(k - 1); - c->DeletePublic(meta, thatValue, mn1->name, &deleteResult); + const StringAtom &nm1 = meta->engine->numberToStringAtom(k - 1); + c->DeletePublic(meta, thatValue, nm1, &deleteResult); } } else { if (newItemCount > deleteCount) { for (k = length - deleteCount; k > start; k--) { bool deleteResult; - mn1->name = meta->engine->numberToString(k + deleteCount - 1); - mn2->name = meta->engine->numberToString(k + newItemCount - 1); - if (meta->hasOwnProperty(thisObj, mn1->name)) { + const StringAtom &nm1 = meta->engine->numberToStringAtom(k + deleteCount - 1); + const StringAtom &nm2 = meta->engine->numberToStringAtom(k + newItemCount - 1); + if (meta->hasOwnProperty(thisObj, nm1)) { js2val rval; - c->ReadPublic(meta, &thatValue, mn1->name, RunPhase, &rval); - meta->arrayClass->WritePublic(meta, result, mn2->name, true, rval); + c->ReadPublic(meta, &thatValue, nm1, RunPhase, &rval); + meta->arrayClass->WritePublic(meta, result, nm2, true, rval); } else - c->DeletePublic(meta, thatValue, mn2->name, &deleteResult); + c->DeletePublic(meta, thatValue, nm2, &deleteResult); } } } k = start; for (uint32 i = 2; i < argc; i++) { - mn2->name = meta->engine->numberToString(k++); - meta->arrayClass->WritePublic(meta, result, mn2->name, true, argv[i]); + const StringAtom &nm2 = meta->engine->numberToStringAtom(k++); + meta->arrayClass->WritePublic(meta, result, nm2, true, argv[i]); } setLength(meta, thisObj, (length - deleteCount + newItemCount)); return result; @@ -725,28 +704,23 @@ static js2val Array_unshift(JS2Metadata *meta, const js2val thisValue, js2val *a uint32 k; JS2Class *c = meta->objectType(thisObj); - // XXX Need to root the Strings somewhere, this'll do for now.. - Multiname *mn1 = new (meta) Multiname(meta->publicNamespace); - Multiname *mn2 = new (meta) Multiname(meta->publicNamespace); - DEFINE_ROOTKEEPER(meta, rk1, mn1); - DEFINE_ROOTKEEPER(meta, rk2, mn2); for (k = length; k > 0; k--) { bool deleteResult; - mn1->name = meta->engine->numberToString(k - 1); - mn2->name = meta->engine->numberToString(k + argc - 1); - if (meta->hasOwnProperty(thisObj, mn1->name)) { + const StringAtom &nm1 = meta->engine->numberToStringAtom(k - 1); + const StringAtom &nm2 = meta->engine->numberToStringAtom(k + argc - 1); + if (meta->hasOwnProperty(thisObj, nm1)) { js2val rval; - c->ReadPublic(meta, &thatValue, mn1->name, RunPhase, &rval); - c->WritePublic(meta, thatValue, mn2->name, true, rval); + c->ReadPublic(meta, &thatValue, nm1, RunPhase, &rval); + c->WritePublic(meta, thatValue, nm2, true, rval); } else - c->DeletePublic(meta, thatValue, mn2->name, &deleteResult); + c->DeletePublic(meta, thatValue, nm2, &deleteResult); } for (k = 0; k < argc; k++) { - mn1->name = meta->engine->numberToString(k); - c->WritePublic(meta, thatValue, mn1->name, true, argv[k]); + const StringAtom &nm1 = meta->engine->numberToStringAtom(k); + c->WritePublic(meta, thatValue, nm1, true, argv[k]); } setLength(meta, thisObj, (length + argc)); diff --git a/js2/src/js2engine.cpp b/js2/src/js2engine.cpp index 5f804ab7f04..df13b534a50 100644 --- a/js2/src/js2engine.cpp +++ b/js2/src/js2engine.cpp @@ -344,6 +344,30 @@ namespace MetaData { return allocStringPtr(chrp); } + // Convert an integer to a stringAtom + StringAtom &JS2Engine::numberToStringAtom(int32 i) + { + char buf[dtosStandardBufferSize]; + const char *chrp = doubleToStr(buf, dtosStandardBufferSize, i, dtosStandard, 0); + return meta->world.identifiers[chrp]; + } + // Convert an integer to a stringAtom + StringAtom &JS2Engine::numberToStringAtom(uint32 i) + { + char buf[dtosStandardBufferSize]; + const char *chrp = doubleToStr(buf, dtosStandardBufferSize, i, dtosStandard, 0); + return meta->world.identifiers[chrp]; + } + + // Convert a double to a stringAtom + StringAtom &JS2Engine::numberToStringAtom(float64 *number) + { + char buf[dtosStandardBufferSize]; + const char *chrp = doubleToStr(buf, dtosStandardBufferSize, *number, dtosStandard, 0); + return meta->world.identifiers[chrp]; + } + + // x is a Number, validate that it has no fractional component int64 JS2Engine::checkInteger(js2val x) { @@ -460,21 +484,21 @@ namespace MetaData { pc(NULL), bCon(NULL), phase(RunPhase), - INIT_STRINGATOM(true), - INIT_STRINGATOM(false), - INIT_STRINGATOM(null), - INIT_STRINGATOM(undefined), - INIT_STRINGATOM(public), - INIT_STRINGATOM(private), - INIT_STRINGATOM(Function), - INIT_STRINGATOM(Object), - INIT_STRINGATOM(object), - Empty_StringAtom(allocStringPtr("")), - Dollar_StringAtom(allocStringPtr("$")), - INIT_STRINGATOM(prototype), - INIT_STRINGATOM(length), - INIT_STRINGATOM(toString), - INIT_STRINGATOM(valueOf), + true_StringAtom(world.identifiers["true"]), + false_StringAtom(world.identifiers["false"]), + null_StringAtom(world.identifiers["null"]), + undefined_StringAtom(world.identifiers["undefined"]), + public_StringAtom(world.identifiers["public"]), + private_StringAtom(world.identifiers["private"]), + Function_StringAtom(world.identifiers["Function"]), + Object_StringAtom(world.identifiers["Object"]), + object_StringAtom(world.identifiers["object"]), + Empty_StringAtom(world.identifiers[""]), + Dollar_StringAtom(world.identifiers["$"]), + prototype_StringAtom(world.identifiers["prototype"]), + length_StringAtom(world.identifiers["length"]), + toString_StringAtom(world.identifiers["toString"]), + valueOf_StringAtom(world.identifiers["valueOf"]), packageFrame(NULL), parameterFrame(NULL), localFrame(NULL), @@ -690,7 +714,7 @@ namespace MetaData { case TYPE_PTR: { JS2Class *c = BytecodeContainer::getType(pc); - stdOut << " " << *c->name; + stdOut << " " << c->name; pc += sizeof(JS2Class *); } break; @@ -704,7 +728,7 @@ namespace MetaData { case NAME_INDEX: { Multiname *mn = bCon->mMultinameList[BytecodeContainer::getShort(pc)]; - stdOut << " " << *mn->name; + stdOut << " " << mn->name; pc += sizeof(short); } break; @@ -1083,22 +1107,6 @@ namespace MetaData { JS2Object::mark(float64Table[i]); } GCMARKVALUE(retval); - - JS2Object::mark(true_StringAtom); - JS2Object::mark(false_StringAtom); - JS2Object::mark(null_StringAtom); - JS2Object::mark(undefined_StringAtom); - JS2Object::mark(public_StringAtom); - JS2Object::mark(private_StringAtom); - JS2Object::mark(Function_StringAtom); - JS2Object::mark(Object_StringAtom); - JS2Object::mark(object_StringAtom); - JS2Object::mark(Empty_StringAtom); - JS2Object::mark(Dollar_StringAtom); - JS2Object::mark(prototype_StringAtom); - JS2Object::mark(length_StringAtom); - JS2Object::mark(toString_StringAtom); - JS2Object::mark(valueOf_StringAtom); } void JS2Engine::pushHandler(uint8 *pc) @@ -1117,7 +1125,7 @@ namespace MetaData { js2val JS2Engine::typeofString(js2val a) { if (JS2VAL_IS_UNDEFINED(a)) - a = STRING_TO_JS2VAL(undefined_StringAtom); + a = allocString(undefined_StringAtom); else if (JS2VAL_IS_BOOLEAN(a)) a = allocString("boolean"); @@ -1130,7 +1138,7 @@ namespace MetaData { else { ASSERT(JS2VAL_IS_OBJECT(a)); if (JS2VAL_IS_NULL(a)) - a = STRING_TO_JS2VAL(object_StringAtom); + a = allocString(object_StringAtom); else { JS2Object *obj = JS2VAL_TO_OBJECT(a); switch (obj->kind) { @@ -1149,11 +1157,11 @@ namespace MetaData { if (checked_cast(obj)->type == meta->functionClass) a = allocString("function"); //STRING_TO_JS2VAL(Function_StringAtom); else - a = STRING_TO_JS2VAL(object_StringAtom); + a = allocString(object_StringAtom); // a = STRING_TO_JS2VAL(checked_cast(obj)->type->getName()); break; case PackageKind: - a = STRING_TO_JS2VAL(object_StringAtom); + a = allocString(object_StringAtom); break; default: ASSERT(false); diff --git a/js2/src/js2engine.h b/js2/src/js2engine.h index a1e0b9ec2d2..af330c4771e 100644 --- a/js2/src/js2engine.h +++ b/js2/src/js2engine.h @@ -255,6 +255,10 @@ public: String *numberToString(int32 i); String *numberToString(uint32 i); + StringAtom &numberToStringAtom(float64 *number); + StringAtom &numberToStringAtom(int32 i); + StringAtom &numberToStringAtom(uint32 i); + js2val allocFloat(float32 x); js2val pushFloat(float32 x) { js2val retval = allocFloat(x); push(retval); return retval; } @@ -278,21 +282,21 @@ public: // Cached StringAtoms for handy access // These are all engine-allocated, so can be used as JS2VAL's - const String *true_StringAtom; - const String *false_StringAtom; - const String *null_StringAtom; - const String *undefined_StringAtom; - const String *public_StringAtom; - const String *private_StringAtom; - const String *Function_StringAtom; - const String *Object_StringAtom; - const String *object_StringAtom; - const String *Empty_StringAtom; - const String *Dollar_StringAtom; - const String *prototype_StringAtom; - const String *length_StringAtom; - const String *toString_StringAtom; - const String *valueOf_StringAtom; + const StringAtom &true_StringAtom; + const StringAtom &false_StringAtom; + const StringAtom &null_StringAtom; + const StringAtom &undefined_StringAtom; + const StringAtom &public_StringAtom; + const StringAtom &private_StringAtom; + const StringAtom &Function_StringAtom; + const StringAtom &Object_StringAtom; + const StringAtom &object_StringAtom; + const StringAtom &Empty_StringAtom; + const StringAtom &Dollar_StringAtom; + const StringAtom &prototype_StringAtom; + const StringAtom &length_StringAtom; + const StringAtom &toString_StringAtom; + const StringAtom &valueOf_StringAtom; // The activation stack, when it's empty and a return is executed, the // interpreter quits diff --git a/js2/src/js2error.cpp b/js2/src/js2error.cpp index 7815ba99e55..d0baa96df14 100644 --- a/js2/src/js2error.cpp +++ b/js2/src/js2error.cpp @@ -67,7 +67,7 @@ js2val error_ConstructorCore(JS2Metadata *meta, JS2Class *errorClass, js2val arg const String *str = NULL; DEFINE_ROOTKEEPER(meta, rk2, str); str = meta->toString(arg); - errorClass->WritePublic(meta, thatValue, &meta->world.identifiers["message"], true, meta->engine->allocString(str)); + errorClass->WritePublic(meta, thatValue, meta->world.identifiers["message"], true, meta->engine->allocString(str)); } return thatValue; @@ -118,9 +118,9 @@ js2val Error_toString(JS2Metadata *meta, const js2val thisValue, js2val *argv, u String s; JS2Class *c = meta->objectType(thatValue); - if (c->ReadPublic(meta, &thatValue, &meta->world.identifiers["name"], RunPhase, &nameVal)) { + if (c->ReadPublic(meta, &thatValue, meta->world.identifiers["name"], RunPhase, &nameVal)) { s = *meta->toString(nameVal); - if (c->ReadPublic(meta, &thatValue, &meta->world.identifiers["message"], RunPhase, &messageVal)) { + if (c->ReadPublic(meta, &thatValue, meta->world.identifiers["message"], RunPhase, &messageVal)) { s += widenCString(":"); s += *meta->toString(messageVal); } @@ -132,8 +132,8 @@ static void initErrorClass(JS2Metadata *meta, JS2Class *c, Constructor *construc { meta->initBuiltinClass(c, NULL, constructor, constructor); c->prototype = OBJECT_TO_JS2VAL(new (meta) SimpleInstance(meta, meta->errorClass->prototype, meta->errorClass)); - meta->createDynamicProperty(JS2VAL_TO_OBJECT(c->prototype), &meta->world.identifiers["name"], meta->engine->allocString(c->name), ReadAccess, true, true); - meta->createDynamicProperty(JS2VAL_TO_OBJECT(c->prototype), &meta->world.identifiers["message"], meta->engine->allocString("Message"), ReadAccess, true, true); + meta->createDynamicProperty(JS2VAL_TO_OBJECT(c->prototype), meta->world.identifiers["name"], meta->engine->allocString(c->name), ReadAccess, true, true); + meta->createDynamicProperty(JS2VAL_TO_OBJECT(c->prototype), meta->world.identifiers["message"], meta->engine->allocString("Message"), ReadAccess, true, true); } void initErrorObject(JS2Metadata *meta) @@ -150,8 +150,8 @@ void initErrorObject(JS2Metadata *meta) meta->initBuiltinClass(meta->errorClass, NULL, Error_Constructor, Error_Constructor); meta->errorClass->prototype = OBJECT_TO_JS2VAL(new (meta) SimpleInstance(meta, meta->objectClass->prototype, meta->errorClass)); - meta->createDynamicProperty(JS2VAL_TO_OBJECT(meta->errorClass->prototype), &meta->world.identifiers["name"], meta->engine->allocString("Error"), ReadAccess, true, true); - meta->createDynamicProperty(JS2VAL_TO_OBJECT(meta->errorClass->prototype), &meta->world.identifiers["message"], meta->engine->allocString("Message"), ReadAccess, true, true); + meta->createDynamicProperty(JS2VAL_TO_OBJECT(meta->errorClass->prototype), meta->world.identifiers["name"], meta->engine->allocString("Error"), ReadAccess, true, true); + meta->createDynamicProperty(JS2VAL_TO_OBJECT(meta->errorClass->prototype), meta->world.identifiers["message"], meta->engine->allocString("Message"), ReadAccess, true, true); meta->initBuiltinClassPrototype(meta->errorClass, errorProtos); diff --git a/js2/src/js2eval.cpp b/js2/src/js2eval.cpp index 64c4d5e77bc..a6c8965ad00 100644 --- a/js2/src/js2eval.cpp +++ b/js2/src/js2eval.cpp @@ -231,7 +231,7 @@ namespace MetaData { // Invoke the named function on the thisValue object (it is an object) // Returns false if no callable function exists. Otherwise return the // function result value. - bool JS2Metadata::invokeFunctionOnObject(js2val thisValue, const String *fnName, js2val &result) + bool JS2Metadata::invokeFunctionOnObject(js2val thisValue, const StringAtom &fnName, js2val &result) { js2val fnVal; @@ -259,7 +259,7 @@ namespace MetaData { CompilationData *oldData = startCompilationUnit(NULL, bCon->mSource, bCon->mSourceLocation); try { - LexicalReference rVal(new (this) Multiname(&world.identifiers[widenCString(fname)]), false); + LexicalReference rVal(new (this) Multiname(world.identifiers[widenCString(fname)]), false); rVal.emitReadForInvokeBytecode(bCon, 0); bCon->emitOp(eCall, 0, -(0 + 2) + 1); // pop argCount args, the base & function, and push a result bCon->addShort(0); @@ -390,11 +390,14 @@ namespace MetaData { const String *JS2Metadata::convertValueToString(js2val x) { if (JS2VAL_IS_UNDEFINED(x)) - return engine->undefined_StringAtom; + return engine->allocStringPtr(&engine->undefined_StringAtom); if (JS2VAL_IS_NULL(x)) - return engine->null_StringAtom; + return engine->allocStringPtr(&engine->null_StringAtom); if (JS2VAL_IS_BOOLEAN(x)) - return (JS2VAL_TO_BOOLEAN(x)) ? engine->true_StringAtom : engine->false_StringAtom; + if (JS2VAL_TO_BOOLEAN(x)) + return engine->allocStringPtr(&engine->true_StringAtom); + else + return engine->allocStringPtr(&engine->false_StringAtom); if (JS2VAL_IS_INT(x)) return engine->numberToString(JS2VAL_TO_INT(x)); if (JS2VAL_IS_LONG(x)) { @@ -712,27 +715,24 @@ namespace MetaData { } } - bool JS2Class::ReadPublic(JS2Metadata *meta, js2val *base, const String *name, Phase phase, js2val *rval) + bool JS2Class::ReadPublic(JS2Metadata *meta, js2val *base, const StringAtom &name, Phase phase, js2val *rval) { // XXX could speed up by pushing knowledge of single namespace? - DEFINE_ROOTKEEPER(meta, rk1, name); Multiname *mn = new (meta) Multiname(name, meta->publicNamespace); DEFINE_ROOTKEEPER(meta, rk, mn); return Read(meta, base, mn, NULL, phase, rval); } - bool JS2Class::DeletePublic(JS2Metadata *meta, js2val base, const String *name, bool *result) + bool JS2Class::DeletePublic(JS2Metadata *meta, js2val base, const StringAtom &name, bool *result) { - DEFINE_ROOTKEEPER(meta, rk1, name); // XXX could speed up by pushing knowledge of single namespace? Multiname *mn = new (meta) Multiname(name, meta->publicNamespace); DEFINE_ROOTKEEPER(meta, rk, mn); return Delete(meta, base, mn, NULL, result); } - bool JS2Class::WritePublic(JS2Metadata *meta, js2val base, const String *name, bool createIfMissing, js2val newValue) + bool JS2Class::WritePublic(JS2Metadata *meta, js2val base, const StringAtom &name, bool createIfMissing, js2val newValue) { - DEFINE_ROOTKEEPER(meta, rk1, name); // XXX could speed up by pushing knowledge of single namespace? Multiname *mn = new (meta) Multiname(name, meta->publicNamespace); DEFINE_ROOTKEEPER(meta, rk, mn); @@ -743,24 +743,24 @@ namespace MetaData { { const String *indexStr = meta->toString(indexVal); DEFINE_ROOTKEEPER(meta, rk, indexStr); - Multiname *mn = new (meta) Multiname(indexStr, meta->publicNamespace); + Multiname *mn = new (meta) Multiname(meta->world.identifiers[*indexStr], meta->publicNamespace); DEFINE_ROOTKEEPER(meta, rk1, mn); return Read(meta, base, mn, NULL, phase, rval); } - bool isValidIndex(const String *name, uint32 &index) + bool isValidIndex(const StringAtom &name, uint32 &index) { const char16 *numEnd; - float64 f = stringToDouble(name->data(), name->data() + name->length(), numEnd); + float64 f = stringToDouble(name.data(), name.data() + name.length(), numEnd); index = JS2Engine::float64toUInt32(f); char buf[dtosStandardBufferSize]; const char *chrp = doubleToStr(buf, dtosStandardBufferSize, index, dtosStandard, 0); - return (widenCString(chrp) == *name); + return (widenCString(chrp) == name); } bool JS2ArrayClass::Read(JS2Metadata *meta, js2val *base, Multiname *multiname, Environment *env, Phase phase, js2val *rval) { - if ((*multiname->name == *meta->engine->length_StringAtom) && (multiname->nsList->size() == 1) && (multiname->nsList->back() == meta->publicNamespace)) { + if ((multiname->name == meta->engine->length_StringAtom) && (multiname->nsList->size() == 1) && (multiname->nsList->back() == meta->publicNamespace)) { *rval = Array_lengthGet(meta, *base, NULL, 0); return true; } @@ -774,7 +774,7 @@ namespace MetaData { JS2Object *obj = JS2VAL_TO_OBJECT(base); bool result; - if ((*multiname->name == *meta->engine->length_StringAtom) && (multiname->nsList->size() == 1) && (multiname->nsList->back() == meta->publicNamespace)) { + if ((multiname->name == meta->engine->length_StringAtom) && (multiname->nsList->size() == 1) && (multiname->nsList->back() == meta->publicNamespace)) { Array_lengthSet(meta, base, &newValue, 1); result = true; } @@ -783,8 +783,8 @@ namespace MetaData { if (result && (multiname->nsList->size() == 1) && (multiname->nsList->back() == meta->publicNamespace)) { uint32 index; if (isValidIndex(multiname->name, index)) { - uint32 length = getLength(meta, obj); - if (index >= length) + ArrayInstance *arrInst = checked_cast(obj); + if (index >= arrInst->length) setLength(meta, obj, index + 1); } } @@ -794,7 +794,7 @@ namespace MetaData { bool JS2ArrayClass::Delete(JS2Metadata *meta, js2val base, Multiname *multiname, Environment *env, bool *result) { - if ((*multiname->name == *meta->engine->length_StringAtom) && (multiname->nsList->size() == 1) && (multiname->nsList->back() == meta->publicNamespace)) { + if ((multiname->name == meta->engine->length_StringAtom) && (multiname->nsList->size() == 1) && (multiname->nsList->back() == meta->publicNamespace)) { *result = false; return true; } @@ -806,7 +806,7 @@ namespace MetaData { { const String *indexStr = meta->toString(indexVal); DEFINE_ROOTKEEPER(meta, rk, indexStr); - Multiname *mn = new (meta) Multiname(indexStr, meta->publicNamespace); + Multiname *mn = new (meta) Multiname(meta->world.identifiers[*indexStr], meta->publicNamespace); DEFINE_ROOTKEEPER(meta, rk1, mn); ASSERT(JS2VAL_IS_OBJECT(base)); @@ -814,7 +814,7 @@ namespace MetaData { bool result; if (!JS2VAL_IS_INT(indexVal)) { - if (*mn->name == *meta->engine->length_StringAtom) { + if (mn->name == meta->engine->length_StringAtom) { Array_lengthSet(meta, base, &newValue, 1); return true; } @@ -829,9 +829,11 @@ namespace MetaData { return true; // not a valid index, don't need to set length } } - uint32 length = getLength(meta, obj); - if (index >= length) - setLength(meta, obj, index + 1); + ArrayInstance *arrInst = checked_cast(obj); + if (index >= arrInst->length) { + js2val newLength = meta->engine->allocNumber(index + 1); + Array_lengthSet(meta, base, &newLength, 1); + } return result; } @@ -839,7 +841,7 @@ namespace MetaData { { const String *indexStr = meta->toString(indexVal); DEFINE_ROOTKEEPER(meta, rk, indexStr); - Multiname *mn = new (meta) Multiname(indexStr, meta->publicNamespace); + Multiname *mn = new (meta) Multiname(meta->world.identifiers[*indexStr], meta->publicNamespace); DEFINE_ROOTKEEPER(meta, rk1, mn); return Delete(meta, base, mn, NULL, result); } @@ -911,7 +913,7 @@ namespace MetaData { { const String *indexStr = meta->toString(indexVal); DEFINE_ROOTKEEPER(meta, rk, indexStr); - Multiname *mn = new (meta) Multiname(indexStr, meta->publicNamespace); + Multiname *mn = new (meta) Multiname(meta->world.identifiers[*indexStr], meta->publicNamespace); DEFINE_ROOTKEEPER(meta, rk1, mn); return Read(meta, base, mn, NULL, phase, rval); } @@ -920,7 +922,7 @@ namespace MetaData { { const String *indexStr = meta->toString(indexVal); DEFINE_ROOTKEEPER(meta, rk, indexStr); - Multiname *mn = new (meta) Multiname(indexStr, meta->publicNamespace); + Multiname *mn = new (meta) Multiname(meta->world.identifiers[*indexStr], meta->publicNamespace); DEFINE_ROOTKEEPER(meta, rk1, mn); return Write(meta, base, mn, NULL, true, newValue, false); } @@ -929,7 +931,7 @@ namespace MetaData { { const String *indexStr = meta->toString(indexVal); DEFINE_ROOTKEEPER(meta, rk, indexStr); - Multiname *mn = new (meta) Multiname(indexStr, meta->publicNamespace); + Multiname *mn = new (meta) Multiname(meta->world.identifiers[*indexStr], meta->publicNamespace); DEFINE_ROOTKEEPER(meta, rk1, mn); return Delete(meta, base, mn, NULL, result); } @@ -959,8 +961,10 @@ namespace MetaData { && baseObj && ( ((baseObj->kind == SimpleInstanceKind) && !checked_cast(baseObj)->sealed) || ( (baseObj->kind == PackageKind) && !checked_cast(baseObj)->sealed)) ) { - QualifiedName qName = multiname->selectPrimaryName(meta); - Multiname *mn = new (meta) Multiname(qName); + QualifiedName *qName = multiname->selectPrimaryName(meta); + ASSERT(qName); + Multiname *mn = new (meta) Multiname(*qName); + delete qName; DEFINE_ROOTKEEPER(meta, rk, mn); if ( (meta->findBaseInstanceMember(this, mn, ReadAccess) == NULL) && (meta->findCommonMember(&base, mn, ReadAccess, true) == NULL) ) { @@ -1040,7 +1044,7 @@ VariableMemberCommon: else lMap = &checked_cast(container)->localBindings; - LocalBindingEntry **lbeP = (*lMap)[*multiname->name]; + LocalBindingEntry **lbeP = (*lMap)[multiname->name]; if (lbeP) { while (true) { bool deletedOne = false; diff --git a/js2/src/js2function.cpp b/js2/src/js2function.cpp index aaca90265da..f170932aba8 100644 --- a/js2/src/js2function.cpp +++ b/js2/src/js2function.cpp @@ -110,7 +110,7 @@ namespace MetaData { fnInst->fWrap->bCon->emitOp(eReturnVoid, meta->engine->errorPos()); meta->createDynamicProperty(fnInst, meta->engine->length_StringAtom, INT_TO_JS2VAL(0), ReadAccess, true, false); if (meta->cxt.E3compatibility) - meta->createDynamicProperty(fnInst, &meta->world.identifiers["arguments"], JS2VAL_NULL, ReadAccess, true, false); + meta->createDynamicProperty(fnInst, meta->world.identifiers["arguments"], JS2VAL_NULL, ReadAccess, true, false); return thatValue; } } @@ -125,7 +125,7 @@ namespace MetaData { if (fnInst->sourceText) return STRING_TO_JS2VAL(fnInst->sourceText); else - return STRING_TO_JS2VAL(meta->engine->Function_StringAtom); + return meta->engine->allocString(meta->engine->Function_StringAtom); } static js2val Function_call(JS2Metadata *meta, const js2val thisValue, js2val *argv, uint32 argc) @@ -173,7 +173,7 @@ namespace MetaData { js2val *argArray = new js2val[length]; DEFINE_ARRAYROOTKEEPER(meta, rk, argArray, length); for (uint32 i = 0; i < length; i++) - meta->arrayClass->ReadPublic(meta, &argv[1], meta->engine->numberToString(i), RunPhase, &argArray[i]); + meta->arrayClass->ReadPublic(meta, &argv[1], meta->engine->numberToStringAtom(i), RunPhase, &argArray[i]); return meta->invokeFunction(fnInst, callThis, argArray, length, NULL); } else @@ -183,7 +183,7 @@ namespace MetaData { js2val *argArray = new js2val[length]; DEFINE_ARRAYROOTKEEPER(meta, rk, argArray, length); for (uint32 i = 0; i < length; i++) - meta->argumentsClass->ReadPublic(meta, &argv[1], meta->engine->numberToString(i), RunPhase, &argArray[i]); + meta->argumentsClass->ReadPublic(meta, &argv[1], meta->engine->numberToStringAtom(i), RunPhase, &argArray[i]); return meta->invokeFunction(fnInst, callThis, argArray, length, NULL); } } diff --git a/js2/src/js2math.cpp b/js2/src/js2math.cpp index 5f316a5dd6f..46862e5f7c1 100644 --- a/js2/src/js2math.cpp +++ b/js2/src/js2math.cpp @@ -319,7 +319,7 @@ void initMathObject(JS2Metadata *meta, SimpleInstance *mathObject) // Variable *v = new Variable(meta->numberClass, meta->engine->allocNumber(MathObjectConstants[i].value), true); // meta->defineLocalMember(meta->env, &meta->world.identifiers[MathObjectConstants[i].name], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, false); - meta->createDynamicProperty(mathObject, &meta->world.identifiers[MathObjectConstants[i].name], meta->engine->allocNumber(MathObjectConstants[i].value), ReadAccess, true, false); + meta->createDynamicProperty(mathObject, meta->world.identifiers[MathObjectConstants[i].name], meta->engine->allocNumber(MathObjectConstants[i].value), ReadAccess, true, false); } FunctionData prototypeFunctions[] = @@ -351,7 +351,7 @@ void initMathObject(JS2Metadata *meta, SimpleInstance *mathObject) callInst->fWrap = new FunctionWrapper(meta, true, new (meta) ParameterFrame(JS2VAL_INACCESSIBLE, true), pf->code, meta->env); callInst->fWrap->length = pf->length; - meta->createDynamicProperty(mathObject, &meta->world.identifiers[pf->name], OBJECT_TO_JS2VAL(callInst), ReadAccess, true, false); + meta->createDynamicProperty(mathObject, meta->world.identifiers[pf->name], OBJECT_TO_JS2VAL(callInst), ReadAccess, true, false); diff --git a/js2/src/js2metadata.cpp b/js2/src/js2metadata.cpp index 5402cf43278..c159e5fab2a 100644 --- a/js2/src/js2metadata.cpp +++ b/js2/src/js2metadata.cpp @@ -127,12 +127,12 @@ namespace MetaData { ValidateTypeExpression(cxt, env, pb->type); if (unchecked) { pb->member = NULL; - defineHoistedVar(env, pb->name, JS2VAL_UNDEFINED, true, pos); + defineHoistedVar(env, *pb->name, JS2VAL_UNDEFINED, true, pos); } else { FrameVariable *v = new FrameVariable(result->fWrap->compileFrame->allocateSlot(), FrameVariable::Parameter); pb->member = v; - defineLocalMember(env, pb->name, NULL, Attribute::NoOverride, false, ReadWriteAccess, v, pb->pos, true); + defineLocalMember(env, *pb->name, NULL, Attribute::NoOverride, false, ReadWriteAccess, v, pb->pos, true); } pb = pb->next; } @@ -142,7 +142,7 @@ namespace MetaData { result->fWrap->length = pCount; lengthVar->value = INT_TO_JS2VAL(pCount); if (cxt->E3compatibility) - createDynamicProperty(result, &world.identifiers["arguments"], JS2VAL_NULL, ReadAccess, true, false); + createDynamicProperty(result, world.identifiers["arguments"], JS2VAL_NULL, ReadAccess, true, false); result->fWrap->compileFrame->isConstructor = isConstructor; ValidateStmt(cxt, env, Plural, fnDef->body); env->removeTopFrame(); @@ -164,10 +164,10 @@ namespace MetaData { case FunctionName::normal: fnInst = validateStaticFunction(cxt, env, fnDef, a->prototype, unchecked, false, pos); if (hoisted) - defineHoistedVar(env, fnDef->name, OBJECT_TO_JS2VAL(fnInst), false, pos); + defineHoistedVar(env, *fnDef->name, OBJECT_TO_JS2VAL(fnInst), false, pos); else { Variable *v = new Variable(functionClass, OBJECT_TO_JS2VAL(fnInst), true); - defineLocalMember(env, fnDef->name, &a->namespaces, a->overrideMod, a->xplicit, ReadWriteAccess, v, pos, true); + defineLocalMember(env, *fnDef->name, &a->namespaces, a->overrideMod, a->xplicit, ReadWriteAccess, v, pos, true); } break; case FunctionName::Get: @@ -178,7 +178,7 @@ namespace MetaData { // XXX shouldn't be using validateStaticFunction fnInst = validateStaticFunction(cxt, env, fnDef, false, false, false, pos); Getter *g = new Getter(fnInst->fWrap->resultType, fnInst); - defineLocalMember(env, fnDef->name, &a->namespaces, a->overrideMod, a->xplicit, ReadAccess, g, pos, true); + defineLocalMember(env, *fnDef->name, &a->namespaces, a->overrideMod, a->xplicit, ReadAccess, g, pos, true); } break; case FunctionName::Set: @@ -189,7 +189,7 @@ namespace MetaData { // XXX shouldn't be using validateStaticFunction fnInst = validateStaticFunction(cxt, env, fnDef, false, false, false, pos); Setter *s = new Setter(fnInst->fWrap->resultType, fnInst); - defineLocalMember(env, fnDef->name, &a->namespaces, a->overrideMod, a->xplicit, WriteAccess, s, pos, true); + defineLocalMember(env, *fnDef->name, &a->namespaces, a->overrideMod, a->xplicit, WriteAccess, s, pos, true); } break; } @@ -218,7 +218,7 @@ namespace MetaData { FunctionInstance *fnInst = NULL; DEFINE_ROOTKEEPER(this, rk1, fnInst); fnInst = validateStaticFunction(cxt, env, fnDef, false, false, false, pos); - Multiname *mn = new (this) Multiname(fnDef->name, a->namespaces); + Multiname *mn = new (this) Multiname(*fnDef->name, a->namespaces); InstanceMember *m; switch (fnDef->prefix) { case FunctionName::normal: @@ -231,7 +231,7 @@ namespace MetaData { m = new InstanceGetter(mn, fnInst, objectClass, final, true); break; } - defineInstanceMember(c, cxt, fnDef->name, a->namespaces, a->overrideMod, a->xplicit, m, pos); + defineInstanceMember(c, cxt, *fnDef->name, a->namespaces, a->overrideMod, a->xplicit, m, pos); } /* @@ -532,7 +532,7 @@ namespace MetaData { validateStatic(cxt, env, &f->function, a, false, false, p->pos); break; case Attribute::NoModifier: - if (*f->function.name == *(checked_cast(topFrame))->name) + if (*f->function.name == (checked_cast(topFrame))->name) validateConstructor(cxt, env, &f->function, checked_cast(topFrame), a, p->pos); else validateInstance(cxt, env, &f->function, checked_cast(topFrame), a, false, p->pos); @@ -585,7 +585,8 @@ namespace MetaData { VariableBinding *vb = vs->bindings; Frame *regionalFrame = (env->getRegionalFrame())->first; while (vb) { - const StringAtom *name = vb->name; + ASSERT(vb->name); + const StringAtom &name = *vb->name; if (vb->type) ValidateTypeExpression(cxt, env, vb->type); vb->member = NULL; @@ -659,8 +660,8 @@ namespace MetaData { reportError(Exception::definitionError, "Illegal attribute", p->pos); if ( ! ((a->memberMod == Attribute::NoModifier) || ((a->memberMod == Attribute::Static) && (env->getTopFrame()->kind == ClassKind))) ) reportError(Exception::definitionError, "Illegal attribute", p->pos); - Variable *v = new Variable(namespaceClass, OBJECT_TO_JS2VAL(new (this) Namespace(&ns->name)), true); - defineLocalMember(env, &ns->name, &a->namespaces, a->overrideMod, a->xplicit, ReadWriteAccess, v, p->pos, true); + Variable *v = new Variable(namespaceClass, OBJECT_TO_JS2VAL(new (this) Namespace(ns->name)), true); + defineLocalMember(env, ns->name, &a->namespaces, a->overrideMod, a->xplicit, ReadWriteAccess, v, p->pos, true); } break; case StmtNode::Use: @@ -719,10 +720,10 @@ namespace MetaData { reportError(Exception::definitionError, "Illegal modifier for class definition", p->pos); break; } - JS2Class *c = new (this) JS2Class(superClass, protoVal, new (this) Namespace(engine->private_StringAtom), (a->dynamic || superClass->dynamic), final, engine->allocStringPtr(&classStmt->name)); + JS2Class *c = new (this) JS2Class(superClass, protoVal, new (this) Namespace(engine->private_StringAtom), (a->dynamic || superClass->dynamic), final, classStmt->name); classStmt->c = c; Variable *v = new Variable(classClass, OBJECT_TO_JS2VAL(c), true); - defineLocalMember(env, &classStmt->name, &a->namespaces, a->overrideMod, a->xplicit, ReadWriteAccess, v, p->pos, true); + defineLocalMember(env, classStmt->name, &a->namespaces, a->overrideMod, a->xplicit, ReadWriteAccess, v, p->pos, true); if (classStmt->body) { env->addFrame(c); ValidateStmtList(cxt, env, pl, classStmt->body->statements); @@ -754,10 +755,10 @@ namespace MetaData { { PackageStmtNode *ps = checked_cast(p); String packageName = getPackageName(ps->packageIdList); - Package *package = new (this) Package(packageName, new (this) Namespace(&world.identifiers["internal"])); + Package *package = new (this) Package(packageName, new (this) Namespace(world.identifiers["internal"])); Variable *v = new Variable(packageClass, OBJECT_TO_JS2VAL(package), true); - defineLocalMember(env, &packageName, NULL, Attribute::NoOverride, false, ReadAccess, v, 0, true); + defineLocalMember(env, world.identifiers[packageName], NULL, Attribute::NoOverride, false, ReadAccess, v, 0, true); package->status = Package::InTransit; packages.push_back(package); @@ -772,14 +773,14 @@ namespace MetaData { ImportStmtNode *i = checked_cast(p); String packageName; if (i->packageIdList) - packageName = getPackageName(i->packageIdList); + packageName = getPackageName(i->packageIdList); else packageName = *i->packageString; if (!checkForPackage(packageName, i->pos)) loadPackage(packageName, packageName + ".js"); - Multiname mn(&packageName, publicNamespace); + Multiname mn(world.identifiers[packageName], publicNamespace); js2val packageValue; env->lexicalRead(this, &mn, CompilePhase, &packageValue, NULL); if (JS2VAL_IS_VOID(packageValue) || JS2VAL_IS_NULL(packageValue) || !JS2VAL_IS_OBJECT(packageValue) @@ -789,7 +790,7 @@ namespace MetaData { Package *package = checked_cast(JS2VAL_TO_OBJECT(packageValue)); if (i->varName) { Variable *v = new Variable(packageClass, packageValue, true); - defineLocalMember(env, i->varName, NULL, Attribute::NoOverride, false, ReadAccess, v, 0, true); + defineLocalMember(env, *i->varName, NULL, Attribute::NoOverride, false, ReadAccess, v, 0, true); } #if 0 @@ -1004,7 +1005,7 @@ namespace MetaData { if (f->initializer->getKind() == StmtNode::Var) { VariableStmtNode *vs = checked_cast(f->initializer); VariableBinding *vb = vs->bindings; - v = new (*referenceArena) LexicalReference(new (this) Multiname(vb->name), cxt.strict); + v = new (*referenceArena) LexicalReference(new (this) Multiname(*vb->name), cxt.strict); referenceArena->registerDestructor(v); } else { @@ -1300,7 +1301,7 @@ namespace MetaData { } // write the exception object (on stack top) into the named // local variable - Reference *r = new (*referenceArena) LexicalReference(new (this) Multiname(&c->name), false); + Reference *r = new (*referenceArena) LexicalReference(new (this) Multiname(c->name), false); referenceArena->registerDestructor(r); r->emitWriteBytecode(bCon, p->pos); bCon->emitOp(ePop, p->pos); @@ -1469,7 +1470,7 @@ namespace MetaData { if (vb->initializer) { Reference *r = SetupExprNode(env, phase, vb->initializer, &exprType); if (r) r->emitReadBytecode(bCon, p->pos); - LexicalReference *lVal = new (*referenceArena) LexicalReference(new (this) Multiname(vb->name), cxt.strict); + LexicalReference *lVal = new (*referenceArena) LexicalReference(new (this) Multiname(*vb->name), cxt.strict); referenceArena->registerDestructor(lVal); lVal->variableMultiname->addNamespace(publicNamespace); lVal->emitInitBytecode(bCon, p->pos); @@ -1890,6 +1891,8 @@ namespace MetaData { } ep = ep->next; } + if (!positionalCount) + reportError(Exception::argumentMismatchError, "Indexing requires at least 1 argument", p->pos); } break; case ExprNode::dot: @@ -2398,7 +2401,7 @@ doUnary: reportError(Exception::badValueError, "Namespace expected in qualifier", p->pos); Namespace *ns = checked_cast(obj); - returnRef = new (*referenceArena) LexicalReference(new (this) Multiname(&name, ns), cxt.strict); + returnRef = new (*referenceArena) LexicalReference(new (this) Multiname(name, ns), cxt.strict); referenceArena->registerDestructor(returnRef); } break; @@ -2424,7 +2427,7 @@ doUnary: fi++; } } - returnRef = new (*referenceArena) LexicalReference(new (this) Multiname(&i->name), cxt.strict); + returnRef = new (*referenceArena) LexicalReference(new (this) Multiname(i->name), cxt.strict); referenceArena->registerDestructor(returnRef); ((LexicalReference *)returnRef)->variableMultiname->addNamespace(cxt); // Try to find this identifier at compile time, we have to stop if we reach @@ -2622,7 +2625,7 @@ doUnary: IdentifierExprNode *i = checked_cast(b->op2); if (*exprType) { - Multiname multiname(&i->name); + Multiname multiname(i->name); InstanceMember *mBase = findBaseInstanceMember(*exprType, &multiname, ReadAccess); if (mBase) { InstanceMember *m = getDerivedInstanceMember(*exprType, mBase, ReadAccess); @@ -2635,7 +2638,7 @@ doUnary: } if (returnRef == NULL) { - returnRef = new (*referenceArena) DotReference(new (this) Multiname(&i->name)); + returnRef = new (*referenceArena) DotReference(new (this) Multiname(i->name)); referenceArena->registerDestructor(returnRef); checked_cast(returnRef)->propertyMultiname->addNamespace(cxt); } @@ -3185,18 +3188,18 @@ doUnary: nsList->push_back(*nli); } - QualifiedName Multiname::selectPrimaryName(JS2Metadata *meta) + QualifiedName *Multiname::selectPrimaryName(JS2Metadata *meta) { if (nsList->size() == 1) - return QualifiedName(nsList->back(), name); + return new QualifiedName(nsList->back(), name); else { if (listContains(meta->publicNamespace)) - return QualifiedName(meta->publicNamespace, name); + return new QualifiedName(meta->publicNamespace, name); else { meta->reportError(Exception::propertyAccessError, "No good primary name {0}", meta->engine->errorPos(), name); - return QualifiedName(); } } + return NULL; } // gc-mark all contained JS2Objects and visit contained structures to do likewise @@ -3205,12 +3208,12 @@ doUnary: for (NamespaceListIterator n = nsList->begin(), end = nsList->end(); (n != end); n++) { GCMARKOBJECT(*n) } - if (name) JS2Object::mark(name); +// if (name) JS2Object::mark(name); } bool Multiname::subsetOf(Multiname &mn) { - if (*name != *mn.name) + if (name != mn.name) return false; for (NamespaceListIterator n = nsList->begin(), end = nsList->end(); (n != end); n++) { if (!mn.listContains(*n)) @@ -3230,7 +3233,7 @@ doUnary: // - If the binding exists (not forbidden) in lower frames in the regional environment, it's an error. // - Define a forbidden binding in all the lower frames. // - Multiname *JS2Metadata::defineLocalMember(Environment *env, const String *id, NamespaceList *namespaces, + Multiname *JS2Metadata::defineLocalMember(Environment *env, const StringAtom &id, NamespaceList *namespaces, Attribute::OverrideModifier overrideMod, bool xplicit, Access access, LocalMember *m, size_t pos, bool enumerable) { @@ -3238,14 +3241,14 @@ doUnary: if ((overrideMod != Attribute::NoOverride) || (xplicit && innerFrame->kind != PackageKind)) reportError(Exception::definitionError, "Illegal definition", pos); - Multiname *multiname = new (this) Multiname(id); + Multiname *multiname = new (this) Multiname(world.identifiers[id]); if (!namespaces || namespaces->empty()) multiname->addNamespace(publicNamespace); else multiname->addNamespace(namespaces); // Search the local frame for an overlapping definition - LocalBindingEntry **lbeP = innerFrame->localBindings[*id]; + LocalBindingEntry **lbeP = innerFrame->localBindings[id]; if (lbeP) { for (LocalBindingEntry::NS_Iterator i = (*lbeP)->begin(), end = (*lbeP)->end(); (i != end); i++) { LocalBindingEntry::NamespaceBinding &ns = *i; @@ -3265,7 +3268,7 @@ doUnary: while (true) { if (fr->kind != WithFrameKind) { NonWithFrame *nwfr = checked_cast(fr); - LocalBindingEntry **rbeP = nwfr->localBindings[*id]; + LocalBindingEntry **rbeP = nwfr->localBindings[id]; if (rbeP) { for (LocalBindingEntry::NS_Iterator i = (*rbeP)->begin(), end = (*rbeP)->end(); (i != end); i++) { LocalBindingEntry::NamespaceBinding &ns = *i; @@ -3286,8 +3289,8 @@ doUnary: // Now insert the id, via all it's namespaces into the local frame LocalBindingEntry *lbe; if (lbeP == NULL) { - lbe = new LocalBindingEntry(*id); - innerFrame->localBindings.insert(*id, lbe); + lbe = new LocalBindingEntry(id); + innerFrame->localBindings.insert(id, lbe); } else lbe = *lbeP; @@ -3305,7 +3308,7 @@ doUnary: NonWithFrame *nwfr = checked_cast(fr); for (NamespaceListIterator nli = multiname->nsList->begin(), nlend = multiname->nsList->end(); (nli != nlend); nli++) { bool foundEntry = false; - LocalBindingEntry **rbeP = nwfr->localBindings[*id]; + LocalBindingEntry **rbeP = nwfr->localBindings[id]; if (rbeP) { for (LocalBindingEntry::NS_Iterator i = (*rbeP)->begin(), end = (*rbeP)->end(); (i != end); i++) { LocalBindingEntry::NamespaceBinding &ns = *i; @@ -3317,8 +3320,8 @@ doUnary: } } if (!foundEntry) { - LocalBindingEntry *rbe = new LocalBindingEntry(*id); - nwfr->localBindings.insert(*id, rbe); + LocalBindingEntry *rbe = new LocalBindingEntry(id); + nwfr->localBindings.insert(id, rbe); LocalBinding *new_b = new LocalBinding(access, forbiddenMember, false); rbe->bindingList.push_back(LocalBindingEntry::NamespaceBinding(*nli, new_b)); } @@ -3340,7 +3343,7 @@ doUnary: return NULL; JS2Class *s = c; while (s) { - InstanceBindingEntry **ibeP = c->instanceBindings[*qname->name]; + InstanceBindingEntry **ibeP = c->instanceBindings[qname->name]; if (ibeP) { for (InstanceBindingEntry::NS_Iterator i = (*ibeP)->begin(), end = (*ibeP)->end(); (i != end); i++) { InstanceBindingEntry::NamespaceBinding &ns = *i; @@ -3373,7 +3376,7 @@ doUnary: return mBase; } - InstanceMember *JS2Metadata::defineInstanceMember(JS2Class *c, Context *cxt, const String *id, NamespaceList &namespaces, + InstanceMember *JS2Metadata::defineInstanceMember(JS2Class *c, Context *cxt, const StringAtom &id, NamespaceList &namespaces, Attribute::OverrideModifier overrideMod, bool xplicit, InstanceMember *m, size_t pos) { @@ -3382,22 +3385,22 @@ doUnary: Access access = m->instanceMemberAccess(); Multiname requestedMultiname(id, namespaces); Multiname openMultiname(id, cxt); - Multiname definedMultiname; - Multiname searchedMultiname; + Multiname *definedMultiname = NULL; + Multiname *searchedMultiname = NULL; if (requestedMultiname.nsList->empty()) { - definedMultiname = Multiname(id, publicNamespace); - searchedMultiname = openMultiname; + definedMultiname = new Multiname(id, publicNamespace); + searchedMultiname = &openMultiname; } else { - definedMultiname = requestedMultiname; - searchedMultiname = requestedMultiname; + definedMultiname = &requestedMultiname; + searchedMultiname = &requestedMultiname; } - InstanceMember *mBase = searchForOverrides(c, &searchedMultiname, access, pos); + InstanceMember *mBase = searchForOverrides(c, searchedMultiname, access, pos); InstanceMember *mOverridden = NULL; if (mBase) { mOverridden = getDerivedInstanceMember(c, mBase, access); - definedMultiname = *mOverridden->multiname; - if (!requestedMultiname.subsetOf(definedMultiname)) + definedMultiname = mOverridden->multiname; + if (!requestedMultiname.subsetOf(*definedMultiname)) reportError(Exception::definitionError, "Illegal definition", pos); bool goodKind; switch (m->memberKind) { @@ -3419,11 +3422,11 @@ doUnary: if (mOverridden->final || !goodKind) reportError(Exception::definitionError, "Illegal override", pos); } - InstanceBindingEntry **ibeP = c->instanceBindings[*id]; + InstanceBindingEntry **ibeP = c->instanceBindings[id]; if (ibeP) { for (InstanceBindingEntry::NS_Iterator i = (*ibeP)->begin(), end = (*ibeP)->end(); (i != end); i++) { InstanceBindingEntry::NamespaceBinding &ns = *i; - if ((access & ns.second->content->instanceMemberAccess()) && (definedMultiname.listContains(ns.first))) + if ((access & ns.second->content->instanceMemberAccess()) && (definedMultiname->listContains(ns.first))) reportError(Exception::definitionError, "Illegal override", pos); } } @@ -3444,12 +3447,12 @@ doUnary: m->multiname = new (this) Multiname(definedMultiname); InstanceBindingEntry *ibe; if (ibeP == NULL) { - ibe = new InstanceBindingEntry(*id); - c->instanceBindings.insert(*id, ibe); + ibe = new InstanceBindingEntry(id); + c->instanceBindings.insert(id, ibe); } else ibe = *ibeP; - for (NamespaceListIterator nli = definedMultiname.nsList->begin(), nlend = definedMultiname.nsList->end(); (nli != nlend); nli++) { + for (NamespaceListIterator nli = definedMultiname->nsList->begin(), nlend = definedMultiname->nsList->end(); (nli != nlend); nli++) { // XXX here and in defineLocal... why a new binding for each namespace? // (other than it would mess up the destructor sequence :-) InstanceBinding *ib = new InstanceBinding(access, m); @@ -3489,7 +3492,7 @@ doUnary: // will shadow a parameter with the same name for compatibility with ECMAScript Edition 3. // If there are multiple function definitions, the initial value is the last function definition. - LocalMember *JS2Metadata::defineHoistedVar(Environment *env, const String *id, js2val initVal, bool isVar, size_t pos) + LocalMember *JS2Metadata::defineHoistedVar(Environment *env, const StringAtom &id, js2val initVal, bool isVar, size_t pos) { LocalMember *result = NULL; FrameListIterator regionalFrameEnd = env->getRegionalEnvironment(); @@ -3499,7 +3502,7 @@ rescan: // run through all the existing bindings, to see if this variable already exists. LocalBinding *bindingResult = NULL; bool foundMultiple = false; - LocalBindingEntry **lbeP = regionalFrame->localBindings[*id]; + LocalBindingEntry **lbeP = regionalFrame->localBindings[id]; if (lbeP) { for (LocalBindingEntry::NS_Iterator i = (*lbeP)->begin(), end = (*lbeP)->end(); (i != end); i++) { LocalBindingEntry::NamespaceBinding &ns = *i; @@ -3524,8 +3527,8 @@ rescan: if (bindingResult == NULL) { LocalBindingEntry *lbe; if (lbeP == NULL) { - lbe = new LocalBindingEntry(*id); - regionalFrame->localBindings.insert(*id, lbe); + lbe = new LocalBindingEntry(id); + regionalFrame->localBindings.insert(id, lbe); } else lbe = *lbeP; @@ -3825,7 +3828,7 @@ static const uint8 urlCharType[256] = { FunctionInstance *fInst = createFunctionInstance(env, true, true, code, length, NULL); DEFINE_ROOTKEEPER(this, rk1, fInst); - createDynamicProperty(glob, &world.identifiers[name], OBJECT_TO_JS2VAL(fInst), ReadWriteAccess, false, true); + createDynamicProperty(glob, world.identifiers[name], OBJECT_TO_JS2VAL(fInst), ReadWriteAccess, false, true); } static js2val Object_Constructor(JS2Metadata *meta, const js2val thisValue, js2val argv[], uint32 argc) @@ -3855,7 +3858,7 @@ static const uint8 urlCharType[256] = } else { JS2Class *type = (checked_cast(obj))->type; - String s = "[object " + *type->name + "]"; + String s = "[object " + type->name + "]"; return STRING_TO_JS2VAL(meta->engine->allocString(s)); } } @@ -3892,7 +3895,7 @@ static const uint8 urlCharType[256] = { ASSERT(JS2VAL_IS_OBJECT(thisValue)); JS2Object *obj = JS2VAL_TO_OBJECT(thisValue); - Multiname mn(meta->toString(argv[0])); + Multiname mn(meta->world.identifiers[*meta->toString(argv[0])]); bool isEnumerable; if (!meta->findLocalMember(obj, &mn, ReadAccess, isEnumerable)) return JS2VAL_FALSE; @@ -3920,7 +3923,7 @@ static const uint8 urlCharType[256] = { ASSERT(JS2VAL_IS_OBJECT(thisValue)); JS2Object *obj = JS2VAL_TO_OBJECT(thisValue); - Multiname mn(meta->toString(argv[0])); + Multiname mn(meta->world.identifiers[*meta->toString(argv[0])]); bool isEnumerable; LocalMember *m = meta->findLocalMember(obj, &mn, ReadAccess, isEnumerable); if ((m == NULL) || !isEnumerable) @@ -3957,11 +3960,12 @@ static const uint8 urlCharType[256] = if (newLength < arrInst->length) { // need to delete all the elements above the new length bool deleteResult; - Multiname *mn = new (meta) Multiname(NULL, meta->publicNamespace); - DEFINE_ROOTKEEPER(meta, rk, mn); for (uint32 i = newLength; i < arrInst->length; i++) { - mn->name = meta->engine->numberToString(i); - meta->arrayClass->Delete(meta, thisValue, mn, NULL, &deleteResult); + const String *str = meta->engine->numberToString(i); + if (meta->world.identifiers.hasEntry(*str)) { + Multiname mn(meta->world.identifiers[*str], meta->publicNamespace); + meta->arrayClass->Delete(meta, thisValue, &mn, NULL, &deleteResult); + } } } arrInst->length = newLength; @@ -3991,7 +3995,7 @@ static const uint8 urlCharType[256] = { engine = new JS2Engine(this, world); publicNamespace = new (this) Namespace(engine->public_StringAtom); - glob = new (this) Package(widenCString("global"), new (this) Namespace(&world.identifiers["internal"])); + glob = new (this) Package(widenCString("global"), new (this) Namespace(world.identifiers["internal"])); env = new (this) Environment(new (this) SystemFrame(), glob); @@ -4004,18 +4008,18 @@ static const uint8 urlCharType[256] = MAKEBUILTINCLASS(objectClass, NULL, false, false, engine->Object_StringAtom, JS2VAL_VOID); MAKEBUILTINCLASS(undefinedClass, objectClass, false, true, engine->undefined_StringAtom, JS2VAL_VOID); nullClass = new (this) JS2NullClass(objectClass, NULL, new (this) Namespace(engine->private_StringAtom), false, true, engine->null_StringAtom); nullClass->complete = true; nullClass->defaultValue = JS2VAL_NULL; - MAKEBUILTINCLASS(booleanClass, objectClass, false, true, engine->allocStringPtr(&world.identifiers["Boolean"]), JS2VAL_FALSE); - MAKEBUILTINCLASS(generalNumberClass, objectClass, false, false, engine->allocStringPtr(&world.identifiers["general number"]), engine->nanValue); - MAKEBUILTINCLASS(numberClass, generalNumberClass, false, true, engine->allocStringPtr(&world.identifiers["Number"]), engine->nanValue); - integerClass = new (this) JS2IntegerClass(numberClass, NULL, new (this) Namespace(engine->private_StringAtom), false, true, engine->allocStringPtr(&world.identifiers["Integer"])); integerClass->complete = true; integerClass->defaultValue = JS2VAL_ZERO; - MAKEBUILTINCLASS(characterClass, objectClass, false, true, engine->allocStringPtr(&world.identifiers["Character"]), JS2VAL_ZERO); - stringClass = new (this) JS2StringClass(objectClass, NULL, new (this) Namespace(engine->private_StringAtom), false, true, engine->allocStringPtr(&world.identifiers["String"])); stringClass->complete = true; stringClass->defaultValue = JS2VAL_NULL; - MAKEBUILTINCLASS(namespaceClass, objectClass, false, true, engine->allocStringPtr(&world.identifiers["namespace"]), JS2VAL_NULL); - MAKEBUILTINCLASS(attributeClass, objectClass, false, true, engine->allocStringPtr(&world.identifiers["attribute"]), JS2VAL_NULL); - MAKEBUILTINCLASS(classClass, objectClass, false, true, engine->allocStringPtr(&world.identifiers["Class"]), JS2VAL_NULL); + MAKEBUILTINCLASS(booleanClass, objectClass, false, true, world.identifiers["Boolean"], JS2VAL_FALSE); + MAKEBUILTINCLASS(generalNumberClass, objectClass, false, false, world.identifiers["general number"], engine->nanValue); + MAKEBUILTINCLASS(numberClass, generalNumberClass, false, true, world.identifiers["Number"], engine->nanValue); + integerClass = new (this) JS2IntegerClass(numberClass, NULL, new (this) Namespace(engine->private_StringAtom), false, true, world.identifiers["Integer"]); integerClass->complete = true; integerClass->defaultValue = JS2VAL_ZERO; + MAKEBUILTINCLASS(characterClass, objectClass, false, true, world.identifiers["Character"], JS2VAL_ZERO); + stringClass = new (this) JS2StringClass(objectClass, NULL, new (this) Namespace(engine->private_StringAtom), false, true, world.identifiers["String"]); stringClass->complete = true; stringClass->defaultValue = JS2VAL_NULL; + MAKEBUILTINCLASS(namespaceClass, objectClass, false, true, world.identifiers["namespace"], JS2VAL_NULL); + MAKEBUILTINCLASS(attributeClass, objectClass, false, true, world.identifiers["attribute"], JS2VAL_NULL); + MAKEBUILTINCLASS(classClass, objectClass, false, true, world.identifiers["Class"], JS2VAL_NULL); MAKEBUILTINCLASS(functionClass, objectClass, true, true, engine->Function_StringAtom, JS2VAL_NULL); - MAKEBUILTINCLASS(packageClass, objectClass, true, true, engine->allocStringPtr(&world.identifiers["Package"]), JS2VAL_NULL); - argumentsClass = new (this) JS2ArgumentsClass(objectClass, NULL, new (this) Namespace(engine->private_StringAtom), false, true, engine->allocStringPtr(&world.identifiers["Object"])); argumentsClass->complete = true; argumentsClass->defaultValue = JS2VAL_NULL; + MAKEBUILTINCLASS(packageClass, objectClass, true, true, world.identifiers["Package"], JS2VAL_NULL); + argumentsClass = new (this) JS2ArgumentsClass(objectClass, NULL, new (this) Namespace(engine->private_StringAtom), false, true, world.identifiers["Object"]); argumentsClass->complete = true; argumentsClass->defaultValue = JS2VAL_NULL; // A 'forbidden' member, used to mark hidden bindings forbiddenMember = new LocalMember(Member::ForbiddenMember, true); @@ -4037,13 +4041,13 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... /*** ECMA 3 Global Object ***/ // Non-function properties of the global object : 'undefined', 'NaN' and 'Infinity' createDynamicProperty(glob, engine->undefined_StringAtom, JS2VAL_UNDEFINED, ReadAccess, true, false); - createDynamicProperty(glob, &world.identifiers["NaN"], engine->nanValue, ReadAccess, true, false); - createDynamicProperty(glob, &world.identifiers["Infinity"], engine->posInfValue, ReadAccess, true, false); + createDynamicProperty(glob, world.identifiers["NaN"], engine->nanValue, ReadAccess, true, false); + createDynamicProperty(glob, world.identifiers["Infinity"], engine->posInfValue, ReadAccess, true, false); /*** ECMA 3 Object Class ***/ v = new Variable(classClass, OBJECT_TO_JS2VAL(objectClass), true); - defineLocalMember(env, &world.identifiers["Object"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true); + defineLocalMember(env, world.identifiers["Object"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true); // Function properties of the Object prototype object objectClass->prototype = OBJECT_TO_JS2VAL(new (this) SimpleInstance(this, NULL, objectClass)); objectClass->construct = Object_Constructor; @@ -4061,7 +4065,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... /*** ECMA 3 Function Class ***/ // Need this initialized early, as subsequent FunctionInstances need the Function.prototype value v = new Variable(classClass, OBJECT_TO_JS2VAL(functionClass), true); - defineLocalMember(env, &world.identifiers["Function"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true); + defineLocalMember(env, world.identifiers["Function"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true); initFunctionObject(this); // Function properties of the global object @@ -4078,7 +4082,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... // Add __proto__ as a getter/setter instance member to Object & class - Multiname proto_mn(&world.identifiers["__proto__"], publicNamespace); + Multiname proto_mn(world.identifiers["__proto__"], publicNamespace); fInst = createFunctionInstance(env, true, true, class_underbarProtoGet, 0, NULL); InstanceGetter *g = new InstanceGetter(&proto_mn, fInst, objectClass, true, true); defineInstanceMember(classClass, &cxt, proto_mn.name, *proto_mn.nsList, Attribute::NoOverride, false, g, 0); @@ -4102,59 +4106,59 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... createDynamicProperty(JS2VAL_TO_OBJECT(objectClass->prototype), engine->valueOf_StringAtom, OBJECT_TO_JS2VAL(fInst), ReadAccess, true, false); // and 'constructor' fInst = createFunctionInstance(env, true, true, Object_Constructor, 0, NULL); - createDynamicProperty(JS2VAL_TO_OBJECT(objectClass->prototype), &world.identifiers["constructor"], OBJECT_TO_JS2VAL(fInst), ReadWriteAccess, false, false); + createDynamicProperty(JS2VAL_TO_OBJECT(objectClass->prototype), world.identifiers["constructor"], OBJECT_TO_JS2VAL(fInst), ReadWriteAccess, false, false); // and various property/enumerable functions fInst = createFunctionInstance(env, true, true, Object_hasOwnProperty, 0, NULL); - createDynamicProperty(JS2VAL_TO_OBJECT(objectClass->prototype), &world.identifiers["hasOwnProperty"], OBJECT_TO_JS2VAL(fInst), ReadWriteAccess, false, false); + createDynamicProperty(JS2VAL_TO_OBJECT(objectClass->prototype), world.identifiers["hasOwnProperty"], OBJECT_TO_JS2VAL(fInst), ReadWriteAccess, false, false); fInst = createFunctionInstance(env, true, true, Object_isPropertyOf, 0, NULL); - createDynamicProperty(JS2VAL_TO_OBJECT(objectClass->prototype), &world.identifiers["isPropertyOf"], OBJECT_TO_JS2VAL(fInst), ReadWriteAccess, false, false); + createDynamicProperty(JS2VAL_TO_OBJECT(objectClass->prototype), world.identifiers["isPropertyOf"], OBJECT_TO_JS2VAL(fInst), ReadWriteAccess, false, false); fInst = createFunctionInstance(env, true, true, Object_propertyIsEnumerble, 0, NULL); - createDynamicProperty(JS2VAL_TO_OBJECT(objectClass->prototype), &world.identifiers["propertyIsEnumerable"], OBJECT_TO_JS2VAL(fInst), ReadWriteAccess, false, false); + createDynamicProperty(JS2VAL_TO_OBJECT(objectClass->prototype), world.identifiers["propertyIsEnumerable"], OBJECT_TO_JS2VAL(fInst), ReadWriteAccess, false, false); /*** ECMA 4 Integer Class ***/ v = new Variable(classClass, OBJECT_TO_JS2VAL(integerClass), true); - defineLocalMember(env, &world.identifiers["Integer"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true); + defineLocalMember(env, world.identifiers["Integer"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true); /*** ECMA 3 Date Class ***/ - MAKEBUILTINCLASS(dateClass, objectClass, true, true, engine->allocStringPtr(&world.identifiers["Date"]), JS2VAL_NULL); + MAKEBUILTINCLASS(dateClass, objectClass, true, true, world.identifiers["Date"], JS2VAL_NULL); v = new Variable(classClass, OBJECT_TO_JS2VAL(dateClass), true); - defineLocalMember(env, &world.identifiers["Date"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true); + defineLocalMember(env, world.identifiers["Date"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true); initDateObject(this); /*** ECMA 3 RegExp Class ***/ - MAKEBUILTINCLASS(regexpClass, objectClass, true, true, engine->allocStringPtr(&world.identifiers["RegExp"]), JS2VAL_NULL); + MAKEBUILTINCLASS(regexpClass, objectClass, true, true, world.identifiers["RegExp"], JS2VAL_NULL); v = new Variable(classClass, OBJECT_TO_JS2VAL(regexpClass), true); - defineLocalMember(env, &world.identifiers["RegExp"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true); + defineLocalMember(env, world.identifiers["RegExp"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true); initRegExpObject(this); /*** ECMA 3 String Class ***/ v = new Variable(classClass, OBJECT_TO_JS2VAL(stringClass), true); - defineLocalMember(env, &world.identifiers["String"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true); + defineLocalMember(env, world.identifiers["String"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true); initStringObject(this); /*** ECMA 3 Number Class ***/ v = new Variable(classClass, OBJECT_TO_JS2VAL(numberClass), true); - defineLocalMember(env, &world.identifiers["Number"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true); + defineLocalMember(env, world.identifiers["Number"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true); initNumberObject(this); /*** ECMA 3 Boolean Class ***/ v = new Variable(classClass, OBJECT_TO_JS2VAL(booleanClass), true); - defineLocalMember(env, &world.identifiers["Boolean"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true); + defineLocalMember(env, world.identifiers["Boolean"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true); initBooleanObject(this); /*** ECMA 3 Math Object ***/ - MAKEBUILTINCLASS(mathClass, objectClass, false, true, engine->allocStringPtr(&world.identifiers["Math"]), JS2VAL_FALSE); + MAKEBUILTINCLASS(mathClass, objectClass, false, true, world.identifiers["Math"], JS2VAL_FALSE); SimpleInstance *mathObject = new (this) SimpleInstance(this, objectClass->prototype, mathClass); v = new Variable(objectClass, OBJECT_TO_JS2VAL(mathObject), true); - defineLocalMember(env, &world.identifiers["Math"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true); + defineLocalMember(env, world.identifiers["Math"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true); initMathObject(this, mathObject); /*** ECMA 3 Array Class ***/ - arrayClass = new (this) JS2ArrayClass(objectClass, NULL, new (this) Namespace(engine->private_StringAtom), true, true, engine->allocStringPtr(&world.identifiers["Array"])); arrayClass->complete = true; arrayClass->defaultValue = JS2VAL_NULL; + arrayClass = new (this) JS2ArrayClass(objectClass, NULL, new (this) Namespace(engine->private_StringAtom), true, true, world.identifiers["Array"]); arrayClass->complete = true; arrayClass->defaultValue = JS2VAL_NULL; v = new Variable(classClass, OBJECT_TO_JS2VAL(arrayClass), true); - defineLocalMember(env, &world.identifiers["Array"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true); + defineLocalMember(env, world.identifiers["Array"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true); initArrayObject(this); /* Multiname length_mn(&world.identifiers["length"], publicNamespace); @@ -4166,27 +4170,27 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... defineInstanceMember(arrayClass, &cxt, length_mn.name, *length_mn.nsList, Attribute::NoOverride, false, s, 0); */ /*** ECMA 3 Error Classes ***/ - MAKEBUILTINCLASS(errorClass, objectClass, true, true, engine->allocStringPtr(&world.identifiers["Error"]), JS2VAL_NULL); + MAKEBUILTINCLASS(errorClass, objectClass, true, true, world.identifiers["Error"], JS2VAL_NULL); v = new Variable(classClass, OBJECT_TO_JS2VAL(errorClass), true); - defineLocalMember(env, &world.identifiers["Error"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true); - MAKEBUILTINCLASS(evalErrorClass, errorClass, true, true, engine->allocStringPtr(&world.identifiers["Error"]), JS2VAL_NULL); + defineLocalMember(env, world.identifiers["Error"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true); + MAKEBUILTINCLASS(evalErrorClass, errorClass, true, true, world.identifiers["Error"], JS2VAL_NULL); v = new Variable(classClass, OBJECT_TO_JS2VAL(evalErrorClass), true); - defineLocalMember(env, &world.identifiers["EvalError"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true); - MAKEBUILTINCLASS(rangeErrorClass, errorClass, true, true, engine->allocStringPtr(&world.identifiers["Error"]), JS2VAL_NULL); + defineLocalMember(env, world.identifiers["EvalError"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true); + MAKEBUILTINCLASS(rangeErrorClass, errorClass, true, true, world.identifiers["Error"], JS2VAL_NULL); v = new Variable(classClass, OBJECT_TO_JS2VAL(rangeErrorClass), true); - defineLocalMember(env, &world.identifiers["RangeError"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true); - MAKEBUILTINCLASS(referenceErrorClass, errorClass, true, true, engine->allocStringPtr(&world.identifiers["Error"]), JS2VAL_NULL); + defineLocalMember(env, world.identifiers["RangeError"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true); + MAKEBUILTINCLASS(referenceErrorClass, errorClass, true, true, world.identifiers["Error"], JS2VAL_NULL); v = new Variable(classClass, OBJECT_TO_JS2VAL(referenceErrorClass), true); - defineLocalMember(env, &world.identifiers["ReferenceError"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true); - MAKEBUILTINCLASS(syntaxErrorClass, errorClass, true, true, engine->allocStringPtr(&world.identifiers["Error"]), JS2VAL_NULL); + defineLocalMember(env, world.identifiers["ReferenceError"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true); + MAKEBUILTINCLASS(syntaxErrorClass, errorClass, true, true, world.identifiers["Error"], JS2VAL_NULL); v = new Variable(classClass, OBJECT_TO_JS2VAL(syntaxErrorClass), true); - defineLocalMember(env, &world.identifiers["SyntaxError"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true); - MAKEBUILTINCLASS(typeErrorClass, errorClass, true, true, engine->allocStringPtr(&world.identifiers["Error"]), JS2VAL_NULL); + defineLocalMember(env, world.identifiers["SyntaxError"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true); + MAKEBUILTINCLASS(typeErrorClass, errorClass, true, true, world.identifiers["Error"], JS2VAL_NULL); v = new Variable(classClass, OBJECT_TO_JS2VAL(typeErrorClass), true); - defineLocalMember(env, &world.identifiers["TypeError"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true); - MAKEBUILTINCLASS(uriErrorClass, errorClass, true, true, engine->allocStringPtr(&world.identifiers["Error"]), JS2VAL_NULL); + defineLocalMember(env, world.identifiers["TypeError"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true); + MAKEBUILTINCLASS(uriErrorClass, errorClass, true, true, world.identifiers["Error"], JS2VAL_NULL); v = new Variable(classClass, OBJECT_TO_JS2VAL(uriErrorClass), true); - defineLocalMember(env, &world.identifiers["URIError"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true); + defineLocalMember(env, world.identifiers["URIError"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true); initErrorObject(this); } @@ -4260,7 +4264,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... InstanceMember *JS2Metadata::findLocalInstanceMember(JS2Class *limit, Multiname *multiname, Access access) { InstanceMember *result = NULL; - InstanceBindingEntry **ibeP = limit->instanceBindings[*multiname->name]; + InstanceBindingEntry **ibeP = limit->instanceBindings[multiname->name]; if (ibeP) { for (InstanceBindingEntry::NS_Iterator i = (*ibeP)->begin(), end = (*ibeP)->end(); (i != end); i++) { InstanceBindingEntry::NamespaceBinding &ns = *i; @@ -4292,7 +4296,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... // in this case either the getter or the setter is returned at the implementation's discretion InstanceMember *JS2Metadata::getDerivedInstanceMember(JS2Class *c, InstanceMember *mBase, Access access) { - InstanceBindingEntry **ibeP = c->instanceBindings[*mBase->multiname->name]; + InstanceBindingEntry **ibeP = c->instanceBindings[mBase->multiname->name]; if (ibeP) { for (InstanceBindingEntry::NS_Iterator i = (*ibeP)->begin(), end = (*ibeP)->end(); (i != end); i++) { InstanceBindingEntry::NamespaceBinding &ns = *i; @@ -4313,7 +4317,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... else lMap = &checked_cast(container)->localBindings; - LocalBindingEntry **lbeP = (*lMap)[*multiname->name]; + LocalBindingEntry **lbeP = (*lMap)[multiname->name]; if (lbeP) { for (LocalBindingEntry::NS_Iterator i = (*lbeP)->begin(), end = (*lbeP)->end(); (i != end); i++) { LocalBindingEntry::NamespaceBinding &ns = *i; @@ -4576,7 +4580,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... return false; } - bool JS2Metadata::hasOwnProperty(JS2Object *obj, const String *name) + bool JS2Metadata::hasOwnProperty(JS2Object *obj, const StringAtom &name) { Multiname *mn = new (this) Multiname(name, publicNamespace); DEFINE_ROOTKEEPER(this, rk, mn); @@ -4586,7 +4590,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... DynamicVariable *JS2Metadata::createDynamicProperty(JS2Object *obj, const char *name, js2val initVal, Access access, bool sealed, bool enumerable) { - return createDynamicProperty(obj, &world.identifiers[widenCString(name)], initVal, access, sealed, enumerable); + return createDynamicProperty(obj, world.identifiers[widenCString(name)], initVal, access, sealed, enumerable); } /* DynamicVariable *JS2Metadata::createDynamicProperty(JS2Object *obj, const String *name, js2val initVal, Access access, bool sealed, bool enumerable) @@ -4596,14 +4600,14 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... return createDynamicProperty(obj, &qName, initVal, access, sealed, enumerable); } */ - void JS2Metadata::addPublicVariableToLocalMap(LocalBindingMap *lMap, const String *name, LocalMember *v, Access access, bool enumerable) + void JS2Metadata::addPublicVariableToLocalMap(LocalBindingMap *lMap, const StringAtom &name, LocalMember *v, Access access, bool enumerable) { LocalBinding *new_b = new LocalBinding(access, v, enumerable); - LocalBindingEntry **lbeP = (*lMap)[*name]; + LocalBindingEntry **lbeP = (*lMap)[name]; LocalBindingEntry *lbe; if (lbeP == NULL) { - lbe = new LocalBindingEntry(*name); - lMap->insert(*name, lbe); + lbe = new LocalBindingEntry(name); + lMap->insert(name, lbe); } else lbe = *lbeP; @@ -4611,7 +4615,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... } // The caller must make sure that the created property does not already exist and does not conflict with any other property. - DynamicVariable *JS2Metadata::createDynamicProperty(JS2Object *obj, const String *name, js2val initVal, Access access, bool sealed, bool enumerable) + DynamicVariable *JS2Metadata::createDynamicProperty(JS2Object *obj, const StringAtom &name, js2val initVal, Access access, bool sealed, bool enumerable) { DynamicVariable *dv = new DynamicVariable(initVal, sealed); LocalBindingMap *lMap; @@ -4754,7 +4758,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... */ // XXX Set the class object itself as the value of 'constructor' ASSERT(JS2VAL_IS_OBJECT(builtinClass->prototype)); - createDynamicProperty(JS2VAL_TO_OBJECT(builtinClass->prototype), &world.identifiers["constructor"], OBJECT_TO_JS2VAL(builtinClass), ReadWriteAccess, false, false); + createDynamicProperty(JS2VAL_TO_OBJECT(builtinClass->prototype), world.identifiers["constructor"], OBJECT_TO_JS2VAL(builtinClass), ReadWriteAccess, false, false); FunctionData *pf = protoFunctions; if (pf) { @@ -4768,7 +4772,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... defineInstanceMember(builtinClass, &cxt, mn->name, *mn->nsList, Attribute::NoOverride, false, m, 0); */ FunctionInstance *fInst = createFunctionInstance(env, true, true, pf->code, pf->length, NULL); - createDynamicProperty(JS2VAL_TO_OBJECT(builtinClass->prototype), &world.identifiers[pf->name], OBJECT_TO_JS2VAL(fInst), ReadWriteAccess, false, false); + createDynamicProperty(JS2VAL_TO_OBJECT(builtinClass->prototype), world.identifiers[pf->name], OBJECT_TO_JS2VAL(fInst), ReadWriteAccess, false, false); pf++; } } @@ -4792,7 +4796,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... while (pf->name) { FunctionInstance *callInst = createFunctionInstance(env, true, true, pf->code, pf->length, NULL); v = new Variable(functionClass, OBJECT_TO_JS2VAL(callInst), true); - defineLocalMember(env, &world.identifiers[pf->name], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, false); + defineLocalMember(env, world.identifiers[pf->name], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, false); pf++; } } @@ -4887,7 +4891,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... * ************************************************************************************/ - JS2Class::JS2Class(JS2Class *super, js2val proto, Namespace *privateNamespace, bool dynamic, bool final, const String *name) + JS2Class::JS2Class(JS2Class *super, js2val proto, Namespace *privateNamespace, bool dynamic, bool final, const StringAtom &name) : NonWithFrame(ClassKind), super(super), instanceInitOrder(NULL), @@ -4927,8 +4931,6 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... GCMARKVALUE(prototype); GCMARKOBJECT(privateNamespace) GCMARKOBJECT(init) - if (typeofString) JS2Object::mark(typeofString); - if (name) JS2Object::mark(name); GCMARKVALUE(defaultValue); for (InstanceBindingIterator rib = instanceBindings.begin(), riend = instanceBindings.end(); (rib != riend); rib++) { InstanceBindingEntry *ibe = *rib; @@ -5064,7 +5066,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... LocalBindingEntry *lbe = *bi; for (LocalBindingEntry::NS_Iterator i = lbe->begin(), end = lbe->end(); (i != end); i++) { LocalBindingEntry::NamespaceBinding ns = *i; - if (ns.first->name) JS2Object::mark(ns.first->name); +/* if (ns.first->name) JS2Object::mark(ns.first->name); */ ns.second->content->mark(); } } @@ -5113,7 +5115,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... DEFINE_ROOTKEEPER(meta, rk2, protoObj); meta->createDynamicProperty(this, meta->engine->prototype_StringAtom, OBJECT_TO_JS2VAL(protoObj), ReadWriteAccess, true, false); - meta->createDynamicProperty(protoObj, &meta->world.identifiers["constructor"], OBJECT_TO_JS2VAL(this), ReadWriteAccess, true, false); + meta->createDynamicProperty(protoObj, meta->world.identifiers["constructor"], OBJECT_TO_JS2VAL(this), ReadWriteAccess, true, false); } @@ -5293,7 +5295,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... } frameSlots = argsObj->mSlots; // Add the 'arguments' property - String name(widenCString("arguments")); + const StringAtom &name = meta->world.identifiers["arguments"]; ASSERT(localBindings[name] == NULL); LocalBindingEntry *lbe = new LocalBindingEntry(name); LocalBinding *sb = new LocalBinding(ReadWriteAccess, new Variable(meta->objectClass, OBJECT_TO_JS2VAL(argsObj), false), false); @@ -5313,7 +5315,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... } if (plural->buildArguments) { setLength(meta, argsObj, argCount); - meta->argumentsClass->WritePublic(meta, OBJECT_TO_JS2VAL(argsObj), meta->engine->allocStringPtr("callee"), true, OBJECT_TO_JS2VAL(fnObj)); + meta->argumentsClass->WritePublic(meta, OBJECT_TO_JS2VAL(argsObj), meta->world.identifiers["callee"], true, OBJECT_TO_JS2VAL(fnObj)); } } diff --git a/js2/src/js2metadata.h b/js2/src/js2metadata.h index c020232cc2c..c64a81f6429 100644 --- a/js2/src/js2metadata.h +++ b/js2/src/js2metadata.h @@ -326,24 +326,23 @@ public: // A Namespace (is also an attribute) class Namespace : public Attribute { public: - Namespace(const String *name) : Attribute(NamespaceAttr), name(name) { } + Namespace(const StringAtom &name) : Attribute(NamespaceAttr), name(name) { } virtual CompoundAttribute *toCompoundAttribute(JS2Metadata *meta); - virtual void markChildren() { if (name) JS2Object::mark(name); } + virtual void markChildren() { /*if (name) JS2Object::mark(name); */} - const String *name; // The namespace's name (used by toString) + const StringAtom &name; // The namespace's name (used by toString) }; // A QualifiedName is the combination of an identifier and a namespace class QualifiedName { public: - QualifiedName() : nameSpace(NULL), name(NULL) { } - QualifiedName(Namespace *nameSpace, const String *name) : nameSpace(nameSpace), name(name) { } + QualifiedName(Namespace *nameSpace, const StringAtom &name) : nameSpace(nameSpace), name(name) { } - bool operator ==(const QualifiedName &b) { return (nameSpace == b.nameSpace) && (*name == *b.name); } + bool operator ==(const QualifiedName &b) { return (nameSpace == b.nameSpace) && (name == b.name); } Namespace *nameSpace; // The namespace qualifier - const String *name; // The name + const StringAtom &name; // The name }; // A MULTINAME is the semantic domain of sets of qualified names. Multinames are used internally in property lookup. @@ -355,31 +354,31 @@ typedef NamespaceList::iterator NamespaceListIterator; class Multiname : public JS2Object { public: - Multiname() : JS2Object(MultinameKind), name(NULL), nsList(new NamespaceList()) { } - Multiname(Namespace *ns) : JS2Object(MultinameKind), name(NULL), nsList(new NamespaceList()) { nsList->push_back(ns); } - Multiname(const String *name) : JS2Object(MultinameKind), name(name), nsList(new NamespaceList()) { } - Multiname(const String *name, Namespace *ns) : JS2Object(MultinameKind), name(name), nsList(new NamespaceList()) { addNamespace(ns); } +// Multiname() : JS2Object(MultinameKind), name(NULL), nsList(new NamespaceList()) { } +// Multiname(Namespace *ns) : JS2Object(MultinameKind), name(NULL), nsList(new NamespaceList()) { nsList->push_back(ns); } Multiname(QualifiedName& q) : JS2Object(MultinameKind), name(q.name), nsList(new NamespaceList()) { nsList->push_back(q.nameSpace); } - Multiname(const String *name, NamespaceList *ns) : JS2Object(MultinameKind), name(name), nsList(new NamespaceList()) { addNamespace(ns); } - Multiname(const String *name, NamespaceList &ns) : JS2Object(MultinameKind), name(name), nsList(new NamespaceList()) { addNamespace(ns); } - Multiname(const String *name, Context *cxt) : JS2Object(MultinameKind), name(name), nsList(new NamespaceList()) { addNamespace(*cxt); } + Multiname(const StringAtom &name) : JS2Object(MultinameKind), name(name), nsList(new NamespaceList()) { } + Multiname(const StringAtom &name, Namespace *ns) : JS2Object(MultinameKind), name(name), nsList(new NamespaceList()) { addNamespace(ns); } + Multiname(const StringAtom &name, NamespaceList *ns) : JS2Object(MultinameKind), name(name), nsList(new NamespaceList()) { addNamespace(ns); } + Multiname(const StringAtom &name, NamespaceList &ns) : JS2Object(MultinameKind), name(name), nsList(new NamespaceList()) { addNamespace(ns); } + Multiname(const StringAtom &name, Context *cxt) : JS2Object(MultinameKind), name(name), nsList(new NamespaceList()) { addNamespace(*cxt); } Multiname(Multiname *m) : JS2Object(MultinameKind), name(m->name), nsList(new NamespaceList()) { addNamespace(m->nsList); } Multiname(const Multiname& m) : JS2Object(MultinameKind), name(m.name), nsList(new NamespaceList()) { addNamespace(m.nsList); } - void operator =(const Multiname& m) { name = m.name; delete nsList; nsList = new NamespaceList(); addNamespace(m.nsList); } +// void operator =(const Multiname& m) { name = m.name; delete nsList; nsList = new NamespaceList(); addNamespace(m.nsList); } void addNamespace(Namespace *ns) { nsList->push_back(ns); } void addNamespace(NamespaceList &ns); void addNamespace(NamespaceList *ns) { addNamespace(*ns); } void addNamespace(Context &cxt); - bool matches(QualifiedName &q) { return (*name == *q.name) && listContains(q.nameSpace); } + bool matches(QualifiedName &q) { return (name == q.name) && listContains(q.nameSpace); } bool listContains(Namespace *nameSpace); - QualifiedName selectPrimaryName(JS2Metadata *meta); + QualifiedName *selectPrimaryName(JS2Metadata *meta); bool subsetOf(Multiname &mn); - const String *name; + const StringAtom &name; NamespaceList *nsList; virtual void markChildren(); @@ -629,7 +628,7 @@ public: template class BindingEntry { public: - BindingEntry(const String &s) : name(s) { } + BindingEntry(const StringAtom &s) : name(s) { } BindingEntry *clone(); void clear(); @@ -642,7 +641,7 @@ public: NS_Iterator end() { return bindingList.end(); } - const String name; + const StringAtom &name; NamespaceBindingList bindingList; }; @@ -651,14 +650,14 @@ typedef BindingEntry LocalBindingEntry; // A LocalBindingMap maps names to a list of LocalBindings. Each LocalBinding in the list // will have the same QualifiedName.name, but (potentially) different QualifiedName.namespace values -typedef HashTable LocalBindingMap; -typedef TableIterator LocalBindingIterator; +typedef HashTable LocalBindingMap; +typedef TableIterator LocalBindingIterator; typedef BindingEntry InstanceBindingEntry; -typedef HashTable InstanceBindingMap; -typedef TableIterator InstanceBindingIterator; +typedef HashTable InstanceBindingMap; +typedef TableIterator InstanceBindingIterator; // A frame contains bindings defined at a particular scope in a program. A frame is either the top-level system frame, @@ -768,17 +767,17 @@ private: class JS2Class : public NonWithFrame { public: - JS2Class(JS2Class *super, js2val proto, Namespace *privateNamespace, bool dynamic, bool final, const String *name); + JS2Class(JS2Class *super, js2val proto, Namespace *privateNamespace, bool dynamic, bool final, const StringAtom &name); - const String *getTypeofString() { return typeofString; } + const StringAtom &getTypeofString() { return typeofString; } JS2Class *super; // This class's immediate superclass or null if none InstanceBindingMap instanceBindings; // Map of qualified names to instance members defined in this class InstanceVariable **instanceInitOrder; // List of instance variables defined in this class in the order in which they are initialised bool complete; // true after all members of this class have been added to this CLASS record - const String *name; // This class's name + const StringAtom &name; // This class's name js2val prototype; // The default value of the super field of newly created simple instances of this class; for most classes - const String *typeofString; // A strign to return if typeof is invoked on this class's instances + const StringAtom &typeofString; // A strign to return if typeof is invoked on this class's instances Namespace *privateNamespace; // This class's private namespace bool dynamic; // true if this class or any of its ancestors was defined with the dynamic attribute bool final; // true if this class cannot be subclassed @@ -793,9 +792,9 @@ public: void emitDefaultValue(BytecodeContainer *bCon, size_t pos); - bool ReadPublic(JS2Metadata *meta, js2val *base, const String *name, Phase phase, js2val *rval); - bool WritePublic(JS2Metadata *meta, js2val base, const String *name, bool createIfMissing, js2val newValue); - bool DeletePublic(JS2Metadata *meta, js2val base, const String *name, bool *result); + bool ReadPublic(JS2Metadata *meta, js2val *base, const StringAtom &name, Phase phase, js2val *rval); + bool WritePublic(JS2Metadata *meta, js2val base, const StringAtom &name, bool createIfMissing, js2val newValue); + bool DeletePublic(JS2Metadata *meta, js2val base, const StringAtom &name, bool *result); virtual bool Read(JS2Metadata *meta, js2val *base, Multiname *multiname, Environment *env, Phase phase, js2val *rval); virtual bool Write(JS2Metadata *meta, js2val base, Multiname *multiname, Environment *env, bool createIfMissing, js2val newValue, bool initFlag); @@ -817,7 +816,7 @@ public: class JS2ArrayClass : public JS2Class { public: - JS2ArrayClass(JS2Class *super, js2val proto, Namespace *privateNamespace, bool dynamic, bool final, const String *name) + JS2ArrayClass(JS2Class *super, js2val proto, Namespace *privateNamespace, bool dynamic, bool final, const StringAtom &name) : JS2Class(super, proto, privateNamespace, dynamic, final, name) { } virtual bool Read(JS2Metadata *meta, js2val *base, Multiname *multiname, Environment *env, Phase phase, js2val *rval); @@ -830,7 +829,7 @@ public: class JS2IntegerClass : public JS2Class { public: - JS2IntegerClass(JS2Class *super, js2val proto, Namespace *privateNamespace, bool dynamic, bool final, const String *name) + JS2IntegerClass(JS2Class *super, js2val proto, Namespace *privateNamespace, bool dynamic, bool final, const StringAtom &name) : JS2Class(super, proto, privateNamespace, dynamic, final, name) { } virtual js2val ImplicitCoerce(JS2Metadata *meta, js2val newValue); @@ -839,7 +838,7 @@ public: class JS2StringClass : public JS2Class { public: - JS2StringClass(JS2Class *super, js2val proto, Namespace *privateNamespace, bool dynamic, bool final, const String *name) + JS2StringClass(JS2Class *super, js2val proto, Namespace *privateNamespace, bool dynamic, bool final, const StringAtom &name) : JS2Class(super, proto, privateNamespace, dynamic, final, name) { } virtual bool BracketRead(JS2Metadata *meta, js2val *base, js2val indexVal, Phase phase, js2val *rval); @@ -847,7 +846,7 @@ public: class JS2NullClass : public JS2Class { public: - JS2NullClass(JS2Class *super, js2val proto, Namespace *privateNamespace, bool dynamic, bool final, const String *name) + JS2NullClass(JS2Class *super, js2val proto, Namespace *privateNamespace, bool dynamic, bool final, const StringAtom &name) : JS2Class(super, proto, privateNamespace, dynamic, final, name) { } virtual bool Read(JS2Metadata *meta, js2val *base, Multiname *multiname, Environment *env, Phase phase, js2val *rval) { return false; } @@ -860,7 +859,7 @@ public: class JS2ArgumentsClass : public JS2Class { public: - JS2ArgumentsClass(JS2Class *super, js2val proto, Namespace *privateNamespace, bool dynamic, bool final, const String *name) + JS2ArgumentsClass(JS2Class *super, js2val proto, Namespace *privateNamespace, bool dynamic, bool final, const StringAtom &name) : JS2Class(super, proto, privateNamespace, dynamic, final, name) { } virtual bool Read(JS2Metadata *meta, js2val *base, Multiname *multiname, Environment *env, Phase phase, js2val *rval); @@ -1505,9 +1504,9 @@ public: InstanceBinding *resolveInstanceMemberName(JS2Class *js2class, Multiname *multiname, Access access, Phase phase, QualifiedName *qname); FrameVariable *makeFrameVariable(NonWithFrame *regionalFrame); - LocalMember *defineHoistedVar(Environment *env, const String *id, js2val initVal, bool isVar, size_t pos); - Multiname *defineLocalMember(Environment *env, const String *id, NamespaceList *namespaces, Attribute::OverrideModifier overrideMod, bool xplicit, Access access, LocalMember *m, size_t pos, bool enumerable); - InstanceMember *defineInstanceMember(JS2Class *c, Context *cxt, const String *id, NamespaceList &namespaces, + LocalMember *defineHoistedVar(Environment *env, const StringAtom &id, js2val initVal, bool isVar, size_t pos); + Multiname *defineLocalMember(Environment *env, const StringAtom &id, NamespaceList *namespaces, Attribute::OverrideModifier overrideMod, bool xplicit, Access access, LocalMember *m, size_t pos, bool enumerable); + InstanceMember *defineInstanceMember(JS2Class *c, Context *cxt, const StringAtom &idAtom, NamespaceList &namespaces, Attribute::OverrideModifier overrideMod, bool xplicit, InstanceMember *m, size_t pos); InstanceMember *searchForOverrides(JS2Class *c, Multiname *multiname, Access access, size_t pos); @@ -1522,21 +1521,21 @@ public: Member *findCommonMember(js2val *base, Multiname *multiname, Access access, bool flat); js2val invokeFunction(const char *fname); - bool invokeFunctionOnObject(js2val thisValue, const String *fnName, js2val &result); + bool invokeFunctionOnObject(js2val thisValue, const StringAtom &fnName, js2val &result); js2val invokeFunction(JS2Object *fnObj, js2val thisValue, js2val *argv, uint32 argc, ParameterFrame *runtimeFrame); void invokeInit(JS2Class *c, js2val thisValue, js2val* argv, uint32 argc); DynamicVariable *createDynamicProperty(JS2Object *obj, const char *name, js2val initVal, Access access, bool sealed, bool enumerable); // DynamicVariable *createDynamicProperty(JS2Object *obj, QualifiedName *qName, js2val initVal, Access access, bool sealed, bool enumerable); - DynamicVariable *createDynamicProperty(JS2Object *obj, const String *name, js2val initVal, Access access, bool sealed, bool enumerable); - void addPublicVariableToLocalMap(LocalBindingMap *lMap, const String *name, LocalMember *v, Access access, bool enumerable); + DynamicVariable *createDynamicProperty(JS2Object *obj, const StringAtom &name, js2val initVal, Access access, bool sealed, bool enumerable); + void addPublicVariableToLocalMap(LocalBindingMap *lMap, const StringAtom &name, LocalMember *v, Access access, bool enumerable); FunctionInstance *createFunctionInstance(Environment *env, bool prototype, bool unchecked, NativeCode *code, uint32 length, DynamicVariable **lengthProperty); bool readLocalMember(LocalMember *m, Phase phase, js2val *rval, Frame *container); bool readInstanceMember(js2val containerVal, JS2Class *c, InstanceMember *mBase, Phase phase, js2val *rval); - bool JS2Metadata::hasOwnProperty(JS2Object *obj, const String *name); + bool JS2Metadata::hasOwnProperty(JS2Object *obj, const StringAtom &name); bool writeLocalMember(LocalMember *m, js2val newValue, bool initFlag, Frame *container); bool writeInstanceMember(js2val containerVal, JS2Class *c, InstanceMember *mBase, js2val newValue); @@ -1717,11 +1716,11 @@ public: }; // namespace MetaData -inline bool operator==(MetaData::LocalBindingEntry *s1, const String &s2) { return s1->name == s2;} -inline bool operator!=(MetaData::LocalBindingEntry *s1, const String &s2) { return s1->name != s2;} +inline bool operator==(MetaData::LocalBindingEntry *s1, const StringAtom &s2) { return s1->name == s2;} +inline bool operator!=(MetaData::LocalBindingEntry *s1, const StringAtom &s2) { return s1->name != s2;} -inline bool operator==(MetaData::InstanceBindingEntry *s1, const String &s2) { return s1->name == s2;} -inline bool operator!=(MetaData::InstanceBindingEntry *s1, const String &s2) { return s1->name != s2;} +inline bool operator==(MetaData::InstanceBindingEntry *s1, const StringAtom &s2) { return s1->name == s2;} +inline bool operator!=(MetaData::InstanceBindingEntry *s1, const StringAtom &s2) { return s1->name != s2;} }; // namespace Javascript diff --git a/js2/src/js2number.cpp b/js2/src/js2number.cpp index e4682e35b68..2ccc0eceaed 100644 --- a/js2/src/js2number.cpp +++ b/js2/src/js2number.cpp @@ -166,7 +166,7 @@ namespace MetaData { for (i = 0; i < N_CONSTANTS_COUNT; i++) { Variable *v = new Variable(meta->numberClass, meta->engine->allocNumber(NumberObjectConstants[i].value), true); - meta->defineLocalMember(meta->env, &meta->world.identifiers[NumberObjectConstants[i].name], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, false); + meta->defineLocalMember(meta->env, meta->world.identifiers[NumberObjectConstants[i].name], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, false); } meta->env->removeTopFrame(); diff --git a/js2/src/js2op_invocation.cpp b/js2/src/js2op_invocation.cpp index c04f17d8997..f1108439ccf 100644 --- a/js2/src/js2op_invocation.cpp +++ b/js2/src/js2op_invocation.cpp @@ -147,7 +147,7 @@ doCall: pFrame->thisObject = a; // XXX (use fWrap->compileFrame->signature) pFrame->assignArguments(meta, fObj, base(argCount), argCount, length); - jsr(phase, fWrap->bCon, base(argCount + 2) - execStack, JS2VAL_VOID, fWrap->env); // seems out of order, but we need to catch the current top frame + jsr(phase, fWrap->bCon, base(argCount + 2) - execStack, JS2VAL_VOID, fWrap->env); if (fInst->isMethodClosure) meta->env->addFrame(meta->objectType(a)); meta->env->addFrame(pFrame); @@ -155,7 +155,7 @@ doCall: pFrame = NULL; } else { - jsr(phase, fWrap->bCon, base(argCount + 2) - execStack, JS2VAL_VOID, fWrap->env); // seems out of order, but we need to catch the current top frame + jsr(phase, fWrap->bCon, base(argCount + 2) - execStack, JS2VAL_VOID, fWrap->env); // XXX constructing a parameterFrame only for the purpose of holding the 'this' // need to find a more efficient way of stashing 'this' // used to be : "meta->env->addFrame(fWrap->compileFrame->prototype);" @@ -181,7 +181,7 @@ doCall: && (meta->objectType(b) == meta->regexpClass)) { // ECMA extension, call exec() js2val exec_fnVal; - if (!meta->regexpClass->ReadPublic(meta, &b, &meta->world.identifiers["exec"], RunPhase, &exec_fnVal)) + if (!meta->regexpClass->ReadPublic(meta, &b, meta->world.identifiers["exec"], RunPhase, &exec_fnVal)) ASSERT(false); a = b; ASSERT(JS2VAL_IS_OBJECT(exec_fnVal)); @@ -291,7 +291,7 @@ doCall: b = pop(); a = pop(); // doing 'a in b' astr = meta->toString(a); - Multiname mn(astr); + Multiname mn(meta->world.identifiers[*astr]); JS2Class *c = meta->objectType(b); bool result = ( (meta->findBaseInstanceMember(c, &mn, ReadAccess) != NULL) || (meta->findBaseInstanceMember(c, &mn, WriteAccess) != NULL) diff --git a/js2/src/js2op_literal.cpp b/js2/src/js2op_literal.cpp index b560dba12cf..f49832ac17f 100644 --- a/js2/src/js2op_literal.cpp +++ b/js2/src/js2op_literal.cpp @@ -184,7 +184,7 @@ makeLimitedInstance: ASSERT(JS2VAL_IS_STRING(a)); astr = JS2VAL_TO_STRING(a); b = pop(); - meta->createDynamicProperty(sInst, astr, b, ReadWriteAccess, false, true); + meta->createDynamicProperty(sInst, meta->world.identifiers[*astr], b, ReadWriteAccess, false, true); } push(baseVal); baseVal = JS2VAL_VOID; @@ -200,7 +200,7 @@ makeLimitedInstance: baseVal = OBJECT_TO_JS2VAL(aInst); for (uint16 i = 0; i < argCount; i++) { b = pop(); - meta->createDynamicProperty(aInst, numberToString(toUInt32((argCount - 1) - i)), b, ReadWriteAccess, false, true); + meta->createDynamicProperty(aInst, numberToStringAtom(toUInt32((argCount - 1) - i)), b, ReadWriteAccess, false, true); } setLength(meta, aInst, argCount); push(baseVal); diff --git a/js2/src/js2regexp.cpp b/js2/src/js2regexp.cpp index c97a3d02665..1b8c7059793 100644 --- a/js2/src/js2regexp.cpp +++ b/js2/src/js2regexp.cpp @@ -62,30 +62,30 @@ namespace MetaData { void RegExpInstance::setLastIndex(JS2Metadata *meta, js2val a) { - meta->regexpClass->WritePublic(meta, OBJECT_TO_JS2VAL(this), meta->engine->allocStringPtr("lastIndex"), true, a); + meta->regexpClass->WritePublic(meta, OBJECT_TO_JS2VAL(this), meta->world.identifiers["lastIndex"], true, a); } void RegExpInstance::setGlobal(JS2Metadata *meta, js2val a) { - meta->regexpClass->WritePublic(meta, OBJECT_TO_JS2VAL(this), meta->engine->allocStringPtr("global"), true, a); + meta->regexpClass->WritePublic(meta, OBJECT_TO_JS2VAL(this), meta->world.identifiers["global"], true, a); } void RegExpInstance::setMultiline(JS2Metadata *meta, js2val a) { - meta->regexpClass->WritePublic(meta, OBJECT_TO_JS2VAL(this), meta->engine->allocStringPtr("multiline"), true, a); + meta->regexpClass->WritePublic(meta, OBJECT_TO_JS2VAL(this), meta->world.identifiers["multiline"], true, a); } void RegExpInstance::setIgnoreCase(JS2Metadata *meta, js2val a) { - meta->regexpClass->WritePublic(meta, OBJECT_TO_JS2VAL(this), meta->engine->allocStringPtr("ignoreCase"), true, a); + meta->regexpClass->WritePublic(meta, OBJECT_TO_JS2VAL(this), meta->world.identifiers["ignoreCase"], true, a); } void RegExpInstance::setSource(JS2Metadata *meta, js2val a) { - meta->regexpClass->WritePublic(meta, OBJECT_TO_JS2VAL(this), meta->engine->allocStringPtr("source"), true, a); + meta->regexpClass->WritePublic(meta, OBJECT_TO_JS2VAL(this), meta->world.identifiers["source"], true, a); } js2val RegExpInstance::getLastIndex(JS2Metadata *meta) { js2val r; js2val thisVal = OBJECT_TO_JS2VAL(this); - if (!meta->regexpClass->ReadPublic(meta, &thisVal, meta->engine->allocStringPtr("lastIndex"), RunPhase, &r)) + if (!meta->regexpClass->ReadPublic(meta, &thisVal, meta->world.identifiers["lastIndex"], RunPhase, &r)) ASSERT(false); return r; } @@ -93,7 +93,7 @@ namespace MetaData { { js2val r; js2val thisVal = OBJECT_TO_JS2VAL(this); - if (!meta->regexpClass->ReadPublic(meta, &thisVal, meta->engine->allocStringPtr("global"), RunPhase, &r)) + if (!meta->regexpClass->ReadPublic(meta, &thisVal, meta->world.identifiers["global"], RunPhase, &r)) ASSERT(false); return r; } @@ -101,7 +101,7 @@ namespace MetaData { { js2val r; js2val thisVal = OBJECT_TO_JS2VAL(this); - if (!meta->regexpClass->ReadPublic(meta, &thisVal, meta->engine->allocStringPtr("multiline"), RunPhase, &r)) + if (!meta->regexpClass->ReadPublic(meta, &thisVal, meta->world.identifiers["multiline"], RunPhase, &r)) ASSERT(false); return r; } @@ -109,7 +109,7 @@ namespace MetaData { { js2val r; js2val thisVal = OBJECT_TO_JS2VAL(this); - if (!meta->regexpClass->ReadPublic(meta, &thisVal, meta->engine->allocStringPtr("ignoreCase"), RunPhase, &r)) + if (!meta->regexpClass->ReadPublic(meta, &thisVal, meta->world.identifiers["ignoreCase"], RunPhase, &r)) ASSERT(false); return r; } @@ -117,7 +117,7 @@ namespace MetaData { { js2val r; js2val thisVal = OBJECT_TO_JS2VAL(this); - if (!meta->regexpClass->ReadPublic(meta, &thisVal, meta->engine->allocStringPtr("source"), RunPhase, &r)) + if (!meta->regexpClass->ReadPublic(meta, &thisVal, meta->world.identifiers["source"], RunPhase, &r)) ASSERT(false); return r; } @@ -164,7 +164,7 @@ namespace MetaData { js2val result = JS2VAL_NULL; if (argc == 0) { js2val inputVal; - if (!meta->classClass->ReadPublic(meta, ®expClassVal, meta->engine->allocStringPtr("input"), RunPhase, &inputVal)) + if (!meta->classClass->ReadPublic(meta, ®expClassVal, meta->world.identifiers["input"], RunPhase, &inputVal)) ASSERT(false); str = meta->toString(inputVal); } @@ -173,7 +173,7 @@ namespace MetaData { uint32 index = 0; js2val globalMultiline; - if (!meta->classClass->ReadPublic(meta, ®expClassVal, meta->engine->allocStringPtr("multiline"), RunPhase, &globalMultiline)) + if (!meta->classClass->ReadPublic(meta, ®expClassVal, meta->world.identifiers["multiline"], RunPhase, &globalMultiline)) ASSERT(false); if (meta->toBoolean(thisInst->getGlobal(meta))) { @@ -205,7 +205,7 @@ namespace MetaData { js2val inputStr = meta->engine->allocString(str); DEFINE_ROOTKEEPER(meta, rk2, inputStr); if (!test) - meta->createDynamicProperty(A, meta->engine->numberToString((long)0), matchStr, ReadWriteAccess, false, true); + meta->createDynamicProperty(A, meta->engine->numberToStringAtom((long)0), matchStr, ReadWriteAccess, false, true); js2val parenStr = JS2VAL_VOID; DEFINE_ROOTKEEPER(meta, rk3, parenStr); if (match->parenCount == 0) // arrange to set the lastParen to "", not undefined (it's a non-ecma 1.2 thing) @@ -214,22 +214,22 @@ namespace MetaData { if (match->parens[i].index != -1) { parenStr = meta->engine->allocString(str->substr((uint32)(match->parens[i].index), (uint32)(match->parens[i].length))); if (!test) - meta->createDynamicProperty(A, meta->engine->numberToString(toUInt32(i + 1)), parenStr, ReadWriteAccess, false, true); + meta->createDynamicProperty(A, meta->engine->numberToStringAtom(toUInt32(i + 1)), parenStr, ReadWriteAccess, false, true); if (i < 9) { // 0-->8 maps to $1 thru $9 char name[3] = "$0"; name[1] = '1' + i; String staticName(widenCString(name)); - meta->classClass->WritePublic(meta, regexpClassVal, meta->engine->allocStringPtr(&staticName), true, parenStr); + meta->classClass->WritePublic(meta, regexpClassVal, meta->world.identifiers[staticName], true, parenStr); } } else { if (!test) - meta->createDynamicProperty(A, meta->engine->numberToString(toUInt32(i + 1)), JS2VAL_UNDEFINED, ReadWriteAccess, false, true); + meta->createDynamicProperty(A, meta->engine->numberToStringAtom(toUInt32(i + 1)), JS2VAL_UNDEFINED, ReadWriteAccess, false, true); if (i < 9) { // 0-->8 maps to $1 thru $9 char name[3] = "$0"; name[1] = '1' + i; String staticName(widenCString(name)); - meta->classClass->WritePublic(meta, regexpClassVal, meta->engine->allocStringPtr(&staticName), true, JS2VAL_UNDEFINED); + meta->classClass->WritePublic(meta, regexpClassVal, meta->world.identifiers[staticName], true, JS2VAL_UNDEFINED); } } } @@ -237,19 +237,19 @@ namespace MetaData { setLength(meta, A, match->parenCount + 1); // add 'index' and 'input' properties to the result array - meta->createDynamicProperty(A, meta->engine->allocStringPtr("index"), meta->engine->allocNumber((float64)(match->startIndex)), ReadWriteAccess, false, true); - meta->createDynamicProperty(A, meta->engine->allocStringPtr("input"), inputStr, ReadWriteAccess, false, true); + meta->createDynamicProperty(A, meta->world.identifiers["index"], meta->engine->allocNumber((float64)(match->startIndex)), ReadWriteAccess, false, true); + meta->createDynamicProperty(A, meta->world.identifiers["input"], inputStr, ReadWriteAccess, false, true); } // set other RegExp statics - meta->classClass->WritePublic(meta, regexpClassVal, meta->engine->allocStringPtr("input"), true, inputStr); - meta->classClass->WritePublic(meta, regexpClassVal, meta->engine->allocStringPtr("lastMatch"), true, matchStr); - meta->classClass->WritePublic(meta, regexpClassVal, meta->engine->allocStringPtr("lastParen"), true, parenStr); + meta->classClass->WritePublic(meta, regexpClassVal, meta->world.identifiers["input"], true, inputStr); + meta->classClass->WritePublic(meta, regexpClassVal, meta->world.identifiers["lastMatch"], true, matchStr); + meta->classClass->WritePublic(meta, regexpClassVal, meta->world.identifiers["lastParen"], true, parenStr); js2val leftContextVal = meta->engine->allocString(str->substr(0, (uint32)match->startIndex)); DEFINE_ROOTKEEPER(meta, rk4, leftContextVal); - meta->classClass->WritePublic(meta, regexpClassVal, meta->engine->allocStringPtr("leftContext"), true, leftContextVal); + meta->classClass->WritePublic(meta, regexpClassVal, meta->world.identifiers["leftContext"], true, leftContextVal); js2val rightContextVal = meta->engine->allocString(str->substr((uint32)match->endIndex, (uint32)str->length() - match->endIndex)); DEFINE_ROOTKEEPER(meta, rk5, rightContextVal); - meta->classClass->WritePublic(meta, regexpClassVal, meta->engine->allocStringPtr("rightContext"), true, rightContextVal); + meta->classClass->WritePublic(meta, regexpClassVal, meta->world.identifiers["rightContext"], true, rightContextVal); } return result; } @@ -287,9 +287,9 @@ namespace MetaData { RegExpInstance *thisInst = checked_cast(JS2VAL_TO_OBJECT(thisValue)); uint32 flags = 0; - const String *regexpStr = meta->engine->Empty_StringAtom; + const String *regexpStr = &meta->engine->Empty_StringAtom; DEFINE_ROOTKEEPER(meta, rk1, regexpStr); - const String *flagStr = meta->engine->Empty_StringAtom; + const String *flagStr = &meta->engine->Empty_StringAtom; DEFINE_ROOTKEEPER(meta, rk2, flagStr); if (argc > 0) { if (JS2VAL_IS_OBJECT(argv[0]) && !JS2VAL_IS_NULL(argv[0]) @@ -399,9 +399,9 @@ namespace MetaData { else if (RegExpStaticVars[i].type == meta->booleanClass) v->value = JS2VAL_FALSE; - meta->defineLocalMember(meta->env, &meta->world.identifiers[RegExpStaticVars[i].name], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, false); + meta->defineLocalMember(meta->env, meta->world.identifiers[RegExpStaticVars[i].name], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, false); if (RegExpStaticVars[i].aliasName) - meta->defineLocalMember(meta->env, &meta->world.identifiers[RegExpStaticVars[i].aliasName], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, false); + meta->defineLocalMember(meta->env, meta->world.identifiers[RegExpStaticVars[i].aliasName], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, false); } meta->env->removeTopFrame(); @@ -423,7 +423,7 @@ namespace MetaData { for (i = 0; i < INSTANCE_VAR_COUNT; i++) { - Multiname *mn = new (meta) Multiname(meta->engine->allocStringPtr(RegExpInstanceVars[i].name), &publicNamespaceList); + Multiname *mn = new (meta) Multiname(meta->world.identifiers[RegExpInstanceVars[i].name], &publicNamespaceList); InstanceMember *m = new InstanceVariable(mn, RegExpInstanceVars[i].type, false, true, true, meta->regexpClass->slotCount++); meta->defineInstanceMember(meta->regexpClass, &meta->cxt, mn->name, *mn->nsList, Attribute::NoOverride, false, m, 0); } diff --git a/js2/src/js2string.cpp b/js2/src/js2string.cpp index 9f421e9145e..50a6b7b757b 100644 --- a/js2/src/js2string.cpp +++ b/js2/src/js2string.cpp @@ -175,7 +175,7 @@ static js2val String_match(JS2Metadata *meta, const js2val thisValue, js2val *ar else { js2val globalMultilineVal; js2val regexpClassVal = OBJECT_TO_JS2VAL(meta->regexpClass); - if (!meta->classClass->ReadPublic(meta, ®expClassVal, meta->engine->allocStringPtr("multiline"), RunPhase, &globalMultilineVal)) + if (!meta->classClass->ReadPublic(meta, ®expClassVal, meta->world.identifiers["multiline"], RunPhase, &globalMultilineVal)) ASSERT(false); bool globalMultiline = meta->toBoolean(globalMultilineVal); @@ -195,7 +195,7 @@ static js2val String_match(JS2Metadata *meta, const js2val thisValue, js2val *ar DEFINE_ROOTKEEPER(meta, rk3, matchStr); if (A == NULL) A = new (meta) ArrayInstance(meta, meta->arrayClass->prototype, meta->arrayClass); - meta->arrayClass->WritePublic(meta, OBJECT_TO_JS2VAL(A), meta->engine->numberToString(index), true, matchStr); + meta->arrayClass->WritePublic(meta, OBJECT_TO_JS2VAL(A), meta->engine->numberToStringAtom(index), true, matchStr); index++; } thisInst->setLastIndex(meta, meta->engine->allocNumber((float64)lastIndex)); @@ -209,7 +209,7 @@ static const String interpretDollar(JS2Metadata *meta, const String *replaceStr, const char16 *dollarValue = replaceStr->begin() + dollarPos + 1; switch (*dollarValue) { case '$': - return *meta->engine->Dollar_StringAtom; + return meta->engine->Dollar_StringAtom; case '&': return searchStr->substr((uint32)match->startIndex, (uint32)match->endIndex - match->startIndex); case '`': @@ -242,7 +242,7 @@ static const String interpretDollar(JS2Metadata *meta, const String *replaceStr, // fall thru default: skip = 1; - return *meta->engine->Dollar_StringAtom; + return meta->engine->Dollar_StringAtom; } } @@ -442,7 +442,7 @@ static js2val String_split(JS2Metadata *meta, const js2val thisValue, js2val *ar strSplitMatch(S, 0, R, z); if (!z.failure) return result; - meta->arrayClass->WritePublic(meta, OBJECT_TO_JS2VAL(A), meta->engine->numberToString((int32)0), true, STRING_TO_JS2VAL(S)); + meta->arrayClass->WritePublic(meta, OBJECT_TO_JS2VAL(A), meta->engine->numberToStringAtom((int32)0), true, STRING_TO_JS2VAL(S)); return result; } @@ -456,7 +456,7 @@ static js2val String_split(JS2Metadata *meta, const js2val thisValue, js2val *ar step11: if (q == s) { v = meta->engine->allocString(S, p, (s - p)); - meta->arrayClass->WritePublic(meta, OBJECT_TO_JS2VAL(A), meta->engine->numberToString(getLength(meta, A)), true, v); + meta->arrayClass->WritePublic(meta, OBJECT_TO_JS2VAL(A), meta->engine->numberToStringAtom(getLength(meta, A)), true, v); return result; } MatchResult z; @@ -475,13 +475,13 @@ step11: } T = meta->engine->allocStringPtr(S, p, (q - p)); // XXX v = STRING_TO_JS2VAL(T); - meta->arrayClass->WritePublic(meta, OBJECT_TO_JS2VAL(A), meta->engine->numberToString(getLength(meta, A)), true, v); + meta->arrayClass->WritePublic(meta, OBJECT_TO_JS2VAL(A), meta->engine->numberToStringAtom(getLength(meta, A)), true, v); if (getLength(meta, A) == lim) return result; p = e; for (uint32 i = 0; i < z.capturesCount; i++) { - meta->arrayClass->WritePublic(meta, OBJECT_TO_JS2VAL(A), meta->engine->numberToString(getLength(meta, A)), true, z.captures[i]); + meta->arrayClass->WritePublic(meta, OBJECT_TO_JS2VAL(A), meta->engine->numberToStringAtom(getLength(meta, A)), true, z.captures[i]); if (getLength(meta, A) == lim) return result; } @@ -498,7 +498,7 @@ static js2val String_charAt(JS2Metadata *meta, const js2val thisValue, js2val *a pos = meta->valToUInt32(argv[0]); if ((pos < 0) || (pos >= str->size())) - return STRING_TO_JS2VAL(meta->engine->Empty_StringAtom); + return meta->engine->allocString(meta->engine->Empty_StringAtom); else return meta->engine->allocString(new String(1, (*str)[pos])); // XXX @@ -694,7 +694,7 @@ static js2val String_slice(JS2Metadata *meta, const js2val thisValue, js2val *ar end = sourceLength; if (start > end) - return STRING_TO_JS2VAL(meta->engine->Empty_StringAtom); + return meta->engine->allocString(meta->engine->Empty_StringAtom); return meta->engine->allocString(sourceString->substr(start, end - start)); } diff --git a/js2/src/world.cpp b/js2/src/world.cpp index 6c6c7ef51a5..e5558aa432f 100644 --- a/js2/src/world.cpp +++ b/js2/src/world.cpp @@ -58,7 +58,6 @@ JS::StringAtom &JS::StringAtomTable::operator[](const String &s) return ht.insert(r, s); } - JS::World::World() { Token::initKeywords(*this); diff --git a/js2/src/world.h b/js2/src/world.h index 095a03faf38..c67f36002be 100644 --- a/js2/src/world.h +++ b/js2/src/world.h @@ -71,6 +71,8 @@ namespace JavaScript { StringAtom &operator[](const String &s); StringAtom &operator[](const char *s) {return operator[](widenCString(s));} void clear() { ht.clear(); } + bool hasEntry(const String &s) { HT::Reference r(ht, s); return r; } + }; #ifdef DIKDIK