- Extensions which delete global variables need to use new special function
- delete_global_variable() (I'm about to rename it) to remove them.
- Will post to internals@ or via commit messages if there's anything else.
a) We specialize opcodes according to op_type fields. Each opcode has to
be marked with which op_type's it uses.
b) We support different execution methods. Function handlers, switch()
and goto dispatching. goto seems to be the fastest but it really
depends on the compiler and how well it optimizes. I suggest playing
around with optimization flags.
- Warning: Things might break so keep us posted on how things are going.
(Dmitry, Andi)
implementation, and allows exceptions to 'fire' much earlier than before.
Instructions on how to use the new mechanism will follow on internals@
shortly...
Note - this (most probably) breaks the current implementation of
set_exception_handler()
including:
- Whether or not to pass by ref (replaces the old arg_types, with arg_info)
- Argument name (for future use, maybe introspection)
- Class/Interface name (for type hints)
- If a class/interface name is available, whether to allow a null instance
Both user and builtin functions share the same data structures.
To declare a builtin function that expects its first arg to be an instance
of class 'Person', its second argument as a regular arg, and its third by
reference, use:
ZEND_BEGIN_ARG_INFO(my_func_arg_info, 0)
ZEND_ARG_OBJ_INFO(0, someone, Person, 1)
ZEND_ARG_PASS_INFO(0)
ZEND_ARG_PASS_INFO(1)
ZEND_END_ARG_INFO();
and use my_func_arg_info as the arg_info parameter to the ZEND_FE() family
of macros.
The first arg to each ZEND_ARG_*() macro is whether or not to pass by ref.
The boolean arg to ZEND_BEGIN_ARG_INFO() tells the engine whether to treat
the arguments for which there's no explicit information as pass by reference
or not.
The boolean argument to ZEND_ARG_OBJ_INFO() (4th arg) is whether or not to allownull values.
- The fields of zend_namespace were not completely initialized which
led to a variety of problems.
- The occurrence of class/interface/namespace definition is now
captured.
- Functions/classes/interfaces/namespaces can be preceded by doc
comments which are stored for use by extensions.
1. Nested classes are gone.
2. New syntax for namespaces:
namespace foo {
class X { ... }
function bar { ... }
var x = 1;
const ZZ = 2;
}
3. Namespaced symbol access: $x = new foo::X; - etc.
For now, namespaces are case insensitive, just like classes.
Also, there can be no global class and namespace with the same name
(to avoid ambiguities in :: resolution).
We need separate cleanup stage because of the following problem:
Suppose we destroy class X, which destroys function table,
and in function table we have function foo() that has static $bar. Now if
object of class X was assigned to $bar, its destructor will be called and will
fail since X's function table is in mid-destruction.
So we want first of all to clean up all data and then move to tables
destruction.
Note that only run-time accessed data need to be cleaned up, pre-defined
data can not contain objects and thus are not probelmatic.
# Looks like we are having a lots of pain in the various parts of the body
# because of the destructors...
- some fixes by me).
- You can't access protected variables from outside the object. If you want
- to see a protected member from your ancestors you need to declare the
- member as protected in the class you want to use it in. You can't
- redeclare a protected variable as private nor the other way around.
- destructor could be run after its class was already dead. Right now
- object destructors is the first thing whic happens during shutdown in
- order to prevent this problem. It's very likely that destructors will
- cause more grief and we'll have to outline exactly when you should use
- them and what kind of logic you're allowed to do inside of them.
- This bug was reported by sebastian.
Advantages:
- Smaller memory footprint for the op arrays
- Slightly faster compilation times (due to saved erealloc() calls and faster zend_op
initialization)
- include_once() & require_once() share the same file list
- Consistency between include() and require() - this mostly means that return()
works inside require()'d files just as it does in include() files (it used to
be meaningless in require()'d files, most of the time (see below))
- Made require() consistent with itself. Before, if the argument was not a constant
string, require() took the include() behavior (with return()).
- Removed lots of duplicate code.
Bottom line - require() and include() are very similar now; require() is simply an include()
which isn't allowed to fail. Due to the erealloc() calls for large op arrays, require()
didn't end up being any faster than include() in the Zend engine.
- In function declaration instead of the return statement
- In the assignment phase
- Implement ability to turn off support for call-time pass by reference
Later on we will want to delay the write fetches even longer until after their
resulting expression is parsed. The way it is now, will make it very easy
to delay as long as we need.
* updated alloc_persist to use critical sections
* changed extension shutdown to two-phase
* updated dependencies
* PR support (don't remember if there was any really)