зеркало из https://github.com/mozilla/pjs.git
Variable initialization support.
This commit is contained in:
Родитель
2f4d992991
Коммит
137a2c82d2
|
@ -129,17 +129,18 @@ namespace MetaData {
|
|||
attr = EvalAttributeExpression(env, CompilePhase, vs->attributes);
|
||||
}
|
||||
|
||||
VariableBinding *v = vs->bindings;
|
||||
VariableBinding *vb = vs->bindings;
|
||||
Frame *regionalFrame = env->getRegionalFrame();
|
||||
while (v) {
|
||||
const StringAtom *name = v->name;
|
||||
ValidateTypeExpression(v->type);
|
||||
while (vb) {
|
||||
const StringAtom *name = vb->name;
|
||||
ValidateTypeExpression(cxt, env, vb->type);
|
||||
vb->member = NULL;
|
||||
|
||||
if (cxt->strict && ((regionalFrame->kind == GlobalObjectKind)
|
||||
|| (regionalFrame->kind == FunctionKind))
|
||||
&& !immutable
|
||||
&& (vs->attributes == NULL)
|
||||
&& (v->type == NULL)) {
|
||||
&& (vb->type == NULL)) {
|
||||
defineHoistedVar(env, *name, p);
|
||||
}
|
||||
else {
|
||||
|
@ -153,18 +154,19 @@ namespace MetaData {
|
|||
switch (memberMod) {
|
||||
case Attribute::NoModifier:
|
||||
case Attribute::Static: {
|
||||
Variable *var = new Variable(NULL, JS2VAL_UNDEFINED, immutable);
|
||||
defineStaticMember(env, *name, a->namespaces, a->overrideMod, a->xplicit, ReadWriteAccess, var, p->pos);
|
||||
// XXX - not done !!! XXX
|
||||
// the type and the value are 'future'
|
||||
Variable *v = new Variable(FUTURE_TYPE, immutable ? JS2VAL_FUTUREVALUE : JS2VAL_INACCESSIBLE, immutable);
|
||||
vb->member = v;
|
||||
v->vb = vb;
|
||||
vb->mn = defineStaticMember(env, *name, a->namespaces, a->overrideMod, a->xplicit, ReadWriteAccess, v, p->pos);
|
||||
}
|
||||
break;
|
||||
case Attribute::Virtual:
|
||||
case Attribute::Final:
|
||||
{
|
||||
JS2Class *c = checked_cast<JS2Class *>(env->getTopFrame());
|
||||
InstanceMember *m = new InstanceVariable(immutable, (memberMod == Attribute::Final), c->slotCount++);
|
||||
defineInstanceMember(c, cxt, *name, a->namespaces, a->overrideMod, a->xplicit, ReadWriteAccess, m, p->pos);
|
||||
InstanceMember *m = new InstanceVariable(FUTURE_TYPE, immutable, (memberMod == Attribute::Final), c->slotCount++);
|
||||
vb->member = m;
|
||||
vb->osp = defineInstanceMember(c, cxt, *name, a->namespaces, a->overrideMod, a->xplicit, ReadWriteAccess, m, p->pos);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -173,7 +175,7 @@ namespace MetaData {
|
|||
}
|
||||
}
|
||||
|
||||
v = v->next;
|
||||
vb = vb->next;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -292,6 +294,30 @@ namespace MetaData {
|
|||
return retval;
|
||||
}
|
||||
|
||||
JS2Class *JS2Metadata::getVariableType(Variable *v, Phase phase, size_t pos)
|
||||
{
|
||||
JS2Class *type = v->type;
|
||||
if (type == NULL) { // Inaccessible, Note that this can only happen when phase = compile
|
||||
// because the compilation phase ensures that all types are valid,
|
||||
// so invalid types will not occur during the run phase.
|
||||
ASSERT(phase == CompilePhase);
|
||||
reportError(Exception::compileExpressionError, "No type assigned", pos);
|
||||
}
|
||||
else {
|
||||
if (v->type == FUTURE_TYPE) {
|
||||
// Note that phase = compile because all futures are resolved by the end of the compilation phase.
|
||||
ASSERT(phase == CompilePhase);
|
||||
if (v->vb->type) {
|
||||
v->type = NULL;
|
||||
v->type = EvalTypeExpression(&env, CompilePhase, v->vb->type);
|
||||
}
|
||||
else
|
||||
v->type = objectClass;
|
||||
}
|
||||
}
|
||||
return v->type;
|
||||
}
|
||||
|
||||
/*
|
||||
* Evaluate an individual statement 'p', including it's children
|
||||
* - this generates bytecode for each statement, but doesn't actually
|
||||
|
@ -348,12 +374,76 @@ namespace MetaData {
|
|||
case StmtNode::Var:
|
||||
case StmtNode::Const:
|
||||
{
|
||||
VariableStmtNode *vs = checked_cast<VariableStmtNode *>(p);
|
||||
|
||||
VariableBinding *v = vs->bindings;
|
||||
while (v) {
|
||||
// Note that the code here is the PreEval code plus the emit of the Eval bytecode
|
||||
VariableStmtNode *vs = checked_cast<VariableStmtNode *>(p);
|
||||
VariableBinding *vb = vs->bindings;
|
||||
while (vb) {
|
||||
if (vb->member) {
|
||||
if (vb->member->kind == Member::Variable) {
|
||||
Variable *v = checked_cast<Variable *>(vb->member);
|
||||
JS2Class *type = getVariableType(v, CompilePhase, p->pos);
|
||||
if (JS2VAL_IS_FUTURE(v->value)) {
|
||||
v->value = JS2VAL_INACCESSIBLE;
|
||||
try {
|
||||
if (vb->initializer) {
|
||||
js2val newValue = EvalExpression(env, CompilePhase, vb->initializer);
|
||||
v->value = engine->assignmentConversion(newValue, type);
|
||||
}
|
||||
else
|
||||
// Would only have come here if the variable was immutable
|
||||
reportError(Exception::compileExpressionError, "Missing compile time expression", p->pos);
|
||||
}
|
||||
catch (Exception x) {
|
||||
// If a compileExpressionError occurred, then the initialiser is not a compile-time
|
||||
// constant expression. In this case, ignore the error and leave the value of the
|
||||
// variable inaccessible until it is defined at run time.
|
||||
if (x.kind != Exception::compileExpressionError)
|
||||
throw x;
|
||||
}
|
||||
if (vb->initializer) {
|
||||
// XXX more here -
|
||||
//
|
||||
// eGET_TOP_FRAME <-- establish base
|
||||
// eDotRead <v->mn>
|
||||
// eIS_INACCESSIBLE
|
||||
// eBRANCH_FALSE <lbl>
|
||||
// eGET_TOP_FRAME
|
||||
// <vb->initializer code>
|
||||
// <convert to 'type'>
|
||||
// eDotWrite <v->mn>
|
||||
// <lbl>:
|
||||
}
|
||||
|
||||
v = v->next;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ASSERT(vb->member->kind == Member::InstanceVariableKind);
|
||||
InstanceVariable *v = checked_cast<InstanceVariable *>(vb->member);
|
||||
JS2Class *t;
|
||||
if (vb->type)
|
||||
t = EvalTypeExpression(env, CompilePhase, vb->type);
|
||||
else {
|
||||
if (vb->osp->first->overriddenMember && (vb->osp->first->overriddenMember != POTENTIAL_CONFLICT))
|
||||
t = vb->osp->first->overriddenMember->type;
|
||||
else
|
||||
if (vb->osp->second->overriddenMember && (vb->osp->second->overriddenMember != POTENTIAL_CONFLICT))
|
||||
t = vb->osp->second->overriddenMember->type;
|
||||
else
|
||||
t = objectClass;
|
||||
}
|
||||
v->type = t;
|
||||
}
|
||||
}
|
||||
else { // HoistedVariable
|
||||
if (vb->initializer) {
|
||||
Reference *r = EvalExprNode(env, phase, vb->initializer);
|
||||
if (r) r->emitReadBytecode(bCon, p->pos);
|
||||
LexicalReference *lVal = new LexicalReference(*vb->name, cxt.strict);
|
||||
lVal->variableMultiname->addNamespace(publicNamespace);
|
||||
lVal->emitWriteBytecode(bCon, p->pos);
|
||||
}
|
||||
}
|
||||
vb = vb->next;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -687,7 +777,7 @@ namespace MetaData {
|
|||
|
||||
|
||||
/*
|
||||
* Evaluate an expression 'p' and execute the assocaited bytecode
|
||||
* Evaluate an expression 'p' and execute the associated bytecode
|
||||
*/
|
||||
js2val JS2Metadata::EvalExpression(Environment *env, Phase phase, ExprNode *p)
|
||||
{
|
||||
|
@ -856,8 +946,15 @@ doBinary:
|
|||
return returnRef;
|
||||
}
|
||||
|
||||
void JS2Metadata::ValidateTypeExpression(ExprNode *e)
|
||||
JS2Class *JS2Metadata::EvalTypeExpression(Environment *env, Phase phase, ExprNode *p)
|
||||
{
|
||||
js2val retval = EvalExpression(env, phase, p);
|
||||
if (JS2VAL_IS_PRIMITIVE(retval))
|
||||
reportError(Exception::badValueError, "Type expected", p->pos);
|
||||
JS2Object *obj = JS2VAL_TO_OBJECT(retval);
|
||||
if (obj->kind != ClassKind)
|
||||
reportError(Exception::badValueError, "Type expected", p->pos);
|
||||
return checked_cast<JS2Class *>(obj);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
|
@ -1011,7 +1108,7 @@ doBinary:
|
|||
// - 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.
|
||||
//
|
||||
void 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;
|
||||
|
||||
|
@ -1077,7 +1174,7 @@ doBinary:
|
|||
fr = fr->nextFrame;
|
||||
}
|
||||
}
|
||||
|
||||
return mn;
|
||||
}
|
||||
|
||||
// Look through 'c' and all it's super classes for a identifier
|
||||
|
@ -1147,7 +1244,7 @@ doBinary:
|
|||
os->multiname.addNamespace(namespaces);
|
||||
}
|
||||
else {
|
||||
os->overriddenMember = PotentialConflict; // Didn't find the member with a specified namespace, but did with
|
||||
os->overriddenMember = POTENTIAL_CONFLICT; // Didn't find the member with a specified namespace, but did with
|
||||
// the use'd ones. That'll be an error unless the override is
|
||||
// disallowed (in defineInstanceMember below)
|
||||
os->multiname.addNamespace(namespaces);
|
||||
|
@ -1180,11 +1277,11 @@ doBinary:
|
|||
}
|
||||
// Make sure we're getting what we expected
|
||||
if (expectMethod) {
|
||||
if (os->overriddenMember && (os->overriddenMember != PotentialConflict) && (os->overriddenMember->kind != InstanceMember::InstanceMethodKind))
|
||||
if (os->overriddenMember && (os->overriddenMember != POTENTIAL_CONFLICT) && (os->overriddenMember->kind != InstanceMember::InstanceMethodKind))
|
||||
reportError(Exception::definitionError, "Illegal override, expected method", pos);
|
||||
}
|
||||
else {
|
||||
if (os->overriddenMember && (os->overriddenMember != PotentialConflict) && (os->overriddenMember->kind == InstanceMember::InstanceMethodKind))
|
||||
if (os->overriddenMember && (os->overriddenMember != POTENTIAL_CONFLICT) && (os->overriddenMember->kind == InstanceMember::InstanceMethodKind))
|
||||
reportError(Exception::definitionError, "Illegal override, didn't expect method", pos);
|
||||
}
|
||||
|
||||
|
@ -1193,7 +1290,7 @@ doBinary:
|
|||
|
||||
// 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 StringAtom &id, NamespaceList *namespaces, Attribute::OverrideModifier overrideMod, bool xplicit, Access access, InstanceMember *m, size_t pos)
|
||||
OverrideStatusPair *JS2Metadata::defineInstanceMember(JS2Class *c, Context *cxt, const StringAtom &id, NamespaceList *namespaces, Attribute::OverrideModifier overrideMod, bool xplicit, Access access, InstanceMember *m, size_t pos)
|
||||
{
|
||||
OverrideStatus *readStatus;
|
||||
OverrideStatus *writeStatus;
|
||||
|
@ -1210,13 +1307,13 @@ doBinary:
|
|||
else
|
||||
writeStatus = new OverrideStatus(NULL, id);
|
||||
|
||||
if ((readStatus->overriddenMember && (readStatus->overriddenMember != PotentialConflict))
|
||||
|| (writeStatus->overriddenMember && (writeStatus->overriddenMember != PotentialConflict))) {
|
||||
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 == PotentialConflict) || (writeStatus->overriddenMember == PotentialConflict)) {
|
||||
if ((readStatus->overriddenMember == POTENTIAL_CONFLICT) || (writeStatus->overriddenMember == POTENTIAL_CONFLICT)) {
|
||||
if ((overrideMod != Attribute::DontOverride) && (overrideMod != Attribute::OverrideUndefined))
|
||||
reportError(Exception::definitionError, "Illegal override", pos);
|
||||
}
|
||||
|
@ -1237,8 +1334,7 @@ doBinary:
|
|||
c->instanceWriteBindings.insert(e);
|
||||
}
|
||||
|
||||
OverrideStatusPair osp(readStatus, writeStatus);
|
||||
return osp;
|
||||
return new OverrideStatusPair(readStatus, writeStatus);;
|
||||
}
|
||||
|
||||
// Define a hoisted var in the current frame (either Global or a Function)
|
||||
|
@ -1579,7 +1675,7 @@ readClassProperty:
|
|||
return &checked_cast<FixedInstance *>(thisObj)->slots[id->slotIndex];
|
||||
}
|
||||
|
||||
|
||||
// Read the value of an instanceMember, if valid
|
||||
bool JS2Metadata::readInstanceMember(js2val containerVal, JS2Class *c, QualifiedName *qname, Phase phase, js2val *rval)
|
||||
{
|
||||
InstanceMember *m = findInstanceMember(c, qname, ReadAccess);
|
||||
|
|
|
@ -216,25 +216,36 @@ class Signature {
|
|||
bool returnType; // The type of this function's result
|
||||
};
|
||||
|
||||
// A static member is either forbidden, a variable, a hoisted variable, a constructor method, or an accessor:
|
||||
class StaticMember {
|
||||
// A base class for Instance and Static members for convenience.
|
||||
class Member {
|
||||
public:
|
||||
enum StaticMemberKind { Forbidden, Variable, HoistedVariable, ConstructorMethod, Accessor };
|
||||
enum MemberKind { Forbidden, Variable, HoistedVariable, ConstructorMethod, Accessor, InstanceVariableKind, InstanceMethodKind, InstanceAccessorKind };
|
||||
|
||||
Member(MemberKind kind) : kind(kind) { }
|
||||
|
||||
StaticMember(StaticMemberKind kind) : kind(kind) { }
|
||||
MemberKind kind;
|
||||
|
||||
StaticMemberKind kind;
|
||||
#ifdef DEBUG
|
||||
virtual void uselessVirtual() { } // want the checked_cast stuff to work, so need a virtual function
|
||||
#endif
|
||||
};
|
||||
|
||||
// A static member is either forbidden, a variable, a hoisted variable, a constructor method, or an accessor:
|
||||
class StaticMember : public Member {
|
||||
public:
|
||||
StaticMember(MemberKind kind) : Member(kind) { }
|
||||
|
||||
};
|
||||
|
||||
#define FUTURE_TYPE ((JS2Class *)(-1))
|
||||
|
||||
class Variable : public StaticMember {
|
||||
public:
|
||||
Variable() : StaticMember(StaticMember::Variable), type(NULL), value(JS2VAL_VOID), immutable(false) { }
|
||||
Variable() : StaticMember(Member::Variable), type(NULL), value(JS2VAL_VOID), immutable(false) { }
|
||||
Variable(JS2Class *type, js2val value, bool immutable) : StaticMember(StaticMember::Variable), type(type), value(value), immutable(immutable) { }
|
||||
|
||||
JS2Class *type; // Type of values that may be stored in this variable
|
||||
JS2Class *type; // Type of values that may be stored in this variable, NULL if INACCESSIBLE, FUTURE_TYPE if pending
|
||||
VariableBinding *vb; // The variable definition node, to resolve future types
|
||||
js2val value; // This variable's current value; future if the variable has not been declared yet;
|
||||
// uninitialised if the variable must be written before it can be read
|
||||
bool immutable; // true if this variable's value may not be changed once set
|
||||
|
@ -242,21 +253,21 @@ public:
|
|||
|
||||
class HoistedVar : public StaticMember {
|
||||
public:
|
||||
HoistedVar() : StaticMember(StaticMember::HoistedVariable), value(JS2VAL_VOID), hasFunctionInitializer(false) { }
|
||||
HoistedVar() : StaticMember(Member::HoistedVariable), value(JS2VAL_VOID), hasFunctionInitializer(false) { }
|
||||
js2val value; // This variable's current value
|
||||
bool hasFunctionInitializer; // true if this variable was created by a function statement
|
||||
};
|
||||
|
||||
class ConstructorMethod : public StaticMember {
|
||||
public:
|
||||
ConstructorMethod() : StaticMember(StaticMember::ConstructorMethod), code(NULL) { }
|
||||
ConstructorMethod() : StaticMember(Member::ConstructorMethod), code(NULL) { }
|
||||
|
||||
Invokable *code; // This function itself (a callable object)
|
||||
};
|
||||
|
||||
class Accessor : public StaticMember {
|
||||
public:
|
||||
Accessor() : StaticMember(StaticMember::Accessor), type(NULL), code(NULL) { }
|
||||
Accessor() : StaticMember(Member::Accessor), type(NULL), code(NULL) { }
|
||||
|
||||
JS2Class *type; // The type of the value read from the getter or written into the setter
|
||||
Invokable *code; // calling this object does the read or write
|
||||
|
@ -292,14 +303,12 @@ public:
|
|||
StaticMember *content; // The member to which this qualified name was bound
|
||||
};
|
||||
|
||||
class InstanceMember {
|
||||
class InstanceMember : public Member {
|
||||
public:
|
||||
enum InstanceMemberKind { InstanceVariableKind, InstanceMethodKind, InstanceAccessorKind };
|
||||
InstanceMember(MemberKind kind, JS2Class *type, bool final) : Member(kind), type(type), final(final) { }
|
||||
|
||||
InstanceMember(InstanceMemberKind kind, bool final) : kind(kind), final(final) { }
|
||||
|
||||
InstanceMemberKind kind;
|
||||
bool final; // true if this member may not be overridden in subclasses
|
||||
JS2Class *type; // Type of values that may be stored in this variable
|
||||
bool final; // true if this member may not be overridden in subclasses
|
||||
|
||||
#ifdef DEBUG
|
||||
virtual void uselessVirtual() { } // want the checked_cast stuff to work, so need a virtual function
|
||||
|
@ -308,8 +317,7 @@ public:
|
|||
|
||||
class InstanceVariable : public InstanceMember {
|
||||
public:
|
||||
InstanceVariable(bool immutable, bool final, uint32 slotIndex) : InstanceMember(InstanceVariableKind, final), immutable(immutable), slotIndex(slotIndex) { }
|
||||
JS2Class *type; // Type of values that may be stored in this variable
|
||||
InstanceVariable(JS2Class *type, bool immutable, bool final, uint32 slotIndex) : InstanceMember(InstanceVariableKind, type, final), immutable(immutable), slotIndex(slotIndex) { }
|
||||
Invokable *evalInitialValue; // A function that computes this variable's initial value
|
||||
bool immutable; // true if this variable's value may not be changed once set
|
||||
uint32 slotIndex; // The index into an instance's slot array in which this variable is stored
|
||||
|
@ -317,15 +325,14 @@ public:
|
|||
|
||||
class InstanceMethod : public InstanceMember {
|
||||
public:
|
||||
InstanceMethod() : InstanceMember(InstanceMethodKind, false) { }
|
||||
InstanceMethod() : InstanceMember(InstanceMethodKind, NULL, false) { }
|
||||
Signature type; // This method's signature
|
||||
Invokable *code; // This method itself (a callable object); null if this method is abstract
|
||||
};
|
||||
|
||||
class InstanceAccessor : public InstanceMember {
|
||||
public:
|
||||
InstanceAccessor(Invokable *code, bool final) : InstanceMember(InstanceAccessorKind, final), code(code) { }
|
||||
JS2Class *type; // The type of the value read from the getter or written into the setter
|
||||
InstanceAccessor(Invokable *code, JS2Class *type, bool final) : InstanceMember(InstanceAccessorKind, type, final), code(code) { }
|
||||
Invokable *code; // A callable object which does the read or write; null if this method is abstract
|
||||
};
|
||||
|
||||
|
@ -338,7 +345,7 @@ public:
|
|||
};
|
||||
|
||||
// Override status is used to resolve overriden definitions for instance members
|
||||
#define PotentialConflict ((InstanceMember *)(-1))
|
||||
#define POTENTIAL_CONFLICT ((InstanceMember *)(-1))
|
||||
class OverrideStatus {
|
||||
public:
|
||||
OverrideStatus(InstanceMember *overriddenMember, const StringAtom &name)
|
||||
|
@ -667,13 +674,14 @@ public:
|
|||
|
||||
|
||||
void ValidateStmtList(Context *cxt, Environment *env, StmtNode *p);
|
||||
void ValidateTypeExpression(ExprNode *e);
|
||||
void ValidateTypeExpression(Context *cxt, Environment *env, ExprNode *e) { ValidateExpression(cxt, env, e); }
|
||||
void ValidateStmt(Context *cxt, Environment *env, StmtNode *p);
|
||||
void ValidateExpression(Context *cxt, Environment *env, ExprNode *p);
|
||||
void ValidateAttributeExpression(Context *cxt, Environment *env, ExprNode *p);
|
||||
|
||||
js2val ExecuteStmtList(Phase phase, StmtNode *p);
|
||||
js2val EvalExpression(Environment *env, Phase phase, ExprNode *p);
|
||||
JS2Class *EvalTypeExpression(Environment *env, Phase phase, ExprNode *p);
|
||||
Reference *EvalExprNode(Environment *env, Phase phase, ExprNode *p);
|
||||
Attribute *EvalAttributeExpression(Environment *env, Phase phase, ExprNode *p);
|
||||
void EvalStmt(Environment *env, Phase phase, StmtNode *p);
|
||||
|
@ -685,13 +693,14 @@ public:
|
|||
InstanceBinding *resolveInstanceMemberName(JS2Class *js2class, Multiname *multiname, Access access, Phase phase);
|
||||
|
||||
void defineHoistedVar(Environment *env, const StringAtom &id, StmtNode *p);
|
||||
void defineStaticMember(Environment *env, const StringAtom &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);
|
||||
Multiname *defineStaticMember(Environment *env, const StringAtom &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);
|
||||
InstanceMember *findInstanceMember(JS2Class *c, QualifiedName *qname, Access access);
|
||||
Slot *findSlot(js2val thisObjVal, InstanceVariable *id);
|
||||
bool findStaticMember(JS2Class *c, Multiname *multiname, Access access, Phase phase, MemberDescriptor *result);
|
||||
JS2Class *getVariableType(Variable *v, Phase phase, size_t pos);
|
||||
|
||||
|
||||
bool readProperty(js2val container, Multiname *multiname, LookupKind *lookupKind, Phase phase, js2val *rval);
|
||||
|
|
|
@ -51,6 +51,16 @@
|
|||
#define JS2VAL_IS_INITIALIZED(v) (v != JS2VAL_UNINITIALIZED)
|
||||
#define JS2VAL_IS_UNINITIALIZED(v) (v == JS2VAL_UNINITIALIZED)
|
||||
|
||||
#define JS2VAL_INACCESSIBLE 0x90 /* reserve this object reference value as an indication
|
||||
that a variable has yet to become available */
|
||||
#define JS2VAL_IS_ACCESSIBLE(v) (v != JS2VAL_INACCESSIBLE)
|
||||
#define JS2VAL_IS_INACCESSIBLE(v) (v == JS2VAL_INACCESSIBLE)
|
||||
|
||||
#define JS2VAL_FUTUREVALUE 0xA0 /* reserve this object reference value as an indication
|
||||
that a variable has to have it's initializer run */
|
||||
#define JS2VAL_IS_FUTURE(v) (v == JS2VAL_FUTUREVALUE)
|
||||
|
||||
|
||||
/* Type tag bitfield length and derived macros. */
|
||||
#define JS2VAL_TAGBITS 3
|
||||
#define JS2VAL_TAGMASK JS2_BITMASK(JS2VAL_TAGBITS)
|
||||
|
|
|
@ -60,6 +60,10 @@ namespace JavaScript {
|
|||
namespace MetaData {
|
||||
class Context;
|
||||
class JS2Class;
|
||||
class Member;
|
||||
class Multiname;
|
||||
class OverrideStatus;
|
||||
typedef std::pair<OverrideStatus *, OverrideStatus *> OverrideStatusPair;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -141,6 +145,11 @@ namespace JavaScript {
|
|||
JS2Runtime::Property *prop; // the sematics/codegen passes stuff their data in here.
|
||||
JS2Runtime::JSObject *scope; // ditto
|
||||
#endif
|
||||
#ifdef EPIMETHEUS
|
||||
MetaData::Member *member;
|
||||
MetaData::Multiname *mn;
|
||||
MetaData::OverrideStatusPair *osp;
|
||||
#endif
|
||||
|
||||
VariableBinding(size_t pos, const StringAtom *name, ExprNode *type, ExprNode *initializer, bool constant):
|
||||
ParseNode(pos), next(0), name(name), type(type), initializer(initializer), constant(constant) {}
|
||||
|
|
Загрузка…
Ссылка в новой задаче