From 84847ff0bb95a5b490d36435a684d00a484e56fc Mon Sep 17 00:00:00 2001 From: "rogerl%netscape.com" Date: Fri, 9 May 2003 23:05:01 +0000 Subject: [PATCH] New implementation of read/write handling, fixed gc bugs etc. git-svn-id: svn://10.0.0.236/trunk@142286 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/js2/src/js2array.cpp | 37 +++--- mozilla/js2/src/js2engine.cpp | 16 ++- mozilla/js2/src/js2engine.h | 10 +- mozilla/js2/src/js2error.cpp | 1 - mozilla/js2/src/js2eval.cpp | 119 +++++++++++------- mozilla/js2/src/js2metadata.cpp | 102 ++++++++------- mozilla/js2/src/js2metadata.h | 75 +++++------ mozilla/js2/src/js2op_access.cpp | 61 +++------ mozilla/js2/src/js2op_arithmetic.cpp | 65 ++++------ mozilla/js2/src/js2op_invocation.cpp | 10 +- mozilla/js2/src/regexp/regexp.h | 6 - .../src/winbuild/Epimetheus/Epimetheus.dsp | 4 +- 12 files changed, 244 insertions(+), 262 deletions(-) diff --git a/mozilla/js2/src/js2array.cpp b/mozilla/js2/src/js2array.cpp index 1714b1f0646..e9443ef00e5 100644 --- a/mozilla/js2/src/js2array.cpp +++ b/mozilla/js2/src/js2array.cpp @@ -84,8 +84,7 @@ js2val setLength(JS2Metadata *meta, JS2Object *obj, uint32 newLength) } Multiname *mn = new Multiname(meta->engine->length_StringAtom, meta->publicNamespace); DEFINE_ROOTKEEPER(rk, mn); - LookupKind lookup(false, JS2VAL_NULL); - defaultWriteProperty(meta, OBJECT_TO_JS2VAL(obj), meta->arrayClass, mn, &lookup, true, result, false); + defaultWriteProperty(meta, OBJECT_TO_JS2VAL(obj), meta->arrayClass, mn, meta->env, true, result, false); } else { JS2Class *c = meta->objectType(obj); @@ -227,6 +226,7 @@ js2val Array_concat(JS2Metadata *meta, const js2val thisValue, js2val *argv, uin js2val result = OBJECT_TO_JS2VAL(new ArrayInstance(meta, meta->arrayClass->prototype, meta->arrayClass)); ArrayInstance *A = checked_cast(JS2VAL_TO_OBJECT(result)); + DEFINE_ROOTKEEPER(rk, A); uint32 n = 0; uint32 i = 0; @@ -383,6 +383,7 @@ static js2val Array_slice(JS2Metadata *meta, const js2val thisValue, js2val *arg js2val result = OBJECT_TO_JS2VAL(new ArrayInstance(meta, meta->arrayClass->prototype, meta->arrayClass)); ArrayInstance *A = checked_cast(JS2VAL_TO_OBJECT(result)); + DEFINE_ROOTKEEPER(rk, A); uint32 length = getLength(meta, thisObj); @@ -583,25 +584,22 @@ static js2val Array_sort(JS2Metadata *meta, const js2val thisValue, js2val *argv JS2Object *thisObj = JS2VAL_TO_OBJECT(thatValue); uint32 length = getLength(meta, thisObj); - if (length > 0) { - uint32 i; - js2val *vec = new js2val[length]; - - JS2Class *c = meta->objectType(thisObj); - // XXX Need to root the Strings somewhere, this'll do for now.. - Multiname *mn1 = new Multiname(meta->publicNamespace); - DEFINE_ROOTKEEPER(rk1, mn1); - for (i = 0; i < length; i++) { - mn1->name = meta->engine->numberToString(i); - c->readPublic(meta, &thatValue, c, mn1->name, RunPhase, &vec[i]); - } + uint32 i; + // XXX bogus! new[] was supposed to behave itself, not just assert fail or crash + if (length > 0x1000000) + meta->reportError(Exception::internalError, "out of memory", meta->engine->errorPos()); - js_qsort(vec, length, &ca); + js2val *vec = new js2val[length]; + + JS2Class *c = meta->objectType(thisObj); + for (i = 0; i < length; i++) { + c->readPublic(meta, &thatValue, c, meta->engine->numberToString(i), RunPhase, &vec[i]); + } - for (i = 0; i < length; i++) { - mn1->name = meta->engine->numberToString(i); - c->writePublic(meta, thatValue, c, mn1->name, true, vec[i]); - } + js_qsort(vec, length, &ca); + + for (i = 0; i < length; i++) { + c->writePublic(meta, thatValue, c, meta->engine->numberToString(i), true, vec[i]); } return thatValue; } @@ -618,6 +616,7 @@ static js2val Array_splice(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)); + DEFINE_ROOTKEEPER(rk, A); int32 arg0 = meta->toInteger(argv[0]); uint32 start; diff --git a/mozilla/js2/src/js2engine.cpp b/mozilla/js2/src/js2engine.cpp index 1cb2fa8fd6c..160514012a9 100644 --- a/mozilla/js2/src/js2engine.cpp +++ b/mozilla/js2/src/js2engine.cpp @@ -97,6 +97,11 @@ namespace MetaData { DEFINE_ROOTKEEPER(rk2, astr); DEFINE_ROOTKEEPER(rk3, bstr); + DEFINE_ROOTKEEPER(rk4, a); + DEFINE_ROOTKEEPER(rk5, b); + DEFINE_ROOTKEEPER(rk6, baseVal); + DEFINE_ROOTKEEPER(rk7, indexVal); + retval = JS2VAL_VOID; while (true) { try { @@ -125,6 +130,7 @@ namespace MetaData { // one that matches the handler's. The bytecode container, pc and // sp are all reset appropriately, and execution continues. HandlerData *hndlr = (HandlerData *)mTryStack.top(); +// mTryStack.pop(); ActivationFrame *curAct = (activationStackEmpty()) ? NULL : (activationStackTop - 1); js2val x = JS2VAL_UNDEFINED; @@ -247,6 +253,13 @@ namespace MetaData { return result; } + String *JS2Engine::allocStringPtr(const char16 *s, uint32 length) + { + String *p = (String *)(JS2Object::alloc(sizeof(String), PondScum::StringFlag)); + String *result = new (p) String(s, length); + return result; + } + String *JS2Engine::allocStringPtr(const String *s) { String *p = (String *)(JS2Object::alloc(sizeof(String), PondScum::StringFlag)); @@ -977,7 +990,8 @@ namespace MetaData { // jump to start of new bytecodeContainer void JS2Engine::jsr(Phase execPhase, BytecodeContainer *new_bCon, uint32 stackBase, js2val returnVal, Environment *env) { - ASSERT(activationStackTop < (activationStack + MAX_ACTIVATION_STACK)); + if (activationStackTop >= (activationStack + MAX_ACTIVATION_STACK)) + meta->reportError(Exception::internalError, "out of activation stack", meta->engine->errorPos()); activationStackTop->bCon = bCon; activationStackTop->pc = pc; activationStackTop->phase = phase; diff --git a/mozilla/js2/src/js2engine.h b/mozilla/js2/src/js2engine.h index 612854b9a5a..7ba11819c1e 100644 --- a/mozilla/js2/src/js2engine.h +++ b/mozilla/js2/src/js2engine.h @@ -238,12 +238,14 @@ public: js2val posInfValue; js2val negInfValue; - js2val allocString(const String *s) { return STRING_TO_JS2VAL(allocStringPtr(s)); } - js2val allocString(const String &s) { return allocString(&s); } - js2val allocString(const char *s) { return STRING_TO_JS2VAL(allocStringPtr(s)); } - js2val allocString(const String *s, uint32 index, uint32 length) { return STRING_TO_JS2VAL(allocStringPtr(s, index, length)); } + js2val allocString(const String *s) { return STRING_TO_JS2VAL(allocStringPtr(s)); } + js2val allocString(const String &s) { return allocString(&s); } + js2val allocString(const char *s) { return STRING_TO_JS2VAL(allocStringPtr(s)); } + js2val allocString(const char16 *s, uint32 length) { return STRING_TO_JS2VAL(allocStringPtr(s, length)); } + js2val allocString(const String *s, uint32 index, uint32 length) { return STRING_TO_JS2VAL(allocStringPtr(s, index, length)); } String *allocStringPtr(const String *s); String *allocStringPtr(const char *s); + String *allocStringPtr(const char16 *s, uint32 length); String *allocStringPtr(const String *s, uint32 index, uint32 length); String *concatStrings(const String *s1, const String *s2); diff --git a/mozilla/js2/src/js2error.cpp b/mozilla/js2/src/js2error.cpp index 522c26fd331..e4cb96479ea 100644 --- a/mozilla/js2/src/js2error.cpp +++ b/mozilla/js2/src/js2error.cpp @@ -108,7 +108,6 @@ js2val Error_toString(JS2Metadata *meta, const js2val thisValue, js2val *argv, u { js2val thatValue = thisValue; js2val result; - LookupKind lookup(false, JS2VAL_NULL); Multiname mn(&meta->world.identifiers["message"], meta->publicNamespace); JS2Class *c = meta->objectType(thatValue); diff --git a/mozilla/js2/src/js2eval.cpp b/mozilla/js2/src/js2eval.cpp index 762e23585ae..825209f0888 100644 --- a/mozilla/js2/src/js2eval.cpp +++ b/mozilla/js2/src/js2eval.cpp @@ -625,7 +625,7 @@ namespace MetaData { } - bool defaultReadProperty(JS2Metadata *meta, js2val *base, JS2Class *limit, Multiname *multiname, LookupKind *lookupKind, Phase phase, js2val *rval) + bool defaultReadProperty(JS2Metadata *meta, js2val *base, JS2Class *limit, Multiname *multiname, Environment *env, Phase phase, js2val *rval) { InstanceMember *mBase = meta->findBaseInstanceMember(limit, multiname, ReadAccess); if (mBase) @@ -635,9 +635,10 @@ namespace MetaData { Member *m = meta->findCommonMember(base, multiname, ReadAccess, false); if (m == NULL) { - if (lookupKind->isPropertyLookup() && JS2VAL_IS_OBJECT(*base) - && ( (JS2VAL_TO_OBJECT(*base)->kind == SimpleInstanceKind) && !checked_cast(JS2VAL_TO_OBJECT(*base))->sealed) - || ( (JS2VAL_TO_OBJECT(*base)->kind == PackageKind) && !checked_cast(JS2VAL_TO_OBJECT(*base))->sealed) ) { + if ((env == NULL) + && JS2VAL_IS_OBJECT(*base) + && (( (JS2VAL_TO_OBJECT(*base)->kind == SimpleInstanceKind) && !checked_cast(JS2VAL_TO_OBJECT(*base))->sealed) + || ( (JS2VAL_TO_OBJECT(*base)->kind == PackageKind) && !checked_cast(JS2VAL_TO_OBJECT(*base))->sealed) ) ) { if (phase == CompilePhase) meta->reportError(Exception::compileExpressionError, "Inappropriate compile time expression", meta->engine->errorPos()); else { @@ -661,14 +662,12 @@ namespace MetaData { case Member::InstanceMethodMember: case Member::InstanceGetterMember: case Member::InstanceSetterMember: - if ( (JS2VAL_IS_OBJECT(*base) && (JS2VAL_TO_OBJECT(*base)->kind != ClassKind)) - || lookupKind->isPropertyLookup()) - meta->reportError(Exception::propertyAccessError, "Illegal access to instance member", meta->engine->errorPos()); - if (JS2VAL_IS_VOID(lookupKind->thisObject)) - meta->reportError(Exception::propertyAccessError, "Illegal access to instance member", meta->engine->errorPos()); - if (JS2VAL_IS_UNINITIALIZED(lookupKind->thisObject)) - meta->reportError(Exception::compileExpressionError, "Inappropriate compile time expression", meta->engine->errorPos()); - return meta->readInstanceMember(lookupKind->thisObject, meta->objectType(lookupKind->thisObject), checked_cast(m), phase, rval); + { + if (!JS2VAL_IS_OBJECT(*base) || (JS2VAL_TO_OBJECT(*base)->kind != ClassKind) || (env == NULL)) + meta->reportError(Exception::referenceError, "Can't read an instance member without supplying an instance", meta->engine->errorPos()); + js2val thisVal = env->readImplicitThis(meta); + return meta->readInstanceMember(thisVal, meta->objectType(thisVal), checked_cast(m), phase, rval); + } default: NOT_REACHED("bad member kind"); return false; @@ -679,44 +678,44 @@ namespace MetaData { { // XXX could speed up by pushing knowledge of single namespace? DEFINE_ROOTKEEPER(rk1, name); - LookupKind lookup(false, JS2VAL_NULL); Multiname *mn = new Multiname(name, meta->publicNamespace); DEFINE_ROOTKEEPER(rk, mn); - return defaultReadProperty(meta, base, limit, mn, &lookup, phase, rval); + return defaultReadProperty(meta, base, limit, mn, NULL, phase, rval); } bool defaultDeletePublic(JS2Metadata *meta, js2val base, JS2Class *limit, const String *name, bool *result) { DEFINE_ROOTKEEPER(rk1, name); - // XXX could speed up by pushing knowledge of single namespace & lookup? - LookupKind lookup(false, JS2VAL_NULL); + // XXX could speed up by pushing knowledge of single namespace? Multiname *mn = new Multiname(name, meta->publicNamespace); DEFINE_ROOTKEEPER(rk, mn); - return defaultDeleteProperty(meta, base, limit, mn, &lookup, result); + return defaultDeleteProperty(meta, base, limit, mn, NULL, result); } bool defaultWritePublicProperty(JS2Metadata *meta, js2val base, JS2Class *limit, const String *name, bool createIfMissing, js2val newValue) { DEFINE_ROOTKEEPER(rk1, name); // XXX could speed up by pushing knowledge of single namespace? - LookupKind lookup(false, JS2VAL_NULL); Multiname *mn = new Multiname(name, meta->publicNamespace); DEFINE_ROOTKEEPER(rk, mn); - return defaultWriteProperty(meta, base, limit, mn, &lookup, createIfMissing, newValue, false); + return defaultWriteProperty(meta, base, limit, mn, NULL, createIfMissing, newValue, false); } - bool defaultBracketRead(JS2Metadata *meta, js2val *base, JS2Class *limit, Multiname *multiname, Phase phase, js2val *rval) + bool defaultBracketRead(JS2Metadata *meta, js2val *base, JS2Class *limit, js2val indexVal, Phase phase, js2val *rval) { - LookupKind lookup(false, JS2VAL_NULL); - return limit->read(meta, base, limit, multiname, &lookup, phase, rval); + const String *indexStr = meta->toString(indexVal); + DEFINE_ROOTKEEPER(rk, indexStr); + Multiname *mn = new Multiname(indexStr, meta->publicNamespace); + DEFINE_ROOTKEEPER(rk1, mn); + return limit->read(meta, base, limit, mn, NULL, phase, rval); } - bool arrayWriteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, LookupKind *lookupKind, bool createIfMissing, js2val newValue, bool initFlag) + bool arrayClass_WriteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, Environment *env, bool createIfMissing, js2val newValue, bool initFlag) { ASSERT(JS2VAL_IS_OBJECT(base)); JS2Object *obj = JS2VAL_TO_OBJECT(base); - bool result = defaultWriteProperty(meta, base, limit, multiname, lookupKind, createIfMissing, newValue, false); + bool result = defaultWriteProperty(meta, base, limit, multiname, env, createIfMissing, newValue, false); if (result && (multiname->nsList->size() == 1) && (multiname->nsList->back() == meta->publicNamespace)) { const char16 *numEnd; float64 f = stringToDouble(multiname->name->data(), multiname->name->data() + multiname->name->length(), numEnd); @@ -735,17 +734,16 @@ namespace MetaData { return result; } - bool arrayWritePublic(JS2Metadata *meta, js2val base, JS2Class *limit, const String *name, bool createIfMissing, js2val newValue) + bool arrayClass_WritePublic(JS2Metadata *meta, js2val base, JS2Class *limit, const String *name, bool createIfMissing, js2val newValue) { DEFINE_ROOTKEEPER(rk1, name); // XXX could speed up by pushing knowledge of single namespace? - LookupKind lookup(false, JS2VAL_NULL); Multiname *mn = new Multiname(name, meta->publicNamespace); DEFINE_ROOTKEEPER(rk, mn); - return arrayWriteProperty(meta, base, limit, mn, &lookup, createIfMissing, newValue, false); + return arrayClass_WriteProperty(meta, base, limit, mn, meta->env, createIfMissing, newValue, false); } - bool defaultWriteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, LookupKind *lookupKind, bool createIfMissing, js2val newValue, bool initFlag) + bool defaultWriteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, Environment *env, bool createIfMissing, js2val newValue, bool initFlag) { InstanceMember *mBase = meta->findBaseInstanceMember(limit, multiname, WriteAccess); if (mBase) { @@ -794,26 +792,29 @@ namespace MetaData { case Member::InstanceMethodMember: case Member::InstanceGetterMember: case Member::InstanceSetterMember: - if ( (JS2VAL_IS_OBJECT(base) && (JS2VAL_TO_OBJECT(base)->kind != ClassKind)) - || lookupKind->isPropertyLookup()) - meta->reportError(Exception::propertyAccessError, "Illegal access to instance member", meta->engine->errorPos()); - if (JS2VAL_IS_VOID(lookupKind->thisObject)) - meta->reportError(Exception::propertyAccessError, "Illegal access to instance member", meta->engine->errorPos()); - meta->writeInstanceMember(lookupKind->thisObject, meta->objectType(lookupKind->thisObject), checked_cast(m), newValue); - return true; + { + if ( !JS2VAL_IS_OBJECT(base) || (JS2VAL_TO_OBJECT(base)->kind != ClassKind) || (env == NULL)) + meta->reportError(Exception::referenceError, "Can't write an instance member withoutsupplying an instance", meta->engine->errorPos()); + js2val thisVal = env->readImplicitThis(meta); + meta->writeInstanceMember(thisVal, meta->objectType(thisVal), checked_cast(m), newValue); + return true; + } default: NOT_REACHED("bad member kind"); return false; } } - bool defaultBracketWrite(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, js2val newValue) + bool defaultBracketWrite(JS2Metadata *meta, js2val base, JS2Class *limit, js2val indexVal, js2val newValue) { - LookupKind lookup(false, JS2VAL_NULL); - return limit->write(meta, base, limit, multiname, &lookup, true, newValue, false); + const String *indexStr = meta->toString(indexVal); + DEFINE_ROOTKEEPER(rk, indexStr); + Multiname *mn = new Multiname(indexStr, meta->publicNamespace); + DEFINE_ROOTKEEPER(rk1, mn); + return limit->write(meta, base, limit, mn, NULL, true, newValue, false); } - bool defaultDeleteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, LookupKind *lookupKind, bool *result) + bool defaultDeleteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, Environment *env, bool *result) { InstanceMember *mBase = meta->findBaseInstanceMember(limit, multiname, WriteAccess); if (mBase) { @@ -882,12 +883,11 @@ VariableMemberCommon: case Member::InstanceMethodMember: case Member::InstanceGetterMember: case Member::InstanceSetterMember: - if ( (JS2VAL_IS_OBJECT(base) && (JS2VAL_TO_OBJECT(base)->kind != ClassKind)) || lookupKind->isPropertyLookup()) { + if ( (!JS2VAL_IS_OBJECT(base) || (JS2VAL_TO_OBJECT(base)->kind != ClassKind)) || (env == NULL)) { *result = false; return true; } - if (JS2VAL_IS_VOID(lookupKind->thisObject)) - meta->reportError(Exception::propertyAccessError, "Illegal access to instance member", meta->engine->errorPos()); + env->readImplicitThis(meta); *result = false; return true; default: @@ -896,10 +896,13 @@ VariableMemberCommon: } } - bool defaultBracketDelete(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, bool *result) + bool defaultBracketDelete(JS2Metadata *meta, js2val base, JS2Class *limit, js2val indexVal, bool *result) { - LookupKind lookup(false, JS2VAL_NULL); - return limit->deleteProperty(meta, base, limit, multiname, &lookup, result); + const String *indexStr = meta->toString(indexVal); + DEFINE_ROOTKEEPER(rk, indexStr); + Multiname *mn = new Multiname(indexStr, meta->publicNamespace); + DEFINE_ROOTKEEPER(rk1, mn); + return limit->deleteProperty(meta, base, limit, mn, NULL, result); } js2val defaultImplicitCoerce(JS2Metadata *meta, js2val newValue, JS2Class *isClass) @@ -943,6 +946,32 @@ VariableMemberCommon: return BOOLEAN_TO_JS2VAL(result); } + bool stringClass_BracketRead(JS2Metadata *meta, js2val *base, JS2Class *limit, js2val indexVal, Phase phase, js2val *rval) + { + if (JS2VAL_IS_INT(indexVal)) { + const String *str = NULL; + if (JS2VAL_IS_STRING(*base)) { + str = JS2VAL_TO_STRING(*base); + } + else { + ASSERT(JS2VAL_IS_OBJECT(*base)); + JS2Object *obj = JS2VAL_TO_OBJECT(*base); + ASSERT((obj->kind == SimpleInstanceKind) && (checked_cast(obj)->type == meta->stringClass)); + StringInstance *a = checked_cast(obj); + str = a->mValue; + } + int32 i = JS2VAL_TO_INT(indexVal); + if ((i >= 0) && (i < str->length())) + *rval = meta->engine->allocString(&(*str)[i], 1); + else + *rval = JS2VAL_UNDEFINED; + return true; + } + else + return defaultBracketRead(meta, base, limit, indexVal, phase, rval); + } + + }; // namespace MetaData }; // namespace Javascript diff --git a/mozilla/js2/src/js2metadata.cpp b/mozilla/js2/src/js2metadata.cpp index a7dcd1ada40..b85278f6772 100644 --- a/mozilla/js2/src/js2metadata.cpp +++ b/mozilla/js2/src/js2metadata.cpp @@ -2813,6 +2813,20 @@ doUnary: return false; } + js2val Environment::readImplicitThis(JS2Metadata *meta) + { + ParameterFrame *pFrame = getEnclosingParameterFrame(); + if (pFrame == NULL) + meta->reportError(Exception::referenceError, "Can't access instance members outside an instance method without supplying an instance object", meta->engine->errorPos()); + js2val thisVal = pFrame->thisObject; + if ((!JS2VAL_IS_OBJECT(thisVal) || JS2VAL_IS_NULL(thisVal)) || !pFrame->isInstance || !pFrame->isConstructor) + meta->reportError(Exception::referenceError, "Can't access instance members inside a non-instance method without supplying an instance object", meta->engine->errorPos()); + if (!pFrame->superConstructorCalled) + meta->reportError(Exception::uninitializedError, "Can't access instance members from within a constructor before the superconstructor has been called", meta->engine->errorPos()); + return thisVal; + } + + // Read the value of a lexical reference - it's an error if that reference // doesn't have a binding somewhere. // Attempt the read in each frame in the current environment, stopping at the @@ -2822,7 +2836,6 @@ doUnary: { js2val a = JS2VAL_VOID; findThis(meta, false, &a); - LookupKind lookup(true, a); FrameListIterator fi = getBegin(); bool result = false; while (fi != getEnd()) { @@ -2832,7 +2845,7 @@ doUnary: { JS2Class *limit = meta->objectType(OBJECT_TO_JS2VAL(*fi)); js2val frame = OBJECT_TO_JS2VAL(*fi); - result = limit->read(meta, &frame, limit, multiname, &lookup, phase, rval); + result = limit->read(meta, &frame, limit, multiname, this, phase, rval); } break; case SystemKind: @@ -2850,7 +2863,7 @@ doUnary: // XXX uninitialized 'with' object? js2val withVal = OBJECT_TO_JS2VAL(wf->obj); JS2Class *limit = meta->objectType(withVal); - result = limit->read(meta, &withVal, limit, multiname, &lookup, phase, rval); + result = limit->read(meta, &withVal, limit, multiname, this, phase, rval); if (result && base) *base = withVal; } @@ -2869,7 +2882,6 @@ doUnary: { js2val a = JS2VAL_VOID; findThis(meta, false, &a); - LookupKind lookup(true, a); FrameListIterator fi = getBegin(); bool result = false; while (fi != getEnd()) { @@ -2878,7 +2890,7 @@ doUnary: case PackageKind: { JS2Class *limit = meta->objectType(OBJECT_TO_JS2VAL(*fi)); - result = limit->write(meta, OBJECT_TO_JS2VAL(*fi), limit, multiname, &lookup, false, newValue, false); + result = limit->write(meta, OBJECT_TO_JS2VAL(*fi), limit, multiname, this, false, newValue, false); } break; case SystemKind: @@ -2897,7 +2909,7 @@ doUnary: WithFrame *wf = checked_cast(*fi); // XXX uninitialized 'with' object? JS2Class *limit = meta->objectType(OBJECT_TO_JS2VAL(wf->obj)); - result = limit->write(meta, OBJECT_TO_JS2VAL(wf->obj), limit, multiname, &lookup, false, newValue, false); + result = limit->write(meta, OBJECT_TO_JS2VAL(wf->obj), limit, multiname, this, false, newValue, false); } break; } @@ -2908,7 +2920,7 @@ doUnary: if (createIfMissing) { Package *pkg = getPackageFrame(); JS2Class *limit = meta->objectType(OBJECT_TO_JS2VAL(pkg)); - result = limit->write(meta, OBJECT_TO_JS2VAL(pkg), limit, multiname, &lookup, true, newValue, false); + result = limit->write(meta, OBJECT_TO_JS2VAL(pkg), limit, multiname, this, true, newValue, false); if (result) return; } @@ -2923,7 +2935,6 @@ doUnary: { js2val a = JS2VAL_VOID; findThis(meta, false, &a); - LookupKind lookup(true, a); FrameListIterator fi = getBegin(); bool result = false; while (fi != getEnd()) { @@ -2932,7 +2943,7 @@ doUnary: case PackageKind: { JS2Class *limit = meta->objectType(OBJECT_TO_JS2VAL(*fi)); - result = limit->write(meta, OBJECT_TO_JS2VAL(*fi), limit, multiname, &lookup, false, newValue, true); + result = limit->write(meta, OBJECT_TO_JS2VAL(*fi), limit, multiname, this, false, newValue, true); } break; case SystemKind: @@ -2951,7 +2962,7 @@ doUnary: WithFrame *wf = checked_cast(*fi); // XXX uninitialized 'with' object? JS2Class *limit = meta->objectType(OBJECT_TO_JS2VAL(wf->obj)); - result = limit->write(meta, OBJECT_TO_JS2VAL(wf->obj), limit, multiname, &lookup, false, newValue, true); + result = limit->write(meta, OBJECT_TO_JS2VAL(wf->obj), limit, multiname, this, false, newValue, true); } break; } @@ -2963,7 +2974,7 @@ doUnary: ASSERT(false); Package *pkg = getPackageFrame(); JS2Class *limit = meta->objectType(OBJECT_TO_JS2VAL(pkg)); - result = limit->write(meta, OBJECT_TO_JS2VAL(pkg), limit, multiname, &lookup, true, newValue, true); + result = limit->write(meta, OBJECT_TO_JS2VAL(pkg), limit, multiname, this, true, newValue, true); if (result) return; } @@ -2974,7 +2985,6 @@ doUnary: { js2val a = JS2VAL_VOID; findThis(meta, false, &a); - LookupKind lookup(true, a); FrameListIterator fi = getBegin(); bool result = false; while (fi != getEnd()) { @@ -2983,7 +2993,7 @@ doUnary: case PackageKind: { JS2Class *limit = meta->objectType(OBJECT_TO_JS2VAL(*fi)); - if (limit->deleteProperty(meta, OBJECT_TO_JS2VAL(*fi), limit, multiname, &lookup, &result)) + if (limit->deleteProperty(meta, OBJECT_TO_JS2VAL(*fi), limit, multiname, this, &result)) return result; } break; @@ -3001,7 +3011,7 @@ doUnary: WithFrame *wf = checked_cast(*fi); // XXX uninitialized 'with' object? JS2Class *limit = meta->objectType(OBJECT_TO_JS2VAL(wf->obj)); - if (limit->deleteProperty(meta, OBJECT_TO_JS2VAL(wf->obj), limit, multiname, &lookup, &result)) + if (limit->deleteProperty(meta, OBJECT_TO_JS2VAL(wf->obj), limit, multiname, this, &result)) return result; } break; @@ -3773,16 +3783,16 @@ static const uint8 urlCharType[256] = return thisValue; } -bool nullClass_ReadProperty(JS2Metadata *meta, js2val *base, JS2Class *limit, Multiname *multiname, LookupKind *lookupKind, Phase phase, js2val *rval) { return false; } +bool nullClass_ReadProperty(JS2Metadata *meta, js2val *base, JS2Class *limit, Multiname *multiname, Environment *env, Phase phase, js2val *rval) { return false; } bool nullClass_ReadPublicProperty(JS2Metadata *meta, js2val *base, JS2Class *limit, const String *name, Phase phase, js2val *rval) { return false; } -bool nullClass_BracketRead(JS2Metadata *meta, js2val *base, JS2Class *limit, Multiname *multiname, Phase phase, js2val *rval) { return false; } -bool nullClass_arrayWriteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, LookupKind *lookupKind, bool createIfMissing, js2val newValue) { return false; } -bool nullClass_WriteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, LookupKind *lookupKind, bool createIfMissing, js2val newValue, bool initFlag) { return false; } +bool nullClass_BracketRead(JS2Metadata *meta, js2val *base, JS2Class *limit, js2val indexVal, Phase phase, js2val *rval) { return false; } +bool nullClass_arrayWriteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, Environment *env, bool createIfMissing, js2val newValue) { return false; } +bool nullClass_WriteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, Environment *env, bool createIfMissing, js2val newValue, bool initFlag) { return false; } bool nullClass_WritePublicProperty(JS2Metadata *meta, js2val base, JS2Class *limit, const String *name, bool createIfMissing, js2val newValue) { return false; } -bool nullClass_BracketWrite(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, js2val newValue) { return false; } -bool nullClass_DeleteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, LookupKind *lookupKind, bool *result) { return false; } +bool nullClass_BracketWrite(JS2Metadata *meta, js2val base, JS2Class *limit, js2val indexVal, js2val newValue) { return false; } +bool nullClass_DeleteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, Environment *env, bool *result) { return false; } bool nullClass_DeletePublic(JS2Metadata *meta, js2val base, JS2Class *limit, const String *name, bool *result) { return false; } -bool nullClass_BracketDelete(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, bool *result) { return false; } +bool nullClass_BracketDelete(JS2Metadata *meta, js2val base, JS2Class *limit, js2val indexVal, bool *result) { return false; } #define MAKEBUILTINCLASS(c, super, dynamic, final, name, defaultVal) c = new JS2Class(super, NULL, new Namespace(engine->private_StringAtom), dynamic, final, name); c->complete = true; c->defaultValue = defaultVal; @@ -3823,6 +3833,8 @@ bool nullClass_BracketDelete(JS2Metadata *meta, js2val base, JS2Class *limit, Mu integerClass->is = integerIs; MAKEBUILTINCLASS(characterClass, objectClass, false, true, engine->allocStringPtr(&world.identifiers["Character"]), JS2VAL_ZERO); MAKEBUILTINCLASS(stringClass, objectClass, false, true, engine->allocStringPtr(&world.identifiers["String"]), JS2VAL_NULL); + stringClass->bracketRead = stringClass_BracketRead; + 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); @@ -3955,8 +3967,8 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... /*** ECMA 3 Array Class ***/ MAKEBUILTINCLASS(arrayClass, objectClass, true, true, engine->allocStringPtr(&world.identifiers["Array"]), JS2VAL_NULL); - arrayClass->write = arrayWriteProperty; - arrayClass->writePublic = arrayWritePublic; + arrayClass->write = arrayClass_WriteProperty; + arrayClass->writePublic = arrayClass_WritePublic; v = new Variable(classClass, OBJECT_TO_JS2VAL(arrayClass), true); defineLocalMember(env, &world.identifiers["Array"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true); initArrayObject(this); @@ -4852,10 +4864,11 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... JS2Object *result = this; DEFINE_ROOTKEEPER(rk1, result); - JS2Object *obj = new SimpleInstance(meta, meta->objectClass->prototype, meta->objectClass); - DEFINE_ROOTKEEPER(rk2, obj); + JS2Object *protoObj = new SimpleInstance(meta, meta->objectClass->prototype, meta->objectClass); + DEFINE_ROOTKEEPER(rk2, protoObj); - meta->createDynamicProperty(this, meta->engine->prototype_StringAtom, OBJECT_TO_JS2VAL(obj), ReadWriteAccess, true, false); + 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); } @@ -5106,28 +5119,15 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... ************************************************************************************/ Pond JS2Object::pond(POND_SIZE, NULL); -#ifdef DEBUG std::list JS2Object::rootList; -#else - std::list JS2Object::rootList; -#endif // Add a pointer to the (address of a) gc-allocated object to the root list // (Note - we hand out an iterator, so it's essential to // use something like std::list that doesn't mess with locations) -#ifdef DEBUG JS2Object::RootIterator JS2Object::addRoot(RootKeeper *t) { return rootList.insert(rootList.end(), t); } -#else - JS2Object::RootIterator JS2Object::addRoot(void *t) - { - PondScum **p = (PondScum **)t; - ASSERT(p); - return rootList.insert(rootList.end(), p); - } -#endif // Remove a root pointer void JS2Object::removeRoot(RootIterator ri) @@ -5152,22 +5152,20 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... PondScum *scum = NULL; if (r->is_js2val) { js2val *valp = (js2val *)(r->p); - if (JS2VAL_IS_OBJECT(*valp)) - scum = ((PondScum *)(JS2VAL_TO_OBJECT(*valp))) - 1; + markJS2Value(*valp); } else { - JS2Object *objp = (JS2Object *)(r->p); - if (objp) - scum = ((PondScum *)objp - 1); - } - if (scum) { - ASSERT(scum->owner && (scum->getSize() >= sizeof(PondScum)) && (scum->owner->sanity == POND_SANITY)); - if (scum->isJS2Object()) { - JS2Object *obj = (JS2Object *)(scum + 1); - GCMARKOBJECT(obj) + JS2Object **objp = (JS2Object **)(r->p); + if (*objp) { + scum = ((PondScum *)(*objp) - 1); + ASSERT(scum->owner && (scum->getSize() >= sizeof(PondScum)) && (scum->owner->sanity == POND_SANITY)); + if (scum->isJS2Object()) { + JS2Object *obj = (JS2Object *)(scum + 1); + GCMARKOBJECT(obj) + } + else + mark(scum + 1); } - else - mark(scum + 1); } } return pond.moveUnmarkedToFreeList(); diff --git a/mozilla/js2/src/js2metadata.h b/mozilla/js2/src/js2metadata.h index bdd65687416..c2b55a7354c 100644 --- a/mozilla/js2/src/js2metadata.h +++ b/mozilla/js2/src/js2metadata.h @@ -56,7 +56,6 @@ class StringInstance; class FunctionInstance; class ArrayInstance; class RegExpInstance; -class LookupKind; class Package; typedef void (Invokable)(); @@ -64,35 +63,37 @@ typedef js2val (Callor)(JS2Metadata *meta, const js2val thisValue, js2val *argv, typedef js2val (Constructor)(JS2Metadata *meta, const js2val thisValue, js2val *argv, uint32 argc); typedef js2val (NativeCode)(JS2Metadata *meta, const js2val thisValue, js2val argv[], uint32 argc); -typedef bool (Read)(JS2Metadata *meta, js2val *base, JS2Class *limit, Multiname *multiname, LookupKind *lookupKind, Phase phase, js2val *rval); +typedef bool (Read)(JS2Metadata *meta, js2val *base, JS2Class *limit, Multiname *multiname, Environment *env, Phase phase, js2val *rval); typedef bool (ReadPublic)(JS2Metadata *meta, js2val *base, JS2Class *limit, const String *name, Phase phase, js2val *rval); -typedef bool (Write)(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, LookupKind *lookupKind, bool createIfMissing, js2val newValue, bool initFlag); +typedef bool (Write)(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, Environment *env, bool createIfMissing, js2val newValue, bool initFlag); typedef bool (WritePublic)(JS2Metadata *meta, js2val base, JS2Class *limit, const String *name, bool createIfMissing, js2val newValue); -typedef bool (DeleteProperty)(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, LookupKind *lookupKind, bool *result); +typedef bool (DeleteProperty)(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, Environment *env, bool *result); typedef bool (DeletePublic)(JS2Metadata *meta, js2val base, JS2Class *limit, const String *name, bool *result); -typedef bool (BracketRead)(JS2Metadata *meta, js2val *base, JS2Class *limit, Multiname *multiname, Phase phase, js2val *rval); -typedef bool (BracketWrite)(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, js2val newValue); -typedef bool (BracketDelete)(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, bool *result); +typedef bool (BracketRead)(JS2Metadata *meta, js2val *base, JS2Class *limit, js2val indexVal, Phase phase, js2val *rval); +typedef bool (BracketWrite)(JS2Metadata *meta, js2val base, JS2Class *limit, js2val indexVal, js2val newValue); +typedef bool (BracketDelete)(JS2Metadata *meta, js2val base, JS2Class *limit, js2val indexVal, bool *result); typedef js2val (ImplicitCoerce)(JS2Metadata *meta, js2val newValue, JS2Class *toClass); typedef js2val (Is)(JS2Metadata *meta, js2val newValue, JS2Class *isClass); -bool defaultReadProperty(JS2Metadata *meta, js2val *base, JS2Class *limit, Multiname *multiname, LookupKind *lookupKind, Phase phase, js2val *rval); +bool defaultReadProperty(JS2Metadata *meta, js2val *base, JS2Class *limit, Multiname *multiname, Environment *env, Phase phase, js2val *rval); bool defaultReadPublicProperty(JS2Metadata *meta, js2val *base, JS2Class *limit, const String *name, Phase phase, js2val *rval); -bool defaultBracketRead(JS2Metadata *meta, js2val *base, JS2Class *limit, Multiname *multiname, Phase phase, js2val *rval); -bool arrayWriteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, LookupKind *lookupKind, bool createIfMissing, js2val newValue, bool initFlag); -bool defaultWriteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, LookupKind *lookupKind, bool createIfMissing, js2val newValue, bool initFlag); +bool defaultBracketRead(JS2Metadata *meta, js2val *base, JS2Class *limit, js2val indexVal, Phase phase, js2val *rval); +bool defaultWriteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, Environment *env, bool createIfMissing, js2val newValue, bool initFlag); bool defaultWritePublicProperty(JS2Metadata *meta, js2val base, JS2Class *limit, const String *name, bool createIfMissing, js2val newValue); -bool defaultBracketWrite(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, js2val newValue); -bool defaultDeleteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, LookupKind *lookupKind, bool *result); +bool defaultBracketWrite(JS2Metadata *meta, js2val base, JS2Class *limit, js2val indexVal, js2val newValue); +bool defaultDeleteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, Environment *env, bool *result); bool defaultDeletePublic(JS2Metadata *meta, js2val base, JS2Class *limit, const String *name, bool *result); -bool defaultBracketDelete(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, bool *result); -bool arrayWritePublic(JS2Metadata *meta, js2val base, JS2Class *limit, const String *name, bool createIfMissing, js2val newValue); +bool defaultBracketDelete(JS2Metadata *meta, js2val base, JS2Class *limit, js2val indexVal, bool *result); + +bool arrayClass_WriteProperty(JS2Metadata *meta, js2val base, JS2Class *limit, Multiname *multiname, Environment *env, bool createIfMissing, js2val newValue, bool initFlag); +bool arrayClass_WritePublic(JS2Metadata *meta, js2val base, JS2Class *limit, const String *name, bool createIfMissing, js2val newValue); + js2val defaultImplicitCoerce(JS2Metadata *meta, js2val newValue, JS2Class *isClass); js2val defaultIs(JS2Metadata *meta, js2val newValue, JS2Class *isClass); js2val integerImplicitCoerce(JS2Metadata *meta, js2val newValue, JS2Class *isClass); js2val integerIs(JS2Metadata *meta, js2val newValue, JS2Class *isClass); - +bool stringClass_BracketRead(JS2Metadata *meta, js2val *base, JS2Class *limit, js2val indexVal, Phase phase, js2val *rval); extern void initDateObject(JS2Metadata *meta); extern void initStringObject(JS2Metadata *meta); @@ -253,10 +254,16 @@ public: static void markJS2Value(js2val v); }; +#ifdef DEBUG #define ROOTKEEPER_CONSTRUCTOR(type) RootKeeper(type **p, int line, char *pfile) : is_js2val(false), p(p) { init(line, pfile); } +#define DEFINE_ROOTKEEPER(rk_var, obj) RootKeeper rk_var(&obj, __LINE__, __FILE__); +#else +#define ROOTKEEPER_CONSTRUCTOR(type) RootKeeper(type **p) : is_js2val(false), p(p) { ri = JS2Object::addRoot(this); } +#define DEFINE_ROOTKEEPER(rk_var, obj) RootKeeper rk_var(&obj); +#endif + class RootKeeper { public: -#ifdef DEBUG ROOTKEEPER_CONSTRUCTOR(JS2Object) ROOTKEEPER_CONSTRUCTOR(RegExpInstance) @@ -274,22 +281,18 @@ public: ROOTKEEPER_CONSTRUCTOR(FunctionInstance) ROOTKEEPER_CONSTRUCTOR(DateInstance) - RootKeeper(js2val *p, int line, char *pfile) : is_js2val(true), p(p) - { - init(line, pfile); - } +#ifdef DEBUG + RootKeeper(js2val *p, int line, char *pfile) : is_js2val(true), p(p) { init(line, pfile); } ~RootKeeper() { JS2Object::removeRoot(ri); delete file; } - - void RootKeeper::init(int line, char *pfile) + void RootKeeper::init(int ln, char *pfile) { - line = line; + line = ln; file = new char[strlen(pfile) + 1]; strcpy(file, pfile); ri = JS2Object::addRoot(this); } #else - RootKeeper(JS2Object **p) : is_js2val(false), p(p), { ri = JS2Object::addRoot(p); } - RootKeeper(js2val *p) : is_js2val(true), p(p) { ri = JS2Object::addRoot(p); } + RootKeeper(js2val *p) : is_js2val(true), p(p) { ri = JS2Object::addRoot(this); } ~RootKeeper() { JS2Object::removeRoot(ri); } #endif @@ -303,11 +306,6 @@ public: #endif }; -#ifdef DEBUG -#define DEFINE_ROOTKEEPER(rk_var, obj) RootKeeper rk_var(&obj, __LINE__, __FILE__); -#else -#define DEFINE_ROOTKEEPER(rk_var, obj) RootKeeper rk_var(&obj); -#endif class Attribute : public JS2Object { public: @@ -740,6 +738,7 @@ public: void removeTopFrame() { frameList.pop_front(); } bool findThis(JS2Metadata *meta, bool allowPrototypeThis, js2val *result); + js2val readImplicitThis(JS2Metadata *meta); void lexicalRead(JS2Metadata *meta, Multiname *multiname, Phase phase, js2val *rval, js2val *base); void lexicalWrite(JS2Metadata *meta, Multiname *multiname, js2val newValue, bool createIfMissing); void lexicalInit(JS2Metadata *meta, Multiname *multiname, js2val newValue); @@ -1240,6 +1239,7 @@ public: prototype(prototype), buildArguments(false), isConstructor(false), + isInstance(false), callsSuperConstructor(false), superConstructorCalled(true) { } @@ -1249,6 +1249,7 @@ public: prototype(pluralFrame->prototype), buildArguments(pluralFrame->buildArguments), isConstructor(pluralFrame->isConstructor), + isInstance(pluralFrame->isInstance), callsSuperConstructor(pluralFrame->callsSuperConstructor), superConstructorCalled(false) // initialized to false for each construction of a singular frame // and then set true when/if the call occurs @@ -1262,6 +1263,7 @@ public: bool prototype; // true if this function is not an instance method but defines this anyway bool buildArguments; bool isConstructor; + bool isInstance; bool callsSuperConstructor; bool superConstructorCalled; @@ -1286,17 +1288,6 @@ public: }; -class LookupKind { -public: - LookupKind(bool isLexical, js2val thisObject) : isLexical(isLexical), thisObject(thisObject) { } - - bool isPropertyLookup() { return !isLexical; } - - bool isLexical; // if isLexical, use the 'this' below. Otherwise it's a propertyLookup - js2val thisObject; -}; - - typedef std::vector NamespaceList; typedef NamespaceList::iterator NamespaceListIterator; diff --git a/mozilla/js2/src/js2op_access.cpp b/mozilla/js2/src/js2op_access.cpp index 1d3dfe29dca..24c22abce13 100644 --- a/mozilla/js2/src/js2op_access.cpp +++ b/mozilla/js2/src/js2op_access.cpp @@ -34,7 +34,6 @@ // Read a multiname property from a base object, push the value onto the stack case eDotRead: { - LookupKind lookup(false, JS2VAL_NULL); Multiname *mn = bCon->mMultinameList[BytecodeContainer::getShort(pc)]; pc += sizeof(short); b = pop(); @@ -43,12 +42,12 @@ if (JS2VAL_IS_OBJECT(b) && (JS2VAL_TO_OBJECT(b)->kind == LimitedInstanceKind)) { LimitedInstance *li = checked_cast(JS2VAL_TO_OBJECT(b)); b = OBJECT_TO_JS2VAL(li->instance); - if (!li->limit->read(meta, &b, li->limit, mn, &lookup, RunPhase, &a)) + if (!li->limit->read(meta, &b, li->limit, mn, NULL, RunPhase, &a)) meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name); } else { JS2Class *limit = meta->objectType(b); - if (!limit->read(meta, &b, limit, mn, &lookup, RunPhase, &a)) + if (!limit->read(meta, &b, limit, mn, NULL, RunPhase, &a)) meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name); } push(a); @@ -57,13 +56,12 @@ case eDotDelete: { - LookupKind lookup(false, JS2VAL_NULL); Multiname *mn = bCon->mMultinameList[BytecodeContainer::getShort(pc)]; pc += sizeof(short); b = pop(); bool result; JS2Class *limit = meta->objectType(b); - if (!limit->deleteProperty(meta, b, limit, mn, &lookup, &result)) + if (!limit->deleteProperty(meta, b, limit, mn, NULL, &result)) push(JS2VAL_FALSE); else push(BOOLEAN_TO_JS2VAL(result)); @@ -75,7 +73,6 @@ case eDotWrite: { a = pop(); - LookupKind lookup(false, JS2VAL_NULL); Multiname *mn = bCon->mMultinameList[BytecodeContainer::getShort(pc)]; pc += sizeof(short); b = pop(); @@ -84,14 +81,14 @@ if (JS2VAL_IS_OBJECT(b) && (JS2VAL_TO_OBJECT(b)->kind == LimitedInstanceKind)) { LimitedInstance *li = checked_cast(JS2VAL_TO_OBJECT(b)); b = OBJECT_TO_JS2VAL(li->instance); - if (!li->limit->write(meta, b, li->limit, mn, &lookup, true, a, false)) { + if (!li->limit->write(meta, b, li->limit, mn, NULL, true, a, false)) { if (!meta->cxt.E3compatibility) meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name); } } else { JS2Class *limit = meta->objectType(b); - if (!limit->write(meta, b, limit, mn, &lookup, true, a, false)) { + if (!limit->write(meta, b, limit, mn, NULL, true, a, false)) { if (!meta->cxt.E3compatibility) meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name); } @@ -103,12 +100,11 @@ // Read the multiname property, but leave the base and the value on the stack case eDotRef: { - LookupKind lookup(false, JS2VAL_NULL); Multiname *mn = bCon->mMultinameList[BytecodeContainer::getShort(pc)]; pc += sizeof(short); b = pop(); JS2Class *limit = meta->objectType(b); - if (!limit->read(meta, &b, limit, mn, &lookup, RunPhase, &a)) + if (!limit->read(meta, &b, limit, mn, NULL, RunPhase, &a)) meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name); push(b); push(a); @@ -175,32 +171,25 @@ { indexVal = pop(); b = pop(); - astr = meta->toString(indexVal); - Multiname mn(&meta->world.identifiers[*astr], meta->publicNamespace); JS2Class *limit = meta->objectType(b); - if (!limit->bracketRead(meta, &b, limit, &mn, RunPhase, &a)) - meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn.name); + if (!limit->bracketRead(meta, &b, limit, indexVal, RunPhase, &a)) + meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), meta->toString(indexVal)); push(a); indexVal = JS2VAL_VOID; - astr = NULL; } break; case eBracketDelete: { - LookupKind lookup(false, JS2VAL_NULL); indexVal = pop(); b = pop(); - astr = meta->toString(indexVal); - Multiname mn(&meta->world.identifiers[*astr], meta->publicNamespace); bool result; JS2Class *limit = meta->objectType(b); - if (!limit->bracketDelete(meta, b, limit, &mn, &result)) + if (!limit->bracketDelete(meta, b, limit, indexVal, &result)) push(JS2VAL_FALSE); else push(BOOLEAN_TO_JS2VAL(result)); indexVal = JS2VAL_VOID; - astr = NULL; } break; @@ -211,48 +200,40 @@ a = pop(); indexVal = pop(); b = pop(); - astr = meta->toString(indexVal); - Multiname mn(&meta->world.identifiers[*astr], meta->publicNamespace); JS2Class *limit = meta->objectType(b); - if (!limit->bracketWrite(meta, b, limit, &mn, a)) { + if (!limit->bracketWrite(meta, b, limit, indexVal, a)) { if (!meta->cxt.E3compatibility) - meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn.name); + meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), meta->toString(indexVal)); } push(a); indexVal = JS2VAL_VOID; - astr = NULL; } break; // Leave the base object on the stack and push the property value case eBracketRef: { - LookupKind lookup(false, JS2VAL_NULL); indexVal = pop(); b = top(); - astr = meta->toString(indexVal); - Multiname mn(&meta->world.identifiers[*astr], meta->publicNamespace); JS2Class *limit = meta->objectType(b); - if (!limit->bracketRead(meta, &b, limit, &mn, RunPhase, &a)) - meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn.name); + if (!limit->bracketRead(meta, &b, limit, indexVal, RunPhase, &a)) + meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), meta->toString(indexVal)); push(a); indexVal = JS2VAL_VOID; - astr = NULL; } break; // Leave the base object and index value, push the value case eBracketReadForRef: { - LookupKind lookup(false, JS2VAL_NULL); indexVal = pop(); b = top(); astr = meta->toString(indexVal); - push(STRING_TO_JS2VAL(astr)); - Multiname mn(&meta->world.identifiers[*astr], meta->publicNamespace); + indexVal = STRING_TO_JS2VAL(astr); + push(indexVal); JS2Class *limit = meta->objectType(b); - if (!limit->bracketRead(meta, &b, limit, &mn, RunPhase, &a)) - meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn.name); + if (!limit->bracketRead(meta, &b, limit, indexVal, RunPhase, &a)) + meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), astr); push(a); indexVal = JS2VAL_VOID; astr = NULL; @@ -262,16 +243,14 @@ // Beneath the value is a reference pair (base and index), write to that location but leave just the value case eBracketWriteRef: { - LookupKind lookup(false, JS2VAL_NULL); a = pop(); indexVal = pop(); - ASSERT(JS2VAL_IS_STRING(indexVal)); + ASSERT(JS2VAL_IS_STRING(indexVal)); // because the readForRef above will have executed first b = pop(); - Multiname mn(&meta->world.identifiers[*JS2VAL_TO_STRING(indexVal)], meta->publicNamespace); JS2Class *limit = meta->objectType(b); - if (!limit->bracketWrite(meta, b, limit, &mn, a)) { + if (!limit->bracketWrite(meta, b, limit, indexVal, a)) { if (!meta->cxt.E3compatibility) - meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn.name); + meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), JS2VAL_TO_STRING(indexVal)); } push(a); indexVal = JS2VAL_VOID; diff --git a/mozilla/js2/src/js2op_arithmetic.cpp b/mozilla/js2/src/js2op_arithmetic.cpp index 91990c2275b..2f84ea7d534 100644 --- a/mozilla/js2/src/js2op_arithmetic.cpp +++ b/mozilla/js2/src/js2op_arithmetic.cpp @@ -964,15 +964,14 @@ case eDotPostInc: { - LookupKind lookup(false, JS2VAL_NULL); Multiname *mn = bCon->mMultinameList[BytecodeContainer::getShort(pc)]; pc += sizeof(short); baseVal = pop(); JS2Class *limit = meta->objectType(baseVal); - if (!limit->read(meta, &baseVal, limit, mn, &lookup, RunPhase, &a)) + if (!limit->read(meta, &baseVal, limit, mn, NULL, RunPhase, &a)) meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name); float64 num = meta->toFloat64(a); - if (!limit->write(meta, baseVal, limit, mn, &lookup, true, allocNumber(num + 1.0), false)) + if (!limit->write(meta, baseVal, limit, mn, NULL, true, allocNumber(num + 1.0), false)) meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name); pushNumber(num); baseVal = JS2VAL_VOID; @@ -980,15 +979,14 @@ break; case eDotPostDec: { - LookupKind lookup(false, JS2VAL_NULL); Multiname *mn = bCon->mMultinameList[BytecodeContainer::getShort(pc)]; pc += sizeof(short); baseVal = pop(); JS2Class *limit = meta->objectType(baseVal); - if (!limit->read(meta, &baseVal, limit, mn, &lookup, RunPhase, &a)) + if (!limit->read(meta, &baseVal, limit, mn, NULL, RunPhase, &a)) meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name); float64 num = meta->toFloat64(a); - if (!limit->write(meta, baseVal, limit, mn, &lookup, true, allocNumber(num - 1.0), false)) + if (!limit->write(meta, baseVal, limit, mn, NULL, true, allocNumber(num - 1.0), false)) meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name); pushNumber(num); baseVal = JS2VAL_VOID; @@ -996,32 +994,30 @@ break; case eDotPreInc: { - LookupKind lookup(false, JS2VAL_NULL); Multiname *mn = bCon->mMultinameList[BytecodeContainer::getShort(pc)]; pc += sizeof(short); baseVal = pop(); JS2Class *limit = meta->objectType(baseVal); - if (!limit->read(meta, &baseVal, limit, mn, &lookup, RunPhase, &a)) + if (!limit->read(meta, &baseVal, limit, mn, NULL, RunPhase, &a)) meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name); float64 num = meta->toFloat64(a); a = pushNumber(num + 1.0); - if (!limit->write(meta, baseVal, limit, mn, &lookup, true, a, false)) + if (!limit->write(meta, baseVal, limit, mn, NULL, true, a, false)) meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name); baseVal = JS2VAL_VOID; } break; case eDotPreDec: { - LookupKind lookup(false, JS2VAL_NULL); Multiname *mn = bCon->mMultinameList[BytecodeContainer::getShort(pc)]; pc += sizeof(short); baseVal = pop(); JS2Class *limit = meta->objectType(baseVal); - if (!limit->read(meta, &baseVal, limit, mn, &lookup, RunPhase, &a)) + if (!limit->read(meta, &baseVal, limit, mn, NULL, RunPhase, &a)) meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name); float64 num = meta->toFloat64(a); a = pushNumber(num - 1.0); - if (!limit->write(meta, baseVal, limit, mn, &lookup, true, a, false)) + if (!limit->write(meta, baseVal, limit, mn, NULL, true, a, false)) meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn->name); baseVal = JS2VAL_VOID; } @@ -1029,36 +1025,29 @@ case eBracketPostInc: { - LookupKind lookup(false, JS2VAL_NULL); indexVal = pop(); baseVal = pop(); - astr = meta->toString(indexVal); - Multiname mn(&meta->world.identifiers[*astr], meta->publicNamespace); JS2Class *limit = meta->objectType(baseVal); - if (!limit->bracketRead(meta, &baseVal, limit, &mn, RunPhase, &a)) - meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn.name); + if (!limit->bracketRead(meta, &baseVal, limit, indexVal, RunPhase, &a)) + meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), meta->toString(indexVal)); float64 num = meta->toFloat64(a); - if (!limit->bracketWrite(meta, baseVal, limit, &mn, allocNumber(num + 1.0))) - meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn.name); + if (!limit->bracketWrite(meta, baseVal, limit, indexVal, allocNumber(num + 1.0))) + meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), meta->toString(indexVal)); pushNumber(num); baseVal = JS2VAL_VOID; indexVal = JS2VAL_VOID; - astr = NULL; } break; case eBracketPostDec: { - LookupKind lookup(false, JS2VAL_NULL); indexVal = pop(); baseVal = pop(); - astr = meta->toString(indexVal); - Multiname mn(&meta->world.identifiers[*astr], meta->publicNamespace); JS2Class *limit = meta->objectType(baseVal); - if (!limit->bracketRead(meta, &baseVal, limit, &mn, RunPhase, &a)) - meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn.name); + if (!limit->bracketRead(meta, &baseVal, limit, indexVal, RunPhase, &a)) + meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), meta->toString(indexVal)); float64 num = meta->toFloat64(a); - if (!limit->bracketWrite(meta, baseVal, limit, &mn, allocNumber(num - 1.0))) - meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn.name); + if (!limit->bracketWrite(meta, baseVal, limit, indexVal, allocNumber(num - 1.0))) + meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), meta->toString(indexVal)); pushNumber(num); baseVal = JS2VAL_VOID; indexVal = JS2VAL_VOID; @@ -1067,18 +1056,15 @@ break; case eBracketPreInc: { - LookupKind lookup(false, JS2VAL_NULL); indexVal = pop(); baseVal = pop(); - astr = meta->toString(indexVal); - Multiname mn(&meta->world.identifiers[*astr], meta->publicNamespace); JS2Class *limit = meta->objectType(baseVal); - if (!limit->bracketRead(meta, &baseVal, limit, &mn, RunPhase, &a)) - meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn.name); + if (!limit->bracketRead(meta, &baseVal, limit, indexVal, RunPhase, &a)) + meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), meta->toString(indexVal)); float64 num = meta->toFloat64(a); a = pushNumber(num + 1.0); - if (!limit->bracketWrite(meta, baseVal, limit, &mn, a)) - meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn.name); + if (!limit->bracketWrite(meta, baseVal, limit, indexVal, a)) + meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), meta->toString(indexVal)); baseVal = JS2VAL_VOID; indexVal = JS2VAL_VOID; astr = NULL; @@ -1086,18 +1072,15 @@ break; case eBracketPreDec: { - LookupKind lookup(false, JS2VAL_NULL); indexVal = pop(); baseVal = pop(); - astr = meta->toString(indexVal); - Multiname mn(&meta->world.identifiers[*astr], meta->publicNamespace); JS2Class *limit = meta->objectType(baseVal); - if (!limit->bracketRead(meta, &baseVal, limit, &mn, RunPhase, &a)) - meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn.name); + if (!limit->bracketRead(meta, &baseVal, limit, indexVal, RunPhase, &a)) + meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), meta->toString(indexVal)); float64 num = meta->toFloat64(a); a = pushNumber(num - 1.0); - if (!limit->bracketWrite(meta, baseVal, limit, &mn, a)) - meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), mn.name); + if (!limit->bracketWrite(meta, baseVal, limit, indexVal, a)) + meta->reportError(Exception::propertyAccessError, "No property named {0}", errorPos(), meta->toString(indexVal)); baseVal = JS2VAL_VOID; indexVal = JS2VAL_VOID; astr = NULL; diff --git a/mozilla/js2/src/js2op_invocation.cpp b/mozilla/js2/src/js2op_invocation.cpp index 545363c3af0..53186b384c4 100644 --- a/mozilla/js2/src/js2op_invocation.cpp +++ b/mozilla/js2/src/js2op_invocation.cpp @@ -65,11 +65,8 @@ // stack is out of balance anyway... js2val protoVal = OBJECT_TO_JS2VAL(meta->objectClass->prototype); Multiname mn(prototype_StringAtom); // gc safe because the content is rooted elsewhere - LookupKind lookup(true, JS2VAL_NULL); // make it a lexical lookup since we want it to - // fail if 'prototype' hasn't been defined - // XXX (prototype should always exist for functions) JS2Class *limit = meta->objectType(a); - if (limit->read(meta, &a, limit, &mn, &lookup, RunPhase, &protoVal)) { + if (limit->read(meta, &a, limit, &mn, meta->env, RunPhase, &protoVal)) { if (!JS2VAL_IS_OBJECT(protoVal)) meta->reportError(Exception::badValueError, "Non-object prototype value", errorPos()); } @@ -291,11 +288,8 @@ js2val b_protoVal; Multiname mn(prototype_StringAtom); // gc safe because the content is rooted elsewhere - LookupKind lookup(true, JS2VAL_NULL); // make it a lexical lookup since we want it to - // fail if 'prototype' hasn't been defined - // XXX (prototype should always exist for functions) JS2Class *limit = meta->objectType(b); - if (limit->read(meta, &b, limit, &mn, &lookup, RunPhase, &b_protoVal)) { + if (limit->read(meta, &b, limit, &mn, meta->env, RunPhase, &b_protoVal)) { if (!JS2VAL_IS_OBJECT(b_protoVal)) meta->reportError(Exception::typeError, "Non-object prototype value in instanceOf", errorPos()); } diff --git a/mozilla/js2/src/regexp/regexp.h b/mozilla/js2/src/regexp/regexp.h index 735be67559a..a18ee4d07dc 100644 --- a/mozilla/js2/src/regexp/regexp.h +++ b/mozilla/js2/src/regexp/regexp.h @@ -41,14 +41,8 @@ */ -typedef uint32 jsint; typedef char16 jschar; -typedef bool JSBool; -typedef uint32 uintN; -typedef int32 intN; typedef uint8 jsbytecode; -typedef char16 JSString; -typedef char16 JSSubString; typedef struct RECharSet { diff --git a/mozilla/js2/src/winbuild/Epimetheus/Epimetheus.dsp b/mozilla/js2/src/winbuild/Epimetheus/Epimetheus.dsp index e7e0616f31c..1b78206d2dc 100644 --- a/mozilla/js2/src/winbuild/Epimetheus/Epimetheus.dsp +++ b/mozilla/js2/src/winbuild/Epimetheus/Epimetheus.dsp @@ -42,7 +42,7 @@ RSC=rc.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /W3 /GX /O2 /I "..\..\..\js\src" /I "../../RegExp" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "XP_PC" /D "EPIMETHEUS" /D "IS_LITTLE_ENDIAN" /FR /YX /FD /c +# ADD CPP /nologo /W3 /GX /Zi /O2 /I "..\..\..\js\src" /I "../../RegExp" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "XP_PC" /D "EPIMETHEUS" /D "IS_LITTLE_ENDIAN" /FR /YX /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe @@ -50,7 +50,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\..\js\src\release" +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /libpath:"..\..\..\..\js\src\release" !ELSEIF "$(CFG)" == "Epimetheus - Win32 Debug"