зеркало из https://github.com/mozilla/pjs.git
Fixing closure related bugs.
This commit is contained in:
Родитель
01ea097d3c
Коммит
b322e2770d
|
@ -188,9 +188,9 @@ public:
|
|||
String mSource; // for error reporting
|
||||
String mSourceLocation; // for error reporting
|
||||
|
||||
#ifdef DEBUG
|
||||
//#ifdef DEBUG
|
||||
String fName; // relevant function name for trace output
|
||||
#endif
|
||||
//#endif
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -223,7 +223,7 @@ js2val print(JS2Metadata * /* meta */, const js2val /* thisValue */, js2val argv
|
|||
return JS2VAL_UNDEFINED;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
//#ifdef DEBUG
|
||||
js2val trees(JS2Metadata *meta, const js2val /* thisValue */, js2val /* argv */ [], uint32 /* argc */)
|
||||
{
|
||||
meta->showTrees = !meta->showTrees;
|
||||
|
@ -436,7 +436,7 @@ js2val forceGC(JS2Metadata *meta, const js2val /* thisValue */, js2val /* argv *
|
|||
return JS2VAL_VOID;
|
||||
}
|
||||
|
||||
#endif
|
||||
//#endif
|
||||
|
||||
js2val load(JS2Metadata *meta, const js2val /* thisValue */, js2val argv[], uint32 argc)
|
||||
{
|
||||
|
@ -483,13 +483,13 @@ int main(int argc, char **argv)
|
|||
|
||||
metadata->addGlobalObjectFunction("print", print, 1);
|
||||
metadata->addGlobalObjectFunction("load", load, 1);
|
||||
#ifdef DEBUG
|
||||
//#ifdef DEBUG
|
||||
metadata->addGlobalObjectFunction("dump", dump, 1);
|
||||
metadata->addGlobalObjectFunction("dumpAt", dumpAt, 1);
|
||||
metadata->addGlobalObjectFunction("trees", trees, 0);
|
||||
metadata->addGlobalObjectFunction("trace", trace, 0);
|
||||
metadata->addGlobalObjectFunction("gc", forceGC, 0);
|
||||
#endif
|
||||
//#endif
|
||||
|
||||
try {
|
||||
bool doInteractive = true;
|
||||
|
|
|
@ -107,10 +107,10 @@ namespace MetaData {
|
|||
try {
|
||||
a = JS2VAL_VOID;
|
||||
b = JS2VAL_VOID;
|
||||
#ifdef DEBUG
|
||||
//#ifdef DEBUG
|
||||
if (traceInstructions)
|
||||
printInstruction(pc, bCon->getCodeStart(), bCon, this);
|
||||
#endif
|
||||
//#endif
|
||||
JS2Op op = (JS2Op)*pc++;
|
||||
switch (op) {
|
||||
#include "js2op_arithmetic.cpp"
|
||||
|
@ -493,7 +493,7 @@ namespace MetaData {
|
|||
delete [] activationStack;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
//#ifdef DEBUG
|
||||
|
||||
enum { BRANCH_OFFSET = 1, STR_PTR, TYPE_PTR, NAME_INDEX, FRAME_INDEX, BRANCH_PAIR, U16, FLOAT64, S32, BREAK_OFFSET_AND_COUNT };
|
||||
struct {
|
||||
|
@ -535,6 +535,7 @@ namespace MetaData {
|
|||
{ eInteger, "Integer", S32 },
|
||||
{ eRegExp, "RegExp", U16 },
|
||||
{ eFunction, "Function", U16 },
|
||||
{ eClosure, "Closure", U16 },
|
||||
{ eUInt64, "UInt64", 0 },
|
||||
{ eInt64, "Int64", 0 },
|
||||
{ eString, "String", STR_PTR }, // <string pointer:u32>
|
||||
|
@ -619,6 +620,7 @@ namespace MetaData {
|
|||
{ eTypeof, "Typeof", 0 },
|
||||
{ eInstanceof, "Instanceof", 0 },
|
||||
{ eIs, "Is", 0 },
|
||||
{ eIn, "In", 0 },
|
||||
|
||||
{ ePopv, "Popv", 0 },
|
||||
{ ePop, "Pop", 0 },
|
||||
|
@ -749,7 +751,7 @@ namespace MetaData {
|
|||
}
|
||||
}
|
||||
|
||||
#endif // DEBUG
|
||||
//#endif // DEBUG
|
||||
|
||||
// Return the effect of an opcode on the execution stack.
|
||||
// Some ops (e.g. eCall) have a variable effect, those are handled separately
|
||||
|
@ -791,6 +793,7 @@ namespace MetaData {
|
|||
|
||||
case eIs: // pop expr, pop type, push boolean
|
||||
case eInstanceof:
|
||||
case eIn:
|
||||
return 1;
|
||||
|
||||
case eCoerce: // pop value, push coerced value (type is arg)
|
||||
|
@ -821,6 +824,9 @@ namespace MetaData {
|
|||
case eLongZero:
|
||||
return 1; // push literal value
|
||||
|
||||
case eClosure:
|
||||
return 0;
|
||||
|
||||
case eSuperExpr:
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -78,7 +78,8 @@ enum JS2Op {
|
|||
eNumber,
|
||||
eInteger,
|
||||
eRegExp,
|
||||
eFunction,
|
||||
eFunction, // <object index:u16>
|
||||
eClosure, // <object index:u16>
|
||||
eUInt64,
|
||||
eInt64,
|
||||
eString, // <string pointer:u32>
|
||||
|
@ -163,6 +164,7 @@ enum JS2Op {
|
|||
eTypeof,
|
||||
eInstanceof,
|
||||
eIs,
|
||||
eIn,
|
||||
|
||||
ePopv,
|
||||
ePop,
|
||||
|
@ -370,9 +372,9 @@ public:
|
|||
|
||||
};
|
||||
|
||||
#ifdef DEBUG
|
||||
//#ifdef DEBUG
|
||||
uint8 *printInstruction(uint8 *pc, uint8 *start, BytecodeContainer *bCon, JS2Engine *engine);
|
||||
#endif
|
||||
//#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -652,14 +652,15 @@ namespace MetaData {
|
|||
return false;
|
||||
}
|
||||
switch (m->memberKind) {
|
||||
case Member::FrameVariableMember:
|
||||
return meta->readLocalMember(checked_cast<LocalMember *>(m), phase, rval, checked_cast<Frame *>(JS2VAL_TO_OBJECT(*base)));
|
||||
case Member::ForbiddenMember:
|
||||
case Member::DynamicVariableMember:
|
||||
case Member::FrameVariableMember:
|
||||
case Member::VariableMember:
|
||||
case Member::ConstructorMethodMember:
|
||||
case Member::SetterMember:
|
||||
case Member::GetterMember:
|
||||
return meta->readLocalMember(checked_cast<LocalMember *>(m), phase, rval);
|
||||
return meta->readLocalMember(checked_cast<LocalMember *>(m), phase, rval, NULL);
|
||||
case Member::InstanceVariableMember:
|
||||
case Member::InstanceMethodMember:
|
||||
case Member::InstanceGetterMember:
|
||||
|
|
|
@ -76,16 +76,18 @@ namespace MetaData {
|
|||
FunctionExprNode *fnExpr = parser.parseFunctionExpression(meta->engine->errorPos());
|
||||
ASSERT(parser.lexer.peek(true).hasKind(Token::end));
|
||||
ASSERT(fnExpr); // otherwise, an exception would have been thrown out of here
|
||||
fnExpr->obj = NULL;
|
||||
DEFINE_ROOTKEEPER(rk, fnExpr->obj);
|
||||
fnExpr->function.fn = NULL;
|
||||
DEFINE_ROOTKEEPER(rk, fnExpr->function.fn);
|
||||
meta->ValidateExpression(&meta->cxt, meta->env, fnExpr);
|
||||
Arena *oldArena = meta->referenceArena;
|
||||
meta->referenceArena = new Arena;
|
||||
try {
|
||||
CompilationData *oldData = meta->startCompilationUnit(fnExpr->function.fWrap->bCon, *bodyStr, srcLoc);
|
||||
meta->env->addFrame(fnExpr->function.fWrap->compileFrame);
|
||||
FunctionInstance *fnInst = fnExpr->function.fn;
|
||||
ASSERT(fnInst);
|
||||
CompilationData *oldData = meta->startCompilationUnit(fnInst->fWrap->bCon, *bodyStr, srcLoc);
|
||||
meta->env->addFrame(fnInst->fWrap->compileFrame);
|
||||
meta->SetupStmt(meta->env, RunPhase, fnExpr->function.body);
|
||||
fnExpr->function.fWrap->bCon->emitOp(eReturnVoid, meta->engine->errorPos());
|
||||
fnInst->fWrap->bCon->emitOp(eReturnVoid, meta->engine->errorPos());
|
||||
meta->env->removeTopFrame();
|
||||
meta->restoreCompilationUnit(oldData);
|
||||
}
|
||||
|
@ -97,7 +99,7 @@ namespace MetaData {
|
|||
meta->referenceArena->clear();
|
||||
meta->referenceArena = oldArena;
|
||||
ASSERT(fnExpr);
|
||||
return OBJECT_TO_JS2VAL(fnExpr->obj);
|
||||
return OBJECT_TO_JS2VAL(fnExpr->function.fn);
|
||||
}
|
||||
else { // construct an empty function wrapper
|
||||
js2val thatValue = OBJECT_TO_JS2VAL(new FunctionInstance(meta, meta->functionClass->prototype, meta->functionClass));
|
||||
|
|
|
@ -94,10 +94,10 @@ namespace MetaData {
|
|||
FunctionInstance *result = new FunctionInstance(this, functionClass->prototype, functionClass);
|
||||
DEFINE_ROOTKEEPER(rk2, result);
|
||||
result->fWrap = new FunctionWrapper(unchecked, compileFrame, env);
|
||||
fnDef->fWrap = result->fWrap;
|
||||
fnDef->fn = result;
|
||||
|
||||
Frame *curTopFrame = env->getTopFrame();
|
||||
CompilationData *oldData = startCompilationUnit(fnDef->fWrap->bCon, bCon->mSource, bCon->mSourceLocation);
|
||||
CompilationData *oldData = startCompilationUnit(result->fWrap->bCon, bCon->mSource, bCon->mSourceLocation);
|
||||
try {
|
||||
env->addFrame(compileFrame);
|
||||
VariableBinding *pb = fnDef->parameters;
|
||||
|
@ -713,7 +713,14 @@ namespace MetaData {
|
|||
{
|
||||
UnaryStmtNode *w = checked_cast<UnaryStmtNode *>(p);
|
||||
ValidateExpression(cxt, env, w->expr);
|
||||
ValidateStmt(cxt, env, pl, w->stmt);
|
||||
if (w->stmt->getKind() != StmtNode::block) {
|
||||
w->compileFrame = new BlockFrame();
|
||||
env->addFrame(w->compileFrame);
|
||||
ValidateStmt(cxt, env, pl, w->stmt);
|
||||
env->removeTopFrame();
|
||||
}
|
||||
else
|
||||
ValidateStmt(cxt, env, pl, w->stmt);
|
||||
}
|
||||
break;
|
||||
case StmtNode::empty:
|
||||
|
@ -1294,18 +1301,21 @@ namespace MetaData {
|
|||
if (r) r->emitReadBytecode(bCon, p->pos);
|
||||
bCon->emitOp(eReturn, p->pos);
|
||||
}
|
||||
else
|
||||
bCon->emitOp(eReturnVoid, p->pos);
|
||||
}
|
||||
break;
|
||||
case StmtNode::Function:
|
||||
{
|
||||
FunctionStmtNode *f = checked_cast<FunctionStmtNode *>(p);
|
||||
CompilationData *oldData = NULL;
|
||||
FunctionInstance *fnInst = f->function.fn;
|
||||
try {
|
||||
oldData = startCompilationUnit(f->function.fWrap->bCon, bCon->mSource, bCon->mSourceLocation);
|
||||
env->addFrame(f->function.fWrap->compileFrame);
|
||||
#ifdef DEBUG
|
||||
oldData = startCompilationUnit(fnInst->fWrap->bCon, bCon->mSource, bCon->mSourceLocation);
|
||||
env->addFrame(fnInst->fWrap->compileFrame);
|
||||
//#ifdef DEBUG
|
||||
bCon->fName = *f->function.name;
|
||||
#endif
|
||||
//#endif
|
||||
VariableBinding *pb = f->function.parameters;
|
||||
while (pb) {
|
||||
FrameVariable *v = checked_cast<FrameVariable *>(pb->member);
|
||||
|
@ -1316,9 +1326,9 @@ namespace MetaData {
|
|||
pb = pb->next;
|
||||
}
|
||||
if (f->function.resultType)
|
||||
f->function.fWrap->resultType = EvalTypeExpression(env, CompilePhase, f->function.resultType);
|
||||
fnInst->fWrap->resultType = EvalTypeExpression(env, CompilePhase, f->function.resultType);
|
||||
else
|
||||
f->function.fWrap->resultType = objectClass;
|
||||
fnInst->fWrap->resultType = objectClass;
|
||||
|
||||
SetupStmt(env, phase, f->function.body);
|
||||
// XXX need to make sure that all paths lead to an exit of some kind
|
||||
|
@ -1331,6 +1341,8 @@ namespace MetaData {
|
|||
restoreCompilationUnit(oldData);
|
||||
throw x;
|
||||
}
|
||||
bCon->emitOp(eClosure, p->pos);
|
||||
bCon->addObject(fnInst);
|
||||
}
|
||||
break;
|
||||
case StmtNode::Var:
|
||||
|
@ -1483,7 +1495,16 @@ namespace MetaData {
|
|||
Reference *r = SetupExprNode(env, phase, w->expr, &exprType);
|
||||
if (r) r->emitReadBytecode(bCon, p->pos);
|
||||
bCon->emitOp(eWithin, p->pos);
|
||||
SetupStmt(env, phase, w->stmt);
|
||||
if (w->stmt->getKind() != StmtNode::block) {
|
||||
env->addFrame(w->compileFrame);
|
||||
bCon->emitOp(ePushFrame, p->pos);
|
||||
bCon->addFrame(w->compileFrame);
|
||||
SetupStmt(env, phase, w->stmt);
|
||||
bCon->emitOp(ePopFrame, p->pos);
|
||||
env->removeTopFrame();
|
||||
}
|
||||
else
|
||||
SetupStmt(env, phase, w->stmt);
|
||||
bCon->emitOp(eWithout, p->pos);
|
||||
}
|
||||
break;
|
||||
|
@ -1872,6 +1893,7 @@ namespace MetaData {
|
|||
case ExprNode::Instanceof:
|
||||
case ExprNode::identical:
|
||||
case ExprNode::notIdentical:
|
||||
case ExprNode::In:
|
||||
|
||||
{
|
||||
BinaryExprNode *b = checked_cast<BinaryExprNode *>(p);
|
||||
|
@ -1938,7 +1960,7 @@ namespace MetaData {
|
|||
case ExprNode::functionLiteral:
|
||||
{
|
||||
FunctionExprNode *f = checked_cast<FunctionExprNode *>(p);
|
||||
f->obj = validateStaticFunction(cxt, env, &f->function, true, true, false, p->pos);
|
||||
validateStaticFunction(cxt, env, &f->function, true, true, false, p->pos);
|
||||
}
|
||||
break;
|
||||
case ExprNode::superStmt:
|
||||
|
@ -2391,8 +2413,8 @@ doUnary:
|
|||
returnRef = new (*referenceArena) ParameterSlotReference(checked_cast<FrameVariable *>(m)->frameSlot);
|
||||
break;
|
||||
}
|
||||
keepLooking = false;
|
||||
}
|
||||
keepLooking = false;
|
||||
}
|
||||
break;
|
||||
case BlockFrameKind:
|
||||
|
@ -2703,18 +2725,29 @@ doUnary:
|
|||
bCon->emitOp(eInstanceof, p->pos);
|
||||
}
|
||||
break;
|
||||
case ExprNode::In:
|
||||
{
|
||||
BinaryExprNode *b = checked_cast<BinaryExprNode *>(p);
|
||||
Reference *rVal = SetupExprNode(env, phase, b->op1, exprType);
|
||||
if (rVal) rVal->emitReadBytecode(bCon, p->pos);
|
||||
rVal = SetupExprNode(env, phase, b->op2, exprType);
|
||||
if (rVal) rVal->emitReadBytecode(bCon, p->pos);
|
||||
bCon->emitOp(eIn, p->pos);
|
||||
}
|
||||
break;
|
||||
case ExprNode::functionLiteral:
|
||||
{
|
||||
FunctionExprNode *f = checked_cast<FunctionExprNode *>(p);
|
||||
CompilationData *oldData = startCompilationUnit(f->function.fWrap->bCon, bCon->mSource, bCon->mSourceLocation);
|
||||
env->addFrame(f->function.fWrap->compileFrame);
|
||||
FunctionInstance *fnInst = f->function.fn;
|
||||
CompilationData *oldData = startCompilationUnit(fnInst->fWrap->bCon, bCon->mSource, bCon->mSourceLocation);
|
||||
env->addFrame(fnInst->fWrap->compileFrame);
|
||||
SetupStmt(env, phase, f->function.body);
|
||||
// XXX need to make sure that all paths lead to an exit of some kind
|
||||
bCon->emitOp(eReturnVoid, p->pos);
|
||||
env->removeTopFrame();
|
||||
restoreCompilationUnit(oldData);
|
||||
bCon->emitOp(eFunction, p->pos);
|
||||
bCon->addObject(f->obj);
|
||||
bCon->addObject(fnInst);
|
||||
}
|
||||
break;
|
||||
case ExprNode::superStmt:
|
||||
|
@ -2856,7 +2889,7 @@ doUnary:
|
|||
{
|
||||
LocalMember *m = meta->findLocalMember(f, multiname, ReadAccess);
|
||||
if (m)
|
||||
result = meta->readLocalMember(m, phase, rval);
|
||||
result = meta->readLocalMember(m, phase, rval, f);
|
||||
}
|
||||
break;
|
||||
case WithFrameKind:
|
||||
|
@ -3214,7 +3247,7 @@ doUnary:
|
|||
// region if they haven't been marked as such already.
|
||||
if (innerFrame != regionalFrame) {
|
||||
fi = env->getBegin();
|
||||
Frame *fr = ++fi->first;
|
||||
Frame *fr = (++fi)->first;
|
||||
while (true) {
|
||||
if (fr->kind != WithFrameKind) {
|
||||
NonWithFrame *nwfr = checked_cast<NonWithFrame *>(fr);
|
||||
|
@ -3241,7 +3274,7 @@ doUnary:
|
|||
}
|
||||
if (fr == regionalFrame)
|
||||
break;
|
||||
fr = ++fi->first;
|
||||
fr = (++fi)->first;
|
||||
}
|
||||
}
|
||||
return multiname;
|
||||
|
@ -4256,7 +4289,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
|
|||
return false;
|
||||
}
|
||||
|
||||
bool JS2Metadata::readLocalMember(LocalMember *m, Phase phase, js2val *rval)
|
||||
bool JS2Metadata::readLocalMember(LocalMember *m, Phase phase, js2val *rval, Frame *container)
|
||||
{
|
||||
switch (m->memberKind) {
|
||||
case LocalMember::ForbiddenMember:
|
||||
|
@ -4272,25 +4305,27 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
|
|||
}
|
||||
case LocalMember::FrameVariableMember:
|
||||
{
|
||||
ASSERT(container);
|
||||
if (phase == CompilePhase)
|
||||
reportError(Exception::compileExpressionError, "Inappropriate compile time expression", engine->errorPos());
|
||||
FrameVariable *f = checked_cast<FrameVariable *>(m);
|
||||
switch (f->kind) {
|
||||
FrameVariable *fv = checked_cast<FrameVariable *>(m);
|
||||
switch (fv->kind) {
|
||||
case FrameVariable::Package:
|
||||
*rval = (*env->getPackageFrame()->slots)[f->frameSlot];
|
||||
{
|
||||
ASSERT(container->kind == PackageKind);
|
||||
*rval = (*(checked_cast<Package *>(container))->slots)[fv->frameSlot];
|
||||
}
|
||||
break;
|
||||
case FrameVariable::Local:
|
||||
{
|
||||
FrameListIterator fi = env->getRegionalFrame();
|
||||
ASSERT((fi->first)->kind == ParameterFrameKind);
|
||||
*rval = (*checked_cast<NonWithFrame *>((fi - 1)->first)->slots)[f->frameSlot];
|
||||
ASSERT(container->kind == BlockFrameKind);
|
||||
*rval = (*(checked_cast<NonWithFrame *>(container))->slots)[fv->frameSlot];
|
||||
}
|
||||
break;
|
||||
case FrameVariable::Parameter:
|
||||
{
|
||||
FrameListIterator fi = env->getRegionalFrame();
|
||||
ASSERT((fi->first)->kind == ParameterFrameKind);
|
||||
*rval = (*checked_cast<NonWithFrame *>(fi->first)->slots)[f->frameSlot];
|
||||
ASSERT(container->kind == ParameterFrameKind);
|
||||
*rval = (*(checked_cast<ParameterFrame *>(container))->slots)[fv->frameSlot];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -4352,14 +4387,16 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
|
|||
{
|
||||
FrameListIterator fi = env->getRegionalFrame();
|
||||
ASSERT((fi->first)->kind == ParameterFrameKind);
|
||||
(*checked_cast<NonWithFrame *>((fi - 1)->first)->slots)[f->frameSlot] = newValue;
|
||||
NonWithFrame *nwf = checked_cast<NonWithFrame *>((fi - 1)->first);
|
||||
(*nwf->slots)[f->frameSlot] = newValue;
|
||||
}
|
||||
break;
|
||||
case FrameVariable::Parameter:
|
||||
{
|
||||
FrameListIterator fi = env->getRegionalFrame();
|
||||
ASSERT((fi->first)->kind == ParameterFrameKind);
|
||||
(*checked_cast<NonWithFrame *>(fi->first)->slots)[f->frameSlot] = newValue;
|
||||
ParameterFrame *pFrame = checked_cast<ParameterFrame *>(fi->first);
|
||||
(*pFrame->slots)[f->frameSlot] = newValue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -5252,9 +5289,9 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
|
|||
p->resetMark(); // might have lingering mark from previous gc
|
||||
p->clearFlags();
|
||||
p->setFlag(flag);
|
||||
#ifdef DEBUG
|
||||
//#ifdef DEBUG
|
||||
memset((p + 1), 0xB7, p->getSize() - sizeof(PondScum));
|
||||
#endif
|
||||
//#endif
|
||||
return (p + 1);
|
||||
}
|
||||
pre = p;
|
||||
|
@ -5272,9 +5309,9 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
|
|||
}
|
||||
// there was room, so acquire it
|
||||
PondScum *p = (PondScum *)pondTop;
|
||||
#ifdef DEBUG
|
||||
//#ifdef DEBUG
|
||||
memset(p, 0xB7, sz);
|
||||
#endif
|
||||
//#endif
|
||||
p->owner = this;
|
||||
p->setSize(sz);
|
||||
p->setFlag(flag);
|
||||
|
@ -5288,9 +5325,9 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
|
|||
{
|
||||
p->owner = (Pond *)freeHeader;
|
||||
uint8 *t = (uint8 *)(p + 1);
|
||||
#ifdef DEBUG
|
||||
//#ifdef DEBUG
|
||||
memset(t, 0xB3, p->getSize() - sizeof(PondScum));
|
||||
#endif
|
||||
//#endif
|
||||
freeHeader = p;
|
||||
return p->getSize() - sizeof(PondScum);
|
||||
}
|
||||
|
|
|
@ -1492,7 +1492,7 @@ public:
|
|||
|
||||
|
||||
|
||||
bool readLocalMember(LocalMember *m, Phase phase, js2val *rval);
|
||||
bool readLocalMember(LocalMember *m, Phase phase, js2val *rval, Frame *container);
|
||||
bool readInstanceMember(js2val containerVal, JS2Class *c, InstanceMember *mBase, Phase phase, js2val *rval);
|
||||
bool JS2Metadata::hasOwnProperty(JS2Object *obj, const String *name);
|
||||
|
||||
|
|
|
@ -282,6 +282,22 @@ doCall:
|
|||
}
|
||||
break;
|
||||
|
||||
case eIn:
|
||||
{
|
||||
b = pop();
|
||||
a = pop(); // doing 'a in b'
|
||||
astr = meta->toString(a);
|
||||
Multiname mn(astr);
|
||||
JS2Class *c = meta->objectType(b);
|
||||
bool result = ( (meta->findBaseInstanceMember(c, &mn, ReadAccess) != NULL)
|
||||
|| (meta->findBaseInstanceMember(c, &mn, WriteAccess) != NULL)
|
||||
|| (meta->findCommonMember(&b, &mn, ReadAccess, false) != NULL)
|
||||
|| (meta->findCommonMember(&b, &mn, WriteAccess, false) != NULL));
|
||||
push(BOOLEAN_TO_JS2VAL(result));
|
||||
astr = NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
case eInstanceof: // XXX prototype version
|
||||
{
|
||||
b = pop();
|
||||
|
|
|
@ -91,12 +91,37 @@
|
|||
|
||||
case eFunction:
|
||||
{
|
||||
JS2Object *x = checked_cast<JS2Object *>(bCon->mObjectList[BytecodeContainer::getShort(pc)]);
|
||||
FunctionInstance *x = checked_cast<FunctionInstance *>(bCon->mObjectList[BytecodeContainer::getShort(pc)]);
|
||||
push(OBJECT_TO_JS2VAL(x));
|
||||
pc += sizeof(short);
|
||||
}
|
||||
break;
|
||||
|
||||
case eClosure:
|
||||
{
|
||||
FunctionInstance *x = checked_cast<FunctionInstance *>(bCon->mObjectList[BytecodeContainer::getShort(pc)]);
|
||||
pc += sizeof(short);
|
||||
|
||||
x->fWrap->env = new Environment(meta->env);
|
||||
/*
|
||||
// For each active plural frame in the function definition environment, we need
|
||||
// to find it's current singular counterpart and use that as the dohickey
|
||||
FrameListIterator closure_fi = x->fWrap.env->getBegin();
|
||||
FrameListIterator current_fi = meta->env->getBegin();
|
||||
while (true) {
|
||||
Frame *closure_fr = closure_fi->first;
|
||||
Frame *current_fr = current_fi->first;
|
||||
ASSERT(closure_fr->kind == current_fr->kind);
|
||||
if ((closure_fr->kind == ClassKind) || (closure_fr->kind == PackageKind) || (closure_fr->kind == SystemKind))
|
||||
break;
|
||||
|
||||
|
||||
|
||||
}
|
||||
*/
|
||||
}
|
||||
break;
|
||||
|
||||
case eNull:
|
||||
{
|
||||
push(JS2VAL_NULL);
|
||||
|
|
|
@ -278,7 +278,7 @@ static js2val String_replace(JS2Metadata *meta, const js2val thisValue, js2val *
|
|||
const String *replaceStr = meta->toString(replaceValue);
|
||||
DEFINE_ROOTKEEPER(rk2, replaceStr);
|
||||
|
||||
if (meta->objectType(searchValue) != meta->regexpClass) {
|
||||
if (meta->objectType(searchValue) == meta->regexpClass) {
|
||||
RegExpInstance *reInst = checked_cast<RegExpInstance *>(JS2VAL_TO_OBJECT(searchValue));
|
||||
JS2RegExp *re = reInst->mRegExp;
|
||||
REMatchResult *match;
|
||||
|
|
|
@ -64,7 +64,6 @@ namespace JavaScript {
|
|||
class Member;
|
||||
class InstanceMember;
|
||||
class Multiname;
|
||||
class FunctionWrapper;
|
||||
class BlockFrame;
|
||||
class FunctionInstance;
|
||||
typedef uint32 LabelID;
|
||||
|
@ -315,7 +314,7 @@ namespace JavaScript {
|
|||
|
||||
void print(PrettyPrinter &f, const AttributeStmtNode *attributes, bool noSemi) const;
|
||||
#ifdef EPIMETHEUS
|
||||
MetaData::FunctionWrapper *fWrap; // Runtime data, bytecode, parameters etc.
|
||||
MetaData::FunctionInstance *fn; // Runtime data, bytecode, parameters etc.
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -398,9 +397,6 @@ namespace JavaScript {
|
|||
explicit FunctionExprNode(size_t pos): ExprNode(pos, functionLiteral) {}
|
||||
|
||||
void print(PrettyPrinter &f) const;
|
||||
#ifdef EPIMETHEUS
|
||||
MetaData::FunctionInstance *obj; // used by backend to store the function object
|
||||
#endif
|
||||
};
|
||||
|
||||
struct ExprPairList: ArenaObject {
|
||||
|
@ -595,6 +591,7 @@ namespace JavaScript {
|
|||
#ifdef EPIMETHEUS
|
||||
MetaData::LabelID breakLabelID;
|
||||
MetaData::LabelID continueLabelID;
|
||||
MetaData::BlockFrame *compileFrame;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче