HippyVM - an implementation of the PHP language in RPython

Related tags

Strings hippyvm
Overview

HippyVM

HippyVM is an implementation of the PHP language using RPython/PyPy technology.

HippyVM right now works only on 64bit linux on x86 platform (this limitation is temporary though, the RPython toolchain supports 32 and 64 bit x86, ARMv6 and ARMv7 on windows, os x and linux).

Building

The build process was tested for Ubuntu 14.04. Please create an issue/submit pull request if things are not working as expected.

1. Clone this repo ;)

git clone https://github.com/hippyvm/hippyvm

2. Get a full source checkout of RPython:

There are two alternative ways to achieve this, both equally functional:

3. Get the build dependencies:

pip install -r requirements.txt
sudo apt-get install libmysqlclient-dev libpcre3-dev librhash-dev libbz2-dev php5-cli libffi-dev

4. The building process goes like this:

cd hippyvm
<path to pypy>/rpython/bin/rpython -Ojit targethippy.py

This will create a hippy-c binary that works mostly like a php-cli without readline support.

Running it

You can run it with ./hippy-c <file.php>. Example of benchmarks are in bench/ sub-directory.

Contribution

Like many open-source projects, HippyVM is looking for contributors.

In contrast with most language implementations that use C or C++, HippyVM has a low barrier of entry since it uses RPython, a subset of the Python language. It's really easy to write and read. Check out our implementation of strstr

@wrap(['space', str, W_Root, Optional(bool)], aliases=['strchr'])
def strstr(space, haystack, w_needle, before_needle=False):
    """Find the first occurrence of a string."""
    try:
        needle = unwrap_needle(space, w_needle)
    except ValidationError as exc:
        space.ec.warn("strstr(): " + exc.msg)
        return space.w_False
    if len(needle) == 0:
        space.ec.warn("strstr(): Empty delimiter")
        return space.w_False
    pos = haystack.find(needle)
    if pos < 0:
        return space.w_False
    if before_needle:
        return space.newstr(haystack[:pos])
    else:
        return space.newstr(haystack[pos:])

Doesn't look that scary, right?

The reasons why HippyVM uses RPython go beyond this README. If you are interested, you can read more here

HippyVM's tests

If the project is up and running, which means the building section from this README went well, you can try to run HippyVM's tests.

PYTHONPATH=$PYTHONPATH:/path-to-pypy py.test testing

This will execute all the tests that were explicitly written for HippyVM, these tests are written in Python as well. The example test for the strstr is here.

PHP's tests

After having HippyVM tests up and running you can try running PHP's tests against the HippyVM implementation.

PYTHONPATH=$PYTHONPATH:/path-to-pypy py.test test_phpt/

Those tests are exact copies from the reference PHP implementation

What now?

If you find something missing, broken, or poorly implemented:

  • please create an issue, or better,
  • create a pull request and update the AUTHORS file.

Also please visit us on the irc channel #[email protected]

Comments
  • Missing spl_autoload_register support

    Missing spl_autoload_register support

    Fatal error: Call to undefined function spl_autoload_register() in /usr/local/bin/phpunit.phar on line 13

    This is the most used function :/ Cannot make any test without this.

    opened by mcuadros 11
  • New version of rply now depends on appdir

    New version of rply now depends on appdir

    In the pypy-bridge branch, I think requirements.txt needs to be updated to also include https://pypi.python.org/pypi/appdirs/1.4.0#downloads, which rply now seems to need.

    opened by ltratt 10
  • PHP extensions?

    PHP extensions?

    I know its on everybody's mind so I'll go ahead and ask it - what are your thoughts on PHP's extensions - do you expect to implement them soon, or are you expecting other people to contribute them?

    Needless to say any non trivial use of PHP requires one extension or another (pdo, mysqli, zlib, mcrypt ...), also HipHopVM are close to implementing a lot of them.

    That said this is simply incredible effort from you guys - I really really hope this can take off - having so readable php code and possibility for interop with different languages (written in RPython themselves) is simply mind blowing :) Best of :four_leaf_clover:

    opened by ivank 8
  • Iterative comparisons

    Iterative comparisons

    In response to #83, this pull request implements an (optimised) iterative comparison.

    Prior to this change, I was unable to run deltablue with a parameter of more than about 1650. Now it runs larger numbers fine.

    Below are the results before and after on richards and deltablue. Richards is ever so slightly slower, but deltablue is dramatically faster (on par with the same benchmark in python running under pypy).

    1: /home/vext01/research/hippyvm.hippyvm/hippy-c-master richards.php
                Mean        Std.Dev.    Min         Median      Max
    real        2.201       0.009       2.194       2.198       2.218       
    user        2.182       0.014       2.164       2.184       2.204       
    sys         0.015       0.008       0.008       0.012       0.028       
    
    1: /home/ltratt/hippy/hippyvm/hippy-c richards.php
                Mean        Std.Dev.    Min         Median      Max
    real        2.223       0.007       2.211       2.226       2.230       
    user        2.203       0.006       2.192       2.204       2.208       
    sys         0.016       0.003       0.012       0.016       0.020       
    
    
    
    1: /home/vext01/research/hippyvm.hippyvm/hippy-c-master deltablue.php
                Mean        Std.Dev.    Min         Median      Max
    real        3.748       0.007       3.734       3.749       3.756       
    user        3.719       0.015       3.692       3.724       3.732       
    sys         0.023       0.008       0.012       0.020       0.036       
    
    1: /home/ltratt/hippy/hippyvm/hippy-c deltablue.php
                Mean        Std.Dev.    Min         Median      Max
    real        0.317       0.002       0.314       0.318       0.320       
    user        0.302       0.004       0.296       0.304       0.308       
    sys         0.013       0.003       0.008       0.012       0.016       
    

    Note that our method _compare() is not being compiled, probably due to the loop. @cfbolz suggested to add a jit merge point for this loop. This should be a separate unit of work.

    Note that hippy does not deal with comparison cycles very well. I will raise an issue for this.

    Sorry about the large number of commits, it has been quite a journey, with the algorithm evolving over time.

    This needs to be carefully reviewed.

    opened by vext01 6
  • CI/Travis builds

    CI/Travis builds

    While the project is interesting, it would be very useful to see builds for it on either travis-ci or a publicly exposed CI environment.

    Without builds, we can't really know how much can be expected to work with this VM

    opened by Ocramius 6
  • Implement and test all of the

    Implement and test all of the "common" PHP list and dict operators/funcs on adapted PHP arrays.

    Implement and test all of the "common" PHP list and dict operators/funcs on adapted PHP arrays.

    Some xfails for del, which I will fix next.

    Still waiting for translation/performance figures...

    Will need to squash.

    opened by vext01 5
  • Fix CFFI under PyHyp

    Fix CFFI under PyHyp

    Many aspects to this:

    • Fix bogus PHP frame lookup in exception code (found during fixing cffi).
    • Correctly set sys.prefix and sys.exec_prefix. The user needs to supply PYPY_PREFIX.
    • Allow importing of modules from CWD.
    • Ensure the old CFFI interface is not usable from PyHyp.

    As of yet, I have been unable to test CFFI. Seems like this would need some more work (hence the one xfailing test). If there is interest in this, let's do it in another PR.

    Also had problems testing the bogus frame lookup due to some weirdness in py.test.

    Accompanies: https://bitbucket.org/softdevteam/pypy-hippy-bridge/pull-requests/2/hippy_bridge_sprint_cffi

    Pushing on as I have already spent too long on this.

    Assuming it translates (translating now) OK?

    opened by vext01 4
  • Optimise immut cache for cache misses.

    Optimise immut cache for cache misses.

    Hi,

    The following diff optimises Hippy's immutible cache with respect to cache misses. This is achieved by "versioning" the immutable cache and promoting the version attribute when a cell is retrieved. This allows us to build traces in which the contents of the cache can be considered constant. We also return None instead of raising in the case of a cell not existing, since exception handling (so I am told) gets in the way of the tracer/JIT.

    The majority of the was undertaken by Laurence Tratt. I only wrote more tests and benchmarked.

    The motivation behind this work is mostly for the PyPy bridge in which we frequently see cache misses (because we are looking up a Python variable which will not be in the PHP cache). However, there are cases in PHP where this change can improve performance.

    Consider the following program:

    <?php
    
    $num_runs = (int) $argv[1];
    
    for ($i = 0; $i < $num_runs; $i++) {
            function_exists("not_existing");
    }
    
    ?>
    

    The program is continually causing global_function_cache misses.

    Before the change:

    ===> multitime results
    1: ./hippy-c-vanilla /home/vext01/research/vext01.pypy_bridge_examples/err.php 500000000
                Mean        Std.Dev.    Min         Median      Max
    real        15.641      0.067       15.600      15.611      15.775
    user        15.612      0.070       15.573      15.577      15.753
    sys         0.006       0.004       0.000       0.008       0.012
    

    And after:

    ===> multitime results
    1: ./hippy-c-immut-cache-opt /home/vext01/research/vext01.pypy_bridge_examples/err.php
    +500000000
                Mean        Std.Dev.    Min         Median      Max
    real        1.949       0.003       1.944       1.949       1.954
    user        1.941       0.003       1.936       1.940       1.944
    sys         0.004       0.004       0.000       0.004       0.008
    

    So that is a pretty decent speedup.

    We also checked that programs that do not regularly miss the cache are not impacted. Here are measurements against the Richard's benchmark:

    Before:

    ===> multitime results
    1: ./hippy-c-vanilla /home/vext01/research/vext01.pypy_bridge_examples/richards/richards-vanilla.php 3000
                Mean        Std.Dev.    Min         Median      Max
    real        11.253      0.020       11.216      11.264      11.270      
    user        11.214      0.027       11.165      11.229      11.237      
    sys         0.020       0.007       0.012       0.016       0.032     
    

    After:

    ===> multitime results
    1: ./hippy-c-immut-cache-opt /home/vext01/research/vext01.pypy_bridge_examples/richards/richards-vanilla.php 3000
                Mean        Std.Dev.    Min         Median      Max
    real        11.242      0.035       11.199      11.235      11.301      
    user        11.206      0.029       11.173      11.205      11.253      
    sys         0.018       0.008       0.008       0.016       0.032   
    

    So looks pretty good. What do you guys think?

    All tests in testing/ passing.

    P.S.

    I think I can tidy up the existing immut_cache.py tests a bit, but I will make a separate pull later.

    opened by vext01 4
  • Error running rpython -Ojit targethippy.py

    Error running rpython -Ojit targethippy.py

    Hi,

    i followed the steps from documentions 2 times on OSX and Ubuntu Precise, in both cases the output is:

    mcuadros@sd-56536:~/hippyvm$ ../pypy-pypy-fe72a15b0882/rpython/bin/rpython -Ojit targethippy.py
    [translation:info] 2.7.2 (1.8+dfsg-2, Feb 19 2012, 19:18:08)
    [translation:info] [PyPy 1.8.0 with GCC 4.6.2]
    [platform:msg] Set platform with 'host' cc=None, using cc='gcc'
    [translation:info] Translating target as defined by targethippy
    Traceback (most recent call last):
      File "app_main.py", line 51, in run_toplevel
      File "../pypy-pypy-fe72a15b0882/rpython/bin/rpython", line 20, in <module>
        main()
      File "/home/mcuadros/pypy-pypy-fe72a15b0882/rpython/translator/goal/translate.py", line 217, in main
        targetspec_dic, translateconfig, config, args = parse_options_and_load_target()
      File "/home/mcuadros/pypy-pypy-fe72a15b0882/rpython/translator/goal/translate.py", line 156, in parse_options_and_load_target
        targetspec_dic = load_target(targetspec)
      File "/home/mcuadros/pypy-pypy-fe72a15b0882/rpython/translator/goal/translate.py", line 98, in load_target
        mod = __import__(specname)
      File "targethippy.py", line 2, in <module>
        from hippy.main import entry_point
      File "hippy/main.py", line 16, in <module>
        from hippy.phpcompiler import compile_php
      File "hippy/phpcompiler.py", line 1, in <module>
        from hippy.lexer import Token, Lexer
      File "hippy/lexer.py", line 3, in <module>
        from rply.token import BaseBox, Token
    ImportError: No module named rply
    
    opened by mcuadros 4
  • Check that PHPRefs are *not* transparent in Python.

    Check that PHPRefs are *not* transparent in Python.

    In response to: https://bitbucket.org/softdevteam/pypy-hippy-bridge/issues/26/implement-isinstance-on-w_phprefadapter

    (The bug is actually invalid, but the test does not hurt).

    OK?

    opened by vext01 3
  • Opt globals

    Opt globals

    This branch substantially rewrites the handling of globals.

    Previously, there was a special handler for GLOBALS which tried to keep that array and actual variables in sync. This was hampered by the fact that several other classes peeked into the contents of frames.

    This branch does two things 1) it makes globals more efficient by moving to a cell-indirection scheme that covers more cases than the previous version 2) reduces the amount of jiggery-pokery between classes.

    Benchmarks which use global variables normally can get speed-ups of about 50%; those accessing the $GLOBALS array can be upto 3x faster. Even Richards gets a 7% boost.

    opened by ltratt 3
  • Updated sha.h and sha.c to add SHA512_256 SHA512_224 hashing algorithm

    Updated sha.h and sha.c to add SHA512_256 SHA512_224 hashing algorithm

    This was found in PHP and I needed it so I implemented it in a fork. In case others need it.

    In my own driver test, I got output:

    Your hash of "The quick brown fox jumps over the lazy dog" has the SHA512-256 hash: 
    dd9d67b371519c339ed8dbd25af90e976a1eeefd4ad3d889005e532fc5bef04d
    
    Your hash of "The quick brown fox jumps over the lazy dog" has the SHA512-224 hash: 
    944cd2847fb54558d4775db0485a50003111c8e5daa63fe722c6aa37
    

    Which was the same is used on a php webform.

    For clarification below is the driver I made:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "sha.h"
    
    int main()
    {
       /* variables:     */
       /* for loop index */
       int i;                                                                           
       /* string to hash */
       const unsigned char *mystring = "The quick brown fox jumps over the lazy dog";  
       /* digest holders */
       unsigned char digest1[32];
       unsigned char digest2[28];
       /* SHA512 context */
       PHP_SHA512_CTX ctx;
       PHP_SHA512_CTX dtx;
    
       /* initialise the SHA512-256 context */
       SHA512_256Init(&ctx);
       /* update the context with the string to hash */
       SHA512_256Update(&ctx, mystring, strlen(mystring));
       /* finalise the hash context to the digest */
       SHA512_256Final(digest1, &ctx);
    
       /* output the digest */
       printf("\nYour hash of \"%s\" has the SHA512-256 hash: \n", mystring);
       for ( i = 0; i < 32; i++ )
       {
          printf("%02x", digest1[i]);
       }
    	
    	/* 224 time */
    	
       /* initialise to the now SHA512-224 context */
       SHA512_224Init(&dtx);
       /* update the context with the string to hash */
       SHA512_224Update(&dtx, mystring, strlen(mystring));
       /* finalise the hash context to the digest */
       SHA512_224Final(digest2, &dtx);
    
       /* output the digest */
       printf("\n\nYour hash of \"%s\" has the SHA512-224 hash: \n", mystring);
       for ( i = 0; i < 28; i++ )
       {
          printf("%02x", digest2[i]);
       }
    	
    	printf("\n\n");
    	
       return 0;
    }
    
    
    opened by jweinraub 0
  • Need integration documentation

    Need integration documentation

    It would be nice if the wiki had the following articles:

    1. Basic Installation
    2. Integrating with Nginx
    3. Integrating with Apache
    4. Hosting an example PHP application
    5. Known issues and limitations
    opened by MrDrMcCoy 0
  • dirname() and __FILE__  broken.

    dirname() and __FILE__ broken.

    Consider the following scenario:

    $ pwd
    /tmp
    $ find a
    a
    a/z.php
    $ cat a/z.php 
    <?php
    
    $p = dirname(__FILE__);
    echo "p = '$p'\n";
    
    ?>
    

    Now let's run this from /tmp in both php and hippyvm (e.g. php a/z.php):

    PHP gives:

    p = '/tmp/a'
    

    Hippy gives:

    p = '.'
    
    • dirname() is supposed to give an absolute path.
    • The wrong path is reported regardless of absolute/relative paths.
    opened by vext01 1
  • Hippy cannot detect cycles in comparisons.

    Hippy cannot detect cycles in comparisons.

    If you were to run this code on hippy, it would not terminate:

    class A {
        function __construct($x=NULL) {
            $this->x = $x;
        }
    }
    
    $a = new A();
    $b = new A($a);
    $a->x = $b; // completes the loop
    
    echo $a == $b;
    

    There is a test to this effect in #85.

    Zend would say this:

    PHP Fatal error:  Nesting level too deep - recursive dependency? in /tmp/cycle.php on line 9
    

    Notice how it is not sure. This is because -- short of storing all pairs of things that you have previously compared (obviously infeasable) -- they use counters to guess when a cycle has been encountered.

    Relevant code in PHP: https://github.com/php/php-src/blob/master/Zend/zend_object_handlers.c#L1338

    Specifically this macro: https://github.com/php/php-src/blob/master/Zend/zend_object_handlers.c#L42

    It's not yet clear to me if zend could reject programs that don't have cycles. The recursion counter threshold 3 at first glance is fishy (I have not spent much time thinking about this).

    Also relevant:

    http://www.phpinternalsbook.com/classes_objects/internal_structures_and_implementation.html

    Specifically:

    The apply_count member serves the same role as the nApplyCount member of
    HashTable: It protects against infinite recursion. It is used via the macros
    Z_OBJ_UNPROTECT_RECURSION(zval_ptr) (leave recursion) and
    Z_OBJ_PROTECT_RECURSION(zval_ptr) (enter recursion). The latter will throw an error
    if the nesting level for an object is 3 or larger. Currently this protection mechanism
    is only used in the object comparison handler.
    
    opened by vext01 0
  • HHVM deltablue benchmark crashes hippy

    HHVM deltablue benchmark crashes hippy

    Hi,

    We have taken this deltablue benchmark: https://github.com/facebook/hhvm/blob/master/hphp/benchmarks/php-octane/deltablue.php

    and hacked it, removing the dependency upon facebook's benchmark runner, and adding support for our own. Our runner would usually import this benchmark and call run_iter() repeatedly. We removed some extraneous comments also.

    The result is here: https://gist.github.com/vext01/3cc74eac5d416abf05d4

    For the purpose of this bug, i have manually called run_iter(2000) so that the file is standalone.

    This works under Zend PHP:

    $ time php mono.php 
    
    real    0m1.021s
    user    0m1.012s
    sys     0m0.004s
    

    But under hippy:

    vext01@bencher3:~/research/pyhyp_experiments/benchmarks/deltablue$ ~/research/hippyvm.hippyvm/hippy-c  mono.php             
    In function <main>, file mono.php, line 219
      class UnaryConstraint extends Constraint {
    Strict Standards: Declaration of UnaryConstraint::__construct() should be compatible with Constraint::__construct($strength)
     in mono.php on line 219
    In function <main>, file mono.php, line 317
      class BinaryConstraint extends Constraint {
    Strict Standards: Declaration of BinaryConstraint::__construct() should be compatible with Constraint::__construct($strength
    ) in mono.php on line 317
    In function <main>, file mono.php, line 414
      class ScaleConstraint extends BinaryConstraint {
    Strict Standards: Declaration of ScaleConstraint::__construct() should be compatible with BinaryConstraint::__construct($var
    1, $var2, $strength) in mono.php on line 414
    RPython traceback:
      File "hippy_main.c", line 458, in entry_point
      File "hippy_main.c", line 4635, in main
      File "hippy_interpreter.c", line 7081, in Interpreter_run_main
      File "hippy_interpreter.c", line 13681, in Interpreter_interpret
      File "rpython_jit_metainterp_warmspot.c", line 1149, in ll_portal_runner__Signed_hippy_bytecode_ByteCode
      File "hippy_interpreter.c", line 13681, in Interpreter_interpret                                                 [42/1809]
      File "rpython_jit_metainterp_warmspot.c", line 1149, in ll_portal_runner__Signed_hippy_bytecode_ByteCode
      File "hippy_interpreter.c", line 35375, in portal_1
      File "hippy_interpreter_1.c", line 27624, in Interpreter_CALL
      File "hippy_interpreter.c", line 13681, in Interpreter_interpret
      File "rpython_jit_metainterp_warmspot.c", line 1149, in ll_portal_runner__Signed_hippy_bytecode_ByteCode
      File "hippy_interpreter.c", line 35375, in portal_1
      File "hippy_interpreter_1.c", line 27624, in Interpreter_CALL
      File "hippy_interpreter.c", line 13681, in Interpreter_interpret
      File "rpython_jit_metainterp_warmspot.c", line 1149, in ll_portal_runner__Signed_hippy_bytecode_ByteCode
      File "hippy_interpreter.c", line 35375, in portal_1
      File "hippy_interpreter_1.c", line 27624, in Interpreter_CALL
      File "hippy_klass.c", line 3934, in ClassBase_call_args
      File "hippy_interpreter.c", line 13681, in Interpreter_interpret
      File "rpython_jit_metainterp_warmspot.c", line 1149, in ll_portal_runner__Signed_hippy_bytecode_ByteCode
      File "hippy_interpreter.c", line 35375, in portal_1
      File "hippy_interpreter_1.c", line 27624, in Interpreter_CALL
      File "hippy_interpreter.c", line 13681, in Interpreter_interpret
      File "rpython_jit_metainterp_warmspot.c", line 1149, in ll_portal_runner__Signed_hippy_bytecode_ByteCode
      File "hippy_interpreter.c", line 35375, in portal_1
      File "hippy_interpreter_1.c", line 27624, in Interpreter_CALL
      File "hippy_interpreter.c", line 13681, in Interpreter_interpret
      File "rpython_jit_metainterp_warmspot.c", line 1149, in ll_portal_runner__Signed_hippy_bytecode_ByteCode
      File "hippy_interpreter.c", line 35375, in portal_1
      File "hippy_interpreter_1.c", line 27624, in Interpreter_CALL
      File "hippy_interpreter.c", line 13681, in Interpreter_interpret
      File "rpython_jit_metainterp_warmspot.c", line 1149, in ll_portal_runner__Signed_hippy_bytecode_ByteCode
      File "hippy_interpreter.c", line 35375, in portal_1
      File "hippy_interpreter_1.c", line 27624, in Interpreter_CALL
      File "hippy_interpreter.c", line 13681, in Interpreter_interpret
      File "rpython_jit_metainterp_warmspot.c", line 1149, in ll_portal_runner__Signed_hippy_bytecode_ByteCode
      File "hippy_interpreter.c", line 35375, in portal_1
      File "hippy_interpreter_1.c", line 27624, in Interpreter_CALL
      File "hippy_interpreter.c", line 13681, in Interpreter_interpret
      File "rpython_jit_metainterp_warmspot.c", line 1149, in ll_portal_runner__Signed_hippy_bytecode_ByteCode
      File "hippy_interpreter.c", line 35375, in portal_1
      File "hippy_interpreter_1.c", line 27624, in Interpreter_CALL
      File "hippy_interpreter.c", line 13681, in Interpreter_interpret
      File "rpython_jit_metainterp_warmspot.c", line 1149, in ll_portal_runner__Signed_hippy_bytecode_ByteCode
      File "hippy_interpreter.c", line 30465, in portal_1
      File "hippy_interpreter.c", line 61654, in Interpreter_BINARY_NE
      File "hippy_objects_instanceobject.c", line 20941, in W_InstanceObject_compare
      File "hippy_objects_instanceobject.c", line 20941, in W_InstanceObject_compare
      File "hippy_objects_instanceobject.c", line 20941, in W_InstanceObject_compare
      File "hippy_objects_instanceobject.c", line 20941, in W_InstanceObject_compare                                    [0/1809]
      File "hippy_objects_instanceobject.c", line 20941, in W_InstanceObject_compare
      File "hippy_objspace.c", line 13481, in _compare_array
      File "hippy_objects_instanceobject.c", line 20941, in W_InstanceObject_compare
      File "hippy_objects_instanceobject.c", line 20941, in W_InstanceObject_compare
      File "hippy_objects_instanceobject.c", line 20941, in W_InstanceObject_compare
      File "hippy_objspace.c", line 13481, in _compare_array
      File "hippy_objects_instanceobject.c", line 20941, in W_InstanceObject_compare
      File "hippy_objects_instanceobject.c", line 20941, in W_InstanceObject_compare
      File "hippy_objects_instanceobject.c", line 20941, in W_InstanceObject_compare
      File "hippy_objspace.c", line 13481, in _compare_array
      File "hippy_objects_instanceobject.c", line 20941, in W_InstanceObject_compare
      File "hippy_objects_instanceobject.c", line 20941, in W_InstanceObject_compare
      File "hippy_objects_instanceobject.c", line 20941, in W_InstanceObject_compare
      File "hippy_objspace.c", line 13481, in _compare_array
      File "hippy_objects_instanceobject.c", line 20941, in W_InstanceObject_compare
      File "hippy_objects_instanceobject.c", line 20941, in W_InstanceObject_compare
      File "hippy_objects_instanceobject.c", line 20941, in W_InstanceObject_compare
      File "hippy_objspace.c", line 13481, in _compare_array
      File "hippy_objects_instanceobject.c", line 20941, in W_InstanceObject_compare
      File "hippy_objects_instanceobject.c", line 20941, in W_InstanceObject_compare
      File "hippy_objects_instanceobject.c", line 20941, in W_InstanceObject_compare
      File "hippy_objspace.c", line 13481, in _compare_array
      File "hippy_objects_instanceobject.c", line 20941, in W_InstanceObject_compare
      File "hippy_objects_instanceobject.c", line 20941, in W_InstanceObject_compare
      File "hippy_objects_instanceobject.c", line 20941, in W_InstanceObject_compare
      File "hippy_objspace.c", line 13481, in _compare_array
      File "hippy_objects_instanceobject.c", line 20941, in W_InstanceObject_compare
      File "hippy_objects_instanceobject.c", line 20941, in W_InstanceObject_compare
      File "hippy_objects_instanceobject.c", line 20941, in W_InstanceObject_compare
      File "hippy_objspace.c", line 13481, in _compare_array
      File "hippy_objects_instanceobject.c", line 20941, in W_InstanceObject_compare
      File "hippy_objects_instanceobject.c", line 20941, in W_InstanceObject_compare
      File "hippy_objects_instanceobject.c", line 20941, in W_InstanceObject_compare
      File "hippy_objspace.c", line 13481, in _compare_array
      File "hippy_objects_instanceobject.c", line 20941, in W_InstanceObject_compare
      File "hippy_objects_instanceobject.c", line 20941, in W_InstanceObject_compare
      File "hippy_objects_instanceobject.c", line 20941, in W_InstanceObject_compare
      File "hippy_objspace.c", line 13481, in _compare_array
      File "hippy_objects_instanceobject.c", line 20941, in W_InstanceObject_compare
      ...
    Fatal RPython error: StackOverflow
    Aborted
    

    Perhaps Hippy is stuck in infinite recursion?

    opened by vext01 1
A PHP string manipulation library with multibyte support. Compatible with PHP 5.4+, PHP 7+, and HHVM.

A PHP string manipulation library with multibyte support. Compatible with PHP 5.4+, PHP 7+, and HHVM. s('string')->toTitleCase()->ensureRight('y') ==

Daniel St. Jules 2.5k Dec 28, 2022
"結巴"中文分詞:做最好的 PHP 中文分詞、中文斷詞組件。 / "Jieba" (Chinese for "to stutter") Chinese text segmentation: built to be the best PHP Chinese word segmentation module.

jieba-php "結巴"中文分詞:做最好的 PHP 中文分詞、中文斷詞組件,目前翻譯版本為 jieba-0.33 版本,未來再慢慢往上升級,效能也需要再改善,請有興趣的開發者一起加入開發!若想使用 Python 版本請前往 fxsjy/jieba 現在已經可以支援繁體中文!只要將字典切換為 bi

Fukuball Lin 1.2k Dec 31, 2022
highlight.php is a server-side syntax highlighter written in PHP that currently supports 185 languages

highlight.php is a server-side syntax highlighter written in PHP that currently supports 185 languages. It's a port of highlight.js by Ivan Sagalaev that makes full use of the language and style definitions of the original JavaScript project.

Geert Bergman 633 Dec 27, 2022
Mobile_Detect is a lightweight PHP class for detecting mobile devices (including tablets). It uses the User-Agent string combined with specific HTTP headers to detect the mobile environment.

Motto: "Every business should have a detection script to detect mobile readers." About Mobile Detect is a lightweight PHP class for detecting mobile d

Şerban Ghiţă 10.2k Jan 4, 2023
A PHP library for generating universally unique identifiers (UUIDs).

ramsey/uuid A PHP library for generating and working with UUIDs. ramsey/uuid is a PHP library for generating and working with universally unique ident

Ben Ramsey 11.9k Jan 8, 2023
👮 A PHP desktop/mobile user agent parser with support for Laravel, based on Mobiledetect

Agent A PHP desktop/mobile user agent parser with support for Laravel, based on Mobile Detect with desktop support and additional functionality. Insta

Jens Segers 4.2k Jan 5, 2023
A lightweight php class for formatting sql statements. Handles automatic indentation and syntax highlighting.

SqlFormatter A lightweight php class for formatting sql statements. It can automatically indent and add line breaks in addition to syntax highlighting

Jeremy Dorn 3.9k Jan 1, 2023
A PHP string manipulation library with multibyte support

A PHP string manipulation library with multibyte support. Compatible with PHP 5.4+, PHP 7+, and HHVM. s('string')->toTitleCase()->ensureRight('y') ==

Daniel St. Jules 2.5k Jan 3, 2023
A sane interface for php's built in preg_* functions

Making regex great again Php's built in preg_* functions require some odd patterns like passing variables by reference and treating false or null valu

Spatie 1.1k Jan 4, 2023
A fast PHP slug generator and transliteration library that converts non-ascii characters for use in URLs.

URLify for PHP A fast PHP slug generator and transliteration library, started as a PHP port of URLify.js from the Django project. Handles symbols from

Aband*nthecar 667 Dec 20, 2022
🉑 Portable UTF-8 library - performance optimized (unicode) string functions for php.

?? Portable UTF-8 Description It is written in PHP (PHP 7+) and can work without "mbstring", "iconv" or any other extra encoding php-extension on your

Lars Moelleken 474 Dec 22, 2022
ColorJizz is a PHP library for manipulating and converting colors.

#Getting started: ColorJizz-PHP uses the PSR-0 standards for namespaces, so there should be no trouble using with frameworks like Symfony 2. ###Autolo

Mikeemoo 281 Nov 25, 2022
🔡 Portable ASCII library - performance optimized (ascii) string functions for php.

?? Portable ASCII Description It is written in PHP (PHP 7+) and can work without "mbstring", "iconv" or any other extra encoding php-extension on your

Lars Moelleken 380 Jan 6, 2023
:clamp: HtmlMin: HTML Compressor and Minifier via PHP

??️ HtmlMin: HTML Compressor and Minifier for PHP Description HtmlMin is a fast and very easy to use PHP library that minifies given HTML5 source by r

Lars Moelleken 135 Dec 8, 2022
Generate Heroku-like random names to use in your php applications.

HaikunatorPHP Generate Heroku-like random names to use in your PHP applications. Installation composer require atrox/haikunator Usage Haikunator is p

Atrox 99 Jul 19, 2022
Extensive, portable and performant handling of UTF-8 and grapheme clusters for PHP

Patchwork UTF-8 for PHP Patchwork UTF-8 gives PHP developpers extensive, portable and performant handling of UTF-8 and grapheme clusters. It provides

Nicolas Grekas 80 Sep 28, 2022
PHP library to parse urls from string input

Url highlight - PHP library to parse URLs from string input. Works with complex URLs, edge cases and encoded input. Features: Replace URLs in string b

Volodymyr Stelmakh 77 Sep 16, 2022
A lightweight php class for formatting sql statements. Handles automatic indentation and syntax highlighting.

SqlFormatter A lightweight php class for formatting sql statements. It can automatically indent and add line breaks in addition to syntax highlighting

Jeremy Dorn 3.9k Jan 3, 2023
:accept: Stringy - A PHP string manipulation library with multibyte support, performance optimized

?? Stringy A PHP string manipulation library with multibyte support. Compatible with PHP 7+ 100% compatible with the original "Stringy" library, but t

Lars Moelleken 144 Dec 12, 2022