13
13
*/
14
14
namespace Php {
15
15
16
- /* *
17
- * Map function names to their implementation
18
- *
19
- * This is braindead, there should be a way to get this information
20
- * from the "This" zval in the execute_data, I just can't find it
21
- * @todo Find a better way for this
22
- * @var std::map<std::string, Callable*>
23
- */
24
- static std::map<std::string, Callable*> callables;
25
-
26
16
/* *
27
17
* Function that is called by the Zend engine every time that a function gets called
28
18
* @param ht
@@ -34,34 +24,21 @@ static std::map<std::string, Callable*> callables;
34
24
*/
35
25
void Callable::invoke (INTERNAL_FUNCTION_PARAMETERS)
36
26
{
37
- // find the function name
38
- const char *name = get_active_function_name ();
39
- const char *classname = get_active_class_name (nullptr );
27
+ uint32_t argc = EX (func)->common .num_args ;
28
+ zend_arg_info* info = EX (func)->common .arg_info ;
40
29
41
- // the callable we are retrieving
42
- Callable *callable = nullptr ;
30
+ // Sanity check
31
+ assert (info[argc]. class_name != nullptr && info[argc]. name == nullptr ) ;
43
32
44
- // are we invoking a member function?
45
- if (classname && classname[0 ])
46
- {
47
- // construct the full name to search for
48
- auto fullname = std::string{ classname } + " ::" + name;
49
-
50
- // and find the callable in the map
51
- callable = callables.find (fullname)->second ;
52
- }
53
- else
54
- {
55
- // retrieve the callable from the map without mangling
56
- callable = callables.find (name)->second ;
57
- }
33
+ // the callable we are retrieving
34
+ Callable *callable = reinterpret_cast <Callable*>(info[argc].class_name );
58
35
59
36
// check if sufficient parameters were passed (for some reason this check
60
37
// is not done by Zend, so we do it here ourselves)
61
38
if (ZEND_NUM_ARGS () < callable->_required )
62
39
{
63
40
// PHP itself only generates a warning when this happens, so we do the same too
64
- Php::warning << name << " () expects at least " << callable->_required << " parameter(s), " << ZEND_NUM_ARGS () << " given" << std::flush;
41
+ Php::warning << get_active_function_name () << " () expects at least " << callable->_required << " parameter(s), " << ZEND_NUM_ARGS () << " given" << std::flush;
65
42
66
43
// and we return null
67
44
RETURN_NULL ();
@@ -109,22 +86,8 @@ void Callable::initialize(zend_function_entry *entry, const char *classname, int
109
86
}
110
87
else
111
88
{
112
- // if we have a classname we have to combine the two for a unique name
113
- // otherwise similar functions - like __construct - will overwrite functions
114
- // declared before
115
- if (classname)
116
- {
117
- // build the unique name
118
- auto name = std::string{ classname } + " ::" + _name;
119
-
120
- // add it to the map
121
- callables[name] = const_cast <Callable*>(this );
122
- }
123
- else
124
- {
125
- // no need to mangle the name
126
- callables[_name] = const_cast <Callable*>(this );
127
- }
89
+ // install ourselves in the extra argument
90
+ _argv[_argc + 1 ].class_name = reinterpret_cast <const char *>(this );
128
91
129
92
// we use our own invoke method, which does a lookup
130
93
// in the map we just installed ourselves in
0 commit comments