зеркало из https://github.com/mozilla/pjs.git
Changed qualifier evaluation to compile time. Added error handling via
pc map.
This commit is contained in:
Родитель
1fb85916f0
Коммит
0aeef9b5cd
|
@ -64,11 +64,17 @@ namespace MetaData {
|
|||
|
||||
BytecodeContainer::~BytecodeContainer()
|
||||
{
|
||||
delete mBuffer;
|
||||
for (std::vector<Multiname *>::iterator i = mMultinameList.begin(), end = mMultinameList.end(); (i != end); i++)
|
||||
delete *i;
|
||||
}
|
||||
|
||||
size_t BytecodeContainer::getPosition(uint16 pc)
|
||||
{
|
||||
for (std::vector<MapEntry>::iterator i = pcMap.begin(), end = pcMap.end(); (i != end); i++)
|
||||
if (i->first >= pc)
|
||||
return i->second;
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,45 +52,50 @@ class Multiname;
|
|||
|
||||
class BytecodeContainer {
|
||||
public:
|
||||
BytecodeContainer() : mBuffer(new CodeBuffer), mStackTop(0), mStackMax(0) { }
|
||||
BytecodeContainer() : mStackTop(0), mStackMax(0) { }
|
||||
BytecodeContainer::~BytecodeContainer() ;
|
||||
|
||||
|
||||
uint8 *getCodeStart() { return mBuffer->begin(); }
|
||||
uint8 *getCodeStart() { return mBuffer.begin(); }
|
||||
|
||||
typedef std::pair<uint16, size_t> MapEntry;
|
||||
std::vector<MapEntry> pcMap;
|
||||
|
||||
void emitOp(JS2Op op) { adjustStack(op); addByte((uint8)op); }
|
||||
void emitOp(JS2Op op, int32 effect) { adjustStack(op, effect); addByte((uint8)op); }
|
||||
size_t getPosition(uint16 pc);
|
||||
|
||||
void emitOp(JS2Op op, size_t pos) { adjustStack(op); addByte((uint8)op); pcMap.push_back(MapEntry(mBuffer.size(), pos)); }
|
||||
void emitOp(JS2Op op, size_t pos, int32 effect)
|
||||
{ adjustStack(op, effect); addByte((uint8)op); pcMap.push_back(std::pair<uint16, size_t>(mBuffer.size(), pos)); }
|
||||
|
||||
void adjustStack(JS2Op op) { adjustStack(op, JS2Engine::getStackEffect(op)); }
|
||||
void adjustStack(JS2Op op, int32 effect){ mStackTop += effect; if (mStackTop > mStackMax) mStackMax = mStackTop; ASSERT(mStackTop >= 0); }
|
||||
|
||||
void addByte(uint8 v) { mBuffer->push_back(v); }
|
||||
void addByte(uint8 v) { mBuffer.push_back(v); }
|
||||
|
||||
void addPointer(const void *v) { ASSERT(sizeof(void *) == sizeof(uint32)); addLong((uint32)(v)); }
|
||||
static void *getPointer(void *pc) { return (void *)getLong(pc); }
|
||||
|
||||
void addFloat64(float64 v) { mBuffer->insert(mBuffer->end(), (uint8 *)&v, (uint8 *)(&v) + sizeof(float64)); }
|
||||
void addFloat64(float64 v) { mBuffer.insert(mBuffer.end(), (uint8 *)&v, (uint8 *)(&v) + sizeof(float64)); }
|
||||
static float64 getFloat64(void *pc) { return *((float64 *)pc); }
|
||||
|
||||
void addLong(const uint32 v) { mBuffer->insert(mBuffer->end(), (uint8 *)&v, (uint8 *)(&v) + sizeof(uint32)); }
|
||||
void addLong(const uint32 v) { mBuffer.insert(mBuffer.end(), (uint8 *)&v, (uint8 *)(&v) + sizeof(uint32)); }
|
||||
static uint32 getLong(void *pc) { return *((uint32 *)pc); }
|
||||
|
||||
void addShort(uint16 v) { mBuffer->insert(mBuffer->end(), (uint8 *)&v, (uint8 *)(&v) + sizeof(uint16)); }
|
||||
void addShort(uint16 v) { mBuffer.insert(mBuffer.end(), (uint8 *)&v, (uint8 *)(&v) + sizeof(uint16)); }
|
||||
static uint16 getShort(void *pc) { return *((uint16 *)pc); }
|
||||
|
||||
void addMultiname(Multiname *mn) { mMultinameList.push_back(mn); addShort(mMultinameList.size() - 1); }
|
||||
static Multiname *getMultiname(void *pc){ return (Multiname *)getLong(pc); }
|
||||
|
||||
void addString(const StringAtom &x) { emitOp(eString); addPointer(&x); }
|
||||
void addString(String &x) { emitOp(eString); addPointer(&x); }
|
||||
void addString(String *x) { emitOp(eString); addPointer(x); }
|
||||
void addString(const StringAtom &x, size_t pos) { emitOp(eString, pos); addPointer(&x); }
|
||||
void addString(String &x, size_t pos) { emitOp(eString, pos); addPointer(&x); }
|
||||
void addString(String *x, size_t pos) { emitOp(eString, pos); addPointer(x); }
|
||||
static String *getString(void *pc) { return (String *)getPointer(pc); }
|
||||
// XXX We lose StringAtom here - is there anyway of stashing these in a bytecodecontainer?
|
||||
|
||||
typedef std::vector<uint8> CodeBuffer;
|
||||
|
||||
CodeBuffer *mBuffer;
|
||||
CodeBuffer mBuffer;
|
||||
std::vector<Multiname *> mMultinameList; // gc tracking
|
||||
|
||||
int32 mStackTop; // keep these as signed so as to
|
||||
|
|
|
@ -240,7 +240,6 @@ int JS2Engine::getStackEffect(JS2Op op)
|
|||
return 0;
|
||||
|
||||
case eMultiname:
|
||||
case eQMultiname:
|
||||
return 1; // push the multiname object
|
||||
|
||||
case eUse:
|
||||
|
@ -252,5 +251,10 @@ int JS2Engine::getStackEffect(JS2Op op)
|
|||
return 0;
|
||||
}
|
||||
|
||||
size_t JS2Engine::errorPos()
|
||||
{
|
||||
return bCon->getPosition(pc - bCon->getCodeStart());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -61,7 +61,6 @@ enum JS2Op {
|
|||
eReturnVoid,
|
||||
eNewObject, // <argCount:16>
|
||||
eMultiname, // <multiname index>
|
||||
eQMultiname, // <multiname index>
|
||||
eUse,
|
||||
};
|
||||
|
||||
|
@ -81,6 +80,8 @@ public:
|
|||
void *gc_alloc_8();
|
||||
float64 *newDoubleValue(float64 x);
|
||||
|
||||
size_t errorPos();
|
||||
|
||||
void pushNumber(float64 x);
|
||||
|
||||
#define MAX_EXEC_STACK (20)
|
||||
|
|
|
@ -191,11 +191,13 @@ namespace MetaData {
|
|||
{
|
||||
BytecodeContainer *saveBacon = bCon;
|
||||
bCon = new BytecodeContainer();
|
||||
size_t lastPos = p->pos;
|
||||
while (p) {
|
||||
EvalStmt(&env, phase, p);
|
||||
lastPos = p->pos;
|
||||
p = p->next;
|
||||
}
|
||||
bCon->emitOp(eReturnVoid);
|
||||
bCon->emitOp(eReturnVoid, lastPos);
|
||||
js2val retval = engine->interpret(this, phase, bCon);
|
||||
bCon = saveBacon;
|
||||
return retval;
|
||||
|
@ -242,7 +244,7 @@ namespace MetaData {
|
|||
{
|
||||
ExprStmtNode *e = checked_cast<ExprStmtNode *>(p);
|
||||
Reference *r = EvalExprNode(env, phase, e->expr);
|
||||
if (r) r->emitReadBytecode(bCon);
|
||||
if (r) r->emitReadBytecode(bCon, p->pos);
|
||||
}
|
||||
break;
|
||||
case StmtNode::Namespace:
|
||||
|
@ -255,8 +257,8 @@ namespace MetaData {
|
|||
ExprList *eList = u->namespaces;
|
||||
while (eList) {
|
||||
Reference *r = EvalExprNode(env, phase, eList->expr);
|
||||
if (r) r->emitReadBytecode(bCon);
|
||||
bCon->emitOp(eUse);
|
||||
if (r) r->emitReadBytecode(bCon, p->pos);
|
||||
bCon->emitOp(eUse, p->pos);
|
||||
eList = eList->next;
|
||||
}
|
||||
}
|
||||
|
@ -549,8 +551,8 @@ namespace MetaData {
|
|||
BytecodeContainer *saveBacon = bCon;
|
||||
bCon = new BytecodeContainer();
|
||||
Reference *r = EvalExprNode(env, phase, p);
|
||||
if (r) r->emitReadBytecode(bCon);
|
||||
bCon->emitOp(eReturn);
|
||||
if (r) r->emitReadBytecode(bCon, p->pos);
|
||||
bCon->emitOp(eReturn, p->pos);
|
||||
js2val retval = engine->interpret(this, phase, bCon);
|
||||
bCon = saveBacon;
|
||||
return retval;
|
||||
|
@ -572,8 +574,8 @@ namespace MetaData {
|
|||
Reference *lVal = EvalExprNode(env, phase, b->op1);
|
||||
if (lVal) {
|
||||
Reference *rVal = EvalExprNode(env, phase, b->op2);
|
||||
if (rVal) rVal->emitReadBytecode(bCon);
|
||||
lVal->emitWriteBytecode(bCon);
|
||||
if (rVal) rVal->emitReadBytecode(bCon, p->pos);
|
||||
lVal->emitWriteBytecode(bCon, p->pos);
|
||||
}
|
||||
else
|
||||
reportError(Exception::semanticError, "Assignment needs an lValue", p->pos);
|
||||
|
@ -584,9 +586,9 @@ namespace MetaData {
|
|||
BinaryExprNode *b = checked_cast<BinaryExprNode *>(p);
|
||||
Reference *lVal = EvalExprNode(env, phase, b->op1);
|
||||
Reference *rVal = EvalExprNode(env, phase, b->op2);
|
||||
if (lVal) lVal->emitReadBytecode(bCon);
|
||||
if (rVal) rVal->emitReadBytecode(bCon);
|
||||
bCon->emitOp(ePlus);
|
||||
if (lVal) lVal->emitReadBytecode(bCon, p->pos);
|
||||
if (rVal) rVal->emitReadBytecode(bCon, p->pos);
|
||||
bCon->emitOp(ePlus, p->pos);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -601,7 +603,7 @@ namespace MetaData {
|
|||
|
||||
case ExprNode::number:
|
||||
{
|
||||
bCon->emitOp(eNumber);
|
||||
bCon->emitOp(eNumber, p->pos);
|
||||
bCon->addFloat64(checked_cast<NumberExprNode *>(p)->value);
|
||||
}
|
||||
break;
|
||||
|
@ -609,24 +611,31 @@ namespace MetaData {
|
|||
{
|
||||
QualifyExprNode *qe = checked_cast<QualifyExprNode *>(p);
|
||||
const StringAtom &name = checked_cast<IdentifierExprNode *>(p)->name;
|
||||
Reference *rVal = EvalExprNode(env, phase, qe->qualifier);
|
||||
if (rVal) rVal->emitReadBytecode(bCon);
|
||||
returnRef = new LexicalReference(name, cxt.strict, true);
|
||||
((LexicalReference *)returnRef)->emitBindBytecode(bCon);
|
||||
|
||||
js2val av = EvalExpression(env, CompilePhase, qe->qualifier);
|
||||
if (JS2VAL_IS_NULL(av) || !JS2VAL_IS_OBJECT(av))
|
||||
reportError(Exception::badValueError, "Namespace expected in qualifier", p->pos);
|
||||
JS2Object *obj = JS2VAL_TO_OBJECT(av);
|
||||
if ((obj->kind != AttributeObjectKind) || (checked_cast<Attribute *>(obj)->attrKind != Attribute::NamespaceAttr))
|
||||
reportError(Exception::badValueError, "Namespace expected in qualifier", p->pos);
|
||||
Namespace *ns = checked_cast<Namespace *>(obj);
|
||||
|
||||
returnRef = new LexicalReference(name, ns, cxt.strict);
|
||||
((LexicalReference *)returnRef)->emitBindBytecode(bCon, p->pos);
|
||||
}
|
||||
break;
|
||||
case ExprNode::identifier:
|
||||
{
|
||||
IdentifierExprNode *i = checked_cast<IdentifierExprNode *>(p);
|
||||
returnRef = new LexicalReference(i->name, cxt.strict);
|
||||
((LexicalReference *)returnRef)->emitBindBytecode(bCon);
|
||||
((LexicalReference *)returnRef)->emitBindBytecode(bCon, p->pos);
|
||||
}
|
||||
break;
|
||||
case ExprNode::boolean:
|
||||
if (checked_cast<BooleanExprNode *>(p)->value)
|
||||
bCon->emitOp(eTrue);
|
||||
bCon->emitOp(eTrue, p->pos);
|
||||
else
|
||||
bCon->emitOp(eFalse);
|
||||
bCon->emitOp(eFalse, p->pos);
|
||||
break;
|
||||
case ExprNode::objectLiteral:
|
||||
{
|
||||
|
@ -636,16 +645,16 @@ namespace MetaData {
|
|||
while (e) {
|
||||
ASSERT(e->field && e->value);
|
||||
Reference *rVal = EvalExprNode(env, phase, e->value);
|
||||
if (rVal) rVal->emitReadBytecode(bCon);
|
||||
if (rVal) rVal->emitReadBytecode(bCon, p->pos);
|
||||
switch (e->field->getKind()) {
|
||||
case ExprNode::identifier:
|
||||
bCon->addString(checked_cast<IdentifierExprNode *>(e->field)->name);
|
||||
bCon->addString(checked_cast<IdentifierExprNode *>(e->field)->name, p->pos);
|
||||
break;
|
||||
case ExprNode::string:
|
||||
bCon->addString(checked_cast<StringExprNode *>(e->field)->str);
|
||||
bCon->addString(checked_cast<StringExprNode *>(e->field)->str, p->pos);
|
||||
break;
|
||||
case ExprNode::number:
|
||||
bCon->addString(numberToString(&(checked_cast<NumberExprNode *>(e->field))->value));
|
||||
bCon->addString(numberToString(&(checked_cast<NumberExprNode *>(e->field))->value), p->pos);
|
||||
break;
|
||||
default:
|
||||
NOT_REACHED("bad field name");
|
||||
|
@ -742,14 +751,12 @@ namespace MetaData {
|
|||
Frame *pf = firstFrame;
|
||||
while (pf) {
|
||||
js2val rval;
|
||||
// have to wrap the frame in a Monkey object in order
|
||||
// to have readProperty handle it...
|
||||
if (meta->readProperty(pf, multiname, &lookup, phase, &rval))
|
||||
return rval;
|
||||
|
||||
pf = pf->nextFrame;
|
||||
}
|
||||
meta->reportError(Exception::referenceError, "{0} is undefined", meta->errorPos, multiname->name);
|
||||
meta->reportError(Exception::referenceError, "{0} is undefined", meta->engine->errorPos(), multiname->name);
|
||||
return JS2VAL_VOID;
|
||||
}
|
||||
|
||||
|
@ -758,8 +765,6 @@ namespace MetaData {
|
|||
LookupKind lookup(true, findThis(false));
|
||||
Frame *pf = firstFrame;
|
||||
while (pf) {
|
||||
// have to wrap the frame in a Monkey object in order
|
||||
// to have readProperty handle it...
|
||||
if (meta->writeProperty(pf, multiname, &lookup, false, newValue, phase))
|
||||
return;
|
||||
pf = pf->nextFrame;
|
||||
|
@ -771,7 +776,7 @@ namespace MetaData {
|
|||
return;
|
||||
}
|
||||
}
|
||||
meta->reportError(Exception::referenceError, "{0} is undefined", meta->errorPos, multiname->name);
|
||||
meta->reportError(Exception::referenceError, "{0} is undefined", meta->engine->errorPos(), multiname->name);
|
||||
}
|
||||
|
||||
|
||||
|
@ -842,10 +847,9 @@ namespace MetaData {
|
|||
publicNamespaceList.push_back(publicNamespace);
|
||||
namespaces = &publicNamespaceList;
|
||||
}
|
||||
Multiname *mn = new Multiname(id, true);
|
||||
Multiname *mn = new Multiname(id);
|
||||
mn->addNamespace(namespaces);
|
||||
|
||||
|
||||
for (StaticBindingIterator b = localFrame->staticReadBindings.lower_bound(id),
|
||||
end = localFrame->staticReadBindings.upper_bound(id); (b != end); b++) {
|
||||
if (mn->matches(b->second->qname))
|
||||
|
@ -1003,7 +1007,8 @@ namespace MetaData {
|
|||
if (!multiname->onList(publicNamespace))
|
||||
return false;
|
||||
const StringAtom &name = multiname->name;
|
||||
if (phase == CompilePhase) reportError(Exception::compileExpressionError, "Inappropriate compile time expression", errorPos);
|
||||
if (phase == CompilePhase)
|
||||
reportError(Exception::compileExpressionError, "Inappropriate compile time expression", engine->errorPos());
|
||||
DynamicPropertyMap *dMap = NULL;
|
||||
bool isPrototypeInstance = false;
|
||||
if (container->kind == DynamicInstanceKind)
|
||||
|
@ -1093,7 +1098,7 @@ namespace MetaData {
|
|||
return false; // 'None'
|
||||
switch (m->kind) {
|
||||
case StaticMember::Forbidden:
|
||||
reportError(Exception::propertyAccessError, "Forbidden access", errorPos);
|
||||
reportError(Exception::propertyAccessError, "Forbidden access", engine->errorPos());
|
||||
break;
|
||||
case StaticMember::Variable:
|
||||
*rval = (checked_cast<Variable *>(m))->value;
|
||||
|
@ -1117,7 +1122,7 @@ namespace MetaData {
|
|||
switch (m->kind) {
|
||||
case StaticMember::Forbidden:
|
||||
case StaticMember::ConstructorMethod:
|
||||
reportError(Exception::propertyAccessError, "Forbidden access", errorPos);
|
||||
reportError(Exception::propertyAccessError, "Forbidden access", engine->errorPos());
|
||||
break;
|
||||
case StaticMember::Variable:
|
||||
(checked_cast<Variable *>(m))->value = newValue;
|
||||
|
@ -1187,7 +1192,7 @@ namespace MetaData {
|
|||
}
|
||||
if (multiname->matches(b->second->qname)) {
|
||||
if (found && (b->second->content != found))
|
||||
reportError(Exception::propertyAccessError, "Ambiguous reference to {0}", errorPos, multiname->name);
|
||||
reportError(Exception::propertyAccessError, "Ambiguous reference to {0}", engine->errorPos(), multiname->name);
|
||||
else
|
||||
found = b->second->content;
|
||||
}
|
||||
|
@ -1229,7 +1234,7 @@ namespace MetaData {
|
|||
}
|
||||
if (multiname->matches(b->second->qname)) {
|
||||
if (result && (b->second->content != result->content))
|
||||
reportError(Exception::propertyAccessError, "Ambiguous reference to {0}", errorPos, multiname->name);
|
||||
reportError(Exception::propertyAccessError, "Ambiguous reference to {0}", engine->errorPos(), multiname->name);
|
||||
else
|
||||
result = b->second;
|
||||
}
|
||||
|
|
|
@ -145,9 +145,7 @@ public:
|
|||
|
||||
virtual CompoundAttribute *toCompoundAttribute() { ASSERT(false); return NULL; }
|
||||
|
||||
|
||||
AttributeKind attrKind;
|
||||
|
||||
};
|
||||
|
||||
// A Namespace (is also an attribute)
|
||||
|
@ -179,12 +177,10 @@ typedef std::vector<Namespace *> NamespaceList;
|
|||
typedef NamespaceList::iterator NamespaceListIterator;
|
||||
class Multiname : public JS2Object {
|
||||
public:
|
||||
Multiname(const StringAtom &name) : JS2Object(MultinameKind), name(name) { }
|
||||
Multiname(const StringAtom &name, Namespace *ns) : JS2Object(MultinameKind), name(name) { addNamespace(ns); }
|
||||
|
||||
Multiname(const StringAtom &name) : JS2Object(MultinameKind), name(name), qualified(false) { }
|
||||
Multiname(const StringAtom &name, bool qualified) : JS2Object(MultinameKind), name(name), qualified(qualified) { }
|
||||
|
||||
|
||||
void emitBytecode(BytecodeContainer *bCon) { bCon->emitOp(qualified ? eQMultiname : eMultiname); bCon->addMultiname(this); }
|
||||
void emitBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eMultiname, pos); bCon->addMultiname(this); }
|
||||
|
||||
void addNamespace(Namespace *ns) { nsList.push_back(ns); }
|
||||
void addNamespace(NamespaceList *ns);
|
||||
|
@ -195,7 +191,6 @@ public:
|
|||
|
||||
NamespaceList nsList;
|
||||
const StringAtom &name;
|
||||
bool qualified; // true for q::a, otherwise false
|
||||
|
||||
};
|
||||
|
||||
|
@ -446,10 +441,10 @@ public:
|
|||
// References are generated during the eval stage (bytecode generation)
|
||||
class Reference {
|
||||
public:
|
||||
virtual void emitReadBytecode(BytecodeContainer *bCon) { ASSERT(false); }
|
||||
virtual void emitWriteBytecode(BytecodeContainer *bCon) { ASSERT(false); }
|
||||
virtual void emitDeleteBytecode(BytecodeContainer *bCon) { ASSERT(false); };
|
||||
virtual void emitReadForInvokeBytecode(BytecodeContainer *bCon) { ASSERT(false); }
|
||||
virtual void emitReadBytecode(BytecodeContainer *bCon, size_t pos) { ASSERT(false); }
|
||||
virtual void emitWriteBytecode(BytecodeContainer *bCon, size_t pos) { ASSERT(false); }
|
||||
virtual void emitDeleteBytecode(BytecodeContainer *bCon, size_t pos) { ASSERT(false); };
|
||||
virtual void emitReadForInvokeBytecode(BytecodeContainer *bCon, size_t pos) { ASSERT(false); }
|
||||
};
|
||||
|
||||
class LexicalReference : public Reference {
|
||||
|
@ -458,7 +453,7 @@ class LexicalReference : public Reference {
|
|||
// q::a.
|
||||
public:
|
||||
LexicalReference(const StringAtom &name, bool strict) : variableMultiname(new Multiname(name)), env(NULL), strict(strict) { }
|
||||
LexicalReference(const StringAtom &name, bool strict, bool qualified) : variableMultiname(new Multiname(name, qualified)), env(NULL), strict(strict) { }
|
||||
LexicalReference(const StringAtom &name, Namespace *nameSpace, bool strict) : variableMultiname(new Multiname(name, nameSpace)), env(NULL), strict(strict) { }
|
||||
|
||||
|
||||
Multiname *variableMultiname; // A nonempty set of qualified names to which this reference can refer
|
||||
|
@ -466,9 +461,9 @@ public:
|
|||
bool strict; // The strict setting from the context in effect at the point where the reference was created
|
||||
|
||||
|
||||
void emitBindBytecode(BytecodeContainer *bCon) { variableMultiname->emitBytecode(bCon); }
|
||||
virtual void emitReadBytecode(BytecodeContainer *bCon) { bCon->emitOp(eLexicalRead); }
|
||||
virtual void emitWriteBytecode(BytecodeContainer *bCon) { bCon->emitOp(eLexicalWrite); }
|
||||
void emitBindBytecode(BytecodeContainer *bCon, size_t pos) { variableMultiname->emitBytecode(bCon, pos); }
|
||||
virtual void emitReadBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eLexicalRead, pos); }
|
||||
virtual void emitWriteBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eLexicalWrite, pos); }
|
||||
};
|
||||
|
||||
class DotReference : public Reference {
|
||||
|
@ -687,7 +682,6 @@ public:
|
|||
JS2Class *namespaceClass;
|
||||
|
||||
Parser *mParser; // used for error reporting
|
||||
size_t errorPos;
|
||||
|
||||
BytecodeContainer *bCon; // the current output container
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
push(OBJECT_TO_JS2VAL(mn));
|
||||
}
|
||||
break;
|
||||
|
||||
#if 0
|
||||
// Get a multiname literal and pop a namespace value to add to it
|
||||
// Push the resulting multiname object
|
||||
case eQMultiname: {
|
||||
|
@ -56,7 +56,7 @@
|
|||
push(OBJECT_TO_JS2VAL(mn));
|
||||
}
|
||||
break;
|
||||
|
||||
#endif
|
||||
// Pop a multiname object and read it's value from the environment on to the stack.
|
||||
case eLexicalRead: {
|
||||
js2val mnVal = pop();
|
||||
|
@ -85,10 +85,10 @@
|
|||
case eUse: {
|
||||
js2val nsVal = pop();
|
||||
if (!JS2VAL_IS_OBJECT(nsVal))
|
||||
meta->reportError(Exception::badValueError, "Expected a namespace", meta->errorPos);
|
||||
meta->reportError(Exception::badValueError, "Expected a namespace", meta->engine->errorPos());
|
||||
JS2Object *obj = JS2VAL_TO_OBJECT(nsVal);
|
||||
if ((obj->kind != AttributeObjectKind) || ((checked_cast<Attribute *>(obj))->attrKind != Attribute::NamespaceAttr))
|
||||
meta->reportError(Exception::badValueError, "Expected a namespace", meta->errorPos);
|
||||
meta->reportError(Exception::badValueError, "Expected a namespace", meta->engine->errorPos());
|
||||
|
||||
}
|
||||
break;
|
Загрузка…
Ссылка в новой задаче