#ifndef CallFrame_h
#define CallFrame_h
#include "JSGlobalData.h"
#include "RegisterFile.h"
#include "ScopeChain.h"
namespace JSC {
class Arguments;
class JSActivation;
class Interpreter;
class ExecState : private Register {
public:
JSFunction* callee() const { return this[RegisterFile::Callee].function(); }
CodeBlock* codeBlock() const { return this[RegisterFile::CodeBlock].Register::codeBlock(); }
ScopeChainNode* scopeChain() const { return this[RegisterFile::ScopeChain].Register::scopeChain(); }
JSValuePtr thisValue();
JSGlobalObject* dynamicGlobalObject();
JSGlobalObject* lexicalGlobalObject() const
{
return scopeChain()->globalObject();
}
JSObject* globalThisValue() const
{
return scopeChain()->globalThisObject();
}
JSGlobalData& globalData() const
{
return *scopeChain()->globalData;
}
void setException(JSValuePtr exception) { globalData().exception = exception; }
void clearException() { globalData().exception = noValue(); }
JSValuePtr exception() const { return globalData().exception; }
JSValuePtr* exceptionSlot() { return &globalData().exception; }
bool hadException() const { return globalData().exception; }
const CommonIdentifiers& propertyNames() const { return *globalData().propertyNames; }
const ArgList& emptyList() const { return *globalData().emptyList; }
Interpreter* interpreter() { return globalData().interpreter; }
Heap* heap() { return &globalData().heap; }
static const HashTable* arrayTable(CallFrame* callFrame) { return callFrame->globalData().arrayTable; }
static const HashTable* dateTable(CallFrame* callFrame) { return callFrame->globalData().dateTable; }
static const HashTable* mathTable(CallFrame* callFrame) { return callFrame->globalData().mathTable; }
static const HashTable* numberTable(CallFrame* callFrame) { return callFrame->globalData().numberTable; }
static const HashTable* regExpTable(CallFrame* callFrame) { return callFrame->globalData().regExpTable; }
static const HashTable* regExpConstructorTable(CallFrame* callFrame) { return callFrame->globalData().regExpConstructorTable; }
static const HashTable* stringTable(CallFrame* callFrame) { return callFrame->globalData().stringTable; }
private:
friend class Arguments;
friend class JSActivation;
friend class JSGlobalObject;
friend class Interpreter;
static CallFrame* create(Register* callFrameBase) { return static_cast<CallFrame*>(callFrameBase); }
Register* registers() { return this; }
CallFrame& operator=(const Register& r) { *static_cast<Register*>(this) = r; return *this; }
int argumentCount() const { return this[RegisterFile::ArgumentCount].i(); }
CallFrame* callerFrame() const { return this[RegisterFile::CallerFrame].callFrame(); }
Arguments* optionalCalleeArguments() const { return this[RegisterFile::OptionalCalleeArguments].arguments(); }
Instruction* returnPC() const { return this[RegisterFile::ReturnPC].vPC(); }
int returnValueRegister() const { return this[RegisterFile::ReturnValueRegister].i(); }
void setArgumentCount(int count) { this[RegisterFile::ArgumentCount] = count; }
void setCallee(JSFunction* callee) { this[RegisterFile::Callee] = callee; }
void setCalleeArguments(Arguments* arguments) { this[RegisterFile::OptionalCalleeArguments] = arguments; }
void setCallerFrame(CallFrame* callerFrame) { this[RegisterFile::CallerFrame] = callerFrame; }
void setCodeBlock(CodeBlock* codeBlock) { this[RegisterFile::CodeBlock] = codeBlock; }
void setScopeChain(ScopeChainNode* scopeChain) { this[RegisterFile::ScopeChain] = scopeChain; }
ALWAYS_INLINE void init(CodeBlock* codeBlock, Instruction* vPC, ScopeChainNode* scopeChain,
CallFrame* callerFrame, int returnValueRegister, int argc, JSFunction* function)
{
ASSERT(callerFrame);
setCodeBlock(codeBlock);
setScopeChain(scopeChain);
setCallerFrame(callerFrame);
this[RegisterFile::ReturnPC] = vPC; this[RegisterFile::ReturnValueRegister] = returnValueRegister;
setArgumentCount(argc); setCallee(function);
setCalleeArguments(0);
}
static const intptr_t HostCallFrameFlag = 1;
static CallFrame* noCaller() { return reinterpret_cast<CallFrame*>(HostCallFrameFlag); }
bool hasHostCallFrameFlag() const { return reinterpret_cast<intptr_t>(this) & HostCallFrameFlag; }
CallFrame* addHostCallFrameFlag() const { return reinterpret_cast<CallFrame*>(reinterpret_cast<intptr_t>(this) | HostCallFrameFlag); }
CallFrame* removeHostCallFrameFlag() { return reinterpret_cast<CallFrame*>(reinterpret_cast<intptr_t>(this) & ~HostCallFrameFlag); }
ExecState();
~ExecState();
};
}
#endif // CallFrame_h