Bug #80634 [Opn->Ver]: write_property handler of internal classes is skipped on preloaded JITted code

From: Date: Tue, 19 Jan 2021 14:58:33 +0000
Subject: Bug #80634 [Opn->Ver]: write_property handler of internal classes is skipped on preloaded JITted code
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-231646@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=80634&edit=1

 ID:                 80634
 Updated by:         nikic@php.net
 Reported by:        dktapps at pmmp dot io
 Summary:            write_property handler of internal classes is
                     skipped on preloaded JITted code
-Status:             Open
+Status:             Verified
 Type:               Bug
 Package:            JIT
 Operating System:   Linux
 PHP Version:        8.0.1
-Assigned To:        
+Assigned To:        dmitry
 Block user comment: N
 Private report:     N

 New Comment:

Confirm the behavior. I believe the problem is that under preloading we have a prop_info available
here and will generate code based on that and end up ignoring the write_property handler (under
needs_slow_path) entirely. Without preloading we only inherit the class at runtime and the problem
doesn't occur (but I think as tracing also collects classes at runtime, there is probably some
way for it to occur without preloading as well).

Unfortunately, we don't have static information on whether a class of an object has overwritten
write_property -- this is determined by the create_object handler and not stored in the class entry.

I think the correct thing to do here is to conservatively not use any prop_info from internal
classes (or classes with internal parents).

@dmitry What do you think about this?


Previous Comments:
------------------------------------------------------------------------
[2021-01-15 23:13:39] dktapps at pmmp dot io

Description:
------------
When a class which extends an internal class is preloaded and JIT-compiled, the internal class'
write_property handler doesn't get executed. Without preloading it works correctly.

This requires quite an exotic test case to reproduce. While the test case itself doesn't make
any sense, it's a case that I've encountered while updating an extension with real code,
and I spent some time to create a reproducing test case only using PHP's own builtin classes to
ensure that it wasn't some crazy bug in my extension.

Command line is php -dopcache.enable_cli=1 -dopcache.jit=1205 -dopcache.preload=preload.php
test.php



Test script:
---------------
preload.php:
<?php

class SomeClass extends \DatePeriod{
	public $interval;

	public function __construct(int $v){
		parent::__construct(new \DateTime('2020-12-31'), new \DateInterval("P1Y"), 1);
		$this->interval = $v;
		var_dump($this->interval);
	}
}

test.php:
<?php

$v = new SomeClass(5);

Expected result:
----------------
(this output is produced without preloading or JIT)

PHP Fatal error:  Uncaught Error: Writing to DatePeriod->interval is unsupported in
/home/user/pocketmine-mp/preload.php:8
Stack trace:
#0 /home/user/pocketmine-mp/test.php(3): SomeClass->__construct()
#1 {main}
  thrown in /home/user/pocketmine-mp/preload.php on line 8



Actual result:
--------------
int(5)


------------------------------------------------------------------------



--
Edit this bug report at https://bugs.php.net/bug.php?id=80634&edit=1


Thread (3 messages)

« previous php.bugs (#231646) next »