DFGAbstractInterpreter.h [plain text]
#ifndef DFGAbstractInterpreter_h
#define DFGAbstractInterpreter_h
#if ENABLE(DFG_JIT)
#include "DFGAbstractValue.h"
#include "DFGBranchDirection.h"
#include "DFGGraph.h"
#include "DFGNode.h"
namespace JSC { namespace DFG {
template<typename AbstractStateType>
class AbstractInterpreter {
public:
AbstractInterpreter(Graph&, AbstractStateType&);
~AbstractInterpreter();
AbstractValue& forNode(Node* node)
{
return m_state.forNode(node);
}
AbstractValue& forNode(Edge edge)
{
return forNode(edge.node());
}
Operands<AbstractValue>& variables()
{
return m_state.variables();
}
bool needsTypeCheck(Node* node, SpeculatedType typesPassedThrough)
{
return !forNode(node).isType(typesPassedThrough);
}
bool needsTypeCheck(Edge edge, SpeculatedType typesPassedThrough)
{
return needsTypeCheck(edge.node(), typesPassedThrough);
}
bool needsTypeCheck(Edge edge)
{
return needsTypeCheck(edge, typeFilterFor(edge.useKind()));
}
bool execute(unsigned indexInBlock);
bool execute(Node*);
bool startExecuting(Node*);
bool startExecuting(unsigned indexInBlock);
void executeEdges(Node*);
void executeEdges(unsigned indexInBlock);
ALWAYS_INLINE void filterEdgeByUse(Node* node, Edge& edge)
{
ASSERT(mayHaveTypeCheck(edge.useKind()) || !needsTypeCheck(edge));
filterByType(node, edge, typeFilterFor(edge.useKind()));
}
bool executeEffects(unsigned indexInBlock);
bool executeEffects(unsigned clobberLimit, Node*);
void dump(PrintStream& out);
template<typename T>
FiltrationResult filter(T node, const StructureSet& set)
{
return filter(forNode(node), set);
}
template<typename T>
FiltrationResult filterArrayModes(T node, ArrayModes arrayModes)
{
return filterArrayModes(forNode(node), arrayModes);
}
template<typename T>
FiltrationResult filter(T node, SpeculatedType type)
{
return filter(forNode(node), type);
}
template<typename T>
FiltrationResult filterByValue(T node, JSValue value)
{
return filterByValue(forNode(node), value);
}
FiltrationResult filter(AbstractValue&, const StructureSet&);
FiltrationResult filterArrayModes(AbstractValue&, ArrayModes);
FiltrationResult filter(AbstractValue&, SpeculatedType);
FiltrationResult filterByValue(AbstractValue&, JSValue);
private:
void clobberWorld(const CodeOrigin&, unsigned indexInBlock);
void clobberCapturedVars(const CodeOrigin&);
void clobberStructures(unsigned indexInBlock);
enum BooleanResult {
UnknownBooleanResult,
DefinitelyFalse,
DefinitelyTrue
};
BooleanResult booleanResult(Node*, AbstractValue&);
void setBuiltInConstant(Node* node, JSValue value)
{
AbstractValue& abstractValue = forNode(node);
abstractValue.set(m_graph, value);
abstractValue.fixTypeForRepresentation(node);
}
void setConstant(Node* node, JSValue value)
{
setBuiltInConstant(node, value);
m_state.setFoundConstants(true);
}
ALWAYS_INLINE void filterByType(Node* node, Edge& edge, SpeculatedType type)
{
AbstractValue& value = forNode(edge);
if (!value.isType(type)) {
node->setCanExit(true);
edge.setProofStatus(NeedsCheck);
} else
edge.setProofStatus(IsProved);
filter(value, type);
}
void verifyEdge(Node*, Edge);
void verifyEdges(Node*);
CodeBlock* m_codeBlock;
Graph& m_graph;
AbstractStateType& m_state;
};
} }
#endif // ENABLE(DFG_JIT)
#endif // DFGAbstractInterpreter_h