예제 #1
0
// ECMA 15.3.2 The Function Constructor
JSObject* constructFunction(ExecState* exec, const ArgList& args, const Identifier& functionName, const UString& sourceURL, int lineNumber)
{
    UString program;
    if (args.isEmpty())
        program = "(function(){})";
    else if (args.size() == 1)
        program = "(function(){" + args.at(exec, 0)->toString(exec) + "})";
    else {
        program = "(function(" + args.at(exec, 0)->toString(exec);
        for (size_t i = 1; i < args.size() - 1; i++)
            program += "," + args.at(exec, i)->toString(exec);
        program += "){" + args.at(exec, args.size() - 1)->toString(exec) + "})";
    }

    int errLine;
    UString errMsg;
    SourceCode source = makeSource(program, sourceURL, lineNumber);
    RefPtr<ProgramNode> programNode = exec->globalData().parser->parse<ProgramNode>(exec, exec->dynamicGlobalObject()->debugger(), source, &errLine, &errMsg);

    FunctionBodyNode* body = functionBody(programNode.get());
    if (!body)
        return throwError(exec, SyntaxError, errMsg, errLine, source.provider()->asID(), source.provider()->url());

    JSGlobalObject* globalObject = exec->lexicalGlobalObject();
    ScopeChain scopeChain(globalObject, globalObject->globalData(), exec->globalThisValue());
    return new (exec) JSFunction(exec, functionName, body, scopeChain.node());
}
예제 #2
0
Expression *TypeCompiler::visit(FunctionLiteral *literal)
{
    lmAssert(!literal->classDecl, "local function belongs to a class");

    inLocalFunction++;
    FunctionLiteral *lastFunctionLiteral = currentFunctionLiteral;
    currentFunctionLiteral = literal;

    char funcname[256];
    snprintf(funcname, 250, "__ls_localfunction%i", functioncount++);

    ExpDesc v;
    BC::newLocalVar(cs, funcname, 0);
    BC::initExpDesc(&v, VLOCAL, cs->fs->freereg);
    BC::reserveRegs(cs->fs, 1);
    BC::adjustLocalVars(cs, 1);

    // store funcinfo
    // setup closure info here so it is captured as an upvalue, must be unique
    char funcinfo[256];
    snprintf(funcinfo, 250, "__ls_funcinfo_numargs_%i", literal->childIndex);

    ExpDesc funcInfo;
    ExpDesc value;
    BC::singleVar(cs, &funcInfo, funcinfo);
    BC::initExpDesc(&value, VKNUM, 0);
    value.u.nval = 0;
    if (literal->parameters)
    {
        value.u.nval = (int)literal->parameters->size();
    }

    BC::storeVar(cs->fs, &funcInfo, &value);

    ExpDesc closure;
    functionBody(&closure, literal, literal->lineNumber);

    BC::storeVar(cs->fs, &v, &closure);

    literal->e = v;

    inLocalFunction--;
    currentFunctionLiteral = lastFunctionLiteral;

    return literal;
}