Added Function constructor.

git-svn-id: svn://10.0.0.236/trunk@137881 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
rogerl%netscape.com 2003-02-17 01:17:24 +00:00
parent 8d56f6596b
commit 4f1113315a
2 changed files with 84 additions and 15 deletions

View File

@ -59,7 +59,55 @@ namespace MetaData {
{
js2val thatValue = OBJECT_TO_JS2VAL(new FunctionInstance(meta->functionClass->prototype, meta->functionClass));
FunctionInstance *fnInst = checked_cast<FunctionInstance *>(JS2VAL_TO_OBJECT(thatValue));
JS2Object::RootIterator ri = JS2Object::addRoot(&fnInst);
fnInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_INACCESSIBLE, true));
if (argc) {
const String *str = meta->toString(argv[0]);
const String &srcLoc = widenCString("Function constructor source");
Arena a;
Pragma::Flags flags = Pragma::js1; // XXX get flags from meta/context ?
Parser parser(meta->world, a, flags, *str, srcLoc);
CompilationData *oldData = NULL;
try {
StmtNode *parsedStatements = parser.parseProgram();
ASSERT(parser.lexer.peek(true).hasKind(Token::end));
if (meta->showTrees)
{
PrettyPrinter f(stdOut, 80);
{
PrettyPrinter::Block b(f, 2);
f << "Program =";
f.linearBreak(1);
StmtNode::printStatements(f, parsedStatements);
}
f.end();
stdOut << '\n';
}
if (parsedStatements) {
oldData = meta->startCompilationUnit(fnInst->fWrap->bCon, *str, srcLoc);
meta->ValidateStmtList(parsedStatements);
StmtNode *p = parsedStatements;
size_t lastPos = p->pos;
while (p) {
meta->SetupStmt(meta->env, RunPhase, p);
lastPos = p->pos;
p = p->next;
}
fnInst->fWrap->bCon->emitOp(eReturnVoid, lastPos);
}
}
catch (Exception &x) {
if (oldData)
meta->restoreCompilationUnit(oldData);
JS2Object::removeRoot(ri);
throw x;
}
if (oldData)
meta->restoreCompilationUnit(oldData);
}
JS2Object::removeRoot(ri);
return thatValue;
}

View File

@ -4017,26 +4017,47 @@ deleteClassProperty:
fWrap = (checked_cast<SimpleInstance *>(fnObj))->fWrap;
}
else
if ((fnObj->kind == PrototypeInstanceKind)
&& ((checked_cast<PrototypeInstance *>(fnObj))->type == functionClass)) {
fWrap = (checked_cast<FunctionInstance *>(fnObj))->fWrap;
}
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
if (fnObj->kind == MethodClosureKind) {
// XXX here we accept the bound this, can that be right?
MethodClosure *mc = checked_cast<MethodClosure *>(fnObj);
SimpleInstance *fInst = mc->method->fInst;
FunctionWrapper *fWrap = fInst->fWrap;
if (fWrap->code) {
result = (fWrap->code)(this, mc->thisObject, 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;
}
}
}
}