Beispiel #1
0
void FunctionImp::initialCompile(ExecState* newExec)
{
    FunctionBodyNode* body = this->body.get();

    // Reserve various slots needed for the activation object. We do it only once,
    // --- isCompiled() would return true even if debugging state changed
    body->reserveSlot(ActivationImp::LengthSlot, false);
    body->reserveSlot(ActivationImp::TearOffNeeded, false);
    body->reserveSlot(ActivationImp::ScopeLink, false /* will mark via ScopeChain::mark() */);
    body->reserveSlot(ActivationImp::FunctionSlot, true);
    body->reserveSlot(ActivationImp::ArgumentsObjectSlot, true);

    // Create declarations for parameters, and allocate the symbols.
    // We always just give them sequential positions, to make passInParameters
    // simple (though perhaps wasting memory in the trivial case)
    for (size_t i = 0; i < body->numParams(); ++i)
      body->addSymbolOverwriteID(i + ActivationImp::NumReservedSlots, body->paramName(i), DontDelete);

    body->processDecls(newExec);
    body->compile(FunctionCode, newExec->dynamicInterpreter()->debugger() ? Debug : Release);
}
Beispiel #2
0
// ECMA 10.1.6
void ActivationImp::setup(ExecState* exec, FunctionImp *function,
                          const List* arguments, LocalStorageEntry* entries)
{
    FunctionBodyNode* body = function->body.get();

    size_t total = body->numLocalsAndRegisters();
    localStorage  = entries;
    lengthSlot()  = total;

    // we can now link ourselves into the scope, which will also fix up our scopeLink().
    exec->pushVariableObjectScope(this);

    const FunctionBodyNode::SymbolInfo* symInfo = body->getLocalInfo();

    // Setup our fields
    this->arguments = arguments;
    functionSlot()  = function;
    argumentsObjectSlot() = jsUndefined();
    symbolTable     = &body->symbolTable();

    // Set the mark/don't mark flags and attributes for everything
    for (size_t p = 0; p < total; ++p)
      entries[p].attributes = symInfo[p].attr;

    // Pass in the parameters (ECMA 10.1.3q)
#ifdef KJS_VERBOSE
    fprintf(stderr, "%s---------------------------------------------------\n"
            "%sprocessing parameters for %s call\n", ind(), ind(), 
            function->functionName().isEmpty() ? "(internal)" : function->functionName().ascii());
#endif
    size_t numParams   = body->numParams();
    size_t numPassedIn = min(numParams, static_cast<size_t>(arguments->size()));

    size_t pos = 0; 
    for (; pos < numPassedIn; ++pos) {
        size_t symNum = pos + ActivationImp::NumReservedSlots;
        JSValue* v = arguments->atUnchecked(pos);

        entries[symNum].val.valueVal = v;

#ifdef KJS_VERBOSE
        fprintf(stderr, "%s setting parameter %s", ind(), body->paramName(pos).ascii());
        printInfo(exec, "to", v);
#endif
    }

    for (; pos < numParams; ++pos) {
        size_t symNum = pos + ActivationImp::NumReservedSlots;
        entries[symNum].val.valueVal = jsUndefined();

#ifdef KJS_VERBOSE
        fprintf(stderr, "%s setting parameter %s to undefined (not passed in)", ind(), body->paramName(pos).ascii());
#endif
    }
    
#ifdef KJS_VERBOSE
    fprintf(stderr, "\n%s---------------------------------\n", ind());
    fprintf(stderr, "%sBody:\n", ind());
    fprintf(stderr, "%s---------------------------------\n", ind());
    printInd(body->toString().ascii());
    fprintf(stderr, "\n%s---------------------------------\n\n", ind());
#endif

    // Initialize the rest of the locals to 'undefined'
    for (size_t pos = numParams + ActivationImp::NumReservedSlots; pos < total; ++pos)
        entries[pos].val.valueVal = jsUndefined();

    // Finally, put in the functions. Note that this relies on above
    // steps to have completed, since it can trigger a GC.
    size_t  numFuns  = body->numFunctionLocals();
    size_t* funsData = body->getFunctionLocalInfo();
    for (size_t fun = 0; fun < numFuns; ++fun) {
        size_t id = funsData[fun];
        entries[id].val.valueVal = symInfo[id].funcDecl->makeFunctionObject(exec);
    }
}