Bug 927782 - Part 1: Expose JSScript::getBlockScope(jsbytecode *). r=luke

This commit is contained in:
Andy Wingo 2013-12-06 17:56:20 +01:00
Родитель 9c371ba053
Коммит 6068ab757b
5 изменённых файлов: 57 добавлений и 58 удалений

Просмотреть файл

@ -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();