Bug fixes, realigning StringAtom use.

This commit is contained in:
rogerl%netscape.com 2003-01-04 01:20:59 +00:00
Родитель 6d74664081
Коммит 8f8b78cd6e
8 изменённых файлов: 89 добавлений и 40 удалений

Просмотреть файл

@ -237,7 +237,7 @@ void printFrameBindings(Frame *f)
{
stdOut << " Static Bindings:\n";
for (StaticBindingIterator rsb = f->staticReadBindings.begin(), rsend = f->staticReadBindings.end(); (rsb != rsend); rsb++) {
stdOut << "\t" << *rsb->second->qname.nameSpace->name << "::" << rsb->second->qname.id;
stdOut << "\t" << *rsb->second->qname.nameSpace->name << "::" << *rsb->second->qname.id;
bool found = false;
for (StaticBindingIterator wsb = f->staticWriteBindings.begin(), wsend = f->staticWriteBindings.end(); (wsb != wsend); wsb++) {
if (rsb->second->qname == wsb->second->qname) {
@ -256,7 +256,7 @@ void printFrameBindings(Frame *f)
}
}
if (!found)
stdOut << "\t" << *wsb->second->qname.nameSpace->name << "::" << wsb->second->qname.id << " [write-only]" << "\n";
stdOut << "\t" << *wsb->second->qname.nameSpace->name << "::" << *wsb->second->qname.id << " [write-only]" << "\n";
}
}
@ -289,7 +289,7 @@ js2val dump(JS2Metadata *meta, const js2val /* thisValue */, js2val argv[], uint
stdOut << " Instance Bindings:\n";
for (InstanceBindingIterator rib = c->instanceReadBindings.begin(), riend = c->instanceReadBindings.end(); (rib != riend); rib++) {
stdOut << "\t" << *rib->second->qname.nameSpace->name << "::" << rib->second->qname.id;
stdOut << "\t" << *rib->second->qname.nameSpace->name << "::" << *rib->second->qname.id;
bool found = false;
for (InstanceBindingIterator wib = c->instanceWriteBindings.begin(), wiend = c->instanceWriteBindings.end(); (wib != wiend); wib++) {
if (rib->second->qname == wib->second->qname) {
@ -308,7 +308,7 @@ js2val dump(JS2Metadata *meta, const js2val /* thisValue */, js2val argv[], uint
}
}
if (!found)
stdOut << "\t" << *wib->second->qname.nameSpace->name << "::" << wib->second->qname.id << " [write-only]" << "\n";
stdOut << "\t" << *wib->second->qname.nameSpace->name << "::" << *wib->second->qname.id << " [write-only]" << "\n";
}
}
else {

Просмотреть файл

@ -67,6 +67,14 @@ namespace MetaData {
return thatValue;
}
static js2val Boolean_Call(JS2Metadata *meta, const js2val thisValue, js2val argv[], uint32 argc)
{
if (argc > 0)
return BOOLEAN_TO_JS2VAL(meta->toBoolean(argv[0]));
else
return JS2VAL_FALSE;
}
static js2val Boolean_toString(JS2Metadata *meta, const js2val thisValue, js2val * /*argv*/, uint32 /*argc*/)
{
if (meta->objectType(thisValue) != meta->booleanClass)
@ -75,9 +83,18 @@ namespace MetaData {
return (boolInst->mValue) ? meta->engine->allocString(meta->engine->true_StringAtom) : meta->engine->allocString(meta->engine->false_StringAtom);
}
static js2val Boolean_valueOf(JS2Metadata *meta, const js2val thisValue, js2val * /*argv*/, uint32 /*argc*/)
{
if (meta->objectType(thisValue) != meta->booleanClass)
meta->reportError(Exception::typeError, "Boolean.valueOf called on something other than a boolean thing", meta->engine->errorPos());
BooleanInstance *boolInst = checked_cast<BooleanInstance *>(JS2VAL_TO_OBJECT(thisValue));
return (boolInst->mValue) ? JS2VAL_TRUE : JS2VAL_FALSE;
}
void initBooleanObject(JS2Metadata *meta)
{
meta->booleanClass->construct = Boolean_Constructor;
meta->booleanClass->call = Boolean_Call;
typedef struct {
char *name;
@ -87,8 +104,8 @@ namespace MetaData {
PrototypeFunction prototypeFunctions[] =
{
{ "toString", 0, Boolean_toString },
// { "valueOf", 0, Boolean_valueOf },
{ "toString", 0, Boolean_toString },
{ "valueOf", 0, Boolean_valueOf },
{ NULL }
};
@ -96,13 +113,20 @@ namespace MetaData {
NamespaceList publicNamespaceList;
publicNamespaceList.push_back(meta->publicNamespace);
meta->booleanClass->prototype = new PrototypeInstance(meta->objectClass->prototype, meta->booleanClass);
meta->env->addFrame(meta->booleanClass);
Variable *v = new Variable(meta->booleanClass, OBJECT_TO_JS2VAL(meta->booleanClass->prototype), true);
meta->defineStaticMember(meta->env, meta->engine->prototype_StringAtom, &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
meta->env->removeTopFrame();
PrototypeFunction *pf = &prototypeFunctions[0];
while (pf->name) {
CallableInstance *fInst = new CallableInstance(meta->functionClass);
fInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_INACCESSIBLE, true), pf->code);
/*
XXX not prototype object function properties, like ECMA3, but members of the Date class
meta->writeDynamicProperty(meta->dateClass->prototype, new Multiname(meta->world.identifiers[pf->name], meta->publicNamespace), true, OBJECT_TO_JS2VAL(fInst), RunPhase);
XXX not prototype object function properties, like ECMA3
meta->writeDynamicProperty(meta->booleanClass->prototype, new Multiname(meta->world.identifiers[pf->name], meta->publicNamespace), true, OBJECT_TO_JS2VAL(fInst), RunPhase);
*/
/*
XXX not static members, since those can't be accessed from the instance

Просмотреть файл

@ -1472,7 +1472,7 @@ void initDateObject(JS2Metadata *meta)
CallableInstance *fInst = new CallableInstance(meta->functionClass);
fInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_INACCESSIBLE, true), pf->code);
/*
XXX not prototype object function properties, like ECMA3, but members of the Date class
XXX not prototype object function properties, like ECMA3
meta->writeDynamicProperty(meta->dateClass->prototype, new Multiname(meta->world.identifiers[pf->name], meta->publicNamespace), true, OBJECT_TO_JS2VAL(fInst), RunPhase);
*/
/*

Просмотреть файл

@ -2600,7 +2600,7 @@ doUnary:
// - If the binding exists (not forbidden) in lower frames in the regional environment, it's an error.
// - Define a forbidden binding in all the lower frames.
//
Multiname *JS2Metadata::defineStaticMember(Environment *env, const StringAtom *id, NamespaceList *namespaces,
Multiname *JS2Metadata::defineStaticMember(Environment *env, const String *id, NamespaceList *namespaces,
Attribute::OverrideModifier overrideMod, bool xplicit, Access access,
StaticMember *m, size_t pos)
{
@ -2671,7 +2671,7 @@ doUnary:
// 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);
QualifiedName qName(*nli, id);
StaticBinding *sb = new StaticBinding(qName, m);
const StaticBindingMap::value_type e(*id, sb);
if (access & ReadAccess)
@ -2690,7 +2690,7 @@ doUnary:
Frame *fr = *++fi;
while (true) {
for (NamespaceListIterator nli = mn->nsList.begin(), nlend = mn->nsList.end(); (nli != nlend); nli++) {
QualifiedName qName(*nli, *id);
QualifiedName qName(*nli, id);
StaticBinding *sb = new StaticBinding(qName, forbiddenMember);
const StaticBindingMap::value_type e(*id, sb);
if (access & ReadAccess)
@ -2715,15 +2715,15 @@ doUnary:
JS2Class *s = c;
while (s) {
if (access & ReadAccess) {
for (InstanceBindingIterator b = s->instanceReadBindings.lower_bound(qname->id),
end = s->instanceReadBindings.upper_bound(qname->id); (b != end); b++) {
for (InstanceBindingIterator b = s->instanceReadBindings.lower_bound(*qname->id),
end = s->instanceReadBindings.upper_bound(*qname->id); (b != end); b++) {
if (*qname == b->second->qname)
return b->second->content;
}
}
if (access & WriteAccess) {
for (InstanceBindingIterator b = s->instanceWriteBindings.lower_bound(qname->id),
end = s->instanceWriteBindings.upper_bound(qname->id); (b != end); b++) {
for (InstanceBindingIterator b = s->instanceWriteBindings.lower_bound(*qname->id),
end = s->instanceWriteBindings.upper_bound(*qname->id); (b != end); b++) {
if (*qname == b->second->qname)
return b->second->content;
}
@ -2739,7 +2739,7 @@ doUnary:
{
OverrideStatus *os = new OverrideStatus(NULL, id);
for (NamespaceListIterator ns = namespaces->begin(), end = namespaces->end(); (ns != end); ns++) {
QualifiedName qname(*ns, *id);
QualifiedName qname(*ns, id);
InstanceMember *m = findInstanceMember(c, &qname, access);
if (m) {
os->multiname.addNamespace(*ns);
@ -2789,7 +2789,7 @@ doUnary:
}
// For all the discovered possible overrides, make sure the member doesn't already exist in the class
for (NamespaceListIterator nli = os->multiname.nsList.begin(), nlend = os->multiname.nsList.end(); (nli != nlend); nli++) {
QualifiedName qname(*nli, *id);
QualifiedName qname(*nli, id);
if (access & ReadAccess) {
for (InstanceBindingIterator b = c->instanceReadBindings.lower_bound(*id),
end = c->instanceReadBindings.upper_bound(*id); (b != end); b++) {
@ -2851,14 +2851,14 @@ doUnary:
NamespaceListIterator nli, nlend;
for (nli = readStatus->multiname.nsList.begin(), nlend = readStatus->multiname.nsList.end(); (nli != nlend); nli++) {
QualifiedName qName(*nli, *id);
QualifiedName qName(*nli, id);
InstanceBinding *ib = new InstanceBinding(qName, m);
const InstanceBindingMap::value_type e(*id, ib);
c->instanceReadBindings.insert(e);
}
for (nli = writeStatus->multiname.nsList.begin(), nlend = writeStatus->multiname.nsList.end(); (nli != nlend); nli++) {
QualifiedName qName(*nli, *id);
QualifiedName qName(*nli, id);
InstanceBinding *ib = new InstanceBinding(qName, m);
const InstanceBindingMap::value_type e(*id, ib);
c->instanceWriteBindings.insert(e);
@ -2880,7 +2880,7 @@ doUnary:
HoistedVar *JS2Metadata::defineHoistedVar(Environment *env, const StringAtom *id, StmtNode *p)
{
HoistedVar *result = NULL;
QualifiedName qName(publicNamespace, *id);
QualifiedName qName(publicNamespace, id);
FrameListIterator regionalFrameMark = env->getRegionalFrame();
Frame *regionalFrame = *regionalFrameMark;
ASSERT((regionalFrame->kind == GlobalObjectKind) || (regionalFrame->kind == ParameterKind));

Просмотреть файл

@ -55,7 +55,7 @@ class CallableInstance;
typedef void (Invokable)();
typedef Invokable Callor;
typedef js2val (Callor)(JS2Metadata *meta, const js2val thisValue, js2val *argv, uint32 argc);
typedef js2val (Constructor)(JS2Metadata *meta, const js2val thisValue, js2val *argv, uint32 argc);
extern void initDateObject(JS2Metadata *meta);
@ -217,12 +217,12 @@ public:
// A QualifiedName is the combination of an identifier and a namespace
class QualifiedName {
public:
QualifiedName(Namespace *nameSpace, const StringAtom &id) : nameSpace(nameSpace), id(id) { }
QualifiedName(Namespace *nameSpace, const String *id) : nameSpace(nameSpace), id(id) { }
bool operator ==(const QualifiedName &b) { return (nameSpace == b.nameSpace) && (id == b.id); }
bool operator ==(const QualifiedName &b) { return (nameSpace == b.nameSpace) && (*id == *b.id); }
Namespace *nameSpace; // The namespace qualifier
const StringAtom &id; // The name
const String *id; // The name
};
// A MULTINAME is the semantic domain of sets of qualified names. Multinames are used internally in property lookup.
@ -239,7 +239,7 @@ public:
void addNamespace(NamespaceList *ns);
void addNamespace(Context &cxt);
bool matches(QualifiedName &q) { return (*name == q.id) && onList(q.nameSpace); }
bool matches(QualifiedName &q) { return (*name == *q.id) && onList(q.nameSpace); }
bool onList(Namespace *nameSpace);
NamespaceList nsList;
@ -1035,7 +1035,7 @@ public:
InstanceBinding *resolveInstanceMemberName(JS2Class *js2class, Multiname *multiname, Access access, Phase phase);
HoistedVar *defineHoistedVar(Environment *env, const StringAtom *id, StmtNode *p);
Multiname *defineStaticMember(Environment *env, const StringAtom *id, NamespaceList *namespaces, Attribute::OverrideModifier overrideMod, bool xplicit, Access access, StaticMember *m, size_t pos);
Multiname *defineStaticMember(Environment *env, const String *id, NamespaceList *namespaces, Attribute::OverrideModifier overrideMod, bool xplicit, Access access, StaticMember *m, size_t pos);
OverrideStatusPair *defineInstanceMember(JS2Class *c, Context *cxt, const StringAtom *id, NamespaceList *namespaces, Attribute::OverrideModifier overrideMod, bool xplicit, Access access, InstanceMember *m, size_t pos);
OverrideStatus *resolveOverrides(JS2Class *c, Context *cxt, const StringAtom *id, NamespaceList *namespaces, Access access, bool expectMethod, size_t pos);
OverrideStatus *searchForOverrides(JS2Class *c, const StringAtom *id, NamespaceList *namespaces, Access access, size_t pos);

Просмотреть файл

@ -98,6 +98,8 @@
case eCall:
{
// XXX Remove the arguments from the stack, (native calls have done this already)
// (important that they're tracked for gc in any mechanism)
uint16 argCount = BytecodeContainer::getShort(pc);
pc += sizeof(uint16);
a = top(argCount + 2); // 'this'
@ -156,8 +158,18 @@
push(a);
}
}
// XXX Remove the arguments from the stack, (native calls have done this already)
// (important that they're tracked for gc in any mechanism)
else
if (fObj->kind == ClassKind) {
JS2Class *c = checked_cast<JS2Class *>(fObj);
if (c->call)
a = c->call(meta, JS2VAL_NULL, base(argCount), argCount);
else
a = JS2VAL_UNDEFINED;
pop(argCount + 1);
push(a);
}
else
meta->reportError(Exception::badValueError, "Un-callable object", errorPos());
}
break;
@ -263,4 +275,11 @@
}
break;
case eCoerce:
{
JS2Class *c = BytecodeContainer::getType(pc);
pc += sizeof(JS2Class *);
a = pop();
push(c->implicitCoerce(meta, a));
}
break;

Просмотреть файл

@ -88,6 +88,12 @@
}
break;
case eUndefined:
{
push(JS2VAL_UNDEFINED);
}
break;
case eThis: // XXX literal?
{
a = meta->env->findThis(true);

Просмотреть файл

@ -62,62 +62,62 @@ namespace MetaData {
void RegExpInstance::setLastIndex(JS2Metadata *meta, js2val a)
{
QualifiedName qname(meta->publicNamespace, meta->world.identifiers["lastIndex"]);
QualifiedName qname(meta->publicNamespace, &meta->world.identifiers["lastIndex"]);
if (!meta->writeInstanceMember(OBJECT_TO_JS2VAL(this), meta->regexpClass, &qname, a, RunPhase)) ASSERT(false);
}
void RegExpInstance::setGlobal(JS2Metadata *meta, js2val a)
{
QualifiedName qname(meta->publicNamespace, meta->world.identifiers["global"]);
QualifiedName qname(meta->publicNamespace, &meta->world.identifiers["global"]);
if (!meta->writeInstanceMember(OBJECT_TO_JS2VAL(this), meta->regexpClass, &qname, a, RunPhase)) ASSERT(false);
}
void RegExpInstance::setMultiline(JS2Metadata *meta, js2val a)
{
QualifiedName qname(meta->publicNamespace, meta->world.identifiers["multiline"]);
QualifiedName qname(meta->publicNamespace, &meta->world.identifiers["multiline"]);
if (!meta->writeInstanceMember(OBJECT_TO_JS2VAL(this), meta->regexpClass, &qname, a, RunPhase)) ASSERT(false);
}
void RegExpInstance::setIgnoreCase(JS2Metadata *meta, js2val a)
{
QualifiedName qname(meta->publicNamespace, meta->world.identifiers["ignoreCase"]);
QualifiedName qname(meta->publicNamespace, &meta->world.identifiers["ignoreCase"]);
if (!meta->writeInstanceMember(OBJECT_TO_JS2VAL(this), meta->regexpClass, &qname, a, RunPhase)) ASSERT(false);
}
void RegExpInstance::setSource(JS2Metadata *meta, js2val a)
{
QualifiedName qname(meta->publicNamespace, meta->world.identifiers["source"]);
QualifiedName qname(meta->publicNamespace, &meta->world.identifiers["source"]);
if (!meta->writeInstanceMember(OBJECT_TO_JS2VAL(this), meta->regexpClass, &qname, a, RunPhase)) ASSERT(false);
}
js2val RegExpInstance::getLastIndex(JS2Metadata *meta)
{
js2val r;
QualifiedName qname(meta->publicNamespace, meta->world.identifiers["lastIndex"]);
QualifiedName qname(meta->publicNamespace, &meta->world.identifiers["lastIndex"]);
if (!meta->readInstanceMember(OBJECT_TO_JS2VAL(this), meta->regexpClass, &qname, RunPhase, &r)) ASSERT(false);
return r;
}
js2val RegExpInstance::getGlobal(JS2Metadata *meta)
{
js2val r;
QualifiedName qname(meta->publicNamespace, meta->world.identifiers["global"]);
QualifiedName qname(meta->publicNamespace, &meta->world.identifiers["global"]);
if (!meta->readInstanceMember(OBJECT_TO_JS2VAL(this), meta->regexpClass, &qname, RunPhase, &r)) ASSERT(false);
return r;
}
js2val RegExpInstance::getMultiline(JS2Metadata *meta)
{
js2val r;
QualifiedName qname(meta->publicNamespace, meta->world.identifiers["multiline"]);
QualifiedName qname(meta->publicNamespace, &meta->world.identifiers["multiline"]);
if (!meta->readInstanceMember(OBJECT_TO_JS2VAL(this), meta->regexpClass, &qname, RunPhase, &r)) ASSERT(false);
return r;
}
js2val RegExpInstance::getIgnoreCase(JS2Metadata *meta)
{
js2val r;
QualifiedName qname(meta->publicNamespace, meta->world.identifiers["ignoreCase"]);
QualifiedName qname(meta->publicNamespace, &meta->world.identifiers["ignoreCase"]);
if (!meta->readInstanceMember(OBJECT_TO_JS2VAL(this), meta->regexpClass, &qname, RunPhase, &r)) ASSERT(false);
return r;
}
js2val RegExpInstance::getSource(JS2Metadata *meta)
{
js2val r;
QualifiedName qname(meta->publicNamespace, meta->world.identifiers["source"]);
QualifiedName qname(meta->publicNamespace, &meta->world.identifiers["source"]);
if (!meta->readInstanceMember(OBJECT_TO_JS2VAL(this), meta->regexpClass, &qname, RunPhase, &r)) ASSERT(false);
return r;
}