From 4fb72211d2d8bb59ff23cac4ecf00eb7ecf45830 Mon Sep 17 00:00:00 2001 From: "rogerl%netscape.com" Date: Mon, 10 Mar 2003 20:00:20 +0000 Subject: [PATCH] String & Array class fixes. git-svn-id: svn://10.0.0.236/trunk@139210 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/js2/src/js2array.cpp | 24 +++++++++++++----------- mozilla/js2/src/js2engine.cpp | 4 ++-- mozilla/js2/src/js2metadata.cpp | 6 ++++-- mozilla/js2/src/js2metadata.h | 7 +++++++ mozilla/js2/src/js2string.cpp | 12 +++++++++--- 5 files changed, 35 insertions(+), 18 deletions(-) diff --git a/mozilla/js2/src/js2array.cpp b/mozilla/js2/src/js2array.cpp index 9330c413a2d..42bb1df09cd 100644 --- a/mozilla/js2/src/js2array.cpp +++ b/mozilla/js2/src/js2array.cpp @@ -72,15 +72,18 @@ js2val setLength(JS2Metadata *meta, JS2Object *obj, uint32 newLength) { js2val result = meta->engine->allocNumber(newLength); - uint32 length = getLength(meta, obj); - if (newLength < length) { - // need to delete all the elements above the new length - // XXX (But only for array instances!) XXX - LookupKind lookup(false, JS2VAL_NULL); - bool deleteResult; - for (uint32 i = newLength; i < length; i++) { - meta->mn1->name = meta->engine->numberToString(i); - meta->deleteProperty(OBJECT_TO_JS2VAL(obj), meta->mn1, &lookup, RunPhase, &deleteResult); + if ((obj->kind == PrototypeInstanceKind) + || (checked_cast(obj)->type == meta->arrayClass)) { + uint32 length = getLength(meta, obj); + if (newLength < length) { + // need to delete all the elements above the new length + // XXX (But only for array instances, maybe should have setArrayLength as a specialization) + LookupKind lookup(false, JS2VAL_NULL); + bool deleteResult; + for (uint32 i = newLength; i < length; i++) { + meta->mn1->name = meta->engine->numberToString(i); + meta->deleteProperty(OBJECT_TO_JS2VAL(obj), meta->mn1, &lookup, RunPhase, &deleteResult); + } } } @@ -128,8 +131,7 @@ js2val Array_Constructor(JS2Metadata *meta, const js2val /*thisValue*/, js2val * const DynamicPropertyMap::value_type e(*meta->engine->numberToString(i), DynamicPropertyValue(argv[i], DynamicPropertyValue::ENUMERATE)); arrInst->dynamicProperties.insert(e); } - const DynamicPropertyMap::value_type e(*meta->engine->length_StringAtom, DynamicPropertyValue(INT_TO_JS2VAL(i), DynamicPropertyValue::PERMANENT)); - arrInst->dynamicProperties.insert(e); + setLength(meta, arrInst, i); } } JS2Object::removeRoot(ri); diff --git a/mozilla/js2/src/js2engine.cpp b/mozilla/js2/src/js2engine.cpp index acf62ac7ce9..477e22ada56 100644 --- a/mozilla/js2/src/js2engine.cpp +++ b/mozilla/js2/src/js2engine.cpp @@ -394,8 +394,8 @@ namespace MetaData { INIT_STRINGATOM(Function), INIT_STRINGATOM(Object), INIT_STRINGATOM(object), - Empty_StringAtom(&world.identifiers[""]), - Dollar_StringAtom(&world.identifiers["$"]), + Empty_StringAtom(allocStringPtr(&world.identifiers[""])), + Dollar_StringAtom(allocStringPtr(&world.identifiers["$"])), INIT_STRINGATOM(prototype), INIT_STRINGATOM(length), INIT_STRINGATOM(toString), diff --git a/mozilla/js2/src/js2metadata.cpp b/mozilla/js2/src/js2metadata.cpp index 8e4071b6cd5..c0fe2dcd326 100644 --- a/mozilla/js2/src/js2metadata.cpp +++ b/mozilla/js2/src/js2metadata.cpp @@ -3592,7 +3592,8 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... setLength(this, container, newLength); } else - i->second.value = newValue; + if ((i->second.flags & DynamicPropertyValue::READONLY) == 0) + i->second.value = newValue; return true; } if (!createIfMissing) @@ -4318,7 +4319,7 @@ deleteClassProperty: NamespaceList publicNamespaceList; publicNamespaceList.push_back(publicNamespace); - // Adding "prototype" & "length" as static members of the class - not dynamic properties; XXX + // Adding "prototype" & "length", etc as static members of the class - not dynamic properties; XXX env->addFrame(builtinClass); { Variable *v = new Variable(builtinClass, OBJECT_TO_JS2VAL(builtinClass->prototype), true); @@ -4333,6 +4334,7 @@ deleteClassProperty: callInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_INACCESSIBLE, true), pf->code); v = new Variable(functionClass, OBJECT_TO_JS2VAL(callInst), true); defineLocalMember(env, &world.identifiers[pf->name], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0); + writeDynamicProperty(callInst, new Multiname(engine->length_StringAtom, publicNamespace), true, INT_TO_JS2VAL(pf->length), RunPhase); pf++; } } diff --git a/mozilla/js2/src/js2metadata.h b/mozilla/js2/src/js2metadata.h index fa7157a0079..834e2733fbb 100644 --- a/mozilla/js2/src/js2metadata.h +++ b/mozilla/js2/src/js2metadata.h @@ -199,7 +199,14 @@ public: static void markJS2Value(js2val v); virtual void writeProperty(JS2Metadata *meta, const String *name, js2val newValue, uint32 flags) { ASSERT(false); } +}; +class RootKeeper { +public: + RootKeeper(void *t) : ri(JS2Object::addRoot(t)) { } + ~RootKeeper() { JS2Object::removeRoot(ri); } + + JS2Object::RootIterator ri; }; class Attribute : public JS2Object { diff --git a/mozilla/js2/src/js2string.cpp b/mozilla/js2/src/js2string.cpp index 6c6ab2f815d..359f27f14f4 100644 --- a/mozilla/js2/src/js2string.cpp +++ b/mozilla/js2/src/js2string.cpp @@ -66,7 +66,9 @@ js2val String_Constructor(JS2Metadata *meta, const js2val /*thisValue*/, js2val strInst->mValue = meta->engine->allocStringPtr(meta->toString(argv[0])); else strInst->mValue = meta->engine->allocStringPtr(""); - const DynamicPropertyMap::value_type e(*meta->engine->length_StringAtom, DynamicPropertyValue(meta->engine->allocNumber(strInst->mValue->length()), DynamicPropertyValue::PERMANENT)); + const DynamicPropertyMap::value_type e(*meta->engine->length_StringAtom, + DynamicPropertyValue(meta->engine->allocNumber(strInst->mValue->length()), + DynamicPropertyValue::READONLY | DynamicPropertyValue::PERMANENT)); strInst->dynamicProperties.insert(e); JS2Object::removeRoot(ri); return thatValue; @@ -172,6 +174,7 @@ static js2val String_match(JS2Metadata *meta, const js2val thisValue, js2val *ar } else { PrototypeInstance *A = new ArrayInstance(meta, meta->arrayClass->prototype, meta->arrayClass); + RootKeeper rk(&A); int32 index = 0; int32 lastIndex = 0; while (true) { @@ -408,6 +411,7 @@ static js2val String_split(JS2Metadata *meta, const js2val thisValue, js2val *ar js2val result = OBJECT_TO_JS2VAL(new ArrayInstance(meta, meta->arrayClass->prototype, meta->arrayClass)); ArrayInstance *A = checked_cast(JS2VAL_TO_OBJECT(result)); + RootKeeper rk(&A); uint32 lim; js2val separatorV = (argc > 0) ? argv[0] : JS2VAL_UNDEFINED; @@ -787,14 +791,16 @@ void initStringObject(JS2Metadata *meta) FunctionData staticFunctions[] = { - { "fromCharCode", 1, String_fromCharCode }, + { "fromCharCode", 1, String_fromCharCode }, { NULL } }; StringInstance *strInst = new StringInstance(meta, meta->objectClass->prototype, meta->stringClass); meta->stringClass->prototype = strInst; strInst->mValue = meta->engine->allocStringPtr(""); - const DynamicPropertyMap::value_type e(*meta->engine->length_StringAtom, DynamicPropertyValue(meta->engine->allocNumber(strInst->mValue->length()), DynamicPropertyValue::PERMANENT)); + const DynamicPropertyMap::value_type e(*meta->engine->length_StringAtom, + DynamicPropertyValue(meta->engine->allocNumber(strInst->mValue->length()), + DynamicPropertyValue::READONLY | DynamicPropertyValue::PERMANENT)); strInst->dynamicProperties.insert(e); meta->initBuiltinClass(meta->stringClass, &prototypeFunctions[0], &staticFunctions[0], String_Constructor, String_Call);