本文整理汇总了C++中ParseNode::setFunArg方法的典型用法代码示例。如果您正苦于以下问题:C++ ParseNode::setFunArg方法的具体用法?C++ ParseNode::setFunArg怎么用?C++ ParseNode::setFunArg使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类ParseNode
的用法示例。
在下文中一共展示了ParseNode::setFunArg方法的1个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: int
/*
* Mark as funargs any functions that reach up to one or more upvars across an
* already-known funarg. The parser will flag the o_m lambda as a funarg in:
*
* function f(o, p) {
* o.m = function o_m(a) {
* function g() { return p; }
* function h() { return a; }
* return g() + h();
* }
* }
*
* but without this extra marking phase, function g will not be marked as a
* funarg since it is called from within its parent scope. But g reaches up to
* f's parameter p, so if o_m escapes f's activation scope, g does too and
* cannot assume that p's stack slot is still alive. In contast function h
* neither escapes nor uses an upvar "above" o_m's level.
*
* If function g itself contained lambdas that contained non-lambdas that reach
* up above its level, then those non-lambdas would have to be marked too. This
* process is potentially exponential in the number of functions, but generally
* not so complex. But it can't be done during a single recursive traversal of
* the funbox tree, so we must use a work queue.
*
* Return the minimal "skipmin" for funbox and its siblings. This is the delta
* between the static level of the bodies of funbox and its peers (which must
* be funbox->level + 1), and the static level of the nearest upvar among all
* the upvars contained by funbox and its peers. If there are no upvars, return
* FREE_STATIC_LEVEL. Thus this function never returns 0.
*/
static uintN
FindFunArgs(FunctionBox *funbox, int level, FunctionBoxQueue *queue)
{
uintN allskipmin = UpvarCookie::FREE_LEVEL;
do {
ParseNode *fn = funbox->node;
JS_ASSERT(fn->isArity(PN_FUNC));
int fnlevel = level;
/*
* An eval can leak funbox, functions along its ancestor line, and its
* immediate kids. Since FindFunArgs uses DFS and the parser propagates
* TCF_FUN_HEAVYWEIGHT bottom up, funbox's ancestor function nodes have
* already been marked as funargs by this point. Therefore we have to
* flag only funbox->node and funbox->kids' nodes here.
*
* Generators need to be treated in the same way. Even if the value
* of a generator function doesn't escape, anything defined or referred
* to inside the generator can escape through a call to the generator.
* We could imagine doing static analysis to track the calls and see
* if any iterators or values returned by iterators escape, but that
* would be hard, so instead we just assume everything might escape.
*/
if (funbox->tcflags & (TCF_FUN_HEAVYWEIGHT | TCF_FUN_IS_GENERATOR)) {
fn->setFunArg();
for (FunctionBox *kid = funbox->kids; kid; kid = kid->siblings)
kid->node->setFunArg();
}
/*
* Compute in skipmin the least distance from fun's static level up to
* an upvar, whether used directly by fun, or indirectly by a function
* nested in fun.
*/
uintN skipmin = UpvarCookie::FREE_LEVEL;
ParseNode *pn = fn->pn_body;
if (pn->isKind(PNK_UPVARS)) {
AtomDefnMapPtr &upvars = pn->pn_names;
JS_ASSERT(upvars->count() != 0);
for (AtomDefnRange r = upvars->all(); !r.empty(); r.popFront()) {
Definition *defn = r.front().value();
Definition *lexdep = defn->resolve();
if (!lexdep->isFreeVar()) {
uintN upvarLevel = lexdep->frameLevel();
if (int(upvarLevel) <= fnlevel)
fn->setFunArg();
uintN skip = (funbox->level + 1) - upvarLevel;
if (skip < skipmin)
skipmin = skip;
}
}
}
/*
* If this function escapes, whether directly (the parser detects such
* escapes) or indirectly (because this non-escaping function uses an
* upvar that reaches across an outer function boundary where the outer
* function escapes), enqueue it for further analysis, and bump fnlevel
* to trap any non-escaping children.
*/
if (fn->isFunArg()) {
queue->push(funbox);
fnlevel = int(funbox->level);
}
//.........这里部分代码省略.........