Add sub-controls for Hack array compat runtime checks
[hiphop-php.git] / hphp / runtime / base / autoload-handler.h
blob3dfce13694fc9b084719fc867295bb8201ba2491
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2013 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 +----------------------------------------------------------------------+
16 #ifndef incl_HPHP_AUTOLOAD_HANDLER_H_
17 #define incl_HPHP_AUTOLOAD_HANDLER_H_
19 #include <utility>
21 #include "hphp/runtime/base/req-containers.h"
22 #include "hphp/runtime/base/request-event-handler.h"
23 #include "hphp/runtime/base/type-variant.h"
24 #include "hphp/runtime/base/type-array.h"
25 #include "hphp/runtime/base/request-local.h"
27 namespace HPHP {
29 //////////////////////////////////////////////////////////////////////
31 bool is_valid_class_name(folly::StringPiece className);
33 struct AutoloadHandler final : RequestEventHandler {
34 private:
35 enum Result {
36 Failure,
37 Success,
38 StopAutoloading,
39 ContinueAutoloading,
40 RetryAutoloading
43 struct HandlerBundle {
44 HandlerBundle() = delete;
45 HandlerBundle(const Variant& handler,
46 req::unique_ptr<CufIter>& cufIter) :
47 m_handler(handler) {
48 m_cufIter = std::move(cufIter);
50 Variant m_handler; // used to respond to f_spl_autoload_functions
51 req::unique_ptr<CufIter> m_cufIter; // used to invoke handlers
54 struct CompareBundles {
55 explicit CompareBundles(CufIter* cufIter) : m_cufIter(cufIter) { }
56 bool operator()(const HandlerBundle& hb);
57 private:
58 CufIter* m_cufIter;
61 public:
62 AutoloadHandler() { }
64 ~AutoloadHandler() {
65 m_map.detach();
66 m_map_root.detach();
67 // m_handlers won't run a destructor so nothing to do here
68 m_loading.detach();
71 void requestInit() override;
72 void requestShutdown() override;
74 Array getHandlers();
75 bool addHandler(const Variant& handler, bool prepend);
76 void removeHandler(const Variant& handler);
77 void removeAllHandlers();
78 bool isRunning();
80 bool autoloadClass(const String& className, bool forceSplStack = false);
81 bool autoloadClassPHP5Impl(const String& className, bool forceSplStack);
83 /**
84 * autoloadClassOrType() tries to autoload either a class or a type alias
85 * with the specified name. This method avoids calling the failure callback
86 * until one of the following happens: (1) we tried to autoload the specified
87 * name from both the 'class' and 'type' maps but for each map either nothing
88 * was found or the file we included did not define a class or type alias
89 * with the specified name, or (2) there was an uncaught exception or fatal
90 * error during an include operation.
92 bool autoloadClassOrType(const String& className);
94 bool autoloadFunc(StringData* name);
95 bool autoloadConstant(StringData* name);
96 bool autoloadType(const String& name);
97 bool setMap(const Array& map, const String& root);
98 DECLARE_STATIC_REQUEST_LOCAL(AutoloadHandler, s_instance);
100 private:
102 * This method may return Success or Failure.
104 template <class T>
105 Result loadFromMapImpl(const String& name, const String& kind, bool toLower,
106 const T &checkExists, Variant& err);
109 * This method may return ContinueAutoloading, StopAutoloading, or
110 * RetryAutoloading.
112 Result invokeFailureCallback(const Variant& func, const String& kind,
113 const String& name, const Variant& err);
116 * loadFromMap() will call the failure callback if the specified name is not
117 * present in the specified map, or if there is an entry in the map but there
118 * was an error during the include operation. loadFromMap() will also retry
119 * loading the specified name from the map if the failure callback returned
120 * boolean true. Note that calling this method may throw if the failure
121 * callback throws an exception or raises a fatal error.
123 * This method may return Success, Failure, ContinueAutoloading, or
124 * StopAutoloading. If the failure callback was called, this method will not
125 * return Failure.
127 template <class T>
128 Result loadFromMap(const String& name, const String& kind, bool toLower,
129 const T &checkExists);
132 * loadFromMapPartial() will call the failure callback if there is an error
133 * during the include operation, but otherwise it will not call the failure
134 * callback.
136 * This method may return Success, Failure, ContinueAutoloading,
137 * StopAutoloading, or RetryAutoloading. If the failure callback was called,
138 * this method will not return Failure.
140 template <class T>
141 Result loadFromMapPartial(const String& className, const String& kind,
142 bool toLower, const T &checkExists, Variant& err);
144 static String getSignature(const Variant& handler);
146 private:
147 Array m_map;
148 String m_map_root;
149 bool m_spl_stack_inited{false};
150 union {
151 req::deque<HandlerBundle> m_handlers;
153 bool m_handlers_valid{false};
154 Array m_loading;
155 TYPE_SCAN_CUSTOM_FIELD(m_handlers) {
156 if (m_handlers_valid) { scanner.scan(m_handlers); }
160 //////////////////////////////////////////////////////////////////////
164 #endif