本文整理汇总了C++中AtomDefnRange类的典型用法代码示例。如果您正苦于以下问题:C++ AtomDefnRange类的具体用法?C++ AtomDefnRange怎么用?C++ AtomDefnRange使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了AtomDefnRange类的8个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: DumpAtomDefnMap
void
DumpAtomDefnMap(const AtomDefnMapPtr &map)
{
if (map->empty()) {
fprintf(stderr, "empty\n");
return;
}
for (AtomDefnRange r = map->all(); !r.empty(); r.popFront()) {
fprintf(stderr, "atom: ");
js_DumpAtom(r.front().key());
fprintf(stderr, "defn: %p\n", (void *) r.front().value());
}
}
示例2: MaybeCheckEvalFreeVariables
static bool
MaybeCheckEvalFreeVariables(ExclusiveContext *cxArg, HandleScript evalCaller, HandleObject scopeChain,
Parser<FullParseHandler> &parser,
ParseContext<FullParseHandler> &pc)
{
if (!evalCaller || !evalCaller->functionOrCallerFunction())
return true;
// Eval scripts are only compiled on the main thread.
JSContext *cx = cxArg->asJSContext();
// Watch for uses of 'arguments' within the evaluated script, both as
// free variables and as variables redeclared with 'var'.
RootedFunction fun(cx, evalCaller->functionOrCallerFunction());
HandlePropertyName arguments = cx->names().arguments;
for (AtomDefnRange r = pc.lexdeps->all(); !r.empty(); r.popFront()) {
if (r.front().key() == arguments) {
if (!CheckArgumentsWithinEval(cx, parser, fun))
return false;
}
}
for (AtomDefnListMap::Range r = pc.decls().all(); !r.empty(); r.popFront()) {
if (r.front().key() == arguments) {
if (!CheckArgumentsWithinEval(cx, parser, fun))
return false;
}
}
// If the eval'ed script contains any debugger statement, force construction
// of arguments objects for the caller script and any other scripts it is
// transitively nested inside. The debugger can access any variable on the
// scope chain.
if (pc.sc->hasDebuggerStatement()) {
RootedObject scope(cx, scopeChain);
while (scope->is<ScopeObject>() || scope->is<DebugScopeObject>()) {
if (scope->is<CallObject>() && !scope->as<CallObject>().isForEval()) {
RootedScript script(cx, scope->as<CallObject>().callee().getOrCreateScript(cx));
if (!script)
return false;
if (script->argumentsHasVarBinding()) {
if (!JSScript::argumentsOptimizationFailed(cx, script))
return false;
}
}
scope = scope->enclosingScope();
}
}
return true;
}
示例3: SetFunctionKinds
static void
SetFunctionKinds(FunctionBox *funbox, uint32 *tcflags, bool isDirectEval)
{
for (; funbox; funbox = funbox->siblings) {
ParseNode *fn = funbox->node;
ParseNode *pn = fn->pn_body;
if (funbox->kids)
SetFunctionKinds(funbox->kids, tcflags, isDirectEval);
JSFunction *fun = funbox->function();
JS_ASSERT(fun->kind() == JSFUN_INTERPRETED);
if (funbox->tcflags & TCF_FUN_HEAVYWEIGHT) {
/* nothing to do */
} else if (isDirectEval || funbox->inAnyDynamicScope()) {
/*
* Either we are in a with-block or a function scope that is
* subject to direct eval; or we are compiling strict direct eval
* code.
*
* In either case, fun may reference names that are not bound but
* are not necessarily global either. (In the strict direct eval
* case, we could bind them, but currently do not bother; see
* the comment about strict mode code in BindTopLevelVar.)
*/
JS_ASSERT(!fun->isNullClosure());
} else {
bool hasUpvars = false;
bool canFlatten = true;
if (pn->isKind(PNK_UPVARS)) {
AtomDefnMapPtr upvars = pn->pn_names;
JS_ASSERT(!upvars->empty());
/*
* For each lexical dependency from this closure to an outer
* binding, analyze whether it is safe to copy the binding's
* value into a flat closure slot when the closure is formed.
*/
for (AtomDefnRange r = upvars->all(); !r.empty(); r.popFront()) {
Definition *defn = r.front().value();
Definition *lexdep = defn->resolve();
if (!lexdep->isFreeVar()) {
hasUpvars = true;
if (!CanFlattenUpvar(lexdep, funbox, *tcflags)) {
/*
* Can't flatten. Enclosing functions holding
* variables used by this function will be flagged
* heavyweight below. FIXME bug 545759: re-enable
* partial flat closures.
*/
canFlatten = false;
break;
}
}
}
}
if (!hasUpvars) {
/* No lexical dependencies => null closure, for best performance. */
fun->setKind(JSFUN_NULL_CLOSURE);
} else if (canFlatten) {
fun->setKind(JSFUN_FLAT_CLOSURE);
switch (fn->getOp()) {
case JSOP_DEFFUN:
fn->setOp(JSOP_DEFFUN_FC);
break;
case JSOP_DEFLOCALFUN:
fn->setOp(JSOP_DEFLOCALFUN_FC);
break;
case JSOP_LAMBDA:
fn->setOp(JSOP_LAMBDA_FC);
break;
default:
/* js::frontend::EmitTree's PNK_FUNCTION case sets op. */
JS_ASSERT(fn->isOp(JSOP_NOP));
}
}
}
if (fun->kind() == JSFUN_INTERPRETED && pn->isKind(PNK_UPVARS)) {
/*
* One or more upvars cannot be safely snapshot into a flat
* closure's non-reserved slot (see JSOP_GETFCSLOT), so we loop
* again over all upvars, and for each non-free upvar, ensure that
* its containing function has been flagged as heavyweight.
*
* The emitter must see TCF_FUN_HEAVYWEIGHT accurately before
* generating any code for a tree of nested functions.
*/
AtomDefnMapPtr upvars = pn->pn_names;
JS_ASSERT(!upvars->empty());
for (AtomDefnRange r = upvars->all(); !r.empty(); r.popFront()) {
Definition *defn = r.front().value();
Definition *lexdep = defn->resolve();
if (!lexdep->isFreeVar())
//.........这里部分代码省略.........
示例4: MarkFunArgs
static bool
MarkFunArgs(JSContext *cx, FunctionBox *funbox, uint32 functionCount)
{
FunctionBoxQueue queue;
if (!queue.init(functionCount)) {
js_ReportOutOfMemory(cx);
return false;
}
FindFunArgs(funbox, -1, &queue);
while ((funbox = queue.pull()) != NULL) {
ParseNode *fn = funbox->node;
JS_ASSERT(fn->isFunArg());
ParseNode *pn = fn->pn_body;
if (pn->isKind(PNK_UPVARS)) {
AtomDefnMapPtr upvars = pn->pn_names;
JS_ASSERT(!upvars->empty());
for (AtomDefnRange r = upvars->all(); !r.empty(); r.popFront()) {
Definition *defn = r.front().value();
Definition *lexdep = defn->resolve();
if (!lexdep->isFreeVar() &&
!lexdep->isFunArg() &&
(lexdep->kind() == Definition::FUNCTION ||
lexdep->isOp(JSOP_CALLEE))) {
/*
* Mark this formerly-Algol-like function as an escaping
* function (i.e., as a funarg), because it is used from
* another funarg.
*
* Progress is guaranteed because we set the funarg flag
* here, which suppresses revisiting this function (thanks
* to the !lexdep->isFunArg() test just above).
*/
lexdep->setFunArg();
FunctionBox *afunbox;
if (lexdep->isOp(JSOP_CALLEE)) {
/*
* A named function expression will not appear to be a
* funarg if it is immediately applied. However, if its
* name is used in an escaping function nested within
* it, then it must become flagged as a funarg again.
* See bug 545980.
*/
afunbox = funbox;
uintN calleeLevel = lexdep->pn_cookie.level();
uintN staticLevel = afunbox->level + 1U;
while (staticLevel != calleeLevel) {
afunbox = afunbox->parent;
--staticLevel;
}
JS_ASSERT(afunbox->level + 1U == calleeLevel);
afunbox->node->setFunArg();
} else {
afunbox = lexdep->pn_funbox;
}
queue.push(afunbox);
/*
* Walk over nested functions again, now that we have
* changed the level across which it is unsafe to access
* upvars using the runtime dynamic link (frame chain).
*/
if (afunbox->kids)
FindFunArgs(afunbox->kids, afunbox->level, &queue);
}
}
}
}
return true;
}
示例5: FindFunArgs
/*
* 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);
}
//.........这里部分代码省略.........
示例6: source
//.........这里部分代码省略.........
* wishes to decompile it while it's running.
*/
ObjectBox *funbox = parser.newObjectBox(callerFrame->fun());
if (!funbox)
return NULL;
funbox->emitLink = bce.objectList.lastbox;
bce.objectList.lastbox = funbox;
bce.objectList.length++;
}
}
ParseNode *pn;
#if JS_HAS_XML_SUPPORT
pn = NULL;
bool onlyXML;
onlyXML = true;
#endif
TokenStream &tokenStream = parser.tokenStream;
{
ParseNode *stringsAtStart = ListNode::create(PNK_STATEMENTLIST, &parser);
if (!stringsAtStart)
return NULL;
stringsAtStart->makeEmpty();
bool ok = parser.processDirectives(stringsAtStart) && EmitTree(cx, &bce, stringsAtStart);
parser.freeTree(stringsAtStart);
if (!ok)
return NULL;
}
JS_ASSERT(sc.strictModeState != StrictMode::UNKNOWN);
for (;;) {
TokenKind tt = tokenStream.peekToken(TSF_OPERAND);
if (tt <= TOK_EOF) {
if (tt == TOK_EOF)
break;
JS_ASSERT(tt == TOK_ERROR);
return NULL;
}
pn = parser.statement();
if (!pn)
return NULL;
if (!FoldConstants(cx, pn, &parser))
return NULL;
if (!AnalyzeFunctions(&parser, callerFrame))
return NULL;
tc.functionList = NULL;
if (!EmitTree(cx, &bce, pn))
return NULL;
#if JS_HAS_XML_SUPPORT
if (!pn->isKind(PNK_SEMI) || !pn->pn_kid || !pn->pn_kid->isXMLItem())
onlyXML = false;
#endif
parser.freeTree(pn);
}
#if JS_HAS_XML_SUPPORT
/*
* Prevent XML data theft via <script src="http://victim.com/foo.xml">.
* For background, see:
*
* https://bugzilla.mozilla.org/show_bug.cgi?id=336551
*/
if (pn && onlyXML && !callerFrame) {
parser.reportError(NULL, JSMSG_XML_WHOLE_PROGRAM);
return NULL;
}
#endif
// It's an error to use |arguments| in a function that has a rest parameter.
if (callerFrame && callerFrame->isFunctionFrame() && callerFrame->fun()->hasRest()) {
PropertyName *arguments = cx->runtime->atomState.argumentsAtom;
for (AtomDefnRange r = tc.lexdeps->all(); !r.empty(); r.popFront()) {
if (r.front().key() == arguments) {
parser.reportError(NULL, JSMSG_ARGUMENTS_AND_REST);
return NULL;
}
}
// We're not in a function context, so we don't expect any bindings.
JS_ASSERT(!sc.bindings.hasBinding(cx, arguments));
}
/*
* Nowadays the threaded interpreter needs a stop instruction, so we
* do have to emit that here.
*/
if (Emit1(cx, &bce, JSOP_STOP) < 0)
return NULL;
if (!JSScript::fullyInitFromEmitter(cx, script, &bce))
return NULL;
bce.tellDebuggerAboutCompiledScript(cx);
return script;
}
示例7: source
//.........这里部分代码省略.........
if (evalCaller && evalCaller->functionOrCallerFunction()) {
/*
* An eval script in a caller frame needs to have its enclosing
* function captured in case it refers to an upvar, and someone
* wishes to decompile it while it's running.
*/
JSFunction *fun = evalCaller->functionOrCallerFunction();
ObjectBox *funbox = parser.newFunctionBox(fun, &pc, fun->strict());
if (!funbox)
return NULL;
bce.objectList.add(funbox);
}
}
bool canHaveDirectives = true;
for (;;) {
TokenKind tt = parser.tokenStream.peekToken(TSF_OPERAND);
if (tt <= TOK_EOF) {
if (tt == TOK_EOF)
break;
JS_ASSERT(tt == TOK_ERROR);
return NULL;
}
ParseNode *pn = parser.statement();
if (!pn)
return NULL;
if (canHaveDirectives) {
if (!parser.maybeParseDirective(pn, &canHaveDirectives))
return NULL;
}
if (!FoldConstants(cx, &pn, &parser))
return NULL;
if (!NameFunctions(cx, pn))
return NULL;
if (!EmitTree(cx, &bce, pn))
return NULL;
parser.handler.freeTree(pn);
}
if (!SetSourceMap(cx, parser.tokenStream, ss, script))
return NULL;
if (evalCaller && evalCaller->functionOrCallerFunction()) {
// Watch for uses of 'arguments' within the evaluated script, both as
// free variables and as variables redeclared with 'var'.
RootedFunction fun(cx, evalCaller->functionOrCallerFunction());
HandlePropertyName arguments = cx->names().arguments;
for (AtomDefnRange r = pc.lexdeps->all(); !r.empty(); r.popFront()) {
if (r.front().key() == arguments) {
if (!CheckArgumentsWithinEval(cx, parser, fun))
return NULL;
}
}
for (AtomDefnListMap::Range r = pc.decls().all(); !r.empty(); r.popFront()) {
if (r.front().key() == arguments) {
if (!CheckArgumentsWithinEval(cx, parser, fun))
return NULL;
}
}
// If the eval'ed script contains any debugger statement, force construction
// of arguments objects for the caller script and any other scripts it is
// transitively nested inside.
if (pc.sc->hasDebuggerStatement()) {
RootedObject scope(cx, scopeChain);
while (scope->isScope() || scope->isDebugScope()) {
if (scope->isCall() && !scope->asCall().isForEval()) {
RootedScript script(cx, scope->asCall().callee().nonLazyScript());
if (script->argumentsHasVarBinding()) {
if (!JSScript::argumentsOptimizationFailed(cx, script))
return NULL;
}
}
scope = scope->enclosingScope();
}
}
}
/*
* Nowadays the threaded interpreter needs a stop instruction, so we
* do have to emit that here.
*/
if (Emit1(cx, &bce, JSOP_STOP) < 0)
return NULL;
if (!JSScript::fullyInitFromEmitter(cx, script, &bce))
return NULL;
bce.tellDebuggerAboutCompiledScript(cx);
if (sct == &mysct && !sct->complete())
return NULL;
return script;
}
示例8: SetFunctionKinds
static void
SetFunctionKinds(FunctionBox *funbox, bool *isHeavyweight, bool topInFunction, bool isDirectEval)
{
for (; funbox; funbox = funbox->siblings) {
ParseNode *fn = funbox->node;
if (!fn)
continue;
ParseNode *pn = fn->pn_body;
if (!pn)
continue;
if (funbox->kids)
SetFunctionKinds(funbox->kids, isHeavyweight, topInFunction, isDirectEval);
JSFunction *fun = funbox->function();
JS_ASSERT(fun->kind() == JSFUN_INTERPRETED);
if (funbox->funIsHeavyweight()) {
/* nothing to do */
} else if (isDirectEval || funbox->inAnyDynamicScope()) {
/*
* Either we are in a with-block or a function scope that is
* subject to direct eval; or we are compiling strict direct eval
* code.
*
* In either case, fun may reference names that are not bound but
* are not necessarily global either. (In the strict direct eval
* case, we could bind them, but currently do not bother; see
* the comment about strict mode code in BindTopLevelVar.)
*/
JS_ASSERT(!fun->isNullClosure());
} else {
bool hasUpvars = false;
if (pn->isKind(PNK_UPVARS)) {
AtomDefnMapPtr upvars = pn->pn_names;
JS_ASSERT(!upvars->empty());
/* Determine whether the this function contains upvars. */
for (AtomDefnRange r = upvars->all(); !r.empty(); r.popFront()) {
if (!r.front().value()->resolve()->isFreeVar()) {
hasUpvars = true;
break;
}
}
}
if (!hasUpvars) {
/* No lexical dependencies => null closure, for best performance. */
fun->setKind(JSFUN_NULL_CLOSURE);
}
}
if (fun->kind() == JSFUN_INTERPRETED && pn->isKind(PNK_UPVARS)) {
/*
* We loop again over all upvars, and for each non-free upvar,
* ensure that its containing function has been flagged as
* heavyweight.
*
* The emitter must see funIsHeavyweight() accurately before
* generating any code for a tree of nested functions.
*/
AtomDefnMapPtr upvars = pn->pn_names;
JS_ASSERT(!upvars->empty());
for (AtomDefnRange r = upvars->all(); !r.empty(); r.popFront()) {
Definition *defn = r.front().value();
Definition *lexdep = defn->resolve();
if (!lexdep->isFreeVar())
FlagHeavyweights(lexdep, funbox, isHeavyweight, topInFunction);
}
}
}
}