Fixes to defineStaticMember

git-svn-id: svn://10.0.0.236/trunk@135662 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
rogerl%netscape.com 2002-12-28 01:40:07 +00:00
parent f8f86e7f05
commit f9eb7ce4cf

View File

@ -1611,6 +1611,8 @@ namespace MetaData {
ValidateExpression(cxt, env, i->op);
ExprPairList *ep = i->pairs;
uint16 positionalCount = 0;
// XXX errors below should only occur at runtime - insert code to throw exception
// or let the bytecodes handle (and throw on) multiple & named arguments?
while (ep) {
if (ep->field)
reportError(Exception::argumentMismatchError, "Indexing doesn't support named arguments", p->pos);
@ -2589,7 +2591,9 @@ doUnary:
// - If the binding exists (not forbidden) in lower frames in the regional environment, it's an error.
// - Define a forbidden binding in all the lower frames.
//
Multiname *JS2Metadata::defineStaticMember(Environment *env, const StringAtom *id, NamespaceList *namespaces, Attribute::OverrideModifier overrideMod, bool xplicit, Access access, StaticMember *m, size_t pos)
Multiname *JS2Metadata::defineStaticMember(Environment *env, const StringAtom *id, NamespaceList *namespaces,
Attribute::OverrideModifier overrideMod, bool xplicit, Access access,
StaticMember *m, size_t pos)
{
NamespaceList publicNamespaceList;
@ -2603,37 +2607,52 @@ doUnary:
}
Multiname *mn = new Multiname(id);
mn->addNamespace(namespaces);
StaticBindingIterator b, end;
for (b = localFrame->staticReadBindings.lower_bound(*id),
end = localFrame->staticReadBindings.upper_bound(*id); (b != end); b++) {
if (mn->matches(b->second->qname))
reportError(Exception::definitionError, "Duplicate definition {0}", pos, id);
StaticBindingIterator b, end;
if (access & ReadAccess) {
for (b = localFrame->staticReadBindings.lower_bound(*id),
end = localFrame->staticReadBindings.upper_bound(*id); (b != end); b++) {
if (mn->matches(b->second->qname))
reportError(Exception::definitionError, "Duplicate definition {0}", pos, id);
}
}
if (access & WriteAccess) {
for (b = localFrame->staticWriteBindings.lower_bound(*id),
end = localFrame->staticWriteBindings.upper_bound(*id); (b != end); b++) {
if (mn->matches(b->second->qname))
reportError(Exception::definitionError, "Duplicate definition {0}", pos, id);
}
}
// Check all frames below the current - up to the RegionalFrame - for a non-forbidden definition
Frame *regionalFrame = *(env->getRegionalFrame());
if (localFrame != regionalFrame) {
Frame *fr = *++fi;
while (fr != regionalFrame) {
while (true) {
for (b = fr->staticReadBindings.lower_bound(*id),
end = fr->staticReadBindings.upper_bound(*id); (b != end); b++) {
if (mn->matches(b->second->qname) && (b->second->content->kind != StaticMember::Forbidden))
reportError(Exception::definitionError, "Duplicate definition {0}", pos, id);
}
if (fr == regionalFrame)
break;
fr = *++fi;
}
fi = env->getBegin();
fr = *++fi;
while (fr != regionalFrame) {
while (true) {
for (b = fr->staticWriteBindings.lower_bound(*id),
end = fr->staticWriteBindings.upper_bound(*id); (b != end); b++) {
if (mn->matches(b->second->qname) && (b->second->content->kind != StaticMember::Forbidden))
reportError(Exception::definitionError, "Duplicate definition {0}", pos, id);
}
if (fr == regionalFrame)
break;
fr = *++fi;
}
}
// If the regional frame is the global object, make sure there's not a dynamic
// property with the same id as the one we're about to define
if (regionalFrame->kind == GlobalObjectKind) {
GlobalObject *gObj = checked_cast<GlobalObject *>(regionalFrame);
DynamicPropertyIterator dp = gObj->dynamicProperties.find(*id);
@ -2641,20 +2660,26 @@ doUnary:
reportError(Exception::definitionError, "Duplicate definition {0}", pos, id);
}
// Now insert the id, via all it's namespaces into the local frame
for (NamespaceListIterator nli = mn->nsList.begin(), nlend = mn->nsList.end(); (nli != nlend); nli++) {
QualifiedName qName(*nli, *id);
StaticBinding *sb = new StaticBinding(qName, m);
const StaticBindingMap::value_type e(*id, sb);
if (access & ReadAccess)
regionalFrame->staticReadBindings.insert(e);
localFrame->staticReadBindings.insert(e);
if (access & WriteAccess)
regionalFrame->staticWriteBindings.insert(e);
localFrame->staticWriteBindings.insert(e);
}
// And mark all (any) lower definitions as Forbidden
// XXX there's a discrepancy in the spec. -- the comment says:
// "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"
// But the code simply adds a Forbidden binding in each namespace to each frame in the region
if (localFrame != regionalFrame) {
fi = env->getBegin();
Frame *fr = *++fi;
while (fr != regionalFrame) {
while (true) {
for (NamespaceListIterator nli = mn->nsList.begin(), nlend = mn->nsList.end(); (nli != nlend); nli++) {
QualifiedName qName(*nli, *id);
StaticBinding *sb = new StaticBinding(qName, forbiddenMember);
@ -2664,6 +2689,8 @@ doUnary:
if (access & WriteAccess)
fr->staticWriteBindings.insert(e);
}
if (fr == regionalFrame)
break;
fr = *++fi;
}
}