mirror of
https://github.com/classilla/tenfourfox.git
synced 2024-06-25 20:29:33 +00:00
259 lines
7.5 KiB
C++
259 lines
7.5 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
* vim: set ts=8 sts=4 et sw=4 tw=99:
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#ifndef vm_ScopeObject_inl_h
|
|
#define vm_ScopeObject_inl_h
|
|
|
|
#include "vm/ScopeObject.h"
|
|
#include "frontend/SharedContext.h"
|
|
|
|
#include "jsobjinlines.h"
|
|
|
|
#include "vm/TypeInference-inl.h"
|
|
|
|
namespace js {
|
|
|
|
inline ClonedBlockObject&
|
|
NearestEnclosingExtensibleLexicalScope(JSObject* scope)
|
|
{
|
|
while (!IsExtensibleLexicalScope(scope))
|
|
scope = scope->enclosingScope();
|
|
return scope->as<ClonedBlockObject>();
|
|
}
|
|
|
|
inline void
|
|
ScopeObject::setAliasedVar(JSContext* cx, ScopeCoordinate sc, PropertyName* name, const Value& v)
|
|
{
|
|
MOZ_ASSERT(is<LexicalScopeBase>() || is<ClonedBlockObject>());
|
|
JS_STATIC_ASSERT(CallObject::RESERVED_SLOTS == BlockObject::RESERVED_SLOTS);
|
|
|
|
// name may be null if we don't need to track side effects on the object.
|
|
MOZ_ASSERT_IF(isSingleton(), name);
|
|
|
|
if (isSingleton()) {
|
|
MOZ_ASSERT(name);
|
|
AddTypePropertyId(cx, this, NameToId(name), v);
|
|
|
|
// Keep track of properties which have ever been overwritten.
|
|
if (!getSlot(sc.slot()).isUndefined()) {
|
|
Shape* shape = lookup(cx, name);
|
|
shape->setOverwritten();
|
|
}
|
|
}
|
|
|
|
setSlot(sc.slot(), v);
|
|
}
|
|
|
|
inline void
|
|
LexicalScopeBase::setAliasedVar(JSContext* cx, AliasedFormalIter fi, PropertyName* name,
|
|
const Value& v)
|
|
{
|
|
MOZ_ASSERT(name == fi->name());
|
|
setSlot(fi.scopeSlot(), v);
|
|
if (isSingleton())
|
|
AddTypePropertyId(cx, this, NameToId(name), v);
|
|
}
|
|
|
|
inline void
|
|
LexicalScopeBase::setAliasedVarFromArguments(JSContext* cx, const Value& argsValue, jsid id,
|
|
const Value& v)
|
|
{
|
|
setSlot(ArgumentsObject::SlotFromMagicScopeSlotValue(argsValue), v);
|
|
if (isSingleton())
|
|
AddTypePropertyId(cx, this, id, v);
|
|
}
|
|
|
|
inline void
|
|
LexicalScopeBase::initRemainingSlotsToUninitializedLexicals(uint32_t begin)
|
|
{
|
|
uint32_t end = slotSpan();
|
|
for (uint32_t slot = begin; slot < end; slot++)
|
|
initSlot(slot, MagicValue(JS_UNINITIALIZED_LEXICAL));
|
|
}
|
|
|
|
inline void
|
|
LexicalScopeBase::initAliasedLexicalsToThrowOnTouch(JSScript* script)
|
|
{
|
|
initRemainingSlotsToUninitializedLexicals(script->bindings.aliasedBodyLevelLexicalBegin());
|
|
}
|
|
|
|
template <AllowGC allowGC>
|
|
inline void
|
|
StaticScopeIter<allowGC>::operator++(int)
|
|
{
|
|
if (obj->template is<NestedScopeObject>()) {
|
|
obj = obj->template as<NestedScopeObject>().enclosingScopeForStaticScopeIter();
|
|
} else if (obj->template is<StaticEvalObject>()) {
|
|
obj = obj->template as<StaticEvalObject>().enclosingScopeForStaticScopeIter();
|
|
} else if (obj->template is<StaticNonSyntacticScopeObjects>()) {
|
|
obj = obj->template as<StaticNonSyntacticScopeObjects>().enclosingScopeForStaticScopeIter();
|
|
} else if (obj->template is<ModuleObject>()) {
|
|
obj = obj->template as<ModuleObject>().enclosingStaticScope();
|
|
} else if (onNamedLambda || !obj->template as<JSFunction>().isNamedLambda()) {
|
|
onNamedLambda = false;
|
|
JSFunction& fun = obj->template as<JSFunction>();
|
|
if (fun.isBeingParsed())
|
|
obj = fun.functionBox()->enclosingStaticScope();
|
|
else
|
|
obj = fun.nonLazyScript()->enclosingStaticScope();
|
|
} else {
|
|
onNamedLambda = true;
|
|
}
|
|
MOZ_ASSERT_IF(obj, IsStaticScope(obj));
|
|
MOZ_ASSERT_IF(onNamedLambda, obj->template is<JSFunction>());
|
|
}
|
|
|
|
template <AllowGC allowGC>
|
|
inline bool
|
|
StaticScopeIter<allowGC>::hasSyntacticDynamicScopeObject() const
|
|
{
|
|
if (obj->template is<JSFunction>()) {
|
|
JSFunction& fun = obj->template as<JSFunction>();
|
|
if (fun.isBeingParsed())
|
|
return fun.functionBox()->needsCallObject();
|
|
return fun.needsCallObject();
|
|
}
|
|
if (obj->template is<ModuleObject>())
|
|
return true;
|
|
if (obj->template is<StaticBlockObject>()) {
|
|
return obj->template as<StaticBlockObject>().needsClone() ||
|
|
obj->template as<StaticBlockObject>().isGlobal();
|
|
}
|
|
if (obj->template is<StaticWithObject>())
|
|
return true;
|
|
if (obj->template is<StaticEvalObject>())
|
|
return obj->template as<StaticEvalObject>().isStrict();
|
|
MOZ_ASSERT(obj->template is<StaticNonSyntacticScopeObjects>());
|
|
return false;
|
|
}
|
|
|
|
template <AllowGC allowGC>
|
|
inline Shape*
|
|
StaticScopeIter<allowGC>::scopeShape() const
|
|
{
|
|
MOZ_ASSERT(hasSyntacticDynamicScopeObject());
|
|
MOZ_ASSERT(type() != NamedLambda && type() != Eval);
|
|
if (type() == Block)
|
|
return block().lastProperty();
|
|
if (type() == Module)
|
|
return moduleScript()->callObjShape();
|
|
return funScript()->callObjShape();
|
|
}
|
|
|
|
template <AllowGC allowGC>
|
|
inline typename StaticScopeIter<allowGC>::Type
|
|
StaticScopeIter<allowGC>::type() const
|
|
{
|
|
if (onNamedLambda)
|
|
return NamedLambda;
|
|
if (obj->template is<StaticBlockObject>())
|
|
return Block;
|
|
if (obj->template is<StaticWithObject>())
|
|
return With;
|
|
if (obj->template is<StaticEvalObject>())
|
|
return Eval;
|
|
if (obj->template is<StaticNonSyntacticScopeObjects>())
|
|
return NonSyntactic;
|
|
if (obj->template is<ModuleObject>())
|
|
return Module;
|
|
MOZ_ASSERT(obj->template is<JSFunction>());
|
|
return Function;
|
|
}
|
|
|
|
template <AllowGC allowGC>
|
|
inline StaticBlockObject&
|
|
StaticScopeIter<allowGC>::block() const
|
|
{
|
|
MOZ_ASSERT(type() == Block);
|
|
return obj->template as<StaticBlockObject>();
|
|
}
|
|
|
|
template <AllowGC allowGC>
|
|
inline StaticWithObject&
|
|
StaticScopeIter<allowGC>::staticWith() const
|
|
{
|
|
MOZ_ASSERT(type() == With);
|
|
return obj->template as<StaticWithObject>();
|
|
}
|
|
|
|
template <AllowGC allowGC>
|
|
inline StaticEvalObject&
|
|
StaticScopeIter<allowGC>::eval() const
|
|
{
|
|
MOZ_ASSERT(type() == Eval);
|
|
return obj->template as<StaticEvalObject>();
|
|
}
|
|
|
|
template <AllowGC allowGC>
|
|
inline StaticNonSyntacticScopeObjects&
|
|
StaticScopeIter<allowGC>::nonSyntactic() const
|
|
{
|
|
MOZ_ASSERT(type() == NonSyntactic);
|
|
return obj->template as<StaticNonSyntacticScopeObjects>();
|
|
}
|
|
|
|
template <AllowGC allowGC>
|
|
inline JSScript*
|
|
StaticScopeIter<allowGC>::funScript() const
|
|
{
|
|
MOZ_ASSERT(type() == Function);
|
|
return obj->template as<JSFunction>().nonLazyScript();
|
|
}
|
|
|
|
template <AllowGC allowGC>
|
|
inline JSFunction&
|
|
StaticScopeIter<allowGC>::fun() const
|
|
{
|
|
MOZ_ASSERT(type() == Function);
|
|
return obj->template as<JSFunction>();
|
|
}
|
|
|
|
template <AllowGC allowGC>
|
|
inline frontend::FunctionBox*
|
|
StaticScopeIter<allowGC>::maybeFunctionBox() const
|
|
{
|
|
MOZ_ASSERT(type() == Function);
|
|
if (fun().isBeingParsed())
|
|
return fun().functionBox();
|
|
return nullptr;
|
|
}
|
|
|
|
template <AllowGC allowGC>
|
|
inline JSScript*
|
|
StaticScopeIter<allowGC>::moduleScript() const
|
|
{
|
|
MOZ_ASSERT(type() == Module);
|
|
return obj->template as<ModuleObject>().script();
|
|
}
|
|
|
|
template <AllowGC allowGC>
|
|
inline ModuleObject&
|
|
StaticScopeIter<allowGC>::module() const
|
|
{
|
|
MOZ_ASSERT(type() == Module);
|
|
return obj->template as<ModuleObject>();
|
|
}
|
|
|
|
} /* namespace js */
|
|
|
|
inline JSObject*
|
|
JSObject::enclosingScope()
|
|
{
|
|
if (is<js::ScopeObject>())
|
|
return &as<js::ScopeObject>().enclosingScope();
|
|
|
|
if (is<js::DebugScopeObject>())
|
|
return &as<js::DebugScopeObject>().enclosingScope();
|
|
|
|
if (is<js::GlobalObject>())
|
|
return nullptr;
|
|
|
|
MOZ_ASSERT_IF(is<JSFunction>(), as<JSFunction>().isInterpreted());
|
|
return &global();
|
|
}
|
|
|
|
#endif /* vm_ScopeObject_inl_h */
|