If a GenArrayWaitHandle is imported, the current implementation imports
only the active child. Try to import other children as well to increase
parallelism.
enterContext() can throw an exception if a cross-context dependency
cycle is found. It is safe to ignore such exception when importing
non-active children. The import will be attempted and fail again once
onBlocked() reaches the dependency that causes the cycle.
Verify sanity of input array of dependencies in advance. Callers get the
error earlier and it also makes it easier to work with the array outside
of the main loop.
Our ext_hhvm generated code is casting TypedValue* to Value*
on the assumption that the offset of TypedValue::m_data is 0.
Fix this assumption, and also while in the same code, replace
some (t == KindOfString || t == KindOfStaticString) with
IS_STATIC_STRING(t), which does a single bit test instead of
two comparisons.
change callers of determine_charset to check for nulls, instead of calling html_supported_charset (to pre-validate charset name) and then calling this (which has to run through a list of names anyway).
In an unlikely situation a user of ext_asio may tamper with Continuation
before passing it to the ext_asio extension. Let's fail with an
exception if this happens. Previously, a user bug would stay unnoticed,
but would not harm the ext_asio code.
This check will be needed once we implement optimistic execution. With
optimistic execution, we iterate continuation and defer construction of
ContinuationWaitHandle until the first blocking event occurs. During
this phase, a standard dependency loop detection is skipped and the code
would try to iterate a continuation that is already being iterated.
I got to do a few optimizations:
* burn in the number of use vars
* not write out uninitialized use vars
* use the staticness of the method as a hint for the incRef
They both returned the late static bound class, not the context
class. This meant that eg "constant('self::FOO')" was actually
returning what "constant('static::FOO')" should have done.
In addition, we often want the Class*, not its name, so
change them to return Class*. The remaining places that then
read the name from the Class* should be fixed to use the Class*
directly (in a later diff).
Finally, noticed that while "defined()" was recently fixed to
support "static::", "constant()" was not. Pulled out a common
function to find the correct Class*.
The callback passed to asio_set_on_{failed, started}_callback was
never null because the way types for input parameters work in
extensions. Null from user PHP code was converted to a stdClass
object, triggering an exception.
The only places where ReturnStatement is constructed are:
- onReturn(check_yield=true) -> not allowed in generator
- onReturn(check_yield=false) -> coming from transform_yield_break, right after creating hphp_continuation_done()
- MethodStatement, end of function call -> hphp_continuation_done() is created at end of generator in prepare_generator()
Emitter is emitting ContExit in ReturnStatements used in generators. As
can be seen from the analysis above, it's always preceded by emitting
ContDone from hphp_continuation_done(). Let's emit ContDone inside the
ReturnStatement directly and kill usage of hphp_continuation_done().
transform_yield_break() becomes a simple onReturn(check_yield=false), so
let's inline it into onYield and create ReturnStatement directly. After
this change, check_yield flag is always true and can be killed.
ContExit was also used after emitting a generator method in case the end
of method is still reachable. ContDone is added so that the generator is
properly closed. I believe this is never actually used, as MethodStatement
creates ReturnStatement at the end of method anyway.
Unhack the parser and introduce YieldExpression that emits the
equivalent set of opcodes that were emitted by bunch of
expressions/statements generated by parser before.
YieldExpression expects evaluation stack to contain just the value
being yielded, so {,List}AssignmentExpression need to evaluate RHS
first. The previous code had the same behavior.
This will let us consolidate continuation-related opcodes and make
them less tied with continuation objects.
PHP added this in 5.4 so that you can say your closure shouldn't capture ##$this##. https://wiki.php.net/rfc/closures
Should we add it? Many of their unit tests use it.
Instead of putting a boolean somewhere I used the same attr framework and set the static bit there. Thoughts? It only needs one change in the ##FPushFunc##.
In Zend 5.3 they decided that closures should inherit the ##$this## from the containing scope. This brings us close to paraity with them. The remaining thing is to make
function() use ($this) {}
fatal after we purge it from WWW.
uidna_openUTS46 overwrites its error code argument only if
there is actually an error. Hence, if the variable is not initialized to
zero it may seem to the calling code that an error has ocurred. This
diff initializes the variable and re-enables the failing test.
Bad memory allocation, the buffer needs to be large enough to fit all
the data we've decompressed so far plus the extra storage we're
incrementally allocationg, not just the incremental part.
Replace "collection" with "collections" in various file names since
we typically use the plural form in conversation and documentation.
Add set() and removeAt() methods needed for collection interfaces. Also
add the KeyedIterable and KeyedIterator interfaces.
Add __construct() methods for collections
This diff eliminates setOpEqual() and appendOpEqual() from Variant, and
it also removes several methods from ObjectData: o_assign_op(), o_argval(),
setDummy(), init(), cloneDynamic(), o_setPublicWithRef(), o_i_set(),
getRedeclaredParent(), and o_propForIteration().
This diff also makes several methods in ObjectData non-virtual: destruct(),
o_toIterArray(), and o_getDynamicProperties(). To achieve this, some of the
logic from Instance was moved to ObjectData.
Finally, this diff gets rid of "hhvm/externals_stubs.cpp" and
"runtime/eval/eval.cpp".
gzinflate tries to do some kind of exponential growth that
hits the max string limit immediately when you try to deflate a string
larger than 128 megs. The logic is a little convoluted with a few
ways to bail, but rather than try to really fix it I just made it
behave close to the same on small strings, but use a smaller starting
factor on long ones and be willing to try to deflate it into a
max-sized string.
This diff removes LVariableTable, RVariableTable, and getHphpBinaryType().
It also consolidates some of the include logic that was spread across
multiple files.
Access to TypedValue.m_aux must now be via TypedValueAux. For now,
TypedValueAux is an empty subclass with accessors to m_aux, which is
now private. Once RefData.m_tv is moved out from under RefData._count,
we can move TypedValue.m_aux to TypedValueAux.
Removed unnecessary initialization of m_aux.u_hash from c_Vector.
This diff removes initializing stores to TypedValue._count, renames
_count to m_aux, and makes m_aux a union with members typed
and named according to their specialized uses. The few remaining
uses of that field for random tweaks are more obvious and easy to
grep for.
TypedValue no longer extends Value, (allowing m_data to move to a
different offset in the future), and Variant now extends TypedValue,
so we only have to maintain one definition.
HphpArray now explicitly uses TypedValue.m_pad instead of overlapping
TypedValue with an anonymous struct, again so we don't have to maintain
another structure to match TypedValue's layout.
The JIT's were using offsetof(TypedValue, _count) all over the place
for access to String/Array/Object/RefData::_count. Instead, use
FAST_REFCOUNT_OFFSET.
In HPHPc it didn't allow closures to be cloned but in HHVM it did. When I migrated to a C++ closure then i left the HPHPc code. Zend 5.4 allows them to be cloned so lets go with this.
Expose the following data to the PHP:
- asio_get_current_context_idx(): get current context index
- asio_get_running_in_context(): get running wait handle in a given context
- asio_get_running(): get running wait handle in a current context (renamed asio_get_current())
- WaitableWaitHandle::getContextIdx(): get context the wait handle operates in
- WaitableWaitHandle::getCreator(): get continuation wait handle that constructed this wait handle
Move the responsibility of entering/exiting contexts from PHP to the
implementation of $wait_handle->join().
This eliminates possibility of weird situations, like contexts without
any running wait handle. This guarantees that asio_get_current() returns
null only if called completely out of asio framework and simplifies some
logic, such as getCurrentWaitHandleDepth().
Noticed this in perf, maybe I'm missing something obvious
but it seemed like there was a pretty easy way to avoid an extra
hashtable lookup during get_class_constants
This shows up because the Enum class call this method once per enum
the first time isValid is call. Might be worth doing something to
make this even more efficient, but seems like an easy win.