3v4l.org

run code in 300+ PHP versions simultaneously
<?php function extract_docblocks($data) { $inBlock = false; $forceNewItem = true; $currentBlock = array(); $blocks = array(); foreach (preg_split('/[\r\n]+/', $data) as $line) { $line = trim($line); if (!$inBlock) { if ($line === '/**') { $inBlock = true; } continue; } if ($line[0] !== '*') { $inBlock = false; $forceNewItem = true; $currentBlock = array(); continue; } if ($line === '*/') { $inBlock = false; $forceNewItem = true; $blocks[] = $currentBlock; $currentBlock = array(); continue; } $line = trim(substr($line, 1)); if ($line[0] === '@' || $forceNewItem) { $forceNewItem = false; $currentBlock[] = $line; } else if ($line === '') { $forceNewItem = true; } else { $currentBlock[count($currentBlock) - 1] .= "\n" . $line; } } return $blocks; } $str = <<<'CLASS' <?php /** * Class EventLoop * * This is not the fastest event loop implementation in the world, at least * partially because it's been stupidified for PHP4. It's not really for high * performance asyncSaucezOMG though, so it shouldn't matter. */ class EventLoop { /** * @var EventLoopConfig */ var $config; /** * @var EventLoopLogger * @access private */ var $_logger; /** * @var WorkerPoolFactory */ var $_workerPoolFactory; /** * @var array * @access private */ var $_streamWatchers = array( 'read' => array( 'streams' => array(), 'callbacks' => array(), ), 'write' => array( 'streams' => array(), 'callbacks' => array(), ), 'except' => array( 'streams' => array(), 'callbacks' => array(), ), ); /** * @var int * @access private */ var $_streamWatcherCount = 0; /** * @var Scheduler * @access private */ var $_scheduler; /** * @var WorkerPool * @access private */ var $_dynamicWorkerPool; /** * @var WorkerPool * @access private */ var $_dnsWorkerPool; /** * @var StreamHandler[] * @access private */ var $_streamHandlers = array(); /** * @var bool * @access private */ var $_running = false; /** * Constructor * * @param WorkerPoolFactory $workerPoolFactory * @param EventLoopConfig $config * @param EventLoopLogger $logger * @param SchedulerFactory $schedulerFactory * @param StreamHandler $socketStreamHandler */ function EventLoop(&$workerPoolFactory, &$config, &$logger, &$schedulerFactory, &$socketStreamHandler) { $this->config = &$config; $this->_logger = &$logger; $this->_workerPoolFactory = &$workerPoolFactory; $this->_scheduler = &$schedulerFactory->create($this->_logger); $this->registerStreamHandler($socketStreamHandler, array('tcp', 'udp', 'unix')); $this->_dynamicWorkerPool = &$workerPoolFactory->create($this, $this->config->workers, $this->_logger, 'Dynamic'); $config->dns->normalizeInheritableProperties($this->config->workers); $this->_dnsWorkerPool = &$workerPoolFactory->create($this, $this->config->dns, $this->_logger, 'DNS'); } /** * Get the current time as a float * * @return float * @access private */ function _now() { list($usec, $sec) = explode(' ', microtime()); return ((float)$usec + (float)$sec); } /** * Check whether at least one client socket or scheduled item is active * * @return bool * @access private */ function _isActive() { return $this->_streamWatcherCount || $this->_scheduler->isActive(); } /** * Get the time until there is something to do * * @return float|null * @access private */ function _getNextActivityTime() { $candidates = array(); if (null !== $time = $this->_scheduler->getNextActivityTime()) { $candidates[] = $time; } if (null !== $time = $this->_dynamicWorkerPool->getNextActivityTime()) { $candidates[] = $time; } if (null !== $time = $this->_dnsWorkerPool->getNextActivityTime()) { $candidates[] = $time; } return $candidates ? max(min($candidates), 0) : null; } /** * Sleep until the next scheduled item is due to be executed * * @access private */ function _awaitNextActivity($timeout) { if ($timeout) { $this->_logger->debug(null, 'Waiting until next scheduled activity, timeout: %f', $timeout); usleep(floor($timeout * 1000000)); } } /** * Process I/O on all active streams * * @access private */ function _processStreams($timeout) { $streams = array( 'read' => $this->_streamWatchers['read']['streams'], 'write' => $this->_streamWatchers['write']['streams'], 'except' => $this->_streamWatchers['except']['streams'], ); if ($timeout !== null) { $secs = floor($timeout); $usecs = floor(($timeout - $secs) * 1000000); } else { $secs = $usecs = null; } $this->_logger->debug( null, 'select() watching %d streams for activity (read: %d, write: %d, except: %d), timeout: %s', count($streams['read']) + count($streams['write']) + count($streams['except']), count($streams['read']), count($streams['write']), count($streams['except']), $secs === null ? 'NULL' : "{$secs}s {$usecs}u" ); $count = stream_select($streams['read'], $streams['write'], $streams['except'], $secs, $usecs); if ($count === false) { $this->_logger->error(null, 'select() operation failed!'); exit(1); } else if ($count === 0) { $this->_logger->debug(null, 'select() returned 0 streams with activity'); return; } $this->_logger->debug( null, 'select() returned %d streams with activity (read: %d, write: %d, except: %d)', $count, count($streams['read']), count($streams['write']), count($streams['except']) ); foreach (array('read', 'write', 'except') as $op) { foreach ($streams[$op] as $stream) { $id = (int) $stream; if (isset($this->_streamWatchers[$op]['callbacks'][$id])) { call_user_func($this->_streamWatchers[$op]['callbacks'][$id], $stream); } } } } /** * Add a watcher for a stream * * @param string $op * @param resource $stream * @param callable $callback * @return bool * @access module */ function _addStreamWatcher($op, $stream, $callback) { $id = (int) $stream; $op = strtolower($op); if (!isset($this->_streamWatchers[$op])) { $this->_logger->debug(null, 'Failed to add %s watcher on stream #%d: unknown op', $op, $id); return false; } else if (!is_resource($stream)) { $this->_logger->debug(null, 'Failed to add %s watcher on stream #%d: not a valid stream resource', $op, $id); return false; } else if (!is_callable($callback)) { $this->_logger->debug(null, 'Failed to add %s watcher on stream #%d: invalid callback', $op, $id); return false; } if (!isset($this->_streamWatchers[$op]['streams'][$id])) { $this->_streamWatchers[$op]['streams'][$id] = $stream; $this->_streamWatcherCount++; } else { $this->_logger->debug(null, 'Overwrote %s watcher on stream #%d', $op, $id); } $this->_streamWatchers[$op]['callbacks'][$id] = $callback; $this->_logger->debug(null, 'Added %s watcher on stream #%d, watchers: %d', $op, $id, $this->_streamWatcherCount); return true; } /** * Remove a watcher for a stream or stream ID * * @param string $op * @param resource|int $stream * @access module */ function _removeStreamWatcher($op, $stream) { $id = (int) $stream; $op = strtolower($op); if (isset($this->_streamWatchers[$op]['streams'][$id])) { unset($this->_streamWatchers[$op]['streams'][$id], $this->_streamWatchers[$op]['callbacks'][$id]); $this->_streamWatcherCount--; $this->_logger->debug(null, 'Removed %s watcher on stream #%d, watchers: %d', $op, $id, $this->_streamWatcherCount); } else { $this->_logger->debug(null, 'Could not remove %s watcher on stream #%d: not registered', $op, $id); } } /** * Clean up and shut down the event loop */ function _shutdown() { $this->_logger->info(null, 'Shutting down event loop'); // Remove all stream watchers apart from workers foreach (array('read', 'write', 'except') as $op) { foreach ($this->_streamWatchers[$op]['callbacks'] as $id => $callback) { if (!is_array($callback) || !is_a($callback[0], 'WorkerParentEndpoint')) { $this->_removeStreamWatcher($op, $id); } } } // Empty the schedule $this->_scheduler->shutdown(); // Send all workers a terminate signal $this->_dynamicWorkerPool->shutdown(); $this->_dnsWorkerPool->shutdown(); // Let workers terminate gracefully while ($this->_streamWatcherCount > 0) { $this->_processStreams($this->_getNextActivityTime()); $this->_scheduler->processActivity(); } } /** * Register a handler for a stream wrapper or set of wrappers * * @param StreamHandler $handler * @param array $schemes * @return bool */ function registerStreamHandler(&$handler, $schemes) { if (!is_a($handler, 'StreamHandler')) { return false; } foreach ($schemes as $scheme) { $this->_streamHandlers[strtolower($scheme)] = &$handler; } return true; } /** * Create a new stream * * @param string $address * @return SocketStream */ function &openStream($address) { if (!$url = parse_url($address)) { $this->_logger->warn(null, 'Unable to parse stream URL %s: Parse failed', $address); return null; } else if (!isset($url['scheme'])) { $this->_logger->warn(null, 'Unable to parse stream URL %s: Missing scheme', $address); return null; } $scheme = strtolower($url['scheme']); if (!isset($this->_streamHandlers[$scheme])) { $this->_logger->warn(null, 'No stream handler registered for URI scheme: %s', $scheme); return null; } $stream = &$this->_streamHandlers[$scheme]->createStream($this, $url); return $stream; } /** * Schedule a job to be run asynchronously in a worker * * @param string $method * @param mixed ...$args * @return AsyncJob */ function &async($method) { $args = func_get_args(); $job = &new AsyncJob($method, array_slice($args, 1)); $this->_dynamicWorkerPool->pushJob($job); $this->_logger->info(null, 'Queued async job, method: %s', $method); return $job; } /** * Resolve a host name to an IP address asynchronously * * @param string $host * @param callable $callback * @param bool $returnHost */ function resolveHost($host, $callback, $returnHost = false) { if ($host === '255.255.255.255' || ip2long($host) !== -1) { $this->in(0, $callback, $returnHost ? array($host, $host) : array($host)); } else { $job = &new AsyncJob('DNSWorker::resolve', array($host)); $this->_dnsWorkerPool->pushJob($job); $job->on('complete', $callback, $returnHost ? array($host) : array()); $job->on('error', $callback, $returnHost ? array($host, null) : array(null)); } } /** * Schedule a callback to be execute after a specified number of microseconds * * @param int $usecs * @param callable $callback * @param array $args * @return int */ function in($usecs, $callback, $args = array()) { return $this->_scheduler->createItem($this->_now() + ($usecs / 1000000), $callback, $args); } /** * Schedule a callback to execute at a specified timestamp * * @param float $timestamp * @param callable $callback * @param array $args * @return int */ function at($timestamp, $callback, $args = array()) { return $this->_scheduler->createItem($timestamp, $callback, $args); } /** * Schedule a recurring callback to execute after a specified number of microseconds * * @param int $usecs * @param callable $callback * @param array $args * @return int */ function every($usecs, $callback, $args = array()) { $secs = $usecs / 1000000; return $this->_scheduler->createItem($this->_now() + $secs, $callback, $args, $secs); } /** * Cancel a scheduled callback * * @param int $id * @return bool */ function cancel($id) { return $this->_scheduler->removeItem($id); } /** * Execute the event loop */ function run() { $this->_logger->info(null, 'Starting event loop'); $this->_running = true; // Main loop while ($this->_running && $this->_isActive()) { $timeout = $this->_getNextActivityTime(); if ($this->_streamWatcherCount > 0) { $this->_processStreams($timeout); } else { $this->_awaitNextActivity($timeout); } $this->_dynamicWorkerPool->processActivity(); $this->_dnsWorkerPool->processActivity(); $this->_scheduler->processActivity(); } $this->_running = false; $this->_shutdown(); $this->_logger->info(null, 'Event loop terminated'); } /** * Check whether the event loop is running * * @return bool */ function isRunning() { return $this->_running; } /** * Stop the event loop after the current iteration */ function stop() { $this->_logger->debug(null, 'Stopping event loop'); $this->_running = false; } } CLASS; print_r(extract_docblocks($str));
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/v007P
function name:  (null)
number of ops:  8
compiled vars:  !0 = $str
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   52     0  E >   ASSIGN                                                   !0, '%3C%3Fphp%0A%0A%2F%2A%2A%0A+%2A+Class+EventLoop%0A+%2A%0A+%2A+This+is+not+the+fastest+event+loop+implementation+in+the+world%2C+at+least%0A+%2A+partially+because+it%27s+been+stupidified+for+PHP4.+It%27s+not+really+for+high%0A+%2A+performance+asyncSaucezOMG+though%2C+so+it+shouldn%27t+matter.%0A+%2A%2F%0Aclass+EventLoop%0A%7B%0A++++%2F%2A%2A%0A+++++%2A+%40var+EventLoopConfig%0A+++++%2A%2F%0A++++var+%24config%3B%0A%0A++++%2F%2A%2A%0A+++++%2A+%40var+EventLoopLogger%0A+++++%2A+%40access+private%0A+++++%2A%2F%0A++++var+%24_logger%3B%0A%0A++++%2F%2A%2A%0A+++++%2A+%40var+WorkerPoolFactory%0A+++++%2A%2F%0A++++var+%24_workerPoolFactory%3B%0A%0A++++%2F%2A%2A%0A+++++%2A+%40var+array%0A+++++%2A+%40access+private%0A+++++%2A%2F%0A++++var+%24_streamWatchers+%3D+array%28%0A++++++++%27read%27+%3D%3E+array%28%0A++++++++++++%27streams%27+%3D%3E+array%28%29%2C%0A++++++++++++%27callbacks%27+%3D%3E+array%28%29%2C%0A++++++++%29%2C%0A++++++++%27write%27+%3D%3E+array%28%0A++++++++++++%27streams%27+%3D%3E+array%28%29%2C%0A++++++++++++%27callbacks%27+%3D%3E+array%28%29%2C%0A++++++++%29%2C%0A++++++++%27except%27+%3D%3E+array%28%0A++++++++++++%27streams%27+%3D%3E+array%28%29%2C%0A++++++++++++%27callbacks%27+%3D%3E+array%28%29%2C%0A++++++++%29%2C%0A++++%29%3B%0A%0A++++%2F%2A%2A%0A+++++%2A+%40var+int%0A+++++%2A+%40access+private%0A+++++%2A%2F%0A++++var+%24_streamWatcherCount+%3D+0%3B%0A%0A++++%2F%2A%2A%0A+++++%2A+%40var+Scheduler%0A+++++%2A+%40access+private%0A+++++%2A%2F%0A++++var+%24_scheduler%3B%0A%0A++++%2F%2A%2A%0A+++++%2A+%40var+WorkerPool%0A+++++%2A+%40access+private%0A+++++%2A%2F%0A++++var+%24_dynamicWorkerPool%3B%0A%0A++++%2F%2A%2A%0A+++++%2A+%40var+WorkerPool%0A+++++%2A+%40access+private%0A+++++%2A%2F%0A++++var+%24_dnsWorkerPool%3B%0A%0A++++%2F%2A%2A%0A+++++%2A+%40var+StreamHandler%5B%5D%0A+++++%2A+%40access+private%0A+++++%2A%2F%0A++++var+%24_streamHandlers+%3D+array%28%29%3B%0A%0A++++%2F%2A%2A%0A+++++%2A+%40var+bool%0A+++++%2A+%40access+private%0A+++++%2A%2F%0A++++var+%24_running+%3D+false%3B%0A%0A++++%2F%2A%2A%0A+++++%2A+Constructor%0A+++++%2A%0A+++++%2A+%40param+WorkerPoolFactory+%24workerPoolFactory%0A+++++%2A+%40param+EventLoopConfig+%24config%0A+++++%2A+%40param+EventLoopLogger+%24logger%0A+++++%2A+%40param+SchedulerFactory+%24schedulerFactory%0A+++++%2A+%40param+StreamHandler+%24socketStreamHandler%0A+++++%2A%2F%0A++++function+EventLoop%28%26%24workerPoolFactory%2C+%26%24config%2C+%26%24logger%2C+%26%24schedulerFactory%2C+%26%24socketStreamHandler%29%0A++++%7B%0A++++++++%24this-%3Econfig+%3D+%26%24config%3B%0A++++++++%24this-%3E_logger+%3D+%26%24logger%3B%0A++++++++%24this-%3E_workerPoolFactory+%3D+%26%24workerPoolFactory%3B%0A%0A++++++++%24this-%3E_scheduler+%3D+%26%24schedulerFactory-%3Ecreate%28%24this-%3E_logger%29%3B%0A++++++++%24this-%3EregisterStreamHandler%28%24socketStreamHandler%2C+array%28%27tcp%27%2C+%27udp%27%2C+%27unix%27%29%29%3B%0A%0A++++++++%24this-%3E_dynamicWorkerPool+%3D+%26%24workerPoolFactory-%3Ecreate%28%24this%2C+%24this-%3Econfig-%3Eworkers%2C+%24this-%3E_logger%2C+%27Dynamic%27%29%3B%0A%0A++++++++%24config-%3Edns-%3EnormalizeInheritableProperties%28%24this-%3Econfig-%3Eworkers%29%3B%0A++++++++%24this-%3E_dnsWorkerPool+%3D+%26%24workerPoolFactory-%3Ecreate%28%24this%2C+%24this-%3Econfig-%3Edns%2C+%24this-%3E_logger%2C+%27DNS%27%29%3B%0A++++%7D%0A%0A++++%2F%2A%2A%0A+++++%2A+Get+the+current+time+as+a+float%0A+++++%2A%0A+++++%2A+%40return+float%0A+++++%2A+%40access+private%0A+++++%2A%2F%0A++++function+_now%28%29%0A++++%7B%0A++++++++list%28%24usec%2C+%24sec%29+%3D+explode%28%27+%27%2C+microtime%28%29%29%3B%0A++++++++return+%28%28float%29%24usec+%2B+%28float%29%24sec%29%3B%0A++++%7D%0A%0A++++%2F%2A%2A%0A+++++%2A+Check+whether+at+least+one+client+socket+or+scheduled+item+is+active%0A+++++%2A%0A+++++%2A+%40return+bool%0A+++++%2A+%40access+private%0A+++++%2A%2F%0A++++function+_isActive%28%29%0A++++%7B%0A++++++++return+%24this-%3E_streamWatcherCount+%7C%7C+%24this-%3E_scheduler-%3EisActive%28%29%3B%0A++++%7D%0A%0A++++%2F%2A%2A%0A+++++%2A+Get+the+time+until+there+is+something+to+do%0A+++++%2A%0A+++++%2A+%40return+float%7Cnull%0A+++++%2A+%40access+private%0A+++++%2A%2F%0A++++function+_getNextActivityTime%28%29%0A++++%7B%0A++++++++%24candidates+%3D+array%28%29%3B%0A%0A++++++++if+%28null+%21%3D%3D+%24time+%3D+%24this-%3E_scheduler-%3EgetNextActivityTime%28%29%29+%7B%0A++++++++++++%24candidates%5B%5D+%3D+%24time%3B%0A++++++++%7D%0A%0A++++++++if+%28null+%21%3D%3D+%24time+%3D+%24this-%3E_dynamicWorkerPool-%3EgetNextActivityTime%28%29%29+%7B%0A++++++++++++%24candidates%5B%5D+%3D+%24time%3B%0A++++++++%7D%0A%0A++++++++if+%28null+%21%3D%3D+%24time+%3D+%24this-%3E_dnsWorkerPool-%3EgetNextActivityTime%28%29%29+%7B%0A++++++++++++%24candidates%5B%5D+%3D+%24time%3B%0A++++++++%7D%0A%0A++++++++return+%24candidates+%3F+max%28min%28%24candidates%29%2C+0%29+%3A+null%3B%0A++++%7D%0A%0A++++%2F%2A%2A%0A+++++%2A+Sleep+until+the+next+scheduled+item+is+due+to+be+executed%0A+++++%2A%0A+++++%2A+%40access+private%0A+++++%2A%2F%0A++++function+_awaitNextActivity%28%24timeout%29%0A++++%7B%0A++++++++if+%28%24timeout%29+%7B%0A++++++++++++%24this-%3E_logger-%3Edebug%28null%2C+%27Waiting+until+next+scheduled+activity%2C+timeout%3A+%25f%27%2C+%24timeout%29%3B%0A%0A++++++++++++usleep%28floor%28%24timeout+%2A+1000000%29%29%3B%0A++++++++%7D%0A++++%7D%0A%0A++++%2F%2A%2A%0A+++++%2A+Process+I%2FO+on+all+active+streams%0A+++++%2A%0A+++++%2A+%40access+private%0A+++++%2A%2F%0A++++function+_processStreams%28%24timeout%29%0A++++%7B%0A++++++++%24streams+%3D+array%28%0A++++++++++++%27read%27+++%3D%3E+%24this-%3E_streamWatchers%5B%27read%27%5D%5B%27streams%27%5D%2C%0A++++++++++++%27write%27++%3D%3E+%24this-%3E_streamWatchers%5B%27write%27%5D%5B%27streams%27%5D%2C%0A++++++++++++%27except%27+%3D%3E+%24this-%3E_streamWatchers%5B%27except%27%5D%5B%27streams%27%5D%2C%0A++++++++%29%3B%0A%0A++++++++if+%28%24timeout+%21%3D%3D+null%29+%7B%0A++++++++++++%24secs+%3D+floor%28%24timeout%29%3B%0A++++++++++++%24usecs+%3D+floor%28%28%24timeout+-+%24secs%29+%2A+1000000%29%3B%0A++++++++%7D+else+%7B%0A++++++++++++%24secs+%3D+%24usecs+%3D+null%3B%0A++++++++%7D%0A%0A++++++++%24this-%3E_logger-%3Edebug%28%0A++++++++++++null%2C+%27select%28%29+watching+%25d+streams+for+activity+%28read%3A+%25d%2C+write%3A+%25d%2C+except%3A+%25d%29%2C+timeout%3A+%25s%27%2C%0A++++++++++++count%28%24streams%5B%27read%27%5D%29+%2B+count%28%24streams%5B%27write%27%5D%29+%2B+count%28%24streams%5B%27except%27%5D%29%2C%0A++++++++++++count%28%24streams%5B%27read%27%5D%29%2C+count%28%24streams%5B%27write%27%5D%29%2C+count%28%24streams%5B%27except%27%5D%29%2C%0A++++++++++++%24secs+%3D%3D%3D+null+%3F+%27NULL%27+%3A+%22%7B%24secs%7Ds+%7B%24usecs%7Du%22%0A++++++++%29%3B%0A%0A++++++++%24count+%3D+stream_select%28%24streams%5B%27read%27%5D%2C+%24streams%5B%27write%27%5D%2C+%24streams%5B%27except%27%5D%2C+%24secs%2C+%24usecs%29%3B%0A%0A++++++++if+%28%24count+%3D%3D%3D+false%29+%7B%0A++++++++++++%24this-%3E_logger-%3Eerror%28null%2C+%27select%28%29+operation+failed%21%27%29%3B%0A++++++++++++exit%281%29%3B%0A++++++++%7D+else+if+%28%24count+%3D%3D%3D+0%29+%7B%0A++++++++++++%24this-%3E_logger-%3Edebug%28null%2C+%27select%28%29+returned+0+streams+with+activity%27%29%3B%0A++++++++++++return%3B%0A++++++++%7D%0A%0A++++++++%24this-%3E_logger-%3Edebug%28%0A++++++++++++null%2C+%27select%28%29+returned+%25d+streams+with+activity+%28read%3A+%25d%2C+write%3A+%25d%2C+except%3A+%25d%29%27%2C%0A++++++++++++%24count%2C+count%28%24streams%5B%27read%27%5D%29%2C+count%28%24streams%5B%27write%27%5D%29%2C+count%28%24streams%5B%27except%27%5D%29%0A++++++++%29%3B%0A%0A++++++++foreach+%28array%28%27read%27%2C+%27write%27%2C+%27except%27%29+as+%24op%29+%7B%0A++++++++++++foreach+%28%24streams%5B%24op%5D+as+%24stream%29+%7B%0A++++++++++++++++%24id+%3D+%28int%29+%24stream%3B%0A%0A++++++++++++++++if+%28isset%28%24this-%3E_streamWatchers%5B%24op%5D%5B%27callbacks%27%5D%5B%24id%5D%29%29+%7B%0A++++++++++++++++++++call_user_func%28%24this-%3E_streamWatchers%5B%24op%5D%5B%27callbacks%27%5D%5B%24id%5D%2C+%24stream%29%3B%0A++++++++++++++++%7D%0A++++++++++++%7D%0A++++++++%7D%0A++++%7D%0A%0A++++%2F%2A%2A%0A+++++%2A+Add+a+watcher+for+a+stream%0A+++++%2A%0A+++++%2A+%40param+string+%24op%0A+++++%2A+%40param+resource+%24stream%0A+++++%2A+%40param+callable+%24callback%0A+++++%2A+%40return+bool%0A+++++%2A+%40access+module%0A+++++%2A%2F%0A++++function+_addStreamWatcher%28%24op%2C+%24stream%2C+%24callback%29%0A++++%7B%0A++++++++%24id+%3D+%28int%29+%24stream%3B%0A++++++++%24op+%3D+strtolower%28%24op%29%3B%0A%0A++++++++if+%28%21isset%28%24this-%3E_streamWatchers%5B%24op%5D%29%29+%7B%0A++++++++++++%24this-%3E_logger-%3Edebug%28null%2C+%27Failed+to+add+%25s+watcher+on+stream+%23%25d%3A+unknown+op%27%2C+%24op%2C+%24id%29%3B%0A++++++++++++return+false%3B%0A++++++++%7D+else+if+%28%21is_resource%28%24stream%29%29+%7B%0A++++++++++++%24this-%3E_logger-%3Edebug%28null%2C+%27Failed+to+add+%25s+watcher+on+stream+%23%25d%3A+not+a+valid+stream+resource%27%2C+%24op%2C+%24id%29%3B%0A++++++++++++return+false%3B%0A++++++++%7D+else+if+%28%21is_callable%28%24callback%29%29+%7B%0A++++++++++++%24this-%3E_logger-%3Edebug%28null%2C+%27Failed+to+add+%25s+watcher+on+stream+%23%25d%3A+invalid+callback%27%2C+%24op%2C+%24id%29%3B%0A++++++++++++return+false%3B%0A++++++++%7D%0A%0A++++++++if+%28%21isset%28%24this-%3E_streamWatchers%5B%24op%5D%5B%27streams%27%5D%5B%24id%5D%29%29+%7B%0A++++++++++++%24this-%3E_streamWatchers%5B%24op%5D%5B%27streams%27%5D%5B%24id%5D+%3D+%24stream%3B%0A++++++++++++%24this-%3E_streamWatcherCount%2B%2B%3B%0A++++++++%7D+else+%7B%0A++++++++++++%24this-%3E_logger-%3Edebug%28null%2C+%27Overwrote+%25s+watcher+on+stream+%23%25d%27%2C+%24op%2C+%24id%29%3B%0A++++++++%7D%0A%0A++++++++%24this-%3E_streamWatchers%5B%24op%5D%5B%27callbacks%27%5D%5B%24id%5D+%3D+%24callback%3B%0A%0A++++++++%24this-%3E_logger-%3Edebug%28null%2C+%27Added+%25s+watcher+on+stream+%23%25d%2C+watchers%3A+%25d%27%2C+%24op%2C+%24id%2C+%24this-%3E_streamWatcherCount%29%3B%0A%0A++++++++return+true%3B%0A++++%7D%0A%0A++++%2F%2A%2A%0A+++++%2A+Remove+a+watcher+for+a+stream+or+stream+ID%0A+++++%2A%0A+++++%2A+%40param+string+%24op%0A+++++%2A+%40param+resource%7Cint+%24stream%0A+++++%2A+%40access+module%0A+++++%2A%2F%0A++++function+_removeStreamWatcher%28%24op%2C+%24stream%29%0A++++%7B%0A++++++++%24id+%3D+%28int%29+%24stream%3B%0A++++++++%24op+%3D+strtolower%28%24op%29%3B%0A%0A++++++++if+%28isset%28%24this-%3E_streamWatchers%5B%24op%5D%5B%27streams%27%5D%5B%24id%5D%29%29+%7B%0A++++++++++++unset%28%24this-%3E_streamWatchers%5B%24op%5D%5B%27streams%27%5D%5B%24id%5D%2C+%24this-%3E_streamWatchers%5B%24op%5D%5B%27callbacks%27%5D%5B%24id%5D%29%3B%0A++++++++++++%24this-%3E_streamWatcherCount--%3B%0A%0A++++++++++++%24this-%3E_logger-%3Edebug%28null%2C+%27Removed+%25s+watcher+on+stream+%23%25d%2C+watchers%3A+%25d%27%2C+%24op%2C+%24id%2C+%24this-%3E_streamWatcherCount%29%3B%0A++++++++%7D+else+%7B%0A++++++++++++%24this-%3E_logger-%3Edebug%28null%2C+%27Could+not+remove+%25s+watcher+on+stream+%23%25d%3A+not+registered%27%2C+%24op%2C+%24id%29%3B%0A++++++++%7D%0A++++%7D%0A%0A++++%2F%2A%2A%0A+++++%2A+Clean+up+and+shut+down+the+event+loop%0A+++++%2A%2F%0A++++function+_shutdown%28%29%0A++++%7B%0A++++++++%24this-%3E_logger-%3Einfo%28null%2C+%27Shutting+down+event+loop%27%29%3B%0A%0A++++++++%2F%2F+Remove+all+stream+watchers+apart+from+workers%0A++++++++foreach+%28array%28%27read%27%2C+%27write%27%2C+%27except%27%29+as+%24op%29+%7B%0A++++++++++++foreach+%28%24this-%3E_streamWatchers%5B%24op%5D%5B%27callbacks%27%5D+as+%24id+%3D%3E+%24callback%29+%7B%0A++++++++++++++++if+%28%21is_array%28%24callback%29+%7C%7C+%21is_a%28%24callback%5B0%5D%2C+%27WorkerParentEndpoint%27%29%29+%7B%0A++++++++++++++++++++%24this-%3E_removeStreamWatcher%28%24op%2C+%24id%29%3B%0A++++++++++++++++%7D%0A++++++++++++%7D%0A++++++++%7D%0A%0A++++++++%2F%2F+Empty+the+schedule%0A++++++++%24this-%3E_scheduler-%3Eshutdown%28%29%3B%0A%0A++++++++%2F%2F+Send+all+workers+a+terminate+signal%0A++++++++%24this-%3E_dynamicWorkerPool-%3Eshutdown%28%29%3B%0A++++++++%24this-%3E_dnsWorkerPool-%3Eshutdown%28%29%3B%0A%0A++++++++%2F%2F+Let+workers+terminate+gracefully%0A++++++++while+%28%24this-%3E_streamWatcherCount+%3E+0%29+%7B%0A++++++++++++%24this-%3E_processStreams%28%24this-%3E_getNextActivityTime%28%29%29%3B%0A++++++++++++%24this-%3E_scheduler-%3EprocessActivity%28%29%3B%0A++++++++%7D%0A++++%7D%0A%0A++++%2F%2A%2A%0A+++++%2A+Register+a+handler+for+a+stream+wrapper+or+set+of+wrappers%0A+++++%2A%0A+++++%2A+%40param+StreamHandler+%24handler%0A+++++%2A+%40param+array+%24schemes%0A+++++%2A+%40return+bool%0A+++++%2A%2F%0A++++function+registerStreamHandler%28%26%24handler%2C+%24schemes%29%0A++++%7B%0A++++++++if+%28%21is_a%28%24handler%2C+%27StreamHandler%27%29%29+%7B%0A++++++++++++return+false%3B%0A++++++++%7D%0A%0A++++++++foreach+%28%24schemes+as+%24scheme%29+%7B%0A++++++++++++%24this-%3E_streamHandlers%5Bstrtolower%28%24scheme%29%5D+%3D+%26%24handler%3B%0A++++++++%7D%0A%0A++++++++return+true%3B%0A++++%7D%0A%0A++++%2F%2A%2A%0A+++++%2A+Create+a+new+stream%0A+++++%2A%0A+++++%2A+%40param+string+%24address%0A+++++%2A+%40return+SocketStream%0A+++++%2A%2F%0A++++function+%26openStream%28%24address%29%0A++++%7B%0A++++++++if+%28%21%24url+%3D+parse_url%28%24address%29%29+%7B%0A++++++++++++%24this-%3E_logger-%3Ewarn%28null%2C+%27Unable+to+parse+stream+URL+%25s%3A+Parse+failed%27%2C+%24address%29%3B%0A++++++++++++return+null%3B%0A++++++++%7D+else+if+%28%21isset%28%24url%5B%27scheme%27%5D%29%29+%7B%0A++++++++++++%24this-%3E_logger-%3Ewarn%28null%2C+%27Unable+to+parse+stream+URL+%25s%3A+Missing+scheme%27%2C+%24address%29%3B%0A++++++++++++return+null%3B%0A++++++++%7D%0A%0A++++++++%24scheme+%3D+strtolower%28%24url%5B%27scheme%27%5D%29%3B%0A++++++++if+%28%21isset%28%24this-%3E_streamHandlers%5B%24scheme%5D%29%29+%7B%0A++++++++++++%24this-%3E_logger-%3Ewarn%28null%2C+%27No+stream+handler+registered+for+URI+scheme%3A+%25s%27%2C+%24scheme%29%3B%0A++++++++++++return+null%3B%0A++++++++%7D%0A%0A++++++++%24stream+%3D+%26%24this-%3E_streamHandlers%5B%24scheme%5D-%3EcreateStream%28%24this%2C+%24url%29%3B%0A%0A++++++++return+%24stream%3B%0A++++%7D%0A%0A++++%2F%2A%2A%0A+++++%2A+Schedule+a+job+to+be+run+asynchronously+in+a+worker%0A+++++%2A%0A+++++%2A+%40param+string+%24method%0A+++++%2A+%40param+mixed+...%24args%0A+++++%2A+%40return+AsyncJob%0A+++++%2A%2F%0A++++function+%26async%28%24method%29%0A++++%7B%0A++++++++%24args+%3D+func_get_args%28%29%3B%0A++++++++%24job+%3D+%26new+AsyncJob%28%24method%2C+array_slice%28%24args%2C+1%29%29%3B%0A++++++++%24this-%3E_dynamicWorkerPool-%3EpushJob%28%24job%29%3B%0A%0A++++++++%24this-%3E_logger-%3Einfo%28null%2C+%27Queued+async+job%2C+method%3A+%25s%27%2C+%24method%29%3B%0A%0A++++++++return+%24job%3B%0A++++%7D%0A%0A++++%2F%2A%2A%0A+++++%2A+Resolve+a+host+name+to+an+IP+address+asynchronously%0A+++++%2A%0A+++++%2A+%40param+string+%24host%0A+++++%2A+%40param+callable+%24callback%0A+++++%2A+%40param+bool+%24returnHost%0A+++++%2A%2F%0A++++function+resolveHost%28%24host%2C+%24callback%2C+%24returnHost+%3D+false%29%0A++++%7B%0A++++++++if+%28%24host+%3D%3D%3D+%27255.255.255.255%27+%7C%7C+ip2long%28%24host%29+%21%3D%3D+-1%29+%7B%0A++++++++++++%24this-%3Ein%280%2C+%24callback%2C+%24returnHost+%3F+array%28%24host%2C+%24host%29+%3A+array%28%24host%29%29%3B%0A++++++++%7D+else+%7B%0A++++++++++++%24job+%3D+%26new+AsyncJob%28%27DNSWorker%3A%3Aresolve%27%2C+array%28%24host%29%29%3B%0A++++++++++++%24this-%3E_dnsWorkerPool-%3EpushJob%28%24job%29%3B%0A%0A++++++++++++%24job-%3Eon%28%27complete%27%2C+%24callback%2C+%24returnHost+%3F+array%28%24host%29+%3A+array%28%29%29%3B%0A++++++++++++%24job-%3Eon%28%27error%27%2C+%24callback%2C+%24returnHost+%3F+array%28%24host%2C+null%29+%3A+array%28null%29%29%3B%0A++++++++%7D%0A++++%7D%0A%0A++++%2F%2A%2A%0A+++++%2A+Schedule+a+callback+to+be+execute+after+a+specified+number+of+microseconds%0A+++++%2A%0A+++++%2A+%40param+int+%24usecs%0A+++++%2A+%40param+callable+%24callback%0A+++++%2A+%40param+array+%24args%0A+++++%2A+%40return+int%0A+++++%2A%2F%0A++++function+in%28%24usecs%2C+%24callback%2C+%24args+%3D+array%28%29%29%0A++++%7B%0A++++++++return+%24this-%3E_scheduler-%3EcreateItem%28%24this-%3E_now%28%29+%2B+%28%24usecs+%2F+1000000%29%2C+%24callback%2C+%24args%29%3B%0A++++%7D%0A%0A++++%2F%2A%2A%0A+++++%2A+Schedule+a+callback+to+execute+at+a+specified+timestamp%0A+++++%2A%0A+++++%2A+%40param+float+%24timestamp%0A+++++%2A+%40param+callable+%24callback%0A+++++%2A+%40param+array+%24args%0A+++++%2A+%40return+int%0A+++++%2A%2F%0A++++function+at%28%24timestamp%2C+%24callback%2C+%24args+%3D+array%28%29%29%0A++++%7B%0A++++++++return+%24this-%3E_scheduler-%3EcreateItem%28%24timestamp%2C+%24callback%2C+%24args%29%3B%0A++++%7D%0A%0A++++%2F%2A%2A%0A+++++%2A+Schedule+a+recurring+callback+to+execute+after+a+specified+number+of+microseconds%0A+++++%2A%0A+++++%2A+%40param+int+%24usecs%0A+++++%2A+%40param+callable+%24callback%0A+++++%2A+%40param+array+%24args%0A+++++%2A+%40return+int%0A+++++%2A%2F%0A++++function+every%28%24usecs%2C+%24callback%2C+%24args+%3D+array%28%29%29%0A++++%7B%0A++++++++%24secs+%3D+%24usecs+%2F+1000000%3B%0A++++++++return+%24this-%3E_scheduler-%3EcreateItem%28%24this-%3E_now%28%29+%2B+%24secs%2C+%24callback%2C+%24args%2C+%24secs%29%3B%0A++++%7D%0A%0A++++%2F%2A%2A%0A+++++%2A+Cancel+a+scheduled+callback%0A+++++%2A%0A+++++%2A+%40param+int+%24id%0A+++++%2A+%40return+bool%0A+++++%2A%2F%0A++++function+cancel%28%24id%29%0A++++%7B%0A++++++++return+%24this-%3E_scheduler-%3EremoveItem%28%24id%29%3B%0A++++%7D%0A%0A++++%2F%2A%2A%0A+++++%2A+Execute+the+event+loop%0A+++++%2A%2F%0A++++function+run%28%29%0A++++%7B%0A++++++++%24this-%3E_logger-%3Einfo%28null%2C+%27Starting+event+loop%27%29%3B%0A++++++++%24this-%3E_running+%3D+true%3B%0A%0A++++++++%2F%2F+Main+loop%0A++++++++while+%28%24this-%3E_running+%26%26+%24this-%3E_isActive%28%29%29+%7B%0A++++++++++++%24timeout+%3D+%24this-%3E_getNextActivityTime%28%29%3B%0A%0A++++++++++++if+%28%24this-%3E_streamWatcherCount+%3E+0%29+%7B%0A++++++++++++++++%24this-%3E_processStreams%28%24timeout%29%3B%0A++++++++++++%7D+else+%7B%0A++++++++++++++++%24this-%3E_awaitNextActivity%28%24timeout%29%3B%0A++++++++++++%7D%0A%0A++++++++++++%24this-%3E_dynamicWorkerPool-%3EprocessActivity%28%29%3B%0A++++++++++++%24this-%3E_dnsWorkerPool-%3EprocessActivity%28%29%3B%0A%0A++++++++++++%24this-%3E_scheduler-%3EprocessActivity%28%29%3B%0A++++++++%7D%0A%0A++++++++%24this-%3E_running+%3D+false%3B%0A++++++++%24this-%3E_shutdown%28%29%3B%0A%0A++++++++%24this-%3E_logger-%3Einfo%28null%2C+%27Event+loop+terminated%27%29%3B%0A++++%7D%0A%0A++++%2F%2A%2A%0A+++++%2A+Check+whether+the+event+loop+is+running%0A+++++%2A%0A+++++%2A+%40return+bool%0A+++++%2A%2F%0A++++function+isRunning%28%29%0A++++%7B%0A++++++++return+%24this-%3E_running%3B%0A++++%7D%0A%0A++++%2F%2A%2A%0A+++++%2A+Stop+the+event+loop+after+the+current+iteration%0A+++++%2A%2F%0A++++function+stop%28%29%0A++++%7B%0A++++++++%24this-%3E_logger-%3Edebug%28null%2C+%27Stopping+event+loop%27%29%3B%0A++++++++%24this-%3E_running+%3D+false%3B%0A++++%7D%0A%7D'
  552     1        INIT_FCALL                                               'print_r'
          2        INIT_FCALL                                               'extract_docblocks'
          3        SEND_VAR                                                 !0
          4        DO_FCALL                                      0  $2      
          5        SEND_VAR                                                 $2
          6        DO_ICALL                                                 
          7      > RETURN                                                   1

Function extract_docblocks:
Finding entry points
Branch analysis from position: 0
2 jumps found. (Code = 77) Position 1 = 10, Position 2 = 63
Branch analysis from position: 10
2 jumps found. (Code = 78) Position 1 = 11, Position 2 = 63
Branch analysis from position: 11
2 jumps found. (Code = 43) Position 1 = 17, Position 2 = 21
Branch analysis from position: 17
2 jumps found. (Code = 43) Position 1 = 19, Position 2 = 20
Branch analysis from position: 19
1 jumps found. (Code = 42) Position 1 = 10
Branch analysis from position: 10
Branch analysis from position: 20
Branch analysis from position: 21
2 jumps found. (Code = 43) Position 1 = 24, Position 2 = 28
Branch analysis from position: 24
1 jumps found. (Code = 42) Position 1 = 10
Branch analysis from position: 10
Branch analysis from position: 28
2 jumps found. (Code = 43) Position 1 = 30, Position 2 = 36
Branch analysis from position: 30
1 jumps found. (Code = 42) Position 1 = 10
Branch analysis from position: 10
Branch analysis from position: 36
2 jumps found. (Code = 47) Position 1 = 47, Position 2 = 48
Branch analysis from position: 47
2 jumps found. (Code = 43) Position 1 = 49, Position 2 = 53
Branch analysis from position: 49
1 jumps found. (Code = 42) Position 1 = 62
Branch analysis from position: 62
1 jumps found. (Code = 42) Position 1 = 10
Branch analysis from position: 10
Branch analysis from position: 53
2 jumps found. (Code = 43) Position 1 = 55, Position 2 = 57
Branch analysis from position: 55
1 jumps found. (Code = 42) Position 1 = 62
Branch analysis from position: 62
Branch analysis from position: 57
1 jumps found. (Code = 42) Position 1 = 10
Branch analysis from position: 10
Branch analysis from position: 48
Branch analysis from position: 63
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 63
filename:       /in/v007P
function name:  extract_docblocks
number of ops:  66
compiled vars:  !0 = $data, !1 = $inBlock, !2 = $forceNewItem, !3 = $currentBlock, !4 = $blocks, !5 = $line
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
    3     0  E >   RECV                                             !0      
    4     1        ASSIGN                                                   !1, <false>
    5     2        ASSIGN                                                   !2, <true>
    6     3        ASSIGN                                                   !3, <array>
    7     4        ASSIGN                                                   !4, <array>
    9     5        INIT_FCALL                                               'preg_split'
          6        SEND_VAL                                                 '%2F%5B%5Cr%5Cn%5D%2B%2F'
          7        SEND_VAR                                                 !0
          8        DO_ICALL                                         $10     
          9      > FE_RESET_R                                       $11     $10, ->63
         10    > > FE_FETCH_R                                               $11, !5, ->63
   10    11    >   INIT_FCALL                                               'trim'
         12        SEND_VAR                                                 !5
         13        DO_ICALL                                         $12     
         14        ASSIGN                                                   !5, $12
   12    15        BOOL_NOT                                         ~14     !1
         16      > JMPZ                                                     ~14, ->21
   13    17    >   IS_IDENTICAL                                             !5, '%2F%2A%2A'
         18      > JMPZ                                                     ~15, ->20
   14    19    >   ASSIGN                                                   !1, <true>
   17    20    > > JMP                                                      ->10
   20    21    >   FETCH_DIM_R                                      ~17     !5, 0
         22        IS_NOT_IDENTICAL                                         ~17, '%2A'
         23      > JMPZ                                                     ~18, ->28
   21    24    >   ASSIGN                                                   !1, <false>
   22    25        ASSIGN                                                   !2, <true>
   23    26        ASSIGN                                                   !3, <array>
   25    27      > JMP                                                      ->10
   28    28    >   IS_IDENTICAL                                             !5, '%2A%2F'
         29      > JMPZ                                                     ~22, ->36
   29    30    >   ASSIGN                                                   !1, <false>
   30    31        ASSIGN                                                   !2, <true>
   31    32        ASSIGN_DIM                                               !4
         33        OP_DATA                                                  !3
   32    34        ASSIGN                                                   !3, <array>
   34    35      > JMP                                                      ->10
   37    36    >   INIT_FCALL                                               'trim'
         37        INIT_FCALL                                               'substr'
         38        SEND_VAR                                                 !5
         39        SEND_VAL                                                 1
         40        DO_ICALL                                         $27     
         41        SEND_VAR                                                 $27
         42        DO_ICALL                                         $28     
         43        ASSIGN                                                   !5, $28
   39    44        FETCH_DIM_R                                      ~30     !5, 0
         45        IS_IDENTICAL                                     ~31     ~30, '%40'
         46      > JMPNZ_EX                                         ~31     ~31, ->48
         47    >   BOOL                                             ~31     !2
         48    > > JMPZ                                                     ~31, ->53
   40    49    >   ASSIGN                                                   !2, <false>
   41    50        ASSIGN_DIM                                               !3
         51        OP_DATA                                                  !5
         52      > JMP                                                      ->62
   42    53    >   IS_IDENTICAL                                             !5, ''
         54      > JMPZ                                                     ~34, ->57
   43    55    >   ASSIGN                                                   !2, <true>
         56      > JMP                                                      ->62
   45    57    >   COUNT                                            ~36     !3
         58        SUB                                              ~37     ~36, 1
         59        CONCAT                                           ~39     '%0A', !5
         60        ASSIGN_DIM_OP                .=               8          !3, ~37
         61        OP_DATA                                                  ~39
    9    62    > > JMP                                                      ->10
         63    >   FE_FREE                                                  $11
   49    64      > RETURN                                                   !4
   50    65*     > RETURN                                                   null

End of function extract_docblocks

Generated using Vulcan Logic Dumper, using php 8.0.0


preferences:
161.26 ms | 1423 KiB | 22 Q