#include "config.h"
#include "DFGMayExit.h"
#if ENABLE(DFG_JIT)
#include "DFGAtTailAbstractState.h"
#include "DFGGraph.h"
#include "DFGNode.h"
#include "DFGNullAbstractState.h"
#include "Operations.h"
namespace JSC { namespace DFG {
namespace {
template<typename StateType>
ExitMode mayExitImpl(Graph& graph, Node* node, StateType& state)
{
ExitMode result = DoesNotExit;
switch (node->op()) {
case SetArgument:
case JSConstant:
case DoubleConstant:
case LazyJSConstant:
case Int52Constant:
case MovHint:
case SetLocal:
case Flush:
case Phantom:
case Check:
case Identity:
case GetLocal:
case LoopHint:
case Phi:
case Upsilon:
case ZombieHint:
case ExitOK:
case BottomValue:
case PutHint:
case PhantomNewObject:
case PutStack:
case KillStack:
case GetStack:
case GetCallee:
case GetArgumentCountIncludingThis:
case GetRestLength:
case GetScope:
case PhantomLocal:
case CountExecution:
case Jump:
case Branch:
case Unreachable:
case DoubleRep:
case Int52Rep:
case ValueRep:
case ExtractOSREntryLocal:
case LogicalNot:
case NotifyWrite:
case PutStructure:
case StoreBarrier:
case FencedStoreBarrier:
case PutByOffset:
case PutClosureVar:
case RecordRegExpCachedResult:
case NukeStructureAndSetButterfly:
break;
case StrCat:
case Call:
case Construct:
case CallVarargs:
case CallEval:
case ConstructVarargs:
case CallForwardVarargs:
case ConstructForwardVarargs:
case CreateActivation:
case MaterializeCreateActivation:
case MaterializeNewObject:
case NewFunction:
case NewGeneratorFunction:
case NewAsyncFunction:
case NewStringObject:
case ToNumber:
result = ExitsForExceptions;
break;
default:
return Exits;
}
graph.doToChildren(
node,
[&] (Edge& edge) {
if (state) {
if (mayHaveTypeCheck(edge.useKind())
&& (state.forNode(edge).m_type & ~typeFilterFor(edge.useKind()))) {
result = Exits;
return;
}
} else {
if (edge.willHaveCheck()) {
result = Exits;
return;
}
}
switch (edge.useKind()) {
case ObjectUse:
case ObjectOrOtherUse:
result = Exits;
break;
case StringObjectUse:
case StringOrStringObjectUse:
result = Exits;
break;
default:
break;
}
});
return result;
}
}
ExitMode mayExit(Graph& graph, Node* node)
{
NullAbstractState state;
return mayExitImpl(graph, node, state);
}
ExitMode mayExit(Graph& graph, Node* node, AtTailAbstractState& state)
{
return mayExitImpl(graph, node, state);
}
} }
namespace WTF {
using namespace JSC::DFG;
void printInternal(PrintStream& out, ExitMode mode)
{
switch (mode) {
case DoesNotExit:
out.print("DoesNotExit");
return;
case ExitsForExceptions:
out.print("ExitsForExceptions");
return;
case Exits:
out.print("Exits");
return;
}
RELEASE_ASSERT_NOT_REACHED();
}
}
#endif // ENABLE(DFG_JIT)