mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-13 21:35:39 +00:00
New function definition structures in place.
This commit is contained in:
parent
b7d1664a5d
commit
9843f65e3b
@ -85,20 +85,9 @@ namespace MetaData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JS2Metadata::validateStatic(FunctionDefinition *fnDef, CompoundAttribute *a, bool unchecked, bool hoisted)
|
FunctionInstance *JS2Metadata::validateStaticFunction(Context *cxt, Environment *env, FunctionDefinition *fnDef, bool prototype, bool unchecked, size_t pos)
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void JS2Metadata::validateConstructor(FunctionDefinition *fnDef, JS2Class *c, CompoundAttribute *a)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void JS2Metadata::validateInstance(FunctionDefinition *fnDef, JS2Class *c, CompoundAttribute *a, bool final)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
FunctionInstance *JS2Metadata::validateStaticFunction(FunctionDefinition *fnDef, js2val compileThis, bool prototype, bool unchecked, Context *cxt, Environment *env)
|
|
||||||
{
|
{
|
||||||
|
js2val compileThis = JS2VAL_VOID;
|
||||||
ParameterFrame *compileFrame = new ParameterFrame(compileThis, prototype);
|
ParameterFrame *compileFrame = new ParameterFrame(compileThis, prototype);
|
||||||
DEFINE_ROOTKEEPER(rk1, compileFrame);
|
DEFINE_ROOTKEEPER(rk1, compileFrame);
|
||||||
|
|
||||||
@ -141,6 +130,68 @@ namespace MetaData {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void JS2Metadata::validateStatic(Context *cxt, Environment *env, FunctionDefinition *fnDef, CompoundAttribute *a, bool unchecked, bool hoisted, size_t pos)
|
||||||
|
{
|
||||||
|
Variable *v;
|
||||||
|
FunctionInstance *fnInst = NULL;
|
||||||
|
DEFINE_ROOTKEEPER(rk1, fnInst);
|
||||||
|
switch (fnDef->prefix) {
|
||||||
|
case FunctionName::normal:
|
||||||
|
fnInst = validateStaticFunction(cxt, env, fnDef, a->prototype, unchecked, pos);
|
||||||
|
if (hoisted)
|
||||||
|
defineHoistedVar(env, fnDef->name, OBJECT_TO_JS2VAL(fnInst), false, pos);
|
||||||
|
else {
|
||||||
|
v = new Variable(functionClass, OBJECT_TO_JS2VAL(fnInst), true);
|
||||||
|
defineLocalMember(env, fnDef->name, &a->namespaces, a->overrideMod, a->xplicit, ReadWriteAccess, v, pos, true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FunctionName::Get:
|
||||||
|
case FunctionName::Set:
|
||||||
|
if (a->prototype)
|
||||||
|
reportError(Exception::attributeError, "A getter or setter cannot have the prototype attribute", pos);
|
||||||
|
ASSERT(!(unchecked || hoisted));
|
||||||
|
// XXX shouldn't be using validateStaticFunction
|
||||||
|
fnInst = validateStaticFunction(cxt, env, fnDef, false, false, pos);
|
||||||
|
v = new Variable(functionClass, OBJECT_TO_JS2VAL(fnInst), true);
|
||||||
|
defineLocalMember(env, fnDef->name, &a->namespaces, a->overrideMod, a->xplicit, ReadWriteAccess, v, pos, true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void JS2Metadata::validateConstructor(Context *cxt, Environment *env, FunctionDefinition *fnDef, JS2Class *c, CompoundAttribute *a, size_t pos)
|
||||||
|
{
|
||||||
|
if (a->prototype)
|
||||||
|
reportError(Exception::attributeError, "A class constructor cannot have the prototype attribute", pos);
|
||||||
|
if (fnDef->prefix != FunctionName::normal)
|
||||||
|
reportError(Exception::syntaxError, "A class constructor cannot be a getter or a setter", pos);
|
||||||
|
// XXX shouldn't be using validateStaticFunction
|
||||||
|
c->init = validateStaticFunction(cxt, env, fnDef, false, false, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void JS2Metadata::validateInstance(Context *cxt, Environment *env, FunctionDefinition *fnDef, JS2Class *c, CompoundAttribute *a, bool final, size_t pos)
|
||||||
|
{
|
||||||
|
if (a->prototype)
|
||||||
|
reportError(Exception::attributeError, "An instance method cannot have the prototype attribute", pos);
|
||||||
|
// XXX shouldn't be using validateStaticFunction
|
||||||
|
FunctionInstance *fnInst = NULL;
|
||||||
|
DEFINE_ROOTKEEPER(rk1, fnInst);
|
||||||
|
fnInst = validateStaticFunction(cxt, env, fnDef, false, false, pos);
|
||||||
|
Multiname *mn = new Multiname(fnDef->name, a->namespaces);
|
||||||
|
InstanceMember *m;
|
||||||
|
switch (fnDef->prefix) {
|
||||||
|
case FunctionName::normal:
|
||||||
|
m = new InstanceMethod(mn, fnInst, final, true);
|
||||||
|
break;
|
||||||
|
case FunctionName::Set:
|
||||||
|
m = new InstanceSetter(mn, fnInst, objectClass, final, true);
|
||||||
|
break;
|
||||||
|
case FunctionName::Get:
|
||||||
|
m = new InstanceGetter(mn, fnInst, objectClass, final, true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
defineInstanceMember(c, cxt, fnDef->name, a->namespaces, a->overrideMod, a->xplicit, m, pos);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Validate an individual statement 'p', including it's children
|
* Validate an individual statement 'p', including it's children
|
||||||
*/
|
*/
|
||||||
@ -434,19 +485,19 @@ namespace MetaData {
|
|||||||
if (topFrame->kind == ClassKind) {
|
if (topFrame->kind == ClassKind) {
|
||||||
switch (a->memberMod) {
|
switch (a->memberMod) {
|
||||||
case Attribute::Static:
|
case Attribute::Static:
|
||||||
validateStatic(&f->function, a, false, false);
|
validateStatic(cxt, env, &f->function, a, false, false, p->pos);
|
||||||
break;
|
break;
|
||||||
case Attribute::NoModifier:
|
case Attribute::NoModifier:
|
||||||
if (*f->function.name == *(checked_cast<JS2Class *>(topFrame))->name)
|
if (*f->function.name == *(checked_cast<JS2Class *>(topFrame))->name)
|
||||||
validateConstructor(&f->function, checked_cast<JS2Class *>(topFrame), a);
|
validateConstructor(cxt, env, &f->function, checked_cast<JS2Class *>(topFrame), a, p->pos);
|
||||||
else
|
else
|
||||||
validateInstance(&f->function, checked_cast<JS2Class *>(topFrame), a, false);
|
validateInstance(cxt, env, &f->function, checked_cast<JS2Class *>(topFrame), a, false, p->pos);
|
||||||
break;
|
break;
|
||||||
case Attribute::Virtual:
|
case Attribute::Virtual:
|
||||||
validateInstance(&f->function, checked_cast<JS2Class *>(topFrame), a, false);
|
validateInstance(cxt, env, &f->function, checked_cast<JS2Class *>(topFrame), a, false, p->pos);
|
||||||
break;
|
break;
|
||||||
case Attribute::Final:
|
case Attribute::Final:
|
||||||
validateInstance(&f->function, checked_cast<JS2Class *>(topFrame), a, true);
|
validateInstance(cxt, env, &f->function, checked_cast<JS2Class *>(topFrame), a, true, p->pos);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -471,7 +522,7 @@ namespace MetaData {
|
|||||||
&& ((topFrame->kind == PackageKind)
|
&& ((topFrame->kind == PackageKind)
|
||||||
|| (topFrame->kind == BlockFrameKind)
|
|| (topFrame->kind == BlockFrameKind)
|
||||||
|| (topFrame->kind == ParameterFrameKind));
|
|| (topFrame->kind == ParameterFrameKind));
|
||||||
validateStatic(&f->function, a, unchecked, hoisted);
|
validateStatic(cxt, env, &f->function, a, unchecked, hoisted, p->pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -570,7 +621,7 @@ namespace MetaData {
|
|||||||
&& !immutable
|
&& !immutable
|
||||||
&& (vs->attributes == NULL)
|
&& (vs->attributes == NULL)
|
||||||
&& (vb->type == NULL)) {
|
&& (vb->type == NULL)) {
|
||||||
defineHoistedVar(env, name, p, true, JS2VAL_UNDEFINED);
|
defineHoistedVar(env, name, JS2VAL_UNDEFINED, true, p->pos);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
a = Attribute::toCompoundAttribute(attr);
|
a = Attribute::toCompoundAttribute(attr);
|
||||||
@ -1913,7 +1964,7 @@ namespace MetaData {
|
|||||||
case ExprNode::functionLiteral:
|
case ExprNode::functionLiteral:
|
||||||
{
|
{
|
||||||
FunctionExprNode *f = checked_cast<FunctionExprNode *>(p);
|
FunctionExprNode *f = checked_cast<FunctionExprNode *>(p);
|
||||||
f->obj = validateStaticFunction(&f->function, JS2VAL_INACCESSIBLE, true, true, cxt, env);
|
f->obj = validateStaticFunction(cxt, env, &f->function, true, true, p->pos);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -3330,7 +3381,7 @@ doUnary:
|
|||||||
// will shadow a parameter with the same name for compatibility with ECMAScript Edition 3.
|
// will shadow a parameter with the same name for compatibility with ECMAScript Edition 3.
|
||||||
// If there are multiple function definitions, the initial value is the last function definition.
|
// If there are multiple function definitions, the initial value is the last function definition.
|
||||||
|
|
||||||
LocalMember *JS2Metadata::defineHoistedVar(Environment *env, const String *id, StmtNode *p, bool isVar, js2val initVal)
|
LocalMember *JS2Metadata::defineHoistedVar(Environment *env, const String *id, js2val initVal, bool isVar, size_t pos)
|
||||||
{
|
{
|
||||||
LocalMember *result = NULL;
|
LocalMember *result = NULL;
|
||||||
FrameListIterator regionalFrameEnd = env->getRegionalEnvironment();
|
FrameListIterator regionalFrameEnd = env->getRegionalEnvironment();
|
||||||
@ -3377,12 +3428,12 @@ rescan:
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (foundMultiple)
|
if (foundMultiple)
|
||||||
reportError(Exception::definitionError, "Duplicate definition {0}", p->pos, id);
|
reportError(Exception::definitionError, "Duplicate definition {0}", pos, id);
|
||||||
else {
|
else {
|
||||||
if ((bindingResult->accesses != ReadWriteAccess)
|
if ((bindingResult->accesses != ReadWriteAccess)
|
||||||
|| ((bindingResult->content->memberKind != LocalMember::DynamicVariableMember)
|
|| ((bindingResult->content->memberKind != LocalMember::DynamicVariableMember)
|
||||||
&& (bindingResult->content->memberKind != LocalMember::FrameVariableMember)))
|
&& (bindingResult->content->memberKind != LocalMember::FrameVariableMember)))
|
||||||
reportError(Exception::definitionError, "Illegal redefinition of {0}", p->pos, id);
|
reportError(Exception::definitionError, "Illegal redefinition of {0}", pos, id);
|
||||||
else {
|
else {
|
||||||
result = bindingResult->content;
|
result = bindingResult->content;
|
||||||
writeLocalMember(result, initVal, true);
|
writeLocalMember(result, initVal, true);
|
||||||
@ -4453,7 +4504,8 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
|
|||||||
: NonWithFrame(ClassKind),
|
: NonWithFrame(ClassKind),
|
||||||
super(super),
|
super(super),
|
||||||
instanceInitOrder(NULL),
|
instanceInitOrder(NULL),
|
||||||
complete(false),
|
complete(false),
|
||||||
|
name(name),
|
||||||
prototype(proto),
|
prototype(proto),
|
||||||
typeofString(name),
|
typeofString(name),
|
||||||
privateNamespace(privateNamespace),
|
privateNamespace(privateNamespace),
|
||||||
@ -4462,6 +4514,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
|
|||||||
defaultValue(JS2VAL_NULL),
|
defaultValue(JS2VAL_NULL),
|
||||||
call(NULL),
|
call(NULL),
|
||||||
construct(JS2Engine::defaultConstructor),
|
construct(JS2Engine::defaultConstructor),
|
||||||
|
init(NULL),
|
||||||
read(defaultReadProperty),
|
read(defaultReadProperty),
|
||||||
readPublic(defaultReadPublicProperty),
|
readPublic(defaultReadPublicProperty),
|
||||||
write(defaultWriteProperty),
|
write(defaultWriteProperty),
|
||||||
|
@ -750,6 +750,8 @@ public:
|
|||||||
Callor *call; // A procedure to call when this class is used in a call expression
|
Callor *call; // A procedure to call when this class is used in a call expression
|
||||||
Constructor *construct; // A procedure to call when this class is used in a new expression
|
Constructor *construct; // A procedure to call when this class is used in a new expression
|
||||||
|
|
||||||
|
FunctionInstance *init;
|
||||||
|
|
||||||
void emitDefaultValue(BytecodeContainer *bCon, size_t pos);
|
void emitDefaultValue(BytecodeContainer *bCon, size_t pos);
|
||||||
|
|
||||||
|
|
||||||
@ -1342,11 +1344,11 @@ public:
|
|||||||
void ValidateStmt(Context *cxt, Environment *env, Plurality pl, StmtNode *p);
|
void ValidateStmt(Context *cxt, Environment *env, Plurality pl, StmtNode *p);
|
||||||
void ValidateExpression(Context *cxt, Environment *env, ExprNode *p);
|
void ValidateExpression(Context *cxt, Environment *env, ExprNode *p);
|
||||||
void ValidateAttributeExpression(Context *cxt, Environment *env, ExprNode *p);
|
void ValidateAttributeExpression(Context *cxt, Environment *env, ExprNode *p);
|
||||||
FunctionInstance *validateStaticFunction(FunctionDefinition *fnDef, js2val compileThis, bool prototype, bool unchecked, Context *cxt, Environment *env);
|
FunctionInstance *validateStaticFunction(Context *cxt, Environment *env, FunctionDefinition *fnDef, bool prototype, bool unchecked, size_t pos);
|
||||||
|
|
||||||
void validateStatic(FunctionDefinition *fnDef, CompoundAttribute *a, bool unchecked, bool hoisted);
|
void validateStatic(Context *cxt, Environment *env, FunctionDefinition *fnDef, CompoundAttribute *a, bool unchecked, bool hoisted, size_t pos);
|
||||||
void validateConstructor(FunctionDefinition *fnDef, JS2Class *c, CompoundAttribute *a);
|
void validateConstructor(Context *cxt, Environment *env, FunctionDefinition *fnDef, JS2Class *c, CompoundAttribute *a, size_t pos);
|
||||||
void validateInstance(FunctionDefinition *fnDef, JS2Class *c, CompoundAttribute *a, bool final);
|
void validateInstance(Context *cxt, Environment *env, FunctionDefinition *fnDef, JS2Class *c, CompoundAttribute *a, bool final, size_t pos);
|
||||||
|
|
||||||
js2val ExecuteStmtList(Phase phase, StmtNode *p);
|
js2val ExecuteStmtList(Phase phase, StmtNode *p);
|
||||||
js2val EvalExpression(Environment *env, Phase phase, ExprNode *p);
|
js2val EvalExpression(Environment *env, Phase phase, ExprNode *p);
|
||||||
@ -1364,7 +1366,7 @@ public:
|
|||||||
InstanceBinding *resolveInstanceMemberName(JS2Class *js2class, Multiname *multiname, Access access, Phase phase, QualifiedName *qname);
|
InstanceBinding *resolveInstanceMemberName(JS2Class *js2class, Multiname *multiname, Access access, Phase phase, QualifiedName *qname);
|
||||||
|
|
||||||
FrameVariable *makeFrameVariable(NonWithFrame *regionalFrame);
|
FrameVariable *makeFrameVariable(NonWithFrame *regionalFrame);
|
||||||
LocalMember *defineHoistedVar(Environment *env, const String *id, StmtNode *p, bool isVar, js2val initVal);
|
LocalMember *defineHoistedVar(Environment *env, const String *id, js2val initVal, bool isVar, size_t pos);
|
||||||
Multiname *defineLocalMember(Environment *env, const String *id, NamespaceList *namespaces, Attribute::OverrideModifier overrideMod, bool xplicit, Access access, LocalMember *m, size_t pos, bool enumerable);
|
Multiname *defineLocalMember(Environment *env, const String *id, NamespaceList *namespaces, Attribute::OverrideModifier overrideMod, bool xplicit, Access access, LocalMember *m, size_t pos, bool enumerable);
|
||||||
InstanceMember *defineInstanceMember(JS2Class *c, Context *cxt, const String *id, NamespaceList &namespaces,
|
InstanceMember *defineInstanceMember(JS2Class *c, Context *cxt, const String *id, NamespaceList &namespaces,
|
||||||
Attribute::OverrideModifier overrideMod, bool xplicit,
|
Attribute::OverrideModifier overrideMod, bool xplicit,
|
||||||
|
Loading…
Reference in New Issue
Block a user