зеркало из https://github.com/mozilla/gecko-dev.git
Bug fixes, realigning StringAtom use.
This commit is contained in:
Родитель
6d74664081
Коммит
8f8b78cd6e
|
@ -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;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче