mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 22:01:30 +00:00
!!! BROKEN !!! Added definitions under new layout.
This commit is contained in:
parent
e57635d85b
commit
9c7a073f85
@ -298,36 +298,6 @@ js2val dump(JS2Metadata *meta, const js2val /* thisValue */, js2val argv[], uint
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (fObj->kind == PrototypeInstanceKind) {
|
||||
PrototypeInstance *pInst = checked_cast<PrototypeInstance *>(fObj);
|
||||
stdOut << "Prototype Instance\n";
|
||||
if (pInst->parent)
|
||||
printFormat(stdOut, "Parent @ 0x%08X\n", pInst->parent);
|
||||
else
|
||||
stdOut << " Null Parent\n";
|
||||
if (pInst->type)
|
||||
stdOut << " Type: " << *pInst->type->getName() << "\n";
|
||||
else
|
||||
stdOut << " Null Type\n";
|
||||
|
||||
stdOut << " Dynamic Properties:\n";
|
||||
for (DynamicPropertyIterator dpi = pInst->dynamicProperties.begin(), dpend = pInst->dynamicProperties.end(); (dpi != dpend); dpi++) {
|
||||
DynamicPropertyBinding *dpb = *dpi;
|
||||
stdOut << "\t" << dpb->name << " = " << *meta->toString(dpb->v.value) << "\n";
|
||||
}
|
||||
if (pInst->type == meta->functionClass) {
|
||||
FunctionWrapper *fWrap = (checked_cast<FunctionInstance *>(fObj))->fWrap;
|
||||
stdOut << "Function:" << "\n";
|
||||
if (fWrap) {
|
||||
stdOut << "Environment depth " << fWrap->env->getSize() << "\n";
|
||||
dumpBytecode(fWrap->bCon);
|
||||
}
|
||||
else
|
||||
stdOut << "<<Empty Function>>\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -61,7 +61,8 @@ uint32 getLength(JS2Metadata *meta, JS2Object *obj)
|
||||
LookupKind lookup(false, JS2VAL_NULL);
|
||||
uint32 length = 0;
|
||||
js2val result;
|
||||
if (meta->readDynamicProperty(obj, meta->engine->length_StringAtom, &lookup, RunPhase, &result))
|
||||
meta->mn1->name = meta->engine->length_StringAtom;
|
||||
if (meta->readDynamicProperty(obj, meta->mn1, &lookup, RunPhase, &result))
|
||||
length = toUInt32(meta->toInteger(result));
|
||||
return length;
|
||||
}
|
||||
@ -88,6 +89,7 @@ js2val setLength(JS2Metadata *meta, JS2Object *obj, uint32 newLength)
|
||||
if (obj->kind == SimpleInstanceKind) {
|
||||
// Can't call 'writeDynamicProperty' as that'll just cycle back here for
|
||||
// ArrayInstances.
|
||||
/*
|
||||
DynamicPropertyMap *dMap = &checked_cast<SimpleInstance *>(obj)->dynamicProperties;
|
||||
DynamicPropertyBinding **dpbP = (*dMap)[*meta->engine->length_StringAtom];
|
||||
if (dpbP) {
|
||||
@ -96,9 +98,11 @@ js2val setLength(JS2Metadata *meta, JS2Object *obj, uint32 newLength)
|
||||
}
|
||||
DynamicPropertyBinding *dpb = new DynamicPropertyBinding(*meta->engine->length_StringAtom, DynamicPropertyValue(result, DynamicPropertyValue::PERMANENT));
|
||||
checked_cast<SimpleInstance *>(obj)->dynamicProperties.insert(dpb->name, dpb);
|
||||
*/
|
||||
}
|
||||
else {
|
||||
meta->writeDynamicProperty(obj, meta->engine->length_StringAtom, true, result, RunPhase);
|
||||
meta->mn1->name = meta->engine->length_StringAtom;
|
||||
meta->writeDynamicProperty(obj, meta->mn1, true, result, RunPhase);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -118,16 +122,15 @@ js2val Array_Constructor(JS2Metadata *meta, const js2val /*thisValue*/, js2val *
|
||||
meta->reportError(Exception::rangeError, "Array length too large", meta->engine->errorPos());
|
||||
}
|
||||
else {
|
||||
String *s = meta->engine->numberToString((int32)0);
|
||||
RootKeeper rk(&s);
|
||||
meta->writeDynamicProperty(arrInst, s, true, argv[0], RunPhase);
|
||||
meta->mn1->name = meta->engine->numberToString((int32)0);
|
||||
meta->writeDynamicProperty(arrInst, meta->mn1, true, argv[0], RunPhase);
|
||||
}
|
||||
}
|
||||
else {
|
||||
uint32 i;
|
||||
for (i = 0; i < argc; i++) {
|
||||
DynamicPropertyBinding *dpb = new DynamicPropertyBinding(*meta->engine->numberToString(i), DynamicPropertyValue(argv[i], DynamicPropertyValue::ENUMERATE));
|
||||
arrInst->dynamicProperties.insert(dpb->name, dpb);
|
||||
// DynamicPropertyBinding *dpb = new DynamicPropertyBinding(*meta->engine->numberToString(i), DynamicPropertyValue(argv[i], DynamicPropertyValue::ENUMERATE));
|
||||
// arrInst->dynamicProperties.insert(dpb->name, dpb);
|
||||
}
|
||||
setLength(meta, arrInst, i);
|
||||
}
|
||||
|
@ -210,56 +210,6 @@ namespace MetaData {
|
||||
JS2Object *fnObj = JS2VAL_TO_OBJECT(fnVal);
|
||||
result = invokeFunction(fnObj, thisValue, NULL, 0);
|
||||
return true;
|
||||
/*
|
||||
FunctionWrapper *fWrap = NULL;
|
||||
if ((fnObj->kind == SimpleInstanceKind)
|
||||
&& (objectType(fnVal) == functionClass)) {
|
||||
fWrap = (checked_cast<SimpleInstance *>(fnObj))->fWrap;
|
||||
}
|
||||
else
|
||||
if ((fnObj->kind == PrototypeInstanceKind)
|
||||
&& ((checked_cast<PrototypeInstance *>(fnObj))->type == functionClass)) {
|
||||
fWrap = (checked_cast<FunctionInstance *>(fnObj))->fWrap;
|
||||
}
|
||||
else
|
||||
if (fnObj->kind == MethodClosureKind) {
|
||||
// XXX here we ignore the bound this, can that be right?
|
||||
MethodClosure *mc = checked_cast<MethodClosure *>(fnObj);
|
||||
fWrap = mc->method->fInst->fWrap;
|
||||
}
|
||||
if (fWrap) {
|
||||
if (fWrap->code) {
|
||||
result = (fWrap->code)(this, thisValue, NULL, 0);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
uint8 *savePC = NULL;
|
||||
BytecodeContainer *bCon = fWrap->bCon;
|
||||
|
||||
CompilationData *oldData = startCompilationUnit(bCon, bCon->mSource, bCon->mSourceLocation);
|
||||
ParameterFrame *runtimeFrame = new ParameterFrame(fWrap->compileFrame);
|
||||
runtimeFrame->instantiate(env);
|
||||
runtimeFrame->thisObject = thisValue;
|
||||
Frame *oldTopFrame = env->getTopFrame();
|
||||
env->addFrame(runtimeFrame);
|
||||
try {
|
||||
savePC = engine->pc;
|
||||
engine->pc = NULL;
|
||||
result = engine->interpret(RunPhase, bCon);
|
||||
}
|
||||
catch (Exception &x) {
|
||||
engine->pc = savePC;
|
||||
restoreCompilationUnit(oldData);
|
||||
env->setTopFrame(oldTopFrame);
|
||||
throw x;
|
||||
}
|
||||
engine->pc = savePC;
|
||||
restoreCompilationUnit(oldData);
|
||||
env->setTopFrame(oldTopFrame);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@ -304,11 +254,6 @@ namespace MetaData {
|
||||
fWrap = (checked_cast<SimpleInstance *>(fnObj))->fWrap;
|
||||
}
|
||||
else
|
||||
if ((fnObj->kind == PrototypeInstanceKind)
|
||||
&& ((checked_cast<PrototypeInstance *>(fnObj))->type == functionClass)) {
|
||||
fWrap = (checked_cast<FunctionInstance *>(fnObj))->fWrap;
|
||||
}
|
||||
else
|
||||
if (fnObj->kind == MethodClosureKind) {
|
||||
// XXX here we ignore the bound this, can that be right?
|
||||
MethodClosure *mc = checked_cast<MethodClosure *>(fnObj);
|
||||
|
@ -2715,7 +2715,7 @@ doUnary:
|
||||
* JS2Metadata
|
||||
*
|
||||
************************************************************************************/
|
||||
#if 0
|
||||
|
||||
// - Define namespaces::id (for all namespaces or at least 'public') in the top frame
|
||||
// unless it's there already.
|
||||
// - If the binding exists (not forbidden) in lower frames in the regional environment, it's an error.
|
||||
@ -2725,18 +2725,15 @@ doUnary:
|
||||
Attribute::OverrideModifier overrideMod, bool xplicit, Access access,
|
||||
LocalMember *m, size_t pos)
|
||||
{
|
||||
NamespaceList publicNamespaceList;
|
||||
|
||||
FrameListIterator fi = env->getBegin();
|
||||
NonWithFrame *localFrame = checked_cast<NonWithFrame *>(*fi);
|
||||
if ((overrideMod != Attribute::NoOverride) || (xplicit && localFrame->kind != PackageKind))
|
||||
NonWithFrame *innerFrame = checked_cast<NonWithFrame *>(*(env->getBegin()));
|
||||
if ((overrideMod != Attribute::NoOverride) || (xplicit && innerFrame->kind != PackageKind))
|
||||
reportError(Exception::definitionError, "Illegal definition", pos);
|
||||
if ((namespaces == NULL) || namespaces->empty()) {
|
||||
publicNamespaceList.push_back(publicNamespace);
|
||||
namespaces = &publicNamespaceList;
|
||||
}
|
||||
Multiname *mn = new Multiname(id);
|
||||
mn->addNamespace(namespaces);
|
||||
|
||||
Multiname *multiname = new Multiname(id);
|
||||
if (namespaces->empty())
|
||||
multiname->addNamespace(publicNamespace);
|
||||
else
|
||||
multiname->addNamespace(namespaces);
|
||||
|
||||
// Search the local frame for an overlapping definition
|
||||
LocalBindingEntry **lbeP = localFrame->localBindings[*id];
|
||||
@ -2910,41 +2907,41 @@ doUnary:
|
||||
}
|
||||
if (mOverridden->final || !goodKind)
|
||||
reportError(Exception::definitionError, "Illegal override", pos);
|
||||
|
||||
InstanceBindingEntry **ibeP = c->instanceBindings[*id];
|
||||
if (ibeP) {
|
||||
for (InstanceBindingEntry::NS_Iterator i = (*ibeP)->begin(), end = (*ibeP)->end(); (i != end); i++) {
|
||||
InstanceBindingEntry::NamespaceBinding &ns = *i;
|
||||
if ((ns.second->accesses & access) && (ns.first == *nli))
|
||||
reportError(Exception::definitionError, "Illegal override", pos);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
InstanceBindingEntry **ibeP = c->instanceBindings[*id];
|
||||
if (ibeP) {
|
||||
for (InstanceBindingEntry::NS_Iterator i = (*ibeP)->begin(), end = (*ibeP)->end(); (i != end); i++) {
|
||||
InstanceBindingEntry::NamespaceBinding &ns = *i;
|
||||
if (access & m2->instanceMemberAccess()) && (definedMultiname->listContaines(ns.first)))
|
||||
reportError(Exception::definitionError, "Illegal override", pos);
|
||||
}
|
||||
}
|
||||
switch (overrideMod) {
|
||||
case Attribute::NoOverride:
|
||||
if (mBase || searchForOverrides(c, openMultiname, access))
|
||||
reportError(Exception::definitionError, "Illegal override", pos);
|
||||
break;
|
||||
case Attribute::DoOverride:
|
||||
if (mBase)
|
||||
reportError(Exception::definitionError, "Illegal override", pos);
|
||||
break;
|
||||
case Attribute::DontOverride:
|
||||
if (mBase == NULL)
|
||||
reportError(Exception::definitionError, "Illegal override", pos);
|
||||
break;
|
||||
}
|
||||
m->multiname = new Multiname(definedMultiname);
|
||||
InstanceBinding *ib = new LocalBinding(access, m);
|
||||
if (ibeP) {
|
||||
for (NamespaceListIterator nli = definedMultiname.nsList->begin(), nlend = definedMultiname.nsList->end(); (nli != nlend); nli++) {
|
||||
*ibeP->bindingList.push_back(InstanceBindingEntry::NamespaceBinding(*nli, ib);
|
||||
}
|
||||
}
|
||||
return mOverridden;
|
||||
}
|
||||
|
||||
|
||||
if mOverridden.final or not goodKind then throw definitionError end if
|
||||
end if;
|
||||
if some m2 OE c.instanceMembers satisfies m2.multiname « definedMultiname ! {} and
|
||||
accessesOverlap(instanceMemberAccesses(m2), accesses) then
|
||||
throw definitionError
|
||||
end if;
|
||||
case overrideMod of
|
||||
{ none } do
|
||||
if mBase ! none or searchForOverrides(c, openMultiname, accesses) ! none then
|
||||
throw definitionError
|
||||
end if;
|
||||
{ false } do if mBase ! none then throw definitionError end if;
|
||||
{ true } do if mBase = none then throw definitionError end if;
|
||||
{ undefined } do nothing
|
||||
end case;
|
||||
m.multiname ¨ definedMultiname;
|
||||
c.instanceMembers ¨ c.instanceMembers » {m};
|
||||
return mOverridden
|
||||
|
||||
|
||||
defineLocalMember
|
||||
|
||||
// Find the possible override conflicts that arise from the given id and namespaces
|
||||
// Fall back on the currently open namespace list if no others are specified.
|
||||
@ -3007,58 +3004,7 @@ return mOverridden
|
||||
return os;
|
||||
}
|
||||
|
||||
// Define an instance member in the class. Verify that, if any overriding is happening, it's legal. The result pair indicates
|
||||
// the members being overridden.
|
||||
OverrideStatusPair *JS2Metadata::defineInstanceMember(JS2Class *c, Context *cxt, const String *id, NamespaceList *namespaces, Attribute::OverrideModifier overrideMod, bool xplicit, Access access, InstanceMember *m, size_t pos)
|
||||
{
|
||||
OverrideStatus *readStatus;
|
||||
OverrideStatus *writeStatus;
|
||||
if (xplicit)
|
||||
reportError(Exception::definitionError, "Illegal use of explicit", pos);
|
||||
|
||||
if (access & ReadAccess)
|
||||
readStatus = resolveOverrides(c, cxt, id, namespaces, ReadAccess, (m->kind == InstanceMember::InstanceMethodKind), pos);
|
||||
else
|
||||
readStatus = new OverrideStatus(NULL, id);
|
||||
|
||||
if (access & WriteAccess)
|
||||
writeStatus = resolveOverrides(c, cxt, id, namespaces, WriteAccess, (m->kind == InstanceMember::InstanceMethodKind), pos);
|
||||
else
|
||||
writeStatus = new OverrideStatus(NULL, id);
|
||||
|
||||
if ((readStatus->overriddenMember && (readStatus->overriddenMember != POTENTIAL_CONFLICT))
|
||||
|| (writeStatus->overriddenMember && (writeStatus->overriddenMember != POTENTIAL_CONFLICT))) {
|
||||
if ((overrideMod != Attribute::DoOverride) && (overrideMod != Attribute::OverrideUndefined))
|
||||
reportError(Exception::definitionError, "Illegal override", pos);
|
||||
}
|
||||
else {
|
||||
if ((readStatus->overriddenMember == POTENTIAL_CONFLICT) || (writeStatus->overriddenMember == POTENTIAL_CONFLICT)) {
|
||||
if ((overrideMod != Attribute::DontOverride) && (overrideMod != Attribute::OverrideUndefined))
|
||||
reportError(Exception::definitionError, "Illegal override", pos);
|
||||
}
|
||||
}
|
||||
|
||||
NamespaceListIterator nli, nlend;
|
||||
InstanceBindingEntry **ibeP = c->instanceBindings[*id];
|
||||
InstanceBindingEntry *ibe;
|
||||
if (ibeP == NULL) {
|
||||
ibe = new InstanceBindingEntry(*id);
|
||||
c->instanceBindings.insert(*id, ibe);
|
||||
}
|
||||
else
|
||||
ibe = *ibeP;
|
||||
for (nli = readStatus->multiname.nsList->begin(), nlend = readStatus->multiname.nsList->end(); (nli != nlend); nli++) {
|
||||
InstanceBinding *ib = new InstanceBinding(ReadAccess, m);
|
||||
ibe->bindingList.push_back(InstanceBindingEntry::NamespaceBinding(*nli, ib));
|
||||
}
|
||||
|
||||
for (nli = writeStatus->multiname.nsList->begin(), nlend = writeStatus->multiname.nsList->end(); (nli != nlend); nli++) {
|
||||
InstanceBinding *ib = new InstanceBinding(ReadAccess, m);
|
||||
ibe->bindingList.push_back(InstanceBindingEntry::NamespaceBinding(*nli, ib));
|
||||
}
|
||||
|
||||
return new OverrideStatusPair(readStatus, writeStatus);;
|
||||
}
|
||||
#endif
|
||||
// Define a hoisted var in the current frame (either Package or a Function)
|
||||
// defineHoistedVar(env, id, initialValue) defines a hoisted variable with the name id in the environment env.
|
||||
|
@ -51,6 +51,7 @@ class CompoundAttribute;
|
||||
class BytecodeContainer;
|
||||
class Pond;
|
||||
class SimpleInstance;
|
||||
class LookupKind;
|
||||
|
||||
|
||||
typedef void (Invokable)();
|
||||
@ -242,27 +243,27 @@ public:
|
||||
// A QualifiedName is the combination of an identifier and a namespace
|
||||
class QualifiedName {
|
||||
public:
|
||||
QualifiedName() : nameSpace(NULL), id(NULL) { }
|
||||
QualifiedName(Namespace *nameSpace, const String *id) : nameSpace(nameSpace), id(id) { }
|
||||
QualifiedName() : nameSpace(NULL), name(NULL) { }
|
||||
QualifiedName(Namespace *nameSpace, const String *name) : nameSpace(nameSpace), name(name) { }
|
||||
|
||||
bool operator ==(const QualifiedName &b) { return (nameSpace == b.nameSpace) && (*id == *b.id); }
|
||||
bool operator ==(const QualifiedName &b) { return (nameSpace == b.nameSpace) && (*name == *b.name); }
|
||||
|
||||
Namespace *nameSpace; // The namespace qualifier
|
||||
const String *id; // The name
|
||||
const String *name; // The name
|
||||
};
|
||||
|
||||
// A MULTINAME is the semantic domain of sets of qualified names. Multinames are used internally in property lookup.
|
||||
// We keep Multinames as a basename and a list of namespace qualifiers (XXX is that right - would the basename
|
||||
// ever be different for the same multiname?)
|
||||
|
||||
// XXX can nsList ever be null, or could allow null nsList to indicate public?
|
||||
typedef std::vector<Namespace *> NamespaceList;
|
||||
typedef NamespaceList::iterator NamespaceListIterator;
|
||||
|
||||
class Multiname : public JS2Object {
|
||||
public:
|
||||
Multiname(const String *name) : JS2Object(MultinameKind), name(name), nsList(new NamespaceList) { }
|
||||
Multiname(const String *name, Namespace *ns) : JS2Object(MultinameKind), name(name), nsList(new NamespaceList) { addNamespace(ns); }
|
||||
Multiname(QualifiedName& q) : JS2Object(MultinameKind), name(q.name), nsList(q.nameSpace) { }
|
||||
Multiname(QualifiedName& q) : JS2Object(MultinameKind), name(q.name), nsList(new NamespaceList) { nsList->push_back(q.nameSpace); }
|
||||
|
||||
Multiname(const Multiname& m) : JS2Object(MultinameKind), name(m.name), nsList(m.nsList) { }
|
||||
|
||||
@ -270,7 +271,7 @@ public:
|
||||
void addNamespace(NamespaceList *ns);
|
||||
void addNamespace(Context &cxt);
|
||||
|
||||
bool matches(QualifiedName &q) { return (*name == *q.id) && listContains(q.nameSpace); }
|
||||
bool matches(QualifiedName &q) { return (*name == *q.name) && listContains(q.nameSpace); }
|
||||
bool listContains(Namespace *nameSpace);
|
||||
|
||||
QualifiedName selectPrimaryName(JS2Metadata *meta);
|
||||
@ -1157,7 +1158,7 @@ public:
|
||||
|
||||
bool readProperty(js2val *container, Multiname *multiname, LookupKind *lookupKind, Phase phase, js2val *rval);
|
||||
bool readProperty(Frame *pf, Multiname *multiname, LookupKind *lookupKind, Phase phase, js2val *rval);
|
||||
bool readDynamicProperty(JS2Object *container, const String *name, LookupKind *lookupKind, Phase phase, js2val *rval);
|
||||
bool readDynamicProperty(JS2Object *container, Multiname *multiname, LookupKind *lookupKind, Phase phase, js2val *rval);
|
||||
bool readLocalMember(LocalMember *m, Phase phase, js2val *rval);
|
||||
bool readInstanceMember(js2val containerVal, JS2Class *c, QualifiedName *qname, Phase phase, js2val *rval);
|
||||
JS2Object *lookupDynamicProperty(JS2Object *obj, const String *name);
|
||||
@ -1165,13 +1166,13 @@ public:
|
||||
|
||||
bool writeProperty(js2val container, Multiname *multiname, LookupKind *lookupKind, bool createIfMissing, js2val newValue, Phase phase);
|
||||
bool writeProperty(Frame *container, Multiname *multiname, LookupKind *lookupKind, bool createIfMissing, js2val newValue, Phase phase, bool initFlag);
|
||||
bool writeDynamicProperty(JS2Object *container, const String *name, bool createIfMissing, js2val newValue, Phase phase);
|
||||
bool writeDynamicProperty(JS2Object *container, Multiname *multiname, bool createIfMissing, js2val newValue, Phase phase);
|
||||
bool writeLocalMember(LocalMember *m, js2val newValue, Phase phase, bool initFlag);
|
||||
bool writeInstanceMember(js2val containerVal, JS2Class *c, QualifiedName *qname, js2val newValue, Phase phase);
|
||||
|
||||
bool deleteProperty(Frame *container, Multiname *multiname, LookupKind *lookupKind, Phase phase, bool *result);
|
||||
bool deleteProperty(js2val container, Multiname *multiname, LookupKind *lookupKind, Phase phase, bool *result);
|
||||
bool deleteDynamicProperty(JS2Object *container, const String *name, LookupKind *lookupKind, bool *result);
|
||||
bool deleteDynamicProperty(JS2Object *container, Multiname *multiname, LookupKind *lookupKind, bool *result);
|
||||
bool deleteLocalMember(LocalMember *m, bool *result);
|
||||
bool deleteInstanceMember(JS2Class *c, QualifiedName *qname, bool *result);
|
||||
|
||||
|
@ -892,23 +892,23 @@
|
||||
{
|
||||
Multiname *mn = bCon->mMultinameList[BytecodeContainer::getShort(pc)];
|
||||
pc += sizeof(short);
|
||||
a = meta->env->lexicalRead(meta, mn, phase);
|
||||
meta->env->lexicalRead(meta, mn, phase, &a);
|
||||
if (JS2VAL_IS_LONG(a)) {
|
||||
int64 i = *JS2VAL_TO_LONG(a);
|
||||
JSLL_ADD(i, i, 1);
|
||||
meta->env->lexicalWrite(meta, mn, allocLong(i), true, phase);
|
||||
meta->env->lexicalWrite(meta, mn, allocLong(i), true);
|
||||
push(a);
|
||||
}
|
||||
else {
|
||||
if (JS2VAL_IS_ULONG(a)) {
|
||||
uint64 i = *JS2VAL_TO_ULONG(a);
|
||||
JSLL_ADD(i, i, 1);
|
||||
meta->env->lexicalWrite(meta, mn, allocULong(i), true, phase);
|
||||
meta->env->lexicalWrite(meta, mn, allocULong(i), true);
|
||||
push(a);
|
||||
}
|
||||
else {
|
||||
float64 num = meta->toFloat64(a);
|
||||
meta->env->lexicalWrite(meta, mn, allocNumber(num + 1.0), true, phase);
|
||||
meta->env->lexicalWrite(meta, mn, allocNumber(num + 1.0), true);
|
||||
pushNumber(num);
|
||||
}
|
||||
}
|
||||
@ -918,9 +918,9 @@
|
||||
{
|
||||
Multiname *mn = bCon->mMultinameList[BytecodeContainer::getShort(pc)];
|
||||
pc += sizeof(short);
|
||||
a = meta->env->lexicalRead(meta, mn, phase);
|
||||
meta->env->lexicalRead(meta, mn, phase, &a);
|
||||
float64 num = meta->toFloat64(a);
|
||||
meta->env->lexicalWrite(meta, mn, allocNumber(num - 1.0), true, phase);
|
||||
meta->env->lexicalWrite(meta, mn, allocNumber(num - 1.0), true);
|
||||
pushNumber(num);
|
||||
}
|
||||
break;
|
||||
@ -928,20 +928,20 @@
|
||||
{
|
||||
Multiname *mn = bCon->mMultinameList[BytecodeContainer::getShort(pc)];
|
||||
pc += sizeof(short);
|
||||
a = meta->env->lexicalRead(meta, mn, phase);
|
||||
meta->env->lexicalRead(meta, mn, phase, &a);
|
||||
float64 num = meta->toFloat64(a);
|
||||
a = pushNumber(num + 1.0);
|
||||
meta->env->lexicalWrite(meta, mn, a, true, phase);
|
||||
meta->env->lexicalWrite(meta, mn, a, true);
|
||||
}
|
||||
break;
|
||||
case eLexicalPreDec:
|
||||
{
|
||||
Multiname *mn = bCon->mMultinameList[BytecodeContainer::getShort(pc)];
|
||||
pc += sizeof(short);
|
||||
a = meta->env->lexicalRead(meta, mn, phase);
|
||||
meta->env->lexicalRead(meta, mn, phase, &a);
|
||||
float64 num = meta->toFloat64(a);
|
||||
a = pushNumber(num - 1.0);
|
||||
meta->env->lexicalWrite(meta, mn, a, true, phase);
|
||||
meta->env->lexicalWrite(meta, mn, a, true);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -54,56 +54,48 @@
|
||||
&& (meta->objectType(a) == meta->functionClass)) {
|
||||
fWrap = (checked_cast<SimpleInstance *>(obj))->fWrap;
|
||||
}
|
||||
else
|
||||
if ((obj->kind == PrototypeInstanceKind)
|
||||
&& ((checked_cast<PrototypeInstance *>(obj))->type == meta->functionClass)) {
|
||||
fWrap = (checked_cast<FunctionInstance *>(obj))->fWrap;
|
||||
if (fWrap) {
|
||||
// XXX - I made this stuff up - extract the 'prototype' property from
|
||||
// the function being invoked (defaulting to Object.prototype). Then
|
||||
// construct a new prototypeInstance, setting the acquired prototype
|
||||
// parent. Finally invoke the function, but insert the constructed
|
||||
// object at the bottom of the stack to be the 'return' value.
|
||||
// XXX this won't last - if a non-primitive is returned from the function,
|
||||
// it's supposed to supplant the constructed object. XXX and I think the
|
||||
// stack is out of balance anyway...
|
||||
js2val protoVal;
|
||||
JS2Object *protoObj = 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)
|
||||
if (meta->readProperty(&a, &mn, &lookup, RunPhase, &protoVal)) {
|
||||
if (!JS2VAL_IS_OBJECT(protoVal))
|
||||
meta->reportError(Exception::badValueError, "Non-object prototype value", errorPos());
|
||||
protoObj = JS2VAL_TO_OBJECT(protoVal);
|
||||
}
|
||||
if (fWrap) {
|
||||
// XXX - I made this stuff up - extract the 'prototype' property from
|
||||
// the function being invoked (defaulting to Object.prototype). Then
|
||||
// construct a new prototypeInstance, setting the acquired prototype
|
||||
// parent. Finally invoke the function, but insert the constructed
|
||||
// object at the bottom of the stack to be the 'return' value.
|
||||
// XXX this won't last - if a non-primitive is returned from the function,
|
||||
// it's supposed to supplant the constructed object. XXX and I think the
|
||||
// stack is out of balance anyway...
|
||||
js2val protoVal;
|
||||
JS2Object *protoObj = 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)
|
||||
if (meta->readProperty(&a, &mn, &lookup, RunPhase, &protoVal)) {
|
||||
if (!JS2VAL_IS_OBJECT(protoVal))
|
||||
meta->reportError(Exception::badValueError, "Non-object prototype value", errorPos());
|
||||
protoObj = JS2VAL_TO_OBJECT(protoVal);
|
||||
}
|
||||
|
||||
if (fWrap->code) { // native code, pass pointer to argument base
|
||||
a = fWrap->code(meta, a, base(argCount), argCount);
|
||||
pop(argCount + 1);
|
||||
push(a);
|
||||
}
|
||||
else {
|
||||
pFrame = new ParameterFrame(fWrap->compileFrame);
|
||||
pFrame->instantiate(meta->env);
|
||||
if (protoObj->kind == PrototypeInstanceKind)
|
||||
baseVal = OBJECT_TO_JS2VAL(new PrototypeInstance(meta, protoObj, (checked_cast<PrototypeInstance *>(protoObj))->type));
|
||||
else
|
||||
baseVal = OBJECT_TO_JS2VAL(new PrototypeInstance(meta, protoObj, meta->objectClass));
|
||||
pFrame->thisObject = baseVal;
|
||||
pFrame->assignArguments(meta, obj, base(argCount), argCount);
|
||||
jsr(phase, fWrap->bCon, base(argCount + 1) - execStack, baseVal, fWrap->env); // seems out of order, but we need to catch the current top frame
|
||||
meta->env->addFrame(pFrame);
|
||||
pFrame = NULL;
|
||||
}
|
||||
if (fWrap->code) { // native code, pass pointer to argument base
|
||||
a = fWrap->code(meta, a, base(argCount), argCount);
|
||||
pop(argCount + 1);
|
||||
push(a);
|
||||
}
|
||||
else
|
||||
meta->reportError(Exception::typeError, "object is not a constructor", errorPos());
|
||||
// }
|
||||
// else
|
||||
// meta->reportError(Exception::typeError, "object is not a constructor", errorPos());
|
||||
else {
|
||||
pFrame = new ParameterFrame(fWrap->compileFrame);
|
||||
pFrame->instantiate(meta->env);
|
||||
if (protoObj->kind == PrototypeInstanceKind)
|
||||
baseVal = OBJECT_TO_JS2VAL(new PrototypeInstance(meta, protoObj, (checked_cast<PrototypeInstance *>(protoObj))->type));
|
||||
else
|
||||
baseVal = OBJECT_TO_JS2VAL(new PrototypeInstance(meta, protoObj, meta->objectClass));
|
||||
pFrame->thisObject = baseVal;
|
||||
pFrame->assignArguments(meta, obj, base(argCount), argCount);
|
||||
jsr(phase, fWrap->bCon, base(argCount + 1) - execStack, baseVal, fWrap->env); // seems out of order, but we need to catch the current top frame
|
||||
meta->env->addFrame(pFrame);
|
||||
pFrame = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
meta->reportError(Exception::typeError, "object is not a constructor", errorPos());
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -152,7 +152,6 @@ namespace JavaScript {
|
||||
#ifdef EPIMETHEUS
|
||||
MetaData::Member *member; // the associated definition...
|
||||
MetaData::Multiname *mn; // ...and name constructed by the semantics phase
|
||||
MetaData::OverrideStatusPair *osp; // Read & Write status for PreEval stage
|
||||
#endif
|
||||
|
||||
VariableBinding(size_t pos, const StringAtom *name, ExprNode *type, ExprNode *initializer, bool constant):
|
||||
|
Loading…
Reference in New Issue
Block a user