From 82cf675d46a03a8e3fa8edd046bf2af8b47db628 Mon Sep 17 00:00:00 2001 From: "rogerl%netscape.com" Date: Thu, 27 Feb 2003 18:37:07 +0000 Subject: [PATCH] Multiple ECMA fixes. git-svn-id: svn://10.0.0.236/trunk@138620 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/js2/src/epimetheus.cpp | 2 +- mozilla/js2/src/js2engine.cpp | 2 +- mozilla/js2/src/js2eval.cpp | 2 +- mozilla/js2/src/js2function.cpp | 1 + mozilla/js2/src/js2metadata.cpp | 232 ++++++++++++++++----------- mozilla/js2/src/js2metadata.h | 49 +++--- mozilla/js2/src/js2op_access.cpp | 4 +- mozilla/js2/src/js2op_invocation.cpp | 6 +- mozilla/js2/src/js2string.cpp | 2 +- 9 files changed, 174 insertions(+), 126 deletions(-) diff --git a/mozilla/js2/src/epimetheus.cpp b/mozilla/js2/src/epimetheus.cpp index 66b93d0b465..3fdad7b3057 100644 --- a/mozilla/js2/src/epimetheus.cpp +++ b/mozilla/js2/src/epimetheus.cpp @@ -233,7 +233,7 @@ js2val trace(JS2Metadata *meta, const js2val /* thisValue */, js2val /* argv */ return JS2VAL_UNDEFINED; } -void printFrameBindings(Frame *f) +void printFrameBindings(NonWithFrame *f) { stdOut << " Local Bindings:\n"; for (LocalBindingIterator rsb = f->localReadBindings.begin(), rsend = f->localReadBindings.end(); (rsb != rsend); rsb++) { diff --git a/mozilla/js2/src/js2engine.cpp b/mozilla/js2/src/js2engine.cpp index 686b9a73d65..b02306d3a2a 100644 --- a/mozilla/js2/src/js2engine.cpp +++ b/mozilla/js2/src/js2engine.cpp @@ -833,7 +833,7 @@ namespace MetaData { activationStackTop++; bCon = new_bCon; if ((int32)bCon->getMaxStack() >= (execStackLimit - sp)) { - uint32 curDepth = execStackLimit - sp; + uint32 curDepth = sp - execStack; uint32 newDepth = curDepth + bCon->getMaxStack(); js2val *newStack = new js2val[newDepth]; ::memcpy(newStack, execStack, curDepth * sizeof(js2val)); diff --git a/mozilla/js2/src/js2eval.cpp b/mozilla/js2/src/js2eval.cpp index 5bfb64f43ab..60f45baac84 100644 --- a/mozilla/js2/src/js2eval.cpp +++ b/mozilla/js2/src/js2eval.cpp @@ -327,7 +327,7 @@ namespace MetaData { JS2Object::RootIterator ri = JS2Object::addRoot(&runtimeFrame); runtimeFrame->instantiate(env); runtimeFrame->thisObject = thisValue; - runtimeFrame->assignArguments(this, argv, argc); + runtimeFrame->assignArguments(this, fnObj, argv, argc); Frame *oldTopFrame = env->getTopFrame(); env->addFrame(runtimeFrame); try { diff --git a/mozilla/js2/src/js2function.cpp b/mozilla/js2/src/js2function.cpp index 8aa5efa2941..0d8bb93141d 100644 --- a/mozilla/js2/src/js2function.cpp +++ b/mozilla/js2/src/js2function.cpp @@ -86,6 +86,7 @@ namespace MetaData { js2val thatValue = OBJECT_TO_JS2VAL(new FunctionInstance(meta->functionClass->prototype, meta->functionClass)); FunctionInstance *fnInst = checked_cast(JS2VAL_TO_OBJECT(thatValue)); fnInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_INACCESSIBLE, true)); + fnInst->fWrap->bCon->emitOp(eReturnVoid, meta->engine->errorPos()); return thatValue; } } diff --git a/mozilla/js2/src/js2metadata.cpp b/mozilla/js2/src/js2metadata.cpp index 06d535cb04d..05d1a258e7b 100644 --- a/mozilla/js2/src/js2metadata.cpp +++ b/mozilla/js2/src/js2metadata.cpp @@ -872,7 +872,7 @@ namespace MetaData { */ { SwitchStmtNode *sw = checked_cast(p); - uint16 swVarIndex = env->getTopFrame()->allocateTemp(); + uint16 swVarIndex = (checked_cast(env->getTopFrame()))->allocateTemp(); BytecodeContainer::LabelID defaultLabel = NotALabel; Reference *r = SetupExprNode(env, phase, sw->expr, &exprType); @@ -2060,7 +2060,11 @@ doUnary: Multiname *multiname = &((LexicalReference *)returnRef)->variableMultiname; FrameListIterator fi = env->getBegin(); while (fi != env->getEnd()) { - Frame *pf = *fi; + Frame *fr = *fi; + if (fr->kind == WithFrameKind) + // XXX unless it's provably not a dynamic object that been with'd?? + break; + NonWithFrame *pf = checked_cast(*fi); if (pf->kind != ClassKind) { LocalMember *m = findFlatMember(pf, multiname, ReadAccess, CompilePhase); if (m && m->kind == Member::Variable) { @@ -2455,7 +2459,7 @@ doUnary: } // Clone the pluralFrame bindings into the singularFrame, instantiating new members for each binding - void Environment::instantiateFrame(Frame *pluralFrame, Frame *singularFrame) + void Environment::instantiateFrame(NonWithFrame *pluralFrame, NonWithFrame *singularFrame) { LocalBindingIterator sbi, sbend; @@ -2579,7 +2583,7 @@ doUnary: NamespaceList publicNamespaceList; FrameListIterator fi = env->getBegin(); - Frame *localFrame = *fi; + NonWithFrame *localFrame = checked_cast(*fi); if ((overrideMod != Attribute::NoOverride) || (xplicit && localFrame->kind != PackageKind)) reportError(Exception::definitionError, "Illegal definition", pos); if ((namespaces == NULL) || namespaces->empty()) { @@ -2606,25 +2610,28 @@ doUnary: } // Check all frames below the current - up to the RegionalFrame - for a non-forbidden definition - Frame *regionalFrame = *(env->getRegionalFrame()); + Frame *regionalFrame = *env->getRegionalFrame(); if (localFrame != regionalFrame) { // The frame iterator is pointing at the top of the environment's // frame list, start at the one below that and continue to the frame // returned by 'getRegionalFrame()'. Frame *fr = *++fi; while (true) { - if (access & ReadAccess) { - for (b = fr->localReadBindings.lower_bound(*id), - end = fr->localReadBindings.upper_bound(*id); (b != end); b++) { - if (mn->matches(b->second->qname) && (b->second->content->kind != LocalMember::Forbidden)) - reportError(Exception::definitionError, "Duplicate definition {0}", pos, id); + if (fr->kind != WithFrameKind) { + NonWithFrame *nwfr = checked_cast(fr); + if (access & ReadAccess) { + for (b = nwfr->localReadBindings.lower_bound(*id), + end = nwfr->localReadBindings.upper_bound(*id); (b != end); b++) { + if (mn->matches(b->second->qname) && (b->second->content->kind != LocalMember::Forbidden)) + reportError(Exception::definitionError, "Duplicate definition {0}", pos, id); + } } - } - if (access & WriteAccess) { - for (b = fr->localWriteBindings.lower_bound(*id), - end = fr->localWriteBindings.upper_bound(*id); (b != end); b++) { - if (mn->matches(b->second->qname) && (b->second->content->kind != LocalMember::Forbidden)) - reportError(Exception::definitionError, "Duplicate definition {0}", pos, id); + if (access & WriteAccess) { + for (b = nwfr->localWriteBindings.lower_bound(*id), + end = nwfr->localWriteBindings.upper_bound(*id); (b != end); b++) { + if (mn->matches(b->second->qname) && (b->second->content->kind != LocalMember::Forbidden)) + reportError(Exception::definitionError, "Duplicate definition {0}", pos, id); + } } } if (fr == regionalFrame) @@ -2644,46 +2651,48 @@ doUnary: if (access & WriteAccess) localFrame->localWriteBindings.insert(e); } - // Mark the bindings of multiname as Forbidden in all non-innermost frames in the current // region if they haven't been marked as such already. if (localFrame != regionalFrame) { fi = env->getBegin(); Frame *fr = *++fi; while (true) { - for (NamespaceListIterator nli = mn->nsList->begin(), nlend = mn->nsList->end(); (nli != nlend); nli++) { - if (access & ReadAccess) { - bool foundEntry = false; - for (b = fr->localReadBindings.lower_bound(*id), - end = fr->localReadBindings.upper_bound(*id); (b != end); b++) { - if (b->second->qname.nameSpace == *nli) { - ASSERT(b->second->content->kind == LocalMember::Forbidden); - foundEntry = true; - break; + if (fr->kind != WithFrameKind) { + NonWithFrame *nwfr = checked_cast(fr); + for (NamespaceListIterator nli = mn->nsList->begin(), nlend = mn->nsList->end(); (nli != nlend); nli++) { + if (access & ReadAccess) { + bool foundEntry = false; + for (b = nwfr->localReadBindings.lower_bound(*id), + end = nwfr->localReadBindings.upper_bound(*id); (b != end); b++) { + if (b->second->qname.nameSpace == *nli) { + ASSERT(b->second->content->kind == LocalMember::Forbidden); + foundEntry = true; + break; + } + } + if (!foundEntry) { + QualifiedName qName(*nli, id); + LocalBinding *sb = new LocalBinding(qName, forbiddenMember); + const LocalBindingMap::value_type e(*id, sb); + nwfr->localReadBindings.insert(e); } } - if (!foundEntry) { - QualifiedName qName(*nli, id); - LocalBinding *sb = new LocalBinding(qName, forbiddenMember); - const LocalBindingMap::value_type e(*id, sb); - fr->localReadBindings.insert(e); - } - } - if (access & WriteAccess) { - bool foundEntry = false; - for (b = fr->localWriteBindings.lower_bound(*id), - end = fr->localWriteBindings.upper_bound(*id); (b != end); b++) { - if (b->second->qname.nameSpace == *nli) { - ASSERT(b->second->content->kind == LocalMember::Forbidden); - foundEntry = true; - break; + if (access & WriteAccess) { + bool foundEntry = false; + for (b = nwfr->localWriteBindings.lower_bound(*id), + end = nwfr->localWriteBindings.upper_bound(*id); (b != end); b++) { + if (b->second->qname.nameSpace == *nli) { + ASSERT(b->second->content->kind == LocalMember::Forbidden); + foundEntry = true; + break; + } + } + if (!foundEntry) { + QualifiedName qName(*nli, id); + LocalBinding *sb = new LocalBinding(qName, forbiddenMember); + const LocalBindingMap::value_type e(*id, sb); + nwfr->localWriteBindings.insert(e); } - } - if (!foundEntry) { - QualifiedName qName(*nli, id); - LocalBinding *sb = new LocalBinding(qName, forbiddenMember); - const LocalBindingMap::value_type e(*id, sb); - fr->localWriteBindings.insert(e); } } } @@ -2871,9 +2880,10 @@ doUnary: DynamicVariable *result = NULL; QualifiedName qName(publicNamespace, id); FrameListIterator regionalFrameMark = env->getRegionalFrame(); - Frame *regionalFrame = *regionalFrameMark; + // XXX can the regionalFrame be a WithFrame? + NonWithFrame *regionalFrame = checked_cast(*regionalFrameMark); ASSERT((regionalFrame->kind == GlobalObjectKind) || (regionalFrame->kind == ParameterKind)); - + // run through all the existing bindings, both read and write, to see if this // variable already exists. LocalBindingIterator b, end; @@ -2914,7 +2924,7 @@ doUnary: } else { // ParameterFrame didn't have any bindings, scan the preceding // frame (should be the outermost function local block) - regionalFrame = *(regionalFrameMark - 1); + regionalFrame = checked_cast(*(regionalFrameMark - 1)); for (b = regionalFrame->localReadBindings.lower_bound(*id), end = regionalFrame->localReadBindings.upper_bound(*id); (b != end); b++) { if (b->second->qname == qName) { @@ -2960,18 +2970,6 @@ doUnary: return result; } - static js2val Object_toString(JS2Metadata *meta, const js2val thisValue, js2val /* argv */ [], uint32 /* argc */) - { - ASSERT(JS2VAL_IS_OBJECT(thisValue)); - JS2Class *type = (checked_cast(JS2VAL_TO_OBJECT(thisValue)))->type; - - // XXX objectType returns the ECMA4 type, not the [[class]] value, so returns class 'Prototype' for ECMA3 objects - // JS2Class *type = meta->objectType(thisValue); - - String s = "[object " + *type->getName() + "]"; - return STRING_TO_JS2VAL(meta->engine->allocString(s)); - } - static js2val GlobalObject_isNaN(JS2Metadata *meta, const js2val /* thisValue */, js2val argv[], uint32 /* argc */) { float64 d = meta->toFloat64(argv[0]); @@ -3159,6 +3157,28 @@ static const uint8 urlCharType[256] = fInst->writeProperty(this, engine->length_StringAtom, INT_TO_JS2VAL(length), DynamicPropertyValue::READONLY); } + static js2val Object_toString(JS2Metadata *meta, const js2val thisValue, js2val /* argv */ [], uint32 /* argc */) + { + ASSERT(JS2VAL_IS_OBJECT(thisValue)); + JS2Object *obj = JS2VAL_TO_OBJECT(thisValue); + if (obj->kind == GlobalObjectKind) { + // special case this for now, ECMA3 test sanity... + return GlobalObject_toString(meta, thisValue, NULL, 0); + } + else { + // XXX insist on Prototype instances, but is toString going to be more + // generic - a member of the class Object? and hence available to all + // instances? + JS2Class *type = (checked_cast(obj))->type; + + // XXX objectType returns the ECMA4 type, not the [[class]] value, so returns class 'Prototype' for ECMA3 objects + // JS2Class *type = meta->objectType(thisValue); + + String s = "[object " + *type->getName() + "]"; + return STRING_TO_JS2VAL(meta->engine->allocString(s)); + } + } + #define MAKEBUILTINCLASS(c, super, dynamic, allowNull, final, name, defaultVal) c = new JS2Class(super, NULL, new Namespace(engine->private_StringAtom), dynamic, allowNull, final, name); c->complete = true; c->defaultValue = defaultVal; JS2Metadata::JS2Metadata(World &world) : JS2Object(MetaDataKind), @@ -3763,12 +3783,17 @@ readClassProperty: bool JS2Metadata::readProperty(Frame *container, Multiname *multiname, LookupKind *lookupKind, Phase phase, js2val *rval) { if (container->kind != ClassKind) { - // Must be System, Global, Package, Parameter or Block - LocalMember *m = findFlatMember(container, multiname, ReadAccess, phase); - if (!m && (container->kind == GlobalObjectKind)) - return readDynamicProperty(container, multiname, lookupKind, phase, rval); - else - return readLocalMember(m, phase, rval); + if (container->kind == WithFrameKind) { + return readDynamicProperty(checked_cast(container)->obj, multiname, lookupKind, phase, rval); + } + else { + // Must be System, Global, Package, Parameter or Block + LocalMember *m = findFlatMember(checked_cast(container), multiname, ReadAccess, phase); + if (!m && (container->kind == GlobalObjectKind)) + return readDynamicProperty(container, multiname, lookupKind, phase, rval); + else + return readLocalMember(m, phase, rval); + } } else { // XXX using JS2VAL_UNINITIALIZED to signal generic 'this' @@ -3870,12 +3895,17 @@ readClassProperty: bool JS2Metadata::writeProperty(Frame *container, Multiname *multiname, LookupKind *lookupKind, bool createIfMissing, js2val newValue, Phase phase, bool initFlag) { if (container->kind != ClassKind) { - // Must be System, Global, Package, Parameter or Block - LocalMember *m = findFlatMember(container, multiname, WriteAccess, phase); - if (!m && (container->kind == GlobalObjectKind)) - return writeDynamicProperty(container, multiname, createIfMissing, newValue, phase); - else - return writeLocalMember(m, newValue, phase, initFlag); + if (container->kind == WithFrameKind) { + return writeDynamicProperty(checked_cast(container)->obj, multiname, createIfMissing, newValue, phase); + } + else { + // Must be System, Global, Package, Parameter or Block + LocalMember *m = findFlatMember(checked_cast(container), multiname, WriteAccess, phase); + if (!m && (container->kind == GlobalObjectKind)) + return writeDynamicProperty(container, multiname, createIfMissing, newValue, phase); + else + return writeLocalMember(m, newValue, phase, initFlag); + } } else { // XXX using JS2VAL_UNINITIALIZED to signal generic 'this' @@ -3946,12 +3976,17 @@ deleteClassProperty: { ASSERT(phase == RunPhase); if (container->kind != ClassKind) { - // Must be System, Global, Package, Parameter or Block - LocalMember *m = findFlatMember(container, multiname, ReadAccess, phase); - if (!m && (container->kind == GlobalObjectKind)) - return deleteDynamicProperty(container, multiname, lookupKind, result); - else - return deleteLocalMember(m, result); + if (container->kind == WithFrameKind) { + return deleteDynamicProperty(checked_cast(container)->obj, multiname, lookupKind, result); + } + else { + // Must be System, Global, Package, Parameter or Block + LocalMember *m = findFlatMember(checked_cast(container), multiname, ReadAccess, phase); + if (!m && (container->kind == GlobalObjectKind)) + return deleteDynamicProperty(container, multiname, lookupKind, result); + else + return deleteLocalMember(m, result); + } } else { // XXX using JS2VAL_UNINITIALIZED to signal generic 'this' @@ -4034,7 +4069,7 @@ deleteClassProperty: // Find a binding that matches the multiname and access. // It's an error if more than one such binding exists. - LocalMember *JS2Metadata::findFlatMember(Frame *container, Multiname *multiname, Access access, Phase /* phase */) + LocalMember *JS2Metadata::findFlatMember(NonWithFrame *container, Multiname *multiname, Access access, Phase /* phase */) { LocalMember *found = NULL; LocalBindingIterator b, end; @@ -4270,7 +4305,7 @@ deleteClassProperty: JS2Class::JS2Class(JS2Class *super, JS2Object *proto, Namespace *privateNamespace, bool dynamic, bool allowNull, bool final, const String *name) - : Frame(ClassKind), + : NonWithFrame(ClassKind), instanceInitOrder(NULL), complete(false), super(super), @@ -4291,7 +4326,7 @@ deleteClassProperty: // gc-mark all contained JS2Objects and visit contained structures to do likewise void JS2Class::markChildren() { - Frame::markChildren(); + NonWithFrame::markChildren(); GCMARKOBJECT(super) GCMARKOBJECT(prototype) GCMARKOBJECT(privateNamespace) @@ -4487,7 +4522,7 @@ deleteClassProperty: // Allocate a new temporary variable in this frame and stick it // on the list (which may need to be created) for gc tracking. - uint16 Frame::allocateTemp() + uint16 NonWithFrame::allocateTemp() { if (temps == NULL) temps = new std::vector; @@ -4498,7 +4533,7 @@ deleteClassProperty: // gc-mark all contained JS2Objects and visit contained structures to do likewise - void Frame::markChildren() + void NonWithFrame::markChildren() { GCMARKOBJECT(pluralFrame) LocalBindingIterator sbi, end; @@ -4524,7 +4559,7 @@ deleteClassProperty: // gc-mark all contained JS2Objects and visit contained structures to do likewise void GlobalObject::markChildren() { - Frame::markChildren(); + NonWithFrame::markChildren(); GCMARKOBJECT(internalNamespace) for (DynamicPropertyIterator i = dynamicProperties.begin(), end = dynamicProperties.end(); (i != end); i++) { GCMARKVALUE(i->second.value); @@ -4546,7 +4581,7 @@ deleteClassProperty: // Assume that instantiate has been called, the plural frame will contain // the cloned Variables assigned into this (singular) frame. Use the // incoming values to initialize the positionals. - void ParameterFrame::assignArguments(JS2Metadata *meta, js2val *argBase, uint32 argCount) + void ParameterFrame::assignArguments(JS2Metadata *meta, JS2Object *fnObj, js2val *argBase, uint32 argCount) { Multiname mn(NULL, meta->publicNamespace); @@ -4554,31 +4589,32 @@ deleteClassProperty: ParameterFrame *plural = checked_cast(pluralFrame); ASSERT((plural->positionalCount == 0) || (plural->positional != NULL)); - ArrayInstance *arrInst = new ArrayInstance(meta, meta->arrayClass->prototype, meta->arrayClass); - js2val argumentsVal = OBJECT_TO_JS2VAL(arrInst); + PrototypeInstance *argsObj = new PrototypeInstance(meta->objectClass->prototype, meta->objectClass); // Add the 'arguments' property QualifiedName qn(meta->publicNamespace, &meta->world.identifiers["arguments"]); - LocalBinding *sb = new LocalBinding(qn, new Variable(meta->arrayClass, argumentsVal, true)); + LocalBinding *sb = new LocalBinding(qn, new Variable(meta->arrayClass, OBJECT_TO_JS2VAL(argsObj), true)); const LocalBindingMap::value_type e(*qn.id, sb); localReadBindings.insert(e); uint32 i; - for (i = 0; ((i < argCount) && (i < plural->positionalCount)); i++) { - ASSERT(plural->positional[i]->cloneContent); - ASSERT(plural->positional[i]->cloneContent->kind == Member::Variable); - (checked_cast(plural->positional[i]->cloneContent))->value = argBase[i]; - - arrInst->writeProperty(meta, meta->engine->numberToString(i), argBase[i], 0); + for (i = 0; (i < argCount); i++) { + if (i < plural->positionalCount) { + ASSERT(plural->positional[i]->cloneContent); + ASSERT(plural->positional[i]->cloneContent->kind == Member::Variable); + (checked_cast(plural->positional[i]->cloneContent))->value = argBase[i]; + } + argsObj->writeProperty(meta, meta->engine->numberToString(i), argBase[i], 0); } - setLength(meta, arrInst, i); + setLength(meta, argsObj, i); + argsObj->writeProperty(meta, &meta->world.identifiers["callee"], OBJECT_TO_JS2VAL(fnObj), 0); } // gc-mark all contained JS2Objects and visit contained structures to do likewise void ParameterFrame::markChildren() { - Frame::markChildren(); + NonWithFrame::markChildren(); GCMARKVALUE(thisObject); } diff --git a/mozilla/js2/src/js2metadata.h b/mozilla/js2/src/js2metadata.h index 3b2890e799d..455758d05f5 100644 --- a/mozilla/js2/src/js2metadata.h +++ b/mozilla/js2/src/js2metadata.h @@ -471,8 +471,20 @@ typedef InstanceBindingMap::iterator InstanceBindingIterator; class Frame : public JS2Object { public: - Frame(ObjectKind kind) : JS2Object(kind), temps(NULL), pluralFrame(NULL) { } - Frame(ObjectKind kind, Frame *pluralFrame) : JS2Object(kind), temps(NULL), pluralFrame(pluralFrame) { } + Frame(ObjectKind kind) : JS2Object(kind) { } + + virtual void instantiate(Environment * /*env*/) { ASSERT(false); } + + virtual void markChildren() { } + virtual ~Frame() { } + +}; + +class NonWithFrame : public Frame { +public: + + NonWithFrame(ObjectKind kind) : Frame(kind), temps(NULL), pluralFrame(NULL) { } + NonWithFrame(ObjectKind kind, NonWithFrame *pluralFrame) : Frame(kind), temps(NULL), pluralFrame(pluralFrame) { } LocalBindingMap localReadBindings; // Map of qualified names to readable members defined in this frame LocalBindingMap localWriteBindings; // Map of qualified names to writable members defined in this frame @@ -482,11 +494,10 @@ public: virtual void instantiate(Environment * /*env*/) { ASSERT(false); } - Frame *pluralFrame; // for a singular frame, this is the plural frame from which it will be instantiated + NonWithFrame *pluralFrame; // for a singular frame, this is the plural frame from which it will be instantiated virtual void markChildren(); - virtual ~Frame() { } - + virtual ~NonWithFrame() { } }; class WithFrame : public Frame { @@ -499,7 +510,7 @@ public: JS2Object *obj; }; -class JS2Class : public Frame { +class JS2Class : public NonWithFrame { public: JS2Class(JS2Class *super, JS2Object *proto, Namespace *privateNamespace, bool dynamic, bool allowNull, bool final, const String *name); @@ -541,9 +552,9 @@ public: }; -class GlobalObject : public Frame { +class GlobalObject : public NonWithFrame { public: - GlobalObject(World &world) : Frame(GlobalObjectKind), internalNamespace(new Namespace(&world.identifiers["internal"])) { } + GlobalObject(World &world) : NonWithFrame(GlobalObjectKind), internalNamespace(new Namespace(&world.identifiers["internal"])) { } Namespace *internalNamespace; // This global object's internal namespace DynamicPropertyMap dynamicProperties; // A set of this global object's dynamic properties @@ -898,17 +909,17 @@ public: // The top-level frame containing predefined constants, functions, and classes. -class SystemFrame : public Frame { +class SystemFrame : public NonWithFrame { public: - SystemFrame() : Frame(SystemKind) { } + SystemFrame() : NonWithFrame(SystemKind) { } virtual ~SystemFrame() { } }; // Frames holding bindings for invoked functions -class ParameterFrame : public Frame { +class ParameterFrame : public NonWithFrame { public: - ParameterFrame(js2val thisObject, bool prototype) : Frame(ParameterKind), thisObject(thisObject), prototype(prototype), positional(NULL), positionalCount(0) { } - ParameterFrame(ParameterFrame *pluralFrame) : Frame(ParameterKind, pluralFrame), thisObject(JS2VAL_UNDEFINED), prototype(pluralFrame->prototype), positional(NULL), positionalCount(0) { } + ParameterFrame(js2val thisObject, bool prototype) : NonWithFrame(ParameterKind), thisObject(thisObject), prototype(prototype), positional(NULL), positionalCount(0) { } + ParameterFrame(ParameterFrame *pluralFrame) : NonWithFrame(ParameterKind, pluralFrame), thisObject(JS2VAL_UNDEFINED), prototype(pluralFrame->prototype), positional(NULL), positionalCount(0) { } // Plurality plurality; js2val thisObject; // The value of this; none if this function doesn't define this; @@ -921,15 +932,15 @@ public: uint32 positionalCount; virtual void instantiate(Environment *env); - void assignArguments(JS2Metadata *meta, js2val *argBase, uint32 argCount); + void assignArguments(JS2Metadata *meta, JS2Object *fnObj, js2val *argBase, uint32 argCount); virtual void markChildren(); virtual ~ParameterFrame() { } }; -class BlockFrame : public Frame { +class BlockFrame : public NonWithFrame { public: - BlockFrame() : Frame(BlockKind) { } - BlockFrame(BlockFrame *pluralFrame) : Frame(BlockKind, pluralFrame) { } + BlockFrame() : NonWithFrame(BlockKind) { } + BlockFrame(BlockFrame *pluralFrame) : NonWithFrame(BlockKind, pluralFrame) { } Plurality plurality; @@ -980,7 +991,7 @@ public: void lexicalInit(JS2Metadata *meta, Multiname *multiname, js2val newValue); bool lexicalDelete(JS2Metadata *meta, Multiname *multiname, Phase phase); - void instantiateFrame(Frame *pluralFrame, Frame *singularFrame); + void instantiateFrame(NonWithFrame *pluralFrame, NonWithFrame *singularFrame); void markChildren(); @@ -1090,7 +1101,7 @@ public: bool hasType(js2val objVal, JS2Class *c); bool relaxedHasType(js2val objVal, JS2Class *c); - LocalMember *findFlatMember(Frame *container, Multiname *multiname, Access access, Phase phase); + LocalMember *findFlatMember(NonWithFrame *container, Multiname *multiname, Access access, Phase phase); InstanceBinding *resolveInstanceMemberName(JS2Class *js2class, Multiname *multiname, Access access, Phase phase); DynamicVariable *defineHoistedVar(Environment *env, const String *id, StmtNode *p); diff --git a/mozilla/js2/src/js2op_access.cpp b/mozilla/js2/src/js2op_access.cpp index 7009ccc3eb0..53032c06fec 100644 --- a/mozilla/js2/src/js2op_access.cpp +++ b/mozilla/js2/src/js2op_access.cpp @@ -233,7 +233,7 @@ { uint16 slotIndex = BytecodeContainer::getShort(pc); pc += sizeof(short); - Frame *f = meta->env->getTopFrame(); + NonWithFrame *f = checked_cast(meta->env->getTopFrame()); a = pop(); (*f->temps)[slotIndex] = a; } @@ -243,7 +243,7 @@ { uint16 slotIndex = BytecodeContainer::getShort(pc); pc += sizeof(short); - Frame *f = meta->env->getTopFrame(); + NonWithFrame *f = checked_cast(meta->env->getTopFrame()); push((*f->temps)[slotIndex]); } break; diff --git a/mozilla/js2/src/js2op_invocation.cpp b/mozilla/js2/src/js2op_invocation.cpp index 468333fcc34..2f5eacd610a 100644 --- a/mozilla/js2/src/js2op_invocation.cpp +++ b/mozilla/js2/src/js2op_invocation.cpp @@ -90,7 +90,7 @@ PrototypeInstance *pInst = new PrototypeInstance(protoObj, meta->objectClass); baseVal = OBJECT_TO_JS2VAL(pInst); pFrame->thisObject = baseVal; - pFrame->assignArguments(meta, base(argCount), argCount); + pFrame->assignArguments(meta, obj, base(argCount), argCount); jsr(phase, fWrap->bCon, base(argCount + 1) - execStack, baseVal); // seems out of order, but we need to catch the current top frame meta->env->addFrame(pFrame); pFrame = NULL; @@ -151,7 +151,7 @@ pFrame->thisObject = a; // assignArguments(runtimeFrame, fWrap->compileFrame->signature); // XXX - pFrame->assignArguments(meta, base(argCount), argCount); + pFrame->assignArguments(meta, fObj, base(argCount), argCount); jsr(phase, fWrap->bCon, base(argCount + 2) - execStack, JS2VAL_VOID); // seems out of order, but we need to catch the current top frame meta->env->addFrame(pFrame); pFrame = NULL; @@ -173,7 +173,7 @@ pFrame->instantiate(meta->env); pFrame->thisObject = mc->thisObject; // assignArguments(runtimeFrame, fWrap->compileFrame->signature); - pFrame->assignArguments(meta, base(argCount), argCount); + pFrame->assignArguments(meta, fObj, base(argCount), argCount); jsr(phase, fWrap->bCon, base(argCount + 2) - execStack, JS2VAL_VOID); // seems out of order, but we need to catch the current top frame meta->env->addFrame(meta->objectType(mc->thisObject)); meta->env->addFrame(pFrame); diff --git a/mozilla/js2/src/js2string.cpp b/mozilla/js2/src/js2string.cpp index 9e0ef116bdc..f4f869d9373 100644 --- a/mozilla/js2/src/js2string.cpp +++ b/mozilla/js2/src/js2string.cpp @@ -736,7 +736,7 @@ static js2val String_substring(JS2Metadata *meta, const js2val thisValue, js2val if (argc > 1) { float64 farg1 = meta->toFloat64(argv[1]); if (JSDOUBLE_IS_NaN(farg1) || (farg1 < 0)) - end = 0; + end = sourceLength; else { if (!JSDOUBLE_IS_FINITE(farg1)) end = sourceLength;