2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2014 Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #ifndef incl_HPHP_EXECUTION_CONTEXT_H_
18 #define incl_HPHP_EXECUTION_CONTEXT_H_
20 #include "hphp/runtime/base/class-info.h"
21 #include "hphp/runtime/base/complex-types.h"
22 #include "hphp/runtime/base/ini-setting.h"
23 #include "hphp/runtime/server/transport.h"
24 #include "hphp/runtime/base/debuggable.h"
25 #include "hphp/runtime/server/virtual-host.h"
26 #include "hphp/runtime/base/string-buffer.h"
27 #include "hphp/runtime/base/hphp-array.h"
28 #include "hphp/runtime/vm/func.h"
29 #include "hphp/runtime/vm/bytecode.h"
30 #include "hphp/util/lock.h"
31 #include "hphp/util/thread-local.h"
34 #define PHP_OUTPUT_HANDLER_START (1<<0)
35 #define PHP_OUTPUT_HANDLER_CONT (1<<1)
36 #define PHP_OUTPUT_HANDLER_END (1<<2)
54 ///////////////////////////////////////////////////////////////////////////////
56 typedef hphp_hash_map
<StringData
*, HPHP::Eval::PhpFile
*, string_data_hash
,
57 string_data_same
> EvaledFilesMap
;
58 typedef std::vector
<HPHP::Eval::PhpFile
*> EvaledFilesVec
;
61 * Mainly designed for extensions to perform initialization and shutdown
62 * sequences at request scope.
64 class RequestEventHandler
{
66 RequestEventHandler() : m_inited(false) {}
67 virtual ~RequestEventHandler() {}
69 virtual void requestInit() = 0;
70 virtual void requestShutdown() = 0;
72 void setInited(bool inited
) { m_inited
= inited
;}
73 bool getInited() const { return m_inited
;}
75 // Priority of request shutdown call. Lower priority value means
76 // requestShutdown is called earlier than higher priority values.
77 virtual int priority() const { return 0;}
90 class MethodInfoVM
: public ClassInfo::MethodInfo
,
91 public AtomicCountable
{
94 void atomicRelease() { delete this; }
97 class ClassInfoVM
: public ClassInfo
,
98 public AtomicCountable
{
101 void atomicRelease() { delete this; }
102 virtual const String
& getParentClass() const { return m_parentClass
; }
104 const InterfaceSet
&getInterfaces() const { return m_interfaces
;}
105 const InterfaceVec
&getInterfacesVec() const { return m_interfacesVec
;}
106 const MethodMap
&getMethods() const { return m_methods
;}
107 const MethodVec
&getMethodsVec() const { return m_methodsVec
;}
108 const PropertyMap
&getProperties() const { return m_properties
;}
109 const PropertyVec
&getPropertiesVec() const { return m_propertiesVec
;}
110 const ConstantMap
&getConstants() const { return m_constants
;}
111 const ConstantVec
&getConstantsVec() const { return m_constantsVec
;}
112 const UserAttributeVec
&getUserAttributeVec() const { return m_userAttrVec
;}
113 const TraitSet
&getTraits() const { return m_traits
;}
114 const TraitVec
&getTraitsVec() const { return m_traitsVec
;}
115 const TraitAliasVec
&getTraitAliasesVec() const { return m_traitAliasesVec
;}
118 String m_parentClass
;
119 InterfaceSet m_interfaces
; // all interfaces
120 InterfaceVec m_interfacesVec
; // all interfaces
121 TraitSet m_traits
; // all used traits
122 TraitVec m_traitsVec
; // all used traits
123 TraitAliasVec m_traitAliasesVec
; // all trait aliases
124 MethodMap m_methods
; // all methods
125 MethodVec m_methodsVec
; // in source order
126 PropertyMap m_properties
; // all properties
127 PropertyVec m_propertiesVec
; // in source order
128 ConstantMap m_constants
; // all constants
129 ConstantVec m_constantsVec
; // in source order
130 UserAttributeVec m_userAttrVec
;
133 friend class HPHP::Class
;
136 enum class CallType
{
141 enum class LookupResult
{
145 MagicCallStaticFound
,
158 operator|(const InclOpFlags
&l
, const InclOpFlags
&r
) {
159 return InclOpFlags(int(l
) | int(r
));
163 operator&(const InclOpFlags
&l
, const InclOpFlags
&r
) {
164 return InclOpFlags(int(l
) & int(r
));
167 struct VMParserFrame
{
168 std::string filename
;
172 ///////////////////////////////////////////////////////////////////////////////
175 * Put all global variables here so we can gather them into one thread-local
176 * variable for easy access.
178 class BaseExecutionContext
: public IDebuggable
{
180 // These members are declared first for performance reasons: they
181 // are accessed from within the TC and having their offset fit
182 // within a single byte makes the generated code slightly smaller
187 int64_t m_currentThreadIdx
;
197 enum class ErrorThrowMode
{
203 enum class ErrorState
{
206 ExecutingUserHandler
,
207 ErrorRaisedByUserHandler
,
211 BaseExecutionContext();
212 ~BaseExecutionContext();
214 // For RPCRequestHandler
215 void backupSession();
216 void restoreSession();
218 // implementing IDebuggable
219 virtual void debuggerInfo(InfoVec
&info
);
224 Transport
*getTransport() { return m_transport
;}
225 void setTransport(Transport
*transport
) { m_transport
= transport
;}
226 std::string
getRequestUrl(size_t szLimit
= std::string::npos
);
227 String
getMimeType() const;
228 void setContentType(const String
& mimetype
, const String
& charset
);
229 String
getRequestMemoryMaxBytes() const { return m_maxMemory
; }
230 void setRequestMemoryMaxBytes(const std::string
& max
);
231 String
getCwd() const { return m_cwd
;}
232 void setCwd(const String
& cwd
) { m_cwd
= cwd
;}
237 void write(const String
& s
);
238 void write(const char *s
, int len
);
239 void write(const char *s
) { write(s
, strlen(s
));}
240 void writeStdout(const char *s
, int len
);
242 typedef void (*PFUNC_STDOUT
)(const char *s
, int len
, void *data
);
243 void setStdout(PFUNC_STDOUT func
, void *data
);
248 void obStart(CVarRef handler
= uninit_null());
249 String
obCopyContents();
250 String
obDetachContents();
251 int obGetContentLength();
258 Array
obGetStatus(bool full
);
259 void obSetImplicitFlush(bool on
);
260 Array
obGetHandlers();
261 void obProtect(bool on
); // making sure obEnd() never passes current level
263 StringBuffer
*swapOutputBuffer(StringBuffer
*sb
) {
264 StringBuffer
*current
= m_out
;
268 String
getRawPostData() const { return m_rawPostData
; }
269 void setRawPostData(String
& pd
) { m_rawPostData
= pd
; }
272 * Request sequences and program execution hooks.
274 void registerRequestEventHandler(RequestEventHandler
*handler
);
275 void registerShutdownFunction(CVarRef function
, Array arguments
,
277 Variant
popShutdownFunction(ShutdownType type
);
278 void onRequestShutdown();
279 void onShutdownPreSend();
280 void onShutdownPostSend();
285 Variant
pushUserErrorHandler(CVarRef function
, int error_types
);
286 Variant
pushUserExceptionHandler(CVarRef function
);
287 void popUserErrorHandler();
288 void popUserExceptionHandler();
289 bool errorNeedsHandling(int errnum
,
290 bool callUserHandler
,
291 ErrorThrowMode mode
);
292 bool errorNeedsLogging(int errnum
);
293 void handleError(const std::string
&msg
,
295 bool callUserHandler
,
297 const std::string
&prefix
,
298 bool skipFrame
= false);
299 bool callUserErrorHandler(const Exception
&e
, int errnum
,
300 bool swallowExceptions
);
301 virtual void recordLastError(const Exception
&e
, int errnum
= 0);
302 bool onFatalError(const Exception
&e
); // returns handled
303 bool onUnhandledException(Object e
);
304 ErrorState
getErrorState() const { return m_errorState
;}
305 void setErrorState(ErrorState state
) { m_errorState
= state
;}
306 String
getLastError() const { return m_lastError
;}
307 int getLastErrorNumber() const { return m_lastErrorNum
;}
308 int getErrorReportingLevel() const { return m_errorReportingLevel
;}
309 void setErrorReportingLevel(int level
) { m_errorReportingLevel
= level
;}
310 String
getErrorPage() const { return m_errorPage
;}
311 void setErrorPage(const String
& page
) { m_errorPage
= (std::string
) page
; }
312 bool getLogErrors() const { return m_logErrors
;}
313 void setLogErrors(bool on
);
314 String
getErrorLog() const { return m_errorLog
;}
315 void setErrorLog(const String
& filename
);
320 String
getenv(const String
& name
) const;
321 void setenv(const String
& name
, const String
& value
);
322 Array
getEnvs() const { return m_envs
; }
324 String
getTimeZone() const { return m_timezone
;}
325 void setTimeZone(const String
& timezone
) { m_timezone
= timezone
;}
326 String
getDefaultTimeZone() const { return m_timezoneDefault
;}
327 void setDefaultTimeZone(const String
& s
) { m_timezoneDefault
= s
;}
328 void setThrowAllErrors(bool f
) { m_throwAllErrors
= f
; }
329 bool getThrowAllErrors() const { return m_throwAllErrors
; }
330 void setExitCallback(Variant f
) { m_exitCallback
= f
; }
331 Variant
getExitCallback() { return m_exitCallback
; }
333 void setStreamContext(Resource
&context
) { m_streamContext
= context
; }
334 Resource
&getStreamContext() { return m_streamContext
; }
336 String
getDefaultCharset() const { return m_defaultCharset
; }
337 int64_t getSocketDefaultTimeout() const { return m_socketDefaultTimeout
; }
339 void restoreIncludePath();
340 void setIncludePath(const String
& path
);
341 String
getIncludePath() const;
342 Array
getIncludePathArray() const { return m_include_paths
; }
343 const VirtualHost
*getVirtualHost() const { return m_vhost
; }
344 void setVirtualHost(const VirtualHost
*vhost
) { m_vhost
= vhost
; }
346 const String
& getSandboxId() const { return m_sandboxId
; }
347 void setSandboxId(const String
& sandboxId
) { m_sandboxId
= sandboxId
; }
349 DECLARE_DBG_SETTING_ACCESSORS
354 OutputBuffer() : oss(8192) {}
360 static const StaticString s_amp
;
362 Transport
*m_transport
;
363 std::string m_maxMemory
;
367 StringBuffer
*m_out
; // current output buffer
368 std::list
<OutputBuffer
*> m_buffers
; // a stack of output buffers
369 bool m_implicitFlush
;
370 int m_protectedLevel
;
371 PFUNC_STDOUT m_stdout
;
373 String m_rawPostData
;
376 std::set
<RequestEventHandler
*> m_requestEventHandlerSet
;
377 std::vector
<RequestEventHandler
*> m_requestEventHandlers
;
381 std::vector
<std::pair
<Variant
,int> > m_userErrorHandlers
;
382 std::vector
<Variant
> m_userExceptionHandlers
;
383 ErrorState m_errorState
;
384 int64_t m_errorReportingLevel
;
387 std::string m_errorPage
;
394 String m_timezoneDefault
;
395 String m_argSeparatorOutput
;
396 bool m_throwAllErrors
;
397 Resource m_streamContext
;
398 String m_defaultCharset
;
399 int64_t m_socketDefaultTimeout
;
401 // session backup/restore for RPCRequestHandler
402 Array m_shutdownsBackup
;
403 std::vector
<std::pair
<Variant
,int> > m_userErrorHandlersBackup
;
404 std::vector
<Variant
> m_userExceptionHandlersBackup
;
406 Variant m_exitCallback
;
408 // include_path configuration option
409 Array m_include_paths
;
411 // cache the sandbox id for the request
414 const VirtualHost
*m_vhost
;
416 void resetCurrentBuffer();
417 void executeFunctions(CArrRef funcs
);
422 class VMExecutionContext
: public BaseExecutionContext
{
424 VMExecutionContext();
425 ~VMExecutionContext();
427 typedef std::set
<ObjectData
*> LiveObjSet
;
428 LiveObjSet m_liveBCObjs
;
431 long m_preg_backtrace_limit
;
432 long m_preg_recursion_limit
;
438 static void fillContinuationVars(
439 ActRec
* origFp
, const Func
* origFunc
, ActRec
* genFp
, const Func
* genFunc
);
440 void pushLocalsAndIterators(const HPHP::Func
* f
, int nparams
= 0);
441 void enqueueAPCHandle(APCHandle
* handle
);
444 std::vector
<APCHandle
*> m_apcHandles
;
445 void manageAPCHandle();
447 enum class VectorLeaveCode
{
451 template <bool setMember
, bool warn
, bool define
, bool unset
, bool reffy
,
452 unsigned mdepth
, VectorLeaveCode mleave
, bool saveResult
>
453 bool memberHelperPre(PC
& pc
, unsigned& ndiscard
, TypedValue
*& base
,
454 TypedValue
& tvScratch
,
455 TypedValue
& tvLiteral
,
456 TypedValue
& tvRef
, TypedValue
& tvRef2
,
457 MemberCode
& mcode
, TypedValue
*& curMember
);
458 template <bool warn
, bool saveResult
, VectorLeaveCode mleave
>
459 void getHelperPre(PC
& pc
, unsigned& ndiscard
,
460 TypedValue
*& base
, TypedValue
& tvScratch
,
461 TypedValue
& tvLiteral
,
462 TypedValue
& tvRef
, TypedValue
& tvRef2
,
463 MemberCode
& mcode
, TypedValue
*& curMember
);
464 template <bool saveResult
>
465 void getHelperPost(unsigned ndiscard
, TypedValue
*& tvRet
,
466 TypedValue
& tvScratch
, Variant
& tvRef
,
468 void getHelper(PC
& pc
, unsigned& ndiscard
, TypedValue
*& tvRet
,
469 TypedValue
*& base
, TypedValue
& tvScratch
,
470 TypedValue
& tvLiteral
,
471 Variant
& tvRef
, Variant
& tvRef2
,
472 MemberCode
& mcode
, TypedValue
*& curMember
);
474 template <bool warn
, bool define
, bool unset
, bool reffy
, unsigned mdepth
,
475 VectorLeaveCode mleave
>
476 bool setHelperPre(PC
& pc
, unsigned& ndiscard
, TypedValue
*& base
,
477 TypedValue
& tvScratch
,
478 TypedValue
& tvLiteral
,
479 TypedValue
& tvRef
, TypedValue
& tvRef2
,
480 MemberCode
& mcode
, TypedValue
*& curMember
);
481 template <unsigned mdepth
>
482 void setHelperPost(unsigned ndiscard
, Variant
& tvRef
,
484 template <bool isEmpty
>
485 void isSetEmptyM(IOP_ARGS
);
487 template<class Op
> void implCellBinOp(IOP_ARGS
, Op op
);
488 template<class Op
> void implCellBinOpBool(IOP_ARGS
, Op op
);
489 void implVerifyRetType(IOP_ARGS
);
490 bool cellInstanceOf(TypedValue
* c
, const HPHP::NamedEntity
* s
);
491 bool iopInstanceOfHelper(const StringData
* s1
, Cell
* c2
);
492 bool initIterator(PC
& pc
, PC
& origPc
, Iter
* it
,
493 Offset offset
, Cell
* c1
);
494 bool initIteratorM(PC
& pc
, PC
& origPc
, Iter
* it
,
495 Offset offset
, Ref
* r1
, TypedValue
* val
, TypedValue
* key
);
496 void jmpSurpriseCheck(Offset o
);
497 template<Op op
> void jmpOpImpl(IOP_ARGS
);
498 template<class Op
> void roundOpImpl(Op op
);
499 #define O(name, imm, pusph, pop, flags) \
500 void iop##name(IOP_ARGS);
504 void classExistsImpl(IOP_ARGS
, Attr typeAttr
);
505 void fPushObjMethodImpl(
506 Class
* cls
, StringData
* name
, ObjectData
* obj
, int numArgs
);
507 ActRec
* fPushFuncImpl(const Func
* func
, int numArgs
);
510 typedef hphp_hash_map
<const StringData
*, ClassInfo::ConstantInfo
*,
511 string_data_hash
, string_data_same
> ConstInfoMap
;
512 ConstInfoMap m_constInfo
;
514 std::unordered_map
<const ObjectData
*,ArrayNoDtor
> dynPropTable
;
516 const HPHP::Func
* lookupMethodCtx(const HPHP::Class
* cls
,
517 const StringData
* methodName
,
518 const HPHP::Class
* pctx
,
521 LookupResult
lookupObjMethod(const HPHP::Func
*& f
,
522 const HPHP::Class
* cls
,
523 const StringData
* methodName
,
526 LookupResult
lookupClsMethod(const HPHP::Func
*& f
,
527 const HPHP::Class
* cls
,
528 const StringData
* methodName
,
532 LookupResult
lookupCtorMethod(const HPHP::Func
*& f
,
533 const HPHP::Class
* cls
,
535 ObjectData
* createObject(StringData
* clsName
,
538 ObjectData
* createObjectOnly(StringData
* clsName
);
541 * Look up a class constant.
543 * The returned Cell is guaranteed not to hold a reference counted
544 * type. Raises an error if the class has no constant with that
545 * name, or if the class is not defined.
547 Cell
lookupClsCns(const HPHP::NamedEntity
* ne
,
548 const StringData
* cls
,
549 const StringData
* cns
);
550 Cell
lookupClsCns(const StringData
* cls
,
551 const StringData
* cns
);
553 // Get the next outermost VM frame, even accross re-entry
554 ActRec
* getOuterVMFrame(const ActRec
* ar
);
556 std::string
prettyStack(const std::string
& prefix
) const;
557 static void DumpStack();
558 static void DumpCurUnit(int skip
= 0);
559 static void PrintTCCallerInfo();
561 VarEnv
* m_globalVarEnv
;
563 EvaledFilesMap m_evaledFiles
;
564 EvaledFilesVec m_evaledFilesOrder
;
565 typedef std::vector
<HPHP::Unit
*> EvaledUnitsVec
;
566 EvaledUnitsVec m_createdFuncs
;
569 * Accessors for VMExecutionContext state that check safety wrt
570 * whether these values may be stale due to TC. Asserts in these
571 * usually mean the need for a VMRegAnchor somewhere in the call
575 void checkRegStateWork() const;
576 void checkRegState() const { if (debug
) checkRegStateWork(); }
578 const ActRec
* getFP() const { checkRegState(); return m_fp
; }
579 ActRec
* getFP() { checkRegState(); return m_fp
; }
580 PC
getPC() const { checkRegState(); return m_pc
; }
581 const Stack
& getStack() const { checkRegState(); return m_stack
; }
582 Stack
& getStack() { checkRegState(); return m_stack
; }
584 Offset
pcOff() const {
585 return getFP()->m_func
->unit()->offsetOf(m_pc
);
589 std::vector
<Fault
> m_faults
;
591 ActRec
* getStackFrame();
592 ObjectData
* getThis();
593 Class
* getContextClass();
594 Class
* getParentContextClass();
595 const String
& getContainingFileName();
597 Array
getCallerInfo();
598 HPHP::Eval::PhpFile
* lookupPhpFile(
599 StringData
* path
, const char* currentDir
, bool* initial
= nullptr);
600 HPHP::Unit
* evalInclude(StringData
* path
,
601 const StringData
* curUnitFilePath
, bool* initial
);
602 HPHP::Unit
* evalIncludeRoot(StringData
* path
,
603 InclOpFlags flags
, bool* initial
);
604 HPHP::Eval::PhpFile
* lookupIncludeRoot(StringData
* path
,
605 InclOpFlags flags
, bool* initial
,
606 HPHP::Unit
* unit
= 0);
607 bool evalUnit(HPHP::Unit
* unit
, PC
& pc
, int funcType
);
608 void invokeUnit(TypedValue
* retval
, HPHP::Unit
* unit
);
609 HPHP::Unit
* compileEvalString(StringData
* code
,
610 const char* evalFilename
= nullptr);
611 const String
& createFunction(const String
& args
, const String
& code
);
612 bool evalPHPDebugger(TypedValue
* retval
, StringData
*code
, int frame
);
613 void enterDebuggerDummyEnv();
614 void exitDebuggerDummyEnv();
615 void preventReturnsToTC();
616 void destructObjects();
618 struct ReentryRecord
{
619 VMState m_savedState
;
620 const ActRec
* m_entryFP
;
621 ReentryRecord(const VMState
&s
, const ActRec
* entryFP
) :
622 m_savedState(s
), m_entryFP(entryFP
) { }
625 typedef TinyVector
<ReentryRecord
, 32> NestedVMVec
;
626 NestedVMVec m_nestedVMs
;
629 bool isNested() { return m_nesting
!= 0; }
630 void pushVMState(VMState
&savedVM
, const ActRec
* reentryAR
);
633 ActRec
* getPrevVMState(const ActRec
* fp
,
634 Offset
* prevPc
= nullptr,
635 TypedValue
** prevSp
= nullptr,
636 bool* fromVMEntry
= nullptr);
637 Array
debugBacktrace(bool skip
= false,
638 bool withSelf
= false,
639 bool withThis
= false,
640 VMParserFrame
* parserFrame
= nullptr,
641 bool ignoreArgs
= false,
643 VarEnv
* getVarEnv(int frame
= 0);
644 void setVar(StringData
* name
, TypedValue
* v
, bool ref
);
645 Array
getLocalDefinedVariables(int frame
);
646 HPHP::PCFilter
* m_breakPointFilter
;
647 HPHP::PCFilter
* m_lastLocFilter
;
649 bool doFCall(HPHP::ActRec
* ar
, PC
& pc
);
650 bool doFCallArray(PC
& pc
);
651 bool doFCallArrayTC(PC pc
);
652 CVarRef
getEvaledArg(const StringData
* val
, const String
& namespacedName
);
653 virtual void recordLastError(const Exception
&e
, int errnum
= 0);
654 String
getLastErrorPath() const { return m_lastErrorPath
; }
655 int getLastErrorLine() const { return m_lastErrorLine
; }
658 void enterVMWork(ActRec
* enterFnAr
);
659 void enterVMPrologue(ActRec
* enterFnAr
);
660 void enterVM(TypedValue
* retval
, ActRec
* ar
);
661 void reenterVM(TypedValue
* retval
, ActRec
* ar
, TypedValue
* savedSP
);
662 void doFPushCuf(IOP_ARGS
, bool forward
, bool safe
);
663 template <bool forwarding
>
664 void pushClsMethodImpl(Class
* cls
, StringData
* name
,
665 ObjectData
* obj
, int numArgs
);
666 bool prepareFuncEntry(ActRec
* ar
, PC
& pc
);
667 bool prepareArrayArgs(ActRec
* ar
, CVarRef arrayArgs
);
668 void recordCodeCoverage(PC pc
);
669 bool isReturnHelper(uintptr_t address
);
670 void switchModeForDebugger();
672 HPHP::Unit
* m_coverPrevUnit
;
674 String m_lastErrorPath
;
677 void resetCoverageCounters();
678 void shuffleMagicArgs(ActRec
* ar
);
685 void invokeFunc(TypedValue
* retval
,
687 CVarRef args_
= init_null_variant
,
688 ObjectData
* this_
= nullptr,
689 HPHP::Class
* class_
= nullptr,
690 VarEnv
* varEnv
= nullptr,
691 StringData
* invName
= nullptr,
692 InvokeFlags flags
= InvokeNormal
);
693 void invokeFunc(TypedValue
* retval
,
696 VarEnv
* varEnv
= nullptr) {
697 invokeFunc(retval
, ctx
.func
, args_
, ctx
.this_
, ctx
.cls
, varEnv
,
700 void invokeFuncCleanupHelper(TypedValue
* retval
,
703 void invokeFuncFew(TypedValue
* retval
,
708 const TypedValue
* argv
);
709 void invokeFuncFew(TypedValue
* retval
,
712 StringData
* invName
= nullptr) {
713 invokeFuncFew(retval
, f
, thisOrCls
, invName
, 0, nullptr);
715 void invokeFuncFew(TypedValue
* retval
,
718 const TypedValue
* argv
) {
719 invokeFuncFew(retval
, ctx
.func
,
720 ctx
.this_
? (void*)ctx
.this_
:
721 ctx
.cls
? (char*)ctx
.cls
+ 1 : nullptr,
722 ctx
.invName
, argc
, argv
);
724 void invokeContFunc(const HPHP::Func
* f
,
726 Cell
* param
= nullptr);
727 // VM ClassInfo support
728 StringIMap
<AtomicSmartPtr
<MethodInfoVM
> > m_functionInfos
;
729 StringIMap
<AtomicSmartPtr
<ClassInfoVM
> > m_classInfos
;
730 StringIMap
<AtomicSmartPtr
<ClassInfoVM
> > m_interfaceInfos
;
731 StringIMap
<AtomicSmartPtr
<ClassInfoVM
> > m_traitInfos
;
732 Array
getUserFunctionsInfo();
733 Array
getConstantsInfo();
734 const ClassInfo::MethodInfo
* findFunctionInfo(const String
& name
);
735 const ClassInfo
* findClassInfo(const String
& name
);
736 const ClassInfo
* findInterfaceInfo(const String
& name
);
737 const ClassInfo
* findTraitInfo(const String
& name
);
738 const ClassInfo::ConstantInfo
* findConstantInfo(const String
& name
);
740 // The op*() methods implement individual opcode handlers.
741 #define O(name, imm, pusph, pop, flags) \
746 LimitInstrs
= 1 << 0,
747 BreakOnCtlFlow
= 1 << 1,
750 template <int dispatchFlags
>
751 void dispatchImpl(int numInstrs
);
753 // dispatchN() runs numInstrs instructions, or to program termination,
754 // whichever comes first. If the program terminates during execution, m_pc is
756 void dispatchN(int numInstrs
);
758 // dispatchBB() tries to run until a control-flow instruction has been run.
762 static Mutex s_threadIdxLock
;
763 static hphp_hash_map
<pid_t
, int64_t> s_threadIdxMap
;
766 static int64_t s_threadIdxCounter
;
767 Variant m_setprofileCallback
;
768 bool m_executingSetprofileCallback
;
770 std::vector
<vixl::Simulator
*> m_activeSims
;
773 class ExecutionContext
: public VMExecutionContext
{};
776 #define g_vmContext (&dynamic_cast<HPHP::VMExecutionContext&>( \
777 *HPHP::g_context.getNoCheck()))
779 #define g_vmContext (static_cast<HPHP::VMExecutionContext*>( \
780 static_cast<HPHP::BaseExecutionContext*>( \
781 HPHP::g_context.getNoCheck())))
784 ///////////////////////////////////////////////////////////////////////////////
786 class PersistentObjectStore
{
788 ~PersistentObjectStore();
792 void set(const char *type
, const char *name
, ResourceData
*obj
);
793 ResourceData
*get(const char *type
, const char *name
);
794 void remove(const char *type
, const char *name
);
796 const ResourceMap
&getMap(const char *type
);
799 ResourceMapMap m_objects
;
801 void removeObject(ResourceData
*data
);
804 ///////////////////////////////////////////////////////////////////////////////
806 extern DECLARE_THREAD_LOCAL_NO_CHECK(ExecutionContext
, g_context
);
807 extern DECLARE_THREAD_LOCAL_NO_CHECK(PersistentObjectStore
,
808 g_persistentObjects
);
810 ///////////////////////////////////////////////////////////////////////////////
813 #endif // incl_HPHP_EXECUTION_CONTEXT_H_