Skip to content

Conversation

thinkverse
Copy link
Owner

Like @ryangjchandler, I wanted to experiment with PHP source code a bit, since his live stream showed it was actually quite easy to start messing with it. Got no experience with C but what the heck. Following Ryan's example, I tried to implement my own clamp function based on his own experiment.

Usage example

This is a snippet from Color, where this function would be useful.

Before

class Color
{
    public function __construct(int $red = 0, int $green = 0, int $blue = 0, float $alpha = 1.0)
    {
        $this->red   = max(0, min(255, $red));
        $this->green = max(0, min(255, $green));
        $this->blue  = max(0, min(255, $blue));
        $this->alpha = max(0, min(1.0, $alpha));
    }
}

After

class Color
{
    public function __construct(int $red = 0, int $green = 0, int $blue = 0, float $alpha = 1.0)
    {
        $this->red   = clamp($red, 0, 255);
        $this->green = clamp($green, 0, 255);
        $this->blue  = clamp($blue, 0, 255);
        $this->alpha = clamp($alpha, 0, 1.0);
    }
}

thinkverse pushed a commit that referenced this pull request Jun 9, 2021
1. For statement "$a->change($a = array("a" => range(1, 5)));", the
following opcodes will be generated:

  0002 ASSIGN CV0($a) V1
  0003 INIT_METHOD_CALL 1 CV0($a) string("change")
  0004 INIT_NS_FCALL_BY_NAME 2 string("A\range")
  0005 SEND_VAL_EX int(1) 1
  0006 SEND_VAL_EX int(5) 2
  0007 V1 = DO_FCALL_BY_NAME

The updates in function zend_jit_init_fcall(), zend_jit_send_val() and
zend_jit_do_fcall() are made to support INIT_NS_FCALL_BY_NAME,
SEND_VAL_EX and DO_FCALL_BY_NAME respectively.

2. For method $change(), opcode RECV is used to obtain the argument:

  0000 #1.CV0($config) [rc1, rcn, array of [any, ref]] = RECV 1

Accordingly the updates in functions zend_jit_recv() and
zend_jit_verify_arg_type() are made.

3. For statement "array_keys($config["a"])", the following opcodes will
be generated:

  0001 INIT_NS_FCALL_BY_NAME 1 string("A\array_keys")
  0002 CHECK_FUNC_ARG 1
  0003 php#3.V1 [ref, rc1, rcn, any] = FETCH_DIM_FUNC_ARG #1.CV0($config)
     ... -> php#2.CV0($config) [rc1, rcn, ...
  0004 SEND_FUNC_ARG php#3.V1 [ref, rc1, rcn, any] 1
  0005 php#4.V1 [ref, rc1, rcn, any] = DO_FCALL_BY_NAME

CHECK_FUNC_ARG and SEND_FUNC_ARG are not supported before. See the
updates in functions zend_jit_check_func_arg() and zend_jit_send_var().

Besides, a new path is covered in macro OBJ_RELEASE when leaving.
thinkverse pushed a commit that referenced this pull request Jun 9, 2021
The opcodes for function $foo are:

  0001 INIT_FCALL 1 96 string("var_dump")
  0002 php#2.T1 [null, long] = FETCH_DIM_R array(...) #1.CV0($n) [...]
  0003 SEND_VAL php#2.T1 [null, long] 1
  0004 DO_ICALL
  0005 RETURN null

Opcode FETCH_DIM_R is not touched before, and the updates in function
zend_jit_fetch_dim_read() are made to support it.
As different types of arguments are used for $foo, several cases in
function zend_jit_fetch_dimension_address_inner() are covered as well.

Besides, opcode DO_ICALL can reach one site of cold code in function
zend_jit_do_fcall().
thinkverse pushed a commit that referenced this pull request Jun 9, 2021
Opcodes for $Test::method are:

  BB0:
  0000 #0.T0 [rcn, any] = FETCH_OBJ_R THIS string("prop")
  0001 #1.T0 [bool] RANGE[0..1] = JMPZ_EX #0.T0 [rcn, any] BB3

  BB1:
  0002 php#2.T1 [rcn, any] = FETCH_OBJ_R THIS string("prop")
  0003 INIT_METHOD_CALL 0 php#2.T1 [rcn, any] string("method2")
  0004 php#3.V1 [ref, rc1, rcn, any] = DO_FCALL
  ...

New path is covered in functions zend_jit_fetch_obj() and
zend_jit_zval_copy_deref() for FETCH_OBJ_R THIS opcode.

New path is covered in function zend_jit_init_method_call() for opcode
INIT_METHOD_CALL.

Major chagnes lie in function zend_jit_bool_jmpznz() to support opcode
JMPZ_EX.

Note that macro ZVAL_DTOR_FUNC is updated to remove the hard-coded use
of REG0.
thinkverse pushed a commit that referenced this pull request Jun 9, 2021
Opcodes for $test are:

  BB0:
  0000 #1.CV0($char_code) [rc1, rcn, any] = RECV 1

  BB1:
  0001 php#2.T1 [rc1, ...] = BW_AND #1.CV0($char_code) ...
  0002 php#3.T2 [bool] RANGE[0..1] = BOOL_NOT php#2.T1 [rc1, ...]
  0003 php#4.T1 [bool] RANGE[0..1] = IS_EQUAL #1.CV0($char_code) ...
  0004 JMPZ php#4.T1 [bool] RANGE[0..1] BB3
  ...

New path is covered in function zend_jit_long_math_helper() for opcode
BW_AND.

New path is covered in function zend_jit_bool_jmpznz() for opcode
BOOL_NOT.

Major changes lie in functions zend_jit_cmp(), zend_jit_cmp_slow() and
zend_jit_check_exception_undef_result() to support opocdes IS_EQUAL and
JMPZ.
thinkverse pushed a commit that referenced this pull request Jun 23, 2021
* JIT/AArch64: Support shifted immediate

As pointed out by MikePall in [1], shifted immediate value is supported.
See [2]. For example, `add x0, x1, php#4096` would be encoded by DynASM
into `add x0, x1, #1, lsl php#12` directly.

In this patch, a helper is added to check whether an immediate value is
in the two allowed ranges: (1) 0 to 4095, and (2) LSL php#12 on all the
values from the first range.

Note that this helper works for add/adds/sub/subs/cmp/cmn instructions.

[1] LuaJIT/LuaJIT#718
[2]
https://github.com/LuaJIT/LuaJIT/blob/v2.1/dynasm/dasm_arm64.lua#L342

Change-Id: I4870048b9b8e6c429b73a4803af2a3b2d5ec0fbb

* Deprecatd CMP_IMM/ADD_SUB_IMM and add test cases

Macros CMP_IMM and ADD_SUB_IMM are deprecated and instead we use
this helper to guard the immediate encoding.

Add two 64-bit only test cases, since 64-bit integers are used
and tested inside.

Change-Id: I0b42d4617b40372e2f4ce5b6ad31a4ddb7d89e49
@thinkverse thinkverse closed this Jul 8, 2021
thinkverse pushed a commit that referenced this pull request Nov 8, 2021
thinkverse pushed a commit that referenced this pull request Nov 8, 2021
* PHP-8.0:
  Tracing JIT: Fixed incorrect assumtion about temporary variable types clobbered by *_ROPE instructions
  Revert "Fix bug GH-1 (mysqli_sql_exception->sqlstate is inaccessible)"
  Fix bug GH-1 (mysqli_sql_exception->sqlstate is inaccessible)
thinkverse pushed a commit that referenced this pull request Nov 8, 2021
* PHP-8.1:
  Tracing JIT: Fixed incorrect assumtion about temporary variable types clobbered by *_ROPE instructions
  Revert "Fix bug GH-1 (mysqli_sql_exception->sqlstate is inaccessible)"
  Fix bug GH-1 (mysqli_sql_exception->sqlstate is inaccessible)
thinkverse pushed a commit that referenced this pull request Mar 12, 2023
…hp#10393)

The CSPRNG failing should be rare nowadays, but it *might* happen and without
this patch it's hard for the user to find out why the salt generation failed:
The error message is not actionable.

This patch will automatically set the CSPRNG exception to the `$previous`
exception of the ValueError that is thrown, allowing the developer to determine
the cause of the salt generation failure.

Before:

    Fatal error: Uncaught ValueError: Unable to generate salt in php-src/test3.php:3
    Stack trace:
    #0 php-src/test3.php(3): password_hash(Object(SensitiveParameterValue), '2y')
    #1 {main}
      thrown in php-src/test3.php on line 3

After:

    Fatal error: Uncaught Random\RandomException: Cannot open /dev/urandom: No such file or directory in php-src/test3.php:3
    Stack trace:
    #0 php-src/test3.php(3): password_hash(Object(SensitiveParameterValue), '2y')
    #1 {main}

    Next ValueError: Unable to generate salt in php-src/test3.php:3
    Stack trace:
    #0 php-src/test3.php(3): password_hash(Object(SensitiveParameterValue), '2y')
    #1 {main}
      thrown in php-src/test3.php on line 3
thinkverse pushed a commit that referenced this pull request Mar 12, 2023
…#10533)

Commit a211956 added a TSRM destructor, but that destructor
will get called by tsrm_shutdown(), which is after opcache.so has
already been unloaded, resulting in a shutdown crash, e.g.:

  #0  0x00007fad01737500 in ?? ()
  #1  0x000055ac54e723c4 in tsrm_shutdown () at TSRM/TSRM.c:194
  php#2  0x000055ac54c42180 in main (argc=80, argv=0x55ac57bc14d0) at sapi/cli/php_cli.c:1388

By calling ts_free_id() before opcache.so gets unloaded, we can easily
fix this crash bug.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant