@@ -66,7 +66,7 @@ zval *pmmpthread_get_property_ptr_ptr_stub(zend_object *object, zend_string *mem
66
66
67
67
/* {{{ */
68
68
zval * pmmpthread_read_dimension (PMMPTHREAD_READ_DIMENSION_PASSTHRU_D ) {
69
- if (pmmpthread_store_read (object , member , type , rv ) == FAILURE ) {
69
+ if (pmmpthread_store_read (object , member , NULL , type , rv ) == FAILURE ) {
70
70
//TODO: this ought to generate warnings, but this is a pain right now due to key type juggling
71
71
//for now this maintains the v4 behaviour of silently generating NULL, which is better than segfaulting
72
72
if (!EG (exception )) {
@@ -81,39 +81,27 @@ zval* pmmpthread_read_dimension(PMMPTHREAD_READ_DIMENSION_PASSTHRU_D) {
81
81
82
82
zval * pmmpthread_read_property (PMMPTHREAD_READ_PROPERTY_PASSTHRU_D ) {
83
83
zval zmember ;
84
- zend_guard * guard ;
85
-
86
- ZVAL_STR (& zmember , member );
84
+ zval result ;
87
85
88
- if (object -> ce -> __get && (guard = zend_get_property_guard (object , member )) && !((* guard ) & IN_GET )) {
89
- (* guard ) |= IN_GET ;
90
- zend_call_known_instance_method_with_1_params (object -> ce -> __get , object , rv , & zmember );
91
- (* guard ) &= ~IN_GET ;
86
+ zend_property_info * info = zend_get_property_info (object -> ce , member , 0 );
87
+ if (info != NULL && info != ZEND_WRONG_PROPERTY_INFO ) {
88
+ ZVAL_STR (& zmember , info -> name );
92
89
} else {
93
- zend_property_info * info = zend_get_property_info (object -> ce , member , 0 );
94
- if (info == ZEND_WRONG_PROPERTY_INFO ) {
95
- rv = & EG (uninitialized_zval );
96
- } else if (info == NULL || !PMMPTHREAD_OBJECT_PROPERTY (info )) { //dynamic property
97
- if (pmmpthread_store_read (object , & zmember , type , rv ) == FAILURE ) {
98
- if (type != BP_VAR_IS ) {
99
- zend_error (E_WARNING , "Undefined property: %s::$%s" , ZSTR_VAL (object -> ce -> name ), ZSTR_VAL (member ));
100
- }
101
- rv = & EG (uninitialized_zval );
102
- }
103
- } else {
104
- //defined property, use mangled name
105
- ZVAL_STR (& zmember , info -> name );
106
-
107
- if (pmmpthread_store_read (object , & zmember , type , rv ) == FAILURE ) {
108
- if (type != BP_VAR_IS && !EG (exception )) {
109
- zend_throw_error (NULL , "Typed property %s::$%s must not be accessed before initialization" ,
110
- ZSTR_VAL (info -> ce -> name ),
111
- ZSTR_VAL (member ));
112
- }
113
- rv = & EG (uninitialized_zval );
114
- }
90
+ ZVAL_STR (& zmember , member );
91
+ }
92
+ //this moves the value to cache for zend_std_read_property() to work on
93
+ pmmpthread_store_read_ex (object , & zmember , info , type , rv , 1 );
94
+ if (EG (exception )) {
95
+ rv = & EG (uninitialized_zval );
96
+ } else {
97
+ //no cache for now - we don't want the VM bypassing this handler
98
+ zend_std_read_property (object , member , type , NULL , rv );
99
+ //tidy property cache so we don't read wrong values later
100
+ if (!pmmpthread_store_retain_in_local_cache (rv )) {
101
+ pmmpthread_store_clean_local_property (object , & zmember , info );
115
102
}
116
103
}
104
+
117
105
return rv ;
118
106
}
119
107
/* }}} */
@@ -129,7 +117,7 @@ zval* pmmpthread_read_property_deny(PMMPTHREAD_READ_PROPERTY_PASSTHRU_D) {
129
117
130
118
/* {{{ */
131
119
void pmmpthread_write_dimension (PMMPTHREAD_WRITE_DIMENSION_PASSTHRU_D ) {
132
- if (pmmpthread_store_write (object , member , value , PMMPTHREAD_STORE_NO_COERCE_ARRAY ) == FAILURE && !EG (exception )){
120
+ if (pmmpthread_store_write (object , member , NULL , value , PMMPTHREAD_STORE_NO_COERCE_ARRAY ) == FAILURE && !EG (exception )){
133
121
zend_throw_error (
134
122
pmmpthread_ce_nts_value_error ,
135
123
"Cannot assign non-thread-safe value of type %s to %s" ,
@@ -144,56 +132,42 @@ zval* pmmpthread_write_property(PMMPTHREAD_WRITE_PROPERTY_PASSTHRU_D) {
144
132
zval tmp ;
145
133
zend_guard * guard ;
146
134
147
- ZVAL_STR (& zmember , member );
148
- ZVAL_UNDEF (& tmp );
149
-
150
- if (object -> ce -> __set && (guard = zend_get_property_guard (object , member )) && !((* guard ) & IN_SET )) {
151
- zval rv ;
152
- ZVAL_UNDEF (& rv );
135
+ //no cache for now - cache would allow the VM to bypass this handler
136
+ //std_write may coerce the var to a different type, so we need to use the result
137
+ value = zend_std_write_property (object , member , value , NULL );
153
138
154
- (* guard ) |= IN_SET ;
155
- zend_call_known_instance_method_with_2_params (object -> ce -> __set , object , & rv , & zmember , value );
156
- (* guard ) &= ~IN_SET ;
157
-
158
- if (Z_TYPE (rv ) != IS_UNDEF )
159
- zval_dtor (& rv );
160
- } else {
161
- bool ok = true;
139
+ if (value != & EG (error_zval )) {
140
+ zval * real_value = NULL ;
141
+ zval zmember ;
142
+ ZVAL_UNDEF (& zmember );
162
143
zend_property_info * info = zend_get_property_info (object -> ce , member , 0 );
163
- if (info != ZEND_WRONG_PROPERTY_INFO ) {
164
- if (info != NULL && PMMPTHREAD_OBJECT_PROPERTY (info )) {
165
- ZVAL_STR (& zmember , info -> name ); //use mangled name to avoid private member shadowing issues
166
-
167
- zend_execute_data * execute_data = EG (current_execute_data );
168
- bool strict = execute_data
169
- && execute_data -> func
170
- && ZEND_CALL_USES_STRICT_TYPES (EG (current_execute_data ));
171
-
172
- //zend_verify_property_type() might modify the value
173
- //value is not copied before we receive it, so it might be
174
- //from opcache protected memory which we can't modify
175
- ZVAL_COPY (& tmp , value );
176
- value = & tmp ;
177
-
178
- if (ZEND_TYPE_IS_SET (info -> type ) && !zend_verify_property_type (info , value , strict )) {
179
- ok = false;
180
- }
144
+ if (info != NULL ) {
145
+ if (info != ZEND_WRONG_PROPERTY_INFO ) {
146
+ ZVAL_STR (& zmember , info -> name );
147
+ real_value = OBJ_PROP (object , info -> offset );
181
148
}
182
-
183
- if (ok && pmmpthread_store_write (object , & zmember , value , PMMPTHREAD_STORE_NO_COERCE_ARRAY ) == FAILURE && !EG (exception )) {
149
+ } else if (object -> properties != NULL ) {
150
+ ZVAL_STR (& zmember , member );
151
+ real_value = zend_hash_find (object -> properties , member );
152
+ }
153
+ if (real_value != NULL ) {
154
+ zend_bool cached = 0 ;
155
+ if (pmmpthread_store_write_ex (object , & zmember , info , real_value , PMMPTHREAD_STORE_NO_COERCE_ARRAY , & cached ) == FAILURE && !EG (exception )) {
184
156
zend_throw_error (
185
157
pmmpthread_ce_nts_value_error ,
186
158
"Cannot assign non-thread-safe value of type %s to thread-safe class property %s::$%s" ,
187
159
zend_zval_type_name (value ),
188
160
ZSTR_VAL (object -> ce -> name ),
189
161
ZSTR_VAL (member )
190
162
);
163
+ value = & EG (error_zval );
164
+ }
165
+ if (!cached ) {
166
+ pmmpthread_store_clean_local_property (object , & zmember , info );
191
167
}
192
168
}
193
169
}
194
170
195
- zval_ptr_dtor (& tmp );
196
-
197
171
return EG (exception ) ? & EG (error_zval ) : value ;
198
172
}
199
173
/* }}} */
@@ -249,34 +223,21 @@ int pmmpthread_has_property_deny(PMMPTHREAD_HAS_PROPERTY_PASSTHRU_D) {
249
223
250
224
/* {{{ */
251
225
void pmmpthread_unset_dimension (PMMPTHREAD_UNSET_DIMENSION_PASSTHRU_D ) {
252
- pmmpthread_store_delete (object , member );
226
+ pmmpthread_store_delete (object , member , NULL );
253
227
}
254
228
255
229
void pmmpthread_unset_property (PMMPTHREAD_UNSET_PROPERTY_PASSTHRU_D ) {
256
230
zval zmember ;
257
- zend_guard * guard ;
258
-
259
- ZVAL_STR (& zmember , member );
260
-
261
- if (object -> ce -> __unset && (guard = zend_get_property_guard (object , member )) && !((* guard ) & IN_UNSET )) {
262
- zval rv ;
263
- ZVAL_UNDEF (& rv );
264
-
265
- (* guard ) |= IN_UNSET ;
266
- zend_call_known_instance_method_with_1_params (object -> ce -> __unset , object , & rv , & zmember );
267
- (* guard ) &= ~IN_UNSET ;
268
-
269
- if (Z_TYPE (rv ) != IS_UNDEF ) {
270
- zval_dtor (& rv );
271
- }
272
- } else {
231
+
232
+ zend_std_unset_property (object , member , NULL );
233
+ if (!EG (exception )) {
273
234
zend_property_info * info = zend_get_property_info (object -> ce , member , 0 );
274
- if (info != ZEND_WRONG_PROPERTY_INFO ) {
275
- if (info != NULL && PMMPTHREAD_OBJECT_PROPERTY (info )) {
276
- ZVAL_STR (& zmember , info -> name ); //defined property, use mangled name
277
- }
278
- pmmpthread_store_delete (object , & zmember );
235
+ if (info != NULL && info != ZEND_WRONG_PROPERTY_INFO ) {
236
+ ZVAL_STR (& zmember , info -> name );
237
+ } else {
238
+ ZVAL_STR (& zmember , member );
279
239
}
240
+ pmmpthread_store_delete (object , & zmember , info );
280
241
}
281
242
}
282
243
/* }}} */
0 commit comments