static function enter($type, $value) { if (!hasMember(self::$stacks, $type)) { self::$stacks[$type] = array(); } // having context depth of 128 is most likely a memory leak bug version_assert and assertTrue(count(self::$stacks[$type]) < 128, "Context too deep"); array_push(self::$stacks[$type], $value); }
function isString($value) { version_assert and assertTrue(count(debug_backtrace()) < 1024, "Infinite recursion detected"); if ($value === null) { return false; } if (is_string($value)) { return true; } if (is_scalar($value)) { return false; } if (hasMember($value, 'isString')) { $result = opAccess($value, 'isString'); version_assert and assertTrue(is_bool($result)); return $result; } return false; }
function opDispatch($symbol, $member) { version_assert and assertTrue(count(func_get_args()) == 2); version_assert and assertTrue(count(debug_backtrace()) < 1024, "Infinite recursion detected"); if (is_array($symbol) && array_key_exists($member, $symbol)) { return $symbol[$member]; } if (is_object($symbol) && method_exists($symbol, $member)) { return array($symbol, $member); } if (is_object($symbol) && property_exists($symbol, $member)) { return $symbol->{$member}; } if (method_exists($symbol, 'opDispatch')) { version_assert and assertTrue(hasMember($symbol, $member)); return $symbol->opDispatch($member); } assertTrue(false, get_class($symbol)); }