forked from facebook/hhvm
/
eval_state.h
223 lines (199 loc) · 8.2 KB
/
eval_state.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
/*
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010- Facebook, Inc. (http://www.facebook.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
*/
#ifndef __EVAL_STATE_H__
#define __EVAL_STATE_H__
#include <runtime/eval/base/eval_base.h>
#include <runtime/base/class_info.h>
#include <runtime/eval/runtime/variant_stack.h>
#include <util/case_insensitive.h>
#include <util/atomic.h>
namespace HPHP {
namespace Eval {
///////////////////////////////////////////////////////////////////////////////
DECLARE_AST_PTR(ClassStatement);
DECLARE_AST_PTR(FunctionStatement);
DECLARE_AST_PTR(MethodStatement);
DECLARE_AST_PTR(Statement);
class PhpFile;
class Function;
class EvalObjectData;
class ClassEvalState {
public:
typedef hphp_const_char_imap<std::pair<const MethodStatement*, int> >
MethodTable;
ClassEvalState() : m_class(NULL), m_constructor(NULL),
m_initializedInstance(false),
m_initializedStatics(false),
m_doneSemanticCheck(false)
{}
void init(const ClassStatement *cls);
const ClassStatement *getClass() const {
return m_class;
}
const MethodStatement *getMethod(const char *m);
MethodTable &getMethodTable() {
return m_methodTable;
}
const MethodStatement* &getConstructor() {
return m_constructor;
}
LVariableTable &getStatics() {
return m_statics;
}
void initializeInstance();
void initializeStatics();
void semanticCheck();
void fiberInit(ClassEvalState &oces, FiberReferenceMap &refMap);
void fiberInitStatics(ClassEvalState &oces, FiberReferenceMap &refMap);
void fiberExit(ClassEvalState &oces, FiberReferenceMap &refMap,
FiberAsyncFunc::Strategy default_strategy);
void fiberExitStatics(ClassEvalState &oces, FiberReferenceMap &refMap,
FiberAsyncFunc::Strategy default_strategy);
private:
const ClassStatement *m_class;
MethodTable m_methodTable;
const MethodStatement *m_constructor;
LVariableTable m_statics;
bool m_initializedInstance;
bool m_initializedStatics;
bool m_doneSemanticCheck;
};
/**
* Containers to live in Globals and do the garbage collection.
*/
class CodeContainer : public AtomicCountable {
public:
virtual ~CodeContainer() {}
void release();
};
class StringCodeContainer : public CodeContainer {
public:
StringCodeContainer(StatementPtr s);
~StringCodeContainer();
private:
StatementPtr m_s;
};
class EvalConstantInfo : public ClassInfo::ConstantInfo,
public AtomicCountable {
public:
void release() { delete this; }
};
class EvalMethodInfo : public ClassInfo::MethodInfo, public AtomicCountable {
public:
void release() { delete this; }
};
class ClassInfoEvaled : public ClassInfo, public AtomicCountable {
public:
~ClassInfoEvaled();
void release() { delete this; }
virtual CStrRef getParentClass() const { return m_parentClass; }
// implementing ClassInfo
const InterfaceSet &getInterfaces() const { return m_interfaces;}
const InterfaceVec &getInterfacesVec() const { return m_interfacesVec;}
const MethodMap &getMethods() const { return m_methods;}
const MethodVec &getMethodsVec() const { return m_methodsVec;}
const PropertyMap &getProperties() const { return m_properties;}
const PropertyVec &getPropertiesVec() const { return m_propertiesVec;}
const ConstantMap &getConstants() const { return m_constants;}
const ConstantVec &getConstantsVec() const { return m_constantsVec;}
private:
friend class ClassStatement;
String m_parentClass;
InterfaceSet m_interfaces; // all interfaces
InterfaceVec m_interfacesVec; // all interfaces
MethodMap m_methods; // all methods
MethodVec m_methodsVec; // in source order
PropertyMap m_properties; // all properties
PropertyVec m_propertiesVec; // in source order
ConstantMap m_constants; // all constants
ConstantVec m_constantsVec; // in source order
};
class RequestEvalState {
public:
static void Reset();
static void DestructObjects();
static void addCodeContainer(SmartPtr<CodeContainer> &cc);
static ClassEvalState &declareClass(const ClassStatement *cls);
static void declareFunction(const FunctionStatement *cls);
static bool declareConstant(CStrRef name, CVarRef value);
static const ClassStatement *findClass(CStrRef name, bool autoload = false);
static ClassEvalState *findClassState(CStrRef name, bool autoload = false);
static const MethodStatement *findMethod(const char *cname, const char *name,
bool &foundClass,
bool autoload = false);
static const FunctionStatement *findUserFunction(CStrRef name);
static const Function *findFunction(CStrRef name);
static bool findConstant(CStrRef name, Variant &ret);
static Variant findUserConstant(CStrRef name, bool error = true);
static bool includeFile(Variant &res, CStrRef path, bool once,
LVariableTable* variables,
const char *currentDir);
static LVariableTable &getFunctionStatics(const FunctionStatement* func);
static LVariableTable &getMethodStatics(const MethodStatement* func,
const char* cls);
static LVariableTable *getClassStatics(const ClassStatement* cls);
// Class info hook methods
static Array getUserFunctionsInfo();
static Array getClassesInfo();
static Array getInterfacesInfo();
static Array getConstants();
static const ClassInfo::MethodInfo *findFunctionInfo(CStrRef name);
static const ClassInfo *findClassInfo(const char *name);
static const ClassInfo *findInterfaceInfo(const char *name);
static const ClassInfo::ConstantInfo *findConstantInfo(const char *name);
// Global state getters
static void GetMethodStaticVariables(Array &arr);
static void GetClassStaticVariables(Array &arr);
static void GetDynamicConstants(Array &arr);
static Array &GetIncludes() { return Get()->m_includes;}
// Misc
static std::string unique();
static void info();
static VariantStack &argStack();
static VariantStack &bytecodeStack();
static void registerObject(EvalObjectData *obj);
static void deregisterObject(EvalObjectData *obj);
static RequestEvalState *Get();
void fiberInit(RequestEvalState *res, FiberReferenceMap &refMap);
void fiberExit(RequestEvalState *res, FiberReferenceMap &refMap,
FiberAsyncFunc::Strategy default_strategy);
private:
std::map<std::string, PhpFile*> m_evaledFiles;
std::list<SmartPtr<CodeContainer> > m_codeContainers;
StringIMap<ClassEvalState> m_classes;
StringIMap<const FunctionStatement*> m_functions;
std::map<const FunctionStatement*, LVariableTable> m_functionStatics;
typedef std::map<const MethodStatement*,
std::map<std::string, LVariableTable, string_lessi> > MethodStatics;
MethodStatics m_methodStatics;
Array m_constants;
std::map<std::string, SmartPtr<EvalConstantInfo> > m_constantInfos;
StringIMap<SmartPtr<EvalMethodInfo> > m_methodInfos;
std::map<std::string, SmartPtr<ClassInfoEvaled> > m_classInfos;
std::map<std::string, SmartPtr<ClassInfoEvaled> > m_interfaceInfos;
std::set<EvalObjectData*> m_livingObjects;
int64 m_ids;
VariantStack m_argStack;
VariantStack m_bytecodeStack;
Array m_includes;
void reset();
void destructObjects();
void destructObject(EvalObjectData *eo);
};
///////////////////////////////////////////////////////////////////////////////
}
}
#endif /* __EVAL_STATE_H__ */