зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1181869 - Update Bindings to use normal Rooted primitives; r=shu
This commit is contained in:
Родитель
59382657f2
Коммит
a9e6bc1d23
|
@ -448,12 +448,13 @@ frontend::CompileScript(ExclusiveContext* cx, LifoAlloc* alloc, HandleObject sco
|
|||
// scope dynamically via JSOP_DEFFUN/VAR). They may have block-scoped
|
||||
// locals, however, which are allocated to the fixed part of the stack
|
||||
// frame.
|
||||
InternalHandle<Bindings*> bindings(script, &script->bindings);
|
||||
if (!Bindings::initWithTemporaryStorage(cx, bindings, 0, 0, 0,
|
||||
Rooted<Bindings> bindings(cx, script->bindings);
|
||||
if (!Bindings::initWithTemporaryStorage(cx, &bindings, 0, 0, 0,
|
||||
pc->blockScopeDepth, 0, 0, nullptr))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
script->bindings = bindings;
|
||||
|
||||
if (!JSScript::fullyInitFromEmitter(cx, script, &bce))
|
||||
return nullptr;
|
||||
|
|
|
@ -3414,8 +3414,7 @@ BytecodeEmitter::emitFunctionScript(ParseNode* body)
|
|||
switchToPrologue();
|
||||
if (!emit1(JSOP_ARGUMENTS))
|
||||
return false;
|
||||
InternalBindingsHandle bindings(script, &script->bindings);
|
||||
BindingIter bi = Bindings::argumentsBinding(cx, bindings);
|
||||
BindingIter bi = Bindings::argumentsBinding(cx, script);
|
||||
if (script->bindingIsAliased(bi)) {
|
||||
ScopeCoordinate sc;
|
||||
sc.setHops(0);
|
||||
|
|
|
@ -371,7 +371,7 @@ template <typename ParseHandler>
|
|||
bool
|
||||
ParseContext<ParseHandler>::generateFunctionBindings(ExclusiveContext* cx, TokenStream& ts,
|
||||
LifoAlloc& alloc,
|
||||
InternalHandle<Bindings*> bindings) const
|
||||
MutableHandle<Bindings> bindings) const
|
||||
{
|
||||
MOZ_ASSERT(sc->isFunctionBox());
|
||||
MOZ_ASSERT(args_.length() < ARGNO_LIMIT);
|
||||
|
@ -847,10 +847,10 @@ Parser<FullParseHandler>::standaloneFunctionBody(HandleFunction fun, const AutoN
|
|||
}
|
||||
}
|
||||
|
||||
InternalHandle<Bindings*> funboxBindings =
|
||||
InternalHandle<Bindings*>::fromMarkedLocation(&funbox->bindings);
|
||||
if (!funpc.generateFunctionBindings(context, tokenStream, alloc, funboxBindings))
|
||||
Rooted<Bindings> bindings(context, funbox->bindings);
|
||||
if (!funpc.generateFunctionBindings(context, tokenStream, alloc, &bindings))
|
||||
return null();
|
||||
funbox->bindings = bindings;
|
||||
|
||||
return fn;
|
||||
}
|
||||
|
@ -1470,9 +1470,12 @@ Parser<FullParseHandler>::leaveFunction(ParseNode* fn, ParseContext<FullParseHan
|
|||
}
|
||||
}
|
||||
|
||||
InternalHandle<Bindings*> bindings =
|
||||
InternalHandle<Bindings*>::fromMarkedLocation(&funbox->bindings);
|
||||
return pc->generateFunctionBindings(context, tokenStream, alloc, bindings);
|
||||
Rooted<Bindings> bindings(context, funbox->bindings);
|
||||
if (!pc->generateFunctionBindings(context, tokenStream, alloc, &bindings))
|
||||
return false;
|
||||
funbox->bindings = bindings;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <>
|
||||
|
@ -2492,10 +2495,10 @@ Parser<FullParseHandler>::standaloneLazyFunction(HandleFunction fun, unsigned st
|
|||
}
|
||||
}
|
||||
|
||||
InternalHandle<Bindings*> bindings =
|
||||
InternalHandle<Bindings*>::fromMarkedLocation(&funbox->bindings);
|
||||
if (!pc->generateFunctionBindings(context, tokenStream, alloc, bindings))
|
||||
Rooted<Bindings> bindings(context, funbox->bindings);
|
||||
if (!pc->generateFunctionBindings(context, tokenStream, alloc, &bindings))
|
||||
return null();
|
||||
funbox->bindings = bindings;
|
||||
|
||||
if (!FoldConstants(context, &pn, this))
|
||||
return null();
|
||||
|
|
|
@ -213,7 +213,7 @@ struct ParseContext : public GenericParseContext
|
|||
*/
|
||||
bool generateFunctionBindings(ExclusiveContext* cx, TokenStream& ts,
|
||||
LifoAlloc& alloc,
|
||||
InternalHandle<Bindings*> bindings) const;
|
||||
MutableHandle<Bindings> bindings) const;
|
||||
|
||||
private:
|
||||
ParseContext** parserPC; /* this points to the Parser's active pc
|
||||
|
|
|
@ -44,12 +44,6 @@ typedef RootedValueMap::Enum RootEnum;
|
|||
// GCC 4.4, since it requires template function parameters to have external
|
||||
// linkage.
|
||||
|
||||
void
|
||||
MarkBindingsRoot(JSTracer* trc, Bindings* bindings, const char* name)
|
||||
{
|
||||
bindings->trace(trc);
|
||||
}
|
||||
|
||||
void
|
||||
MarkPropertyDescriptorRoot(JSTracer* trc, JSPropertyDescriptor* pd, const char* name)
|
||||
{
|
||||
|
@ -87,7 +81,6 @@ MarkExactStackRootsAcrossTypes(T context, JSTracer* trc)
|
|||
MarkExactStackRootList<LazyScript*>(trc, context, "exact-lazy-script");
|
||||
MarkExactStackRootList<jsid>(trc, context, "exact-id");
|
||||
MarkExactStackRootList<Value>(trc, context, "exact-value");
|
||||
MarkExactStackRootList<Bindings, MarkBindingsRoot>(trc, context, "Bindings");
|
||||
MarkExactStackRootList<JSPropertyDescriptor, MarkPropertyDescriptorRoot>(
|
||||
trc, context, "JSPropertyDescriptor");
|
||||
MarkExactStackRootList<JS::StaticTraceable,
|
||||
|
|
|
@ -325,7 +325,6 @@ enum ThingRootKind
|
|||
THING_ROOT_LAZY_SCRIPT,
|
||||
THING_ROOT_ID,
|
||||
THING_ROOT_VALUE,
|
||||
THING_ROOT_BINDINGS,
|
||||
THING_ROOT_PROPERTY_DESCRIPTOR,
|
||||
THING_ROOT_PROP_DESC,
|
||||
THING_ROOT_STATIC_TRACEABLE,
|
||||
|
|
|
@ -61,24 +61,25 @@ using mozilla::PodZero;
|
|||
using mozilla::RotateLeft;
|
||||
|
||||
/* static */ BindingIter
|
||||
Bindings::argumentsBinding(ExclusiveContext* cx, InternalBindingsHandle bindings)
|
||||
Bindings::argumentsBinding(ExclusiveContext* cx, HandleScript script)
|
||||
{
|
||||
HandlePropertyName arguments = cx->names().arguments;
|
||||
BindingIter bi(bindings);
|
||||
BindingIter bi(script);
|
||||
while (bi->name() != arguments)
|
||||
bi++;
|
||||
return bi;
|
||||
}
|
||||
|
||||
bool
|
||||
Bindings::initWithTemporaryStorage(ExclusiveContext* cx, InternalBindingsHandle self,
|
||||
Bindings::initWithTemporaryStorage(ExclusiveContext* cx, MutableHandle<Bindings> self,
|
||||
uint32_t numArgs, uint32_t numVars,
|
||||
uint32_t numBodyLevelLexicals, uint32_t numBlockScoped,
|
||||
uint32_t numUnaliasedVars, uint32_t numUnaliasedBodyLevelLexicals,
|
||||
Binding* bindingArray)
|
||||
const Binding* bindingArray)
|
||||
{
|
||||
MOZ_ASSERT(!self->callObjShape_);
|
||||
MOZ_ASSERT(self->bindingArrayAndFlag_ == TEMPORARY_STORAGE_BIT);
|
||||
MOZ_ASSERT(!self.callObjShape());
|
||||
MOZ_ASSERT(self.bindingArrayUsingTemporaryStorage());
|
||||
MOZ_ASSERT(!self.bindingArray());
|
||||
MOZ_ASSERT(!(uintptr_t(bindingArray) & TEMPORARY_STORAGE_BIT));
|
||||
MOZ_ASSERT(numArgs <= ARGC_LIMIT);
|
||||
MOZ_ASSERT(numVars <= LOCALNO_LIMIT);
|
||||
|
@ -93,13 +94,13 @@ Bindings::initWithTemporaryStorage(ExclusiveContext* cx, InternalBindingsHandle
|
|||
MOZ_ASSERT(numUnaliasedVars <= numVars);
|
||||
MOZ_ASSERT(numUnaliasedBodyLevelLexicals <= numBodyLevelLexicals);
|
||||
|
||||
self->bindingArrayAndFlag_ = uintptr_t(bindingArray) | TEMPORARY_STORAGE_BIT;
|
||||
self->numArgs_ = numArgs;
|
||||
self->numVars_ = numVars;
|
||||
self->numBodyLevelLexicals_ = numBodyLevelLexicals;
|
||||
self->numBlockScoped_ = numBlockScoped;
|
||||
self->numUnaliasedVars_ = numUnaliasedVars;
|
||||
self->numUnaliasedBodyLevelLexicals_ = numUnaliasedBodyLevelLexicals;
|
||||
self.setBindingArray(bindingArray, TEMPORARY_STORAGE_BIT);
|
||||
self.setNumArgs(numArgs);
|
||||
self.setNumVars(numVars);
|
||||
self.setNumBodyLevelLexicals(numBodyLevelLexicals);
|
||||
self.setNumBlockScoped(numBlockScoped);
|
||||
self.setNumUnaliasedVars(numUnaliasedVars);
|
||||
self.setNumUnaliasedBodyLevelLexicals(numUnaliasedBodyLevelLexicals);
|
||||
|
||||
// Get the initial shape to use when creating CallObjects for this script.
|
||||
// After creation, a CallObject's shape may change completely (via direct eval() or
|
||||
|
@ -134,7 +135,7 @@ Bindings::initWithTemporaryStorage(ExclusiveContext* cx, InternalBindingsHandle
|
|||
nslots++;
|
||||
}
|
||||
}
|
||||
self->aliasedBodyLevelLexicalBegin_ = aliasedBodyLevelLexicalBegin;
|
||||
self.setAliasedBodyLevelLexicalBegin(aliasedBodyLevelLexicalBegin);
|
||||
|
||||
// Put as many of nslots inline into the object header as possible.
|
||||
uint32_t nfixed = gc::GetGCKindSlots(gc::GetGCObjectKind(nslots));
|
||||
|
@ -190,7 +191,7 @@ Bindings::initWithTemporaryStorage(ExclusiveContext* cx, InternalBindingsHandle
|
|||
MOZ_ASSERT(slot == nslots);
|
||||
|
||||
MOZ_ASSERT(!shape->inDictionary());
|
||||
self->callObjShape_.init(shape);
|
||||
self.setCallObjShape(shape);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -218,12 +219,12 @@ Bindings::switchToScriptStorage(Binding* newBindingArray)
|
|||
return reinterpret_cast<uint8_t*>(newBindingArray + count());
|
||||
}
|
||||
|
||||
bool
|
||||
Bindings::clone(JSContext* cx, InternalBindingsHandle self,
|
||||
/* static */ bool
|
||||
Bindings::clone(JSContext* cx, MutableHandle<Bindings> self,
|
||||
uint8_t* dstScriptData, HandleScript srcScript)
|
||||
{
|
||||
/* The clone has the same bindingArray_ offset as 'src'. */
|
||||
Bindings& src = srcScript->bindings;
|
||||
Handle<Bindings> src = Handle<Bindings>::fromMarkedLocation(&srcScript->bindings);
|
||||
ptrdiff_t off = (uint8_t*)src.bindingArray() - srcScript->data;
|
||||
MOZ_ASSERT(off >= 0);
|
||||
MOZ_ASSERT(size_t(off) <= srcScript->dataSize());
|
||||
|
@ -243,16 +244,10 @@ Bindings::clone(JSContext* cx, InternalBindingsHandle self,
|
|||
return false;
|
||||
}
|
||||
|
||||
self->switchToScriptStorage(dstPackedBindings);
|
||||
self.switchToScriptStorage(dstPackedBindings);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* static */ Bindings
|
||||
GCMethods<Bindings>::initial()
|
||||
{
|
||||
return Bindings();
|
||||
}
|
||||
|
||||
template<XDRMode mode>
|
||||
static bool
|
||||
XDRScriptBindings(XDRState<mode>* xdr, LifoAllocScope& las, uint16_t numArgs, uint32_t numVars,
|
||||
|
@ -302,14 +297,15 @@ XDRScriptBindings(XDRState<mode>* xdr, LifoAllocScope& las, uint16_t numArgs, ui
|
|||
bindingArray[i] = Binding(name, kind, aliased);
|
||||
}
|
||||
|
||||
InternalBindingsHandle bindings(script, &script->bindings);
|
||||
if (!Bindings::initWithTemporaryStorage(cx, bindings, numArgs, numVars,
|
||||
Rooted<Bindings> bindings(cx, script->bindings);
|
||||
if (!Bindings::initWithTemporaryStorage(cx, &bindings, numArgs, numVars,
|
||||
numBodyLevelLexicals, numBlockScoped,
|
||||
numUnaliasedVars, numUnaliasedBodyLevelLexicals,
|
||||
bindingArray))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
script->bindings = bindings;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -3125,9 +3121,7 @@ js::detail::CopyScript(JSContext* cx, HandleObject scriptStaticScope, HandleScri
|
|||
/* Bindings */
|
||||
|
||||
Rooted<Bindings> bindings(cx);
|
||||
InternalHandle<Bindings*> bindingsHandle =
|
||||
InternalHandle<Bindings*>::fromMarkedLocation(bindings.address());
|
||||
if (!Bindings::clone(cx, bindingsHandle, data, src))
|
||||
if (!Bindings::clone(cx, &bindings, data, src))
|
||||
return false;
|
||||
|
||||
/* Objects */
|
||||
|
@ -3712,8 +3706,7 @@ js::SetFrameArgumentsObject(JSContext* cx, AbstractFramePtr frame,
|
|||
* object. Note that 'arguments' may have already been overwritten.
|
||||
*/
|
||||
|
||||
InternalBindingsHandle bindings(script, &script->bindings);
|
||||
BindingIter bi = Bindings::argumentsBinding(cx, bindings);
|
||||
BindingIter bi = Bindings::argumentsBinding(cx, script);
|
||||
|
||||
if (script->bindingIsAliased(bi)) {
|
||||
/*
|
||||
|
|
|
@ -200,19 +200,18 @@ class Binding
|
|||
|
||||
JS_STATIC_ASSERT(sizeof(Binding) == sizeof(uintptr_t));
|
||||
|
||||
class Bindings;
|
||||
typedef InternalHandle<Bindings*> InternalBindingsHandle;
|
||||
|
||||
/*
|
||||
* Formal parameters and local variables are stored in a shape tree
|
||||
* path encapsulated within this class. This class represents bindings for
|
||||
* both function and top-level scripts (the latter is needed to track names in
|
||||
* strict mode eval code, to give such code its own lexical environment).
|
||||
*/
|
||||
class Bindings
|
||||
class Bindings : public JS::StaticTraceable
|
||||
{
|
||||
friend class BindingIter;
|
||||
friend class AliasedFormalIter;
|
||||
template <typename Outer> friend class BindingsOperations;
|
||||
template <typename Outer> friend class MutableBindingsOperations;
|
||||
|
||||
RelocatablePtrShape callObjShape_;
|
||||
uintptr_t bindingArrayAndFlag_;
|
||||
|
@ -250,7 +249,12 @@ class Bindings
|
|||
return reinterpret_cast<Binding*>(bindingArrayAndFlag_ & ~TEMPORARY_STORAGE_BIT);
|
||||
}
|
||||
|
||||
inline Bindings();
|
||||
Bindings()
|
||||
: callObjShape_(nullptr), bindingArrayAndFlag_(TEMPORARY_STORAGE_BIT),
|
||||
numArgs_(0), numBlockScoped_(0),
|
||||
numBodyLevelLexicals_(0), numUnaliasedBodyLevelLexicals_(0),
|
||||
numVars_(0), numUnaliasedVars_(0)
|
||||
{}
|
||||
|
||||
/*
|
||||
* Initialize a Bindings with a pointer into temporary storage.
|
||||
|
@ -259,11 +263,14 @@ class Bindings
|
|||
* switchToScriptStorage must be called, providing a pointer into the
|
||||
* Binding array stored in script->data.
|
||||
*/
|
||||
static bool initWithTemporaryStorage(ExclusiveContext* cx, InternalBindingsHandle self,
|
||||
uint32_t numArgs, uint32_t numVars,
|
||||
uint32_t numBodyLevelLexicals, uint32_t numBlockScoped,
|
||||
uint32_t numUnaliasedVars, uint32_t numUnaliasedBodyLevelLexicals,
|
||||
Binding* bindingArray);
|
||||
static bool initWithTemporaryStorage(ExclusiveContext* cx, MutableHandle<Bindings> self,
|
||||
uint32_t numArgs,
|
||||
uint32_t numVars,
|
||||
uint32_t numBodyLevelLexicals,
|
||||
uint32_t numBlockScoped,
|
||||
uint32_t numUnaliasedVars,
|
||||
uint32_t numUnaliasedBodyLevelLexicals,
|
||||
const Binding* bindingArray);
|
||||
|
||||
// Initialize a trivial Bindings with no slots and an empty callObjShape.
|
||||
bool initTrivial(ExclusiveContext* cx);
|
||||
|
@ -292,7 +299,7 @@ class Bindings
|
|||
* Clone srcScript's bindings (as part of js::CloneScript). dstScriptData
|
||||
* is the pointer to what will eventually be dstScript->data.
|
||||
*/
|
||||
static bool clone(JSContext* cx, InternalBindingsHandle self, uint8_t* dstScriptData,
|
||||
static bool clone(JSContext* cx, MutableHandle<Bindings> self, uint8_t* dstScriptData,
|
||||
HandleScript srcScript);
|
||||
|
||||
uint32_t numArgs() const { return numArgs_; }
|
||||
|
@ -317,7 +324,7 @@ class Bindings
|
|||
Shape* callObjShape() const { return callObjShape_; }
|
||||
|
||||
/* Convenience method to get the var index of 'arguments'. */
|
||||
static BindingIter argumentsBinding(ExclusiveContext* cx, InternalBindingsHandle);
|
||||
static BindingIter argumentsBinding(ExclusiveContext* cx, HandleScript script);
|
||||
|
||||
/* Return whether the binding at bindingIndex is aliased. */
|
||||
bool bindingIsAliased(uint32_t bindingIndex);
|
||||
|
@ -333,13 +340,122 @@ class Bindings
|
|||
Binding* begin() const { return bindingArray(); }
|
||||
Binding* end() const { return bindingArray() + count(); }
|
||||
|
||||
static js::ThingRootKind rootKind() { return js::THING_ROOT_BINDINGS; }
|
||||
static void trace(Bindings* self, JSTracer* trc) { self->trace(trc); }
|
||||
void trace(JSTracer* trc);
|
||||
};
|
||||
|
||||
template <class Outer>
|
||||
class BindingsOperations
|
||||
{
|
||||
const Bindings& bindings() const { return static_cast<const Outer*>(this)->extract(); }
|
||||
|
||||
public:
|
||||
// Direct data access to the underlying bindings.
|
||||
const RelocatablePtrShape& callObjShape() const {
|
||||
return bindings().callObjShape_;
|
||||
}
|
||||
uint16_t numArgs() const {
|
||||
return bindings().numArgs_;
|
||||
}
|
||||
uint16_t numBlockScoped() const {
|
||||
return bindings().numBlockScoped_;
|
||||
}
|
||||
uint16_t numBodyLevelLexicals() const {
|
||||
return bindings().numBodyLevelLexicals_;
|
||||
}
|
||||
uint16_t aliasedBodyLevelLexicalBegin() const {
|
||||
return bindings().aliasedBodyLevelLexicalBegin_;
|
||||
}
|
||||
uint16_t numUnaliasedBodyLevelLexicals() const {
|
||||
return bindings().numUnaliasedBodyLevelLexicals_;
|
||||
}
|
||||
uint32_t numVars() const {
|
||||
return bindings().numVars_;
|
||||
}
|
||||
uint32_t numUnaliasedVars() const {
|
||||
return bindings().numUnaliasedVars_;
|
||||
}
|
||||
|
||||
// Binding array access.
|
||||
bool bindingArrayUsingTemporaryStorage() const {
|
||||
return bindings().bindingArrayUsingTemporaryStorage();
|
||||
}
|
||||
const Binding* bindingArray() const {
|
||||
return bindings().bindingArray();
|
||||
}
|
||||
uint32_t count() const {
|
||||
return bindings().count();
|
||||
}
|
||||
|
||||
// Helpers.
|
||||
uint32_t numBodyLevelLocals() const {
|
||||
return numVars() + numBodyLevelLexicals();
|
||||
}
|
||||
uint32_t numUnaliasedBodyLevelLocals() const {
|
||||
return numUnaliasedVars() + numUnaliasedBodyLevelLexicals();
|
||||
}
|
||||
uint32_t numAliasedBodyLevelLocals() const {
|
||||
return numBodyLevelLocals() - numUnaliasedBodyLevelLocals();
|
||||
}
|
||||
uint32_t numLocals() const {
|
||||
return numVars() + numBodyLevelLexicals() + numBlockScoped();
|
||||
}
|
||||
uint32_t numFixedLocals() const {
|
||||
return numUnaliasedVars() + numUnaliasedBodyLevelLexicals() + numBlockScoped();
|
||||
}
|
||||
uint32_t lexicalBegin() const {
|
||||
return numArgs() + numVars();
|
||||
}
|
||||
};
|
||||
|
||||
template <class Outer>
|
||||
class MutableBindingsOperations : public BindingsOperations<Outer>
|
||||
{
|
||||
Bindings& bindings() { return static_cast<Outer*>(this)->extractMutable(); }
|
||||
|
||||
public:
|
||||
void setCallObjShape(HandleShape shape) { bindings().callObjShape_ = shape; }
|
||||
void setBindingArray(const Binding* bindingArray, uintptr_t temporaryBit) {
|
||||
bindings().bindingArrayAndFlag_ = uintptr_t(bindingArray) | temporaryBit;
|
||||
}
|
||||
void setNumArgs(uint16_t num) { bindings().numArgs_ = num; }
|
||||
void setNumVars(uint32_t num) { bindings().numVars_ = num; }
|
||||
void setNumBodyLevelLexicals(uint16_t num) { bindings().numBodyLevelLexicals_ = num; }
|
||||
void setNumBlockScoped(uint16_t num) { bindings().numBlockScoped_ = num; }
|
||||
void setNumUnaliasedVars(uint32_t num) { bindings().numUnaliasedVars_ = num; }
|
||||
void setNumUnaliasedBodyLevelLexicals(uint16_t num) {
|
||||
bindings().numUnaliasedBodyLevelLexicals_ = num;
|
||||
}
|
||||
void setAliasedBodyLevelLexicalBegin(uint16_t offset) {
|
||||
bindings().aliasedBodyLevelLexicalBegin_ = offset;
|
||||
}
|
||||
uint8_t* switchToScriptStorage(Binding* permanentStorage) {
|
||||
return bindings().switchToScriptStorage(permanentStorage);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct GCMethods<Bindings> {
|
||||
static Bindings initial();
|
||||
class HandleBase<Bindings> : public BindingsOperations<JS::Handle<Bindings>>
|
||||
{
|
||||
friend class BindingsOperations<JS::Handle<Bindings>>;
|
||||
const Bindings& extract() const {
|
||||
return static_cast<const JS::Handle<Bindings>*>(this)->get();
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
class MutableHandleBase<Bindings>
|
||||
: public MutableBindingsOperations<JS::MutableHandle<Bindings>>
|
||||
{
|
||||
friend class BindingsOperations<JS::MutableHandle<Bindings>>;
|
||||
const Bindings& extract() const {
|
||||
return static_cast<const JS::MutableHandle<Bindings>*>(this)->get();
|
||||
}
|
||||
|
||||
friend class MutableBindingsOperations<JS::MutableHandle<Bindings>>;
|
||||
Bindings& extractMutable() {
|
||||
return static_cast<JS::MutableHandle<Bindings>*>(this)->get();
|
||||
}
|
||||
};
|
||||
|
||||
class ScriptCounts
|
||||
|
@ -1782,7 +1898,7 @@ namespace js {
|
|||
*/
|
||||
class BindingIter
|
||||
{
|
||||
const InternalBindingsHandle bindings_;
|
||||
Handle<Bindings> bindings_;
|
||||
uint32_t i_;
|
||||
uint32_t unaliasedLocal_;
|
||||
|
||||
|
@ -1790,12 +1906,16 @@ class BindingIter
|
|||
friend class Bindings;
|
||||
|
||||
public:
|
||||
explicit BindingIter(const InternalBindingsHandle& bindings)
|
||||
: bindings_(bindings), i_(0), unaliasedLocal_(0) {}
|
||||
explicit BindingIter(const HandleScript& script)
|
||||
: bindings_(script, &script->bindings), i_(0), unaliasedLocal_(0) {}
|
||||
explicit BindingIter(Handle<Bindings> bindings)
|
||||
: bindings_(bindings), i_(0), unaliasedLocal_(0)
|
||||
{}
|
||||
|
||||
bool done() const { return i_ == bindings_->count(); }
|
||||
explicit BindingIter(const HandleScript& script)
|
||||
: bindings_(Handle<Bindings>::fromMarkedLocation(&script->bindings)),
|
||||
i_(0), unaliasedLocal_(0)
|
||||
{}
|
||||
|
||||
bool done() const { return i_ == bindings_.count(); }
|
||||
explicit operator bool() const { return !done(); }
|
||||
BindingIter& operator++() { (*this)++; return *this; }
|
||||
|
||||
|
@ -1813,7 +1933,7 @@ class BindingIter
|
|||
// has no stack slot.
|
||||
uint32_t frameIndex() const {
|
||||
MOZ_ASSERT(!done());
|
||||
if (i_ < bindings_->numArgs())
|
||||
if (i_ < bindings_.numArgs())
|
||||
return i_;
|
||||
MOZ_ASSERT(!(*this)->aliased());
|
||||
return unaliasedLocal_;
|
||||
|
@ -1824,17 +1944,17 @@ class BindingIter
|
|||
// both unaliased and aliased arguments.
|
||||
uint32_t argIndex() const {
|
||||
MOZ_ASSERT(!done());
|
||||
MOZ_ASSERT(i_ < bindings_->numArgs());
|
||||
MOZ_ASSERT(i_ < bindings_.numArgs());
|
||||
return i_;
|
||||
}
|
||||
uint32_t argOrLocalIndex() const {
|
||||
MOZ_ASSERT(!done());
|
||||
return i_ < bindings_->numArgs() ? i_ : i_ - bindings_->numArgs();
|
||||
return i_ < bindings_.numArgs() ? i_ : i_ - bindings_.numArgs();
|
||||
}
|
||||
uint32_t localIndex() const {
|
||||
MOZ_ASSERT(!done());
|
||||
MOZ_ASSERT(i_ >= bindings_->numArgs());
|
||||
return i_ - bindings_->numArgs();
|
||||
MOZ_ASSERT(i_ >= bindings_.numArgs());
|
||||
return i_ - bindings_.numArgs();
|
||||
}
|
||||
bool isBodyLevelLexical() const {
|
||||
MOZ_ASSERT(!done());
|
||||
|
@ -1842,8 +1962,8 @@ class BindingIter
|
|||
return binding.kind() != Binding::ARGUMENT;
|
||||
}
|
||||
|
||||
const Binding& operator*() const { MOZ_ASSERT(!done()); return bindings_->bindingArray()[i_]; }
|
||||
const Binding* operator->() const { MOZ_ASSERT(!done()); return &bindings_->bindingArray()[i_]; }
|
||||
const Binding& operator*() const { MOZ_ASSERT(!done()); return bindings_.bindingArray()[i_]; }
|
||||
const Binding* operator->() const { MOZ_ASSERT(!done()); return &bindings_.bindingArray()[i_]; }
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -20,14 +20,6 @@
|
|||
|
||||
namespace js {
|
||||
|
||||
inline
|
||||
Bindings::Bindings()
|
||||
: callObjShape_(nullptr), bindingArrayAndFlag_(TEMPORARY_STORAGE_BIT),
|
||||
numArgs_(0), numBlockScoped_(0),
|
||||
numBodyLevelLexicals_(0), numUnaliasedBodyLevelLexicals_(0),
|
||||
numVars_(0), numUnaliasedVars_(0)
|
||||
{}
|
||||
|
||||
inline
|
||||
AliasedFormalIter::AliasedFormalIter(JSScript* script)
|
||||
: begin_(script->bindingArray()),
|
||||
|
|
Загрузка…
Ссылка в новой задаче