зеркало из https://github.com/mozilla/gecko-dev.git
Bug 927782 - Part 1: Expose JSScript::getBlockScope(jsbytecode *). r=luke
This commit is contained in:
Родитель
9c371ba053
Коммит
6068ab757b
|
@ -1429,57 +1429,6 @@ js_QuoteString(ExclusiveContext *cx, JSString *str, jschar quote)
|
|||
|
||||
/************************************************************************/
|
||||
|
||||
StaticBlockObject *
|
||||
js::GetBlockChainAtPC(JSScript *script, jsbytecode *pc)
|
||||
{
|
||||
JS_ASSERT(script->containsPC(pc));
|
||||
|
||||
if (!script->hasBlockScopes())
|
||||
return nullptr;
|
||||
|
||||
if (pc < script->main())
|
||||
return nullptr;
|
||||
ptrdiff_t offset = pc - script->main();
|
||||
|
||||
BlockScopeArray *blockScopes = script->blockScopes();
|
||||
StaticBlockObject *blockChain = nullptr;
|
||||
|
||||
// Find the innermost block chain using a binary search.
|
||||
size_t bottom = 0;
|
||||
size_t top = blockScopes->length;
|
||||
|
||||
while (bottom < top) {
|
||||
size_t mid = bottom + (top - bottom) / 2;
|
||||
const BlockScopeNote *note = &blockScopes->vector[mid];
|
||||
if (note->start <= offset) {
|
||||
// Block scopes are ordered in the list by their starting offset, and since
|
||||
// blocks form a tree ones earlier in the list may cover the pc even if
|
||||
// later blocks end before the pc. This only happens when the earlier block
|
||||
// is a parent of the later block, so we need to check parents of |mid| in
|
||||
// the searched range for coverage.
|
||||
size_t check = mid;
|
||||
while (check >= bottom) {
|
||||
const BlockScopeNote *checkNote = &blockScopes->vector[check];
|
||||
JS_ASSERT(checkNote->start <= offset);
|
||||
if (offset < checkNote->start + checkNote->length) {
|
||||
// We found a matching block chain but there may be inner ones
|
||||
// at a higher block chain index than mid. Continue the binary search.
|
||||
blockChain = &script->getObject(checkNote->index)->as<StaticBlockObject>();
|
||||
break;
|
||||
}
|
||||
if (checkNote->parent == UINT32_MAX)
|
||||
break;
|
||||
check = checkNote->parent;
|
||||
}
|
||||
bottom = mid + 1;
|
||||
} else {
|
||||
top = mid;
|
||||
}
|
||||
}
|
||||
|
||||
return blockChain;
|
||||
}
|
||||
|
||||
namespace {
|
||||
/*
|
||||
* The expression decompiler is invoked by error handling code to produce a
|
||||
|
@ -1740,7 +1689,7 @@ JSAtom *
|
|||
ExpressionDecompiler::findLetVar(jsbytecode *pc, unsigned depth)
|
||||
{
|
||||
if (script->hasObjects()) {
|
||||
JSObject *chain = GetBlockChainAtPC(script, pc);
|
||||
JSObject *chain = script->getBlockScope(pc);
|
||||
if (!chain)
|
||||
return nullptr;
|
||||
JS_ASSERT(chain->is<BlockObject>());
|
||||
|
|
|
@ -777,11 +777,6 @@ GetNextPc(jsbytecode *pc)
|
|||
return pc + GetBytecodeLength(pc);
|
||||
}
|
||||
|
||||
class StaticBlockObject;
|
||||
|
||||
StaticBlockObject *
|
||||
GetBlockChainAtPC(JSScript *script, jsbytecode *pc);
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
#if defined(DEBUG)
|
||||
|
|
|
@ -2894,6 +2894,58 @@ LazyScript::finalize(FreeOp *fop)
|
|||
fop->free_(table_);
|
||||
}
|
||||
|
||||
StaticBlockObject *
|
||||
JSScript::getBlockScope(jsbytecode *pc)
|
||||
{
|
||||
JS_ASSERT(containsPC(pc));
|
||||
|
||||
if (!hasBlockScopes())
|
||||
return nullptr;
|
||||
|
||||
ptrdiff_t offset = pc - main();
|
||||
|
||||
if (offset < 0)
|
||||
return nullptr;
|
||||
|
||||
BlockScopeArray *scopes = blockScopes();
|
||||
StaticBlockObject *blockChain = nullptr;
|
||||
|
||||
// Find the innermost block chain using a binary search.
|
||||
size_t bottom = 0;
|
||||
size_t top = scopes->length;
|
||||
|
||||
while (bottom < top) {
|
||||
size_t mid = bottom + (top - bottom) / 2;
|
||||
const BlockScopeNote *note = &scopes->vector[mid];
|
||||
if (note->start <= offset) {
|
||||
// Block scopes are ordered in the list by their starting offset, and since
|
||||
// blocks form a tree ones earlier in the list may cover the pc even if
|
||||
// later blocks end before the pc. This only happens when the earlier block
|
||||
// is a parent of the later block, so we need to check parents of |mid| in
|
||||
// the searched range for coverage.
|
||||
size_t check = mid;
|
||||
while (check >= bottom) {
|
||||
const BlockScopeNote *checkNote = &scopes->vector[check];
|
||||
JS_ASSERT(checkNote->start <= offset);
|
||||
if (offset < checkNote->start + checkNote->length) {
|
||||
// We found a matching block chain but there may be inner ones
|
||||
// at a higher block chain index than mid. Continue the binary search.
|
||||
blockChain = &getObject(checkNote->index)->as<StaticBlockObject>();
|
||||
break;
|
||||
}
|
||||
if (checkNote->parent == UINT32_MAX)
|
||||
break;
|
||||
check = checkNote->parent;
|
||||
}
|
||||
bottom = mid + 1;
|
||||
} else {
|
||||
top = mid;
|
||||
}
|
||||
}
|
||||
|
||||
return blockChain;
|
||||
}
|
||||
|
||||
void
|
||||
JSScript::setArgumentsHasVarBinding()
|
||||
{
|
||||
|
|
|
@ -43,6 +43,7 @@ class RegExpObject;
|
|||
struct SourceCompressionTask;
|
||||
class Shape;
|
||||
class WatchpointMap;
|
||||
class StaticBlockObject;
|
||||
|
||||
namespace analyze {
|
||||
class ScriptAnalysis;
|
||||
|
@ -1268,6 +1269,8 @@ class JSScript : public js::gc::BarrieredCell<JSScript>
|
|||
return arr->vector[index];
|
||||
}
|
||||
|
||||
js::StaticBlockObject *getBlockScope(jsbytecode *pc);
|
||||
|
||||
/*
|
||||
* The isEmpty method tells whether this script has code that computes any
|
||||
* result (not return value, result AKA normal completion value) other than
|
||||
|
|
|
@ -38,7 +38,7 @@ InnermostStaticScope(JSScript *script, jsbytecode *pc)
|
|||
JS_ASSERT(script->containsPC(pc));
|
||||
JS_ASSERT(JOF_OPTYPE(*pc) == JOF_SCOPECOORD);
|
||||
|
||||
StaticBlockObject *block = GetBlockChainAtPC(script, pc);
|
||||
StaticBlockObject *block = script->getBlockScope(pc);
|
||||
if (block)
|
||||
return block;
|
||||
return script->function();
|
||||
|
|
Загрузка…
Ссылка в новой задаче