| 94 | | static void calc_hash_int (HashTable * source, Bucket * start, |
|---|
| 95 | | calc_bucket_t calc_bucket TSRMLS_DC) |
|---|
| 96 | | { |
|---|
| 97 | | Bucket *p; |
|---|
| 98 | | |
|---|
| 99 | | if (source->nNumOfElements > 0) { |
|---|
| 100 | | if (!EAG (compress)) { |
|---|
| 101 | | EACCELERATOR_ALIGN (EAG (mem)); |
|---|
| 102 | | EAG (mem) += source->nTableSize * sizeof (Bucket *); |
|---|
| 103 | | } |
|---|
| 104 | | p = start; |
|---|
| 105 | | while (p) { |
|---|
| 106 | | EACCELERATOR_ALIGN (EAG (mem)); |
|---|
| 107 | | EAG (mem) += offsetof (Bucket, arKey) + p->nKeyLength; |
|---|
| 108 | | calc_bucket (p->pData TSRMLS_CC); |
|---|
| 109 | | p = p->pListNext; |
|---|
| 110 | | } |
|---|
| 111 | | } |
|---|
| 112 | | } |
|---|
| 113 | | |
|---|
| 114 | | void calc_zval (zval * zv TSRMLS_DC) |
|---|
| 115 | | { |
|---|
| 116 | | switch (zv->type & ~IS_CONSTANT_INDEX) { |
|---|
| 117 | | case IS_CONSTANT: |
|---|
| 118 | | case IS_STRING: |
|---|
| 119 | | if (zv->value.str.val == NULL || |
|---|
| 120 | | zv->value.str.val == empty_string || zv->value.str.len == 0) { |
|---|
| 121 | | } else { |
|---|
| 122 | | calc_string (zv->value.str.val, zv->value.str.len + 1 TSRMLS_CC); |
|---|
| 123 | | } |
|---|
| 124 | | break; |
|---|
| 125 | | case IS_ARRAY: |
|---|
| 126 | | case IS_CONSTANT_ARRAY: |
|---|
| 127 | | if (zv->value.ht == NULL || zv->value.ht == &EG (symbol_table)) { |
|---|
| 128 | | } else { |
|---|
| 129 | | EACCELERATOR_ALIGN (EAG (mem)); |
|---|
| 130 | | EAG (mem) += sizeof (HashTable); |
|---|
| 131 | | calc_zval_hash (zv->value.ht); |
|---|
| 132 | | } |
|---|
| 133 | | break; |
|---|
| 134 | | case IS_OBJECT: |
|---|
| | 95 | static void calc_hash_int(HashTable * source, Bucket * start, |
|---|
| | 96 | calc_bucket_t calc_bucket TSRMLS_DC) |
|---|
| | 97 | { |
|---|
| | 98 | Bucket *p; |
|---|
| | 99 | |
|---|
| | 100 | if (source->nNumOfElements > 0) { |
|---|
| | 101 | if (!EAG(compress)) { |
|---|
| | 102 | EACCELERATOR_ALIGN(EAG(mem)); |
|---|
| | 103 | EAG(mem) += source->nTableSize * sizeof(Bucket *); |
|---|
| | 104 | } |
|---|
| | 105 | p = start; |
|---|
| | 106 | while (p) { |
|---|
| | 107 | EACCELERATOR_ALIGN(EAG(mem)); |
|---|
| | 108 | EAG(mem) += offsetof(Bucket, arKey) + p->nKeyLength; |
|---|
| | 109 | calc_bucket(p->pData TSRMLS_CC); |
|---|
| | 110 | p = p->pListNext; |
|---|
| | 111 | } |
|---|
| | 112 | } |
|---|
| | 113 | } |
|---|
| | 114 | |
|---|
| | 115 | void calc_zval(zval * zv TSRMLS_DC) |
|---|
| | 116 | { |
|---|
| | 117 | switch (zv->type & ~IS_CONSTANT_INDEX) { |
|---|
| | 118 | case IS_CONSTANT: |
|---|
| | 119 | case IS_STRING: |
|---|
| | 120 | if (zv->value.str.val == NULL || zv->value.str.val == empty_string || zv->value.str.len == 0) { |
|---|
| | 121 | } else { |
|---|
| | 122 | calc_string(zv->value.str.val, zv->value.str.len + 1 TSRMLS_CC); |
|---|
| | 123 | } |
|---|
| | 124 | break; |
|---|
| | 125 | case IS_ARRAY: |
|---|
| | 126 | case IS_CONSTANT_ARRAY: |
|---|
| | 127 | if (zv->value.ht != NULL && zv->value.ht != &EG(symbol_table)) { |
|---|
| | 128 | EACCELERATOR_ALIGN(EAG(mem)); |
|---|
| | 129 | EAG(mem) += sizeof(HashTable); |
|---|
| | 130 | calc_zval_hash(zv->value.ht); |
|---|
| | 131 | } |
|---|
| | 132 | break; |
|---|
| | 133 | case IS_OBJECT: |
|---|
| 171 | | void calc_op_array (zend_op_array * from TSRMLS_DC) |
|---|
| 172 | | { |
|---|
| 173 | | zend_op *opline; |
|---|
| 174 | | zend_op *end; |
|---|
| 175 | | |
|---|
| 176 | | if (from->type == ZEND_INTERNAL_FUNCTION) { |
|---|
| 177 | | EACCELERATOR_ALIGN (EAG (mem)); |
|---|
| 178 | | EAG (mem) += sizeof (zend_internal_function); |
|---|
| 179 | | } else if (from->type == ZEND_USER_FUNCTION) { |
|---|
| 180 | | EACCELERATOR_ALIGN (EAG (mem)); |
|---|
| 181 | | EAG (mem) += sizeof (eaccelerator_op_array); |
|---|
| 182 | | } else { |
|---|
| 183 | | ea_debug_error ("[%d] EACCELERATOR can't cache function \"%s\"\n", |
|---|
| 184 | | getpid (), from->function_name); |
|---|
| 185 | | zend_bailout (); |
|---|
| 186 | | } |
|---|
| 187 | | #ifdef ZEND_ENGINE_2 |
|---|
| 188 | | if (from->num_args > 0) { |
|---|
| 189 | | zend_uint i; |
|---|
| 190 | | EACCELERATOR_ALIGN (EAG (mem)); |
|---|
| 191 | | EAG (mem) += from->num_args * sizeof (zend_arg_info); |
|---|
| 192 | | for (i = 0; i < from->num_args; i++) { |
|---|
| 193 | | if (from->arg_info[i].name) { |
|---|
| 194 | | calc_string (from->arg_info[i].name, |
|---|
| 195 | | from->arg_info[i].name_len + 1 TSRMLS_CC); |
|---|
| 196 | | } |
|---|
| 197 | | if (from->arg_info[i].class_name) { |
|---|
| 198 | | calc_string (from->arg_info[i].class_name, |
|---|
| 199 | | from->arg_info[i].class_name_len + 1 TSRMLS_CC); |
|---|
| 200 | | } |
|---|
| 201 | | } |
|---|
| 202 | | } |
|---|
| | 166 | void calc_op_array(zend_op_array * from TSRMLS_DC) |
|---|
| | 167 | { |
|---|
| | 168 | zend_op *opline; |
|---|
| | 169 | zend_op *end; |
|---|
| | 170 | |
|---|
| | 171 | if (from->type == ZEND_INTERNAL_FUNCTION) { |
|---|
| | 172 | EACCELERATOR_ALIGN(EAG(mem)); |
|---|
| | 173 | EAG(mem) += sizeof(zend_internal_function); |
|---|
| | 174 | } else if (from->type == ZEND_USER_FUNCTION) { |
|---|
| | 175 | EACCELERATOR_ALIGN(EAG(mem)); |
|---|
| | 176 | EAG(mem) += sizeof(eaccelerator_op_array); |
|---|
| | 177 | } else { |
|---|
| | 178 | ea_debug_error("[%d] EACCELERATOR can't cache function \"%s\"\n", getpid(), from->function_name); |
|---|
| | 179 | zend_bailout(); |
|---|
| | 180 | } |
|---|
| | 181 | #ifdef ZEND_ENGINE_2 |
|---|
| | 182 | if (from->num_args > 0) { |
|---|
| | 183 | zend_uint i; |
|---|
| | 184 | EACCELERATOR_ALIGN(EAG(mem)); |
|---|
| | 185 | EAG(mem) += from->num_args * sizeof(zend_arg_info); |
|---|
| | 186 | for (i = 0; i < from->num_args; i++) { |
|---|
| | 187 | if (from->arg_info[i].name) |
|---|
| | 188 | calc_string(from->arg_info[i].name, from->arg_info[i].name_len + 1 TSRMLS_CC); |
|---|
| | 189 | if (from->arg_info[i].class_name) |
|---|
| | 190 | calc_string(from->arg_info[i].class_name, from->arg_info[i].class_name_len + 1 TSRMLS_CC); |
|---|
| | 191 | } |
|---|
| | 192 | } |
|---|
| 204 | | if (from->arg_types != NULL) { |
|---|
| 205 | | calc_string ((char *) from->arg_types, |
|---|
| 206 | | (from->arg_types[0] + 1) * sizeof (zend_uchar) TSRMLS_CC); |
|---|
| 207 | | } |
|---|
| 208 | | #endif |
|---|
| 209 | | if (from->function_name != NULL) { |
|---|
| 210 | | calc_string (from->function_name, |
|---|
| 211 | | strlen (from->function_name) + 1 TSRMLS_CC); |
|---|
| 212 | | } |
|---|
| 213 | | #ifdef ZEND_ENGINE_2 |
|---|
| 214 | | if (from->scope != NULL) { |
|---|
| 215 | | // HOESH: the same problem? |
|---|
| 216 | | Bucket *q = CG (class_table)->pListHead; |
|---|
| 217 | | while (q != NULL) { |
|---|
| 218 | | if (*(zend_class_entry **) q->pData == from->scope) { |
|---|
| 219 | | calc_string (q->arKey, q->nKeyLength TSRMLS_CC); |
|---|
| 220 | | break; |
|---|
| 221 | | } |
|---|
| 222 | | q = q->pListNext; |
|---|
| 223 | | } |
|---|
| 224 | | } |
|---|
| 225 | | #endif |
|---|
| 226 | | if (from->type == ZEND_INTERNAL_FUNCTION) { |
|---|
| 227 | | return; |
|---|
| 228 | | } |
|---|
| 229 | | |
|---|
| 230 | | if (from->opcodes != NULL) { |
|---|
| 231 | | EACCELERATOR_ALIGN (EAG (mem)); |
|---|
| 232 | | EAG (mem) += from->last * sizeof (zend_op); |
|---|
| 233 | | |
|---|
| 234 | | opline = from->opcodes; |
|---|
| 235 | | end = opline + from->last; |
|---|
| 236 | | EAG (compress) = 0; |
|---|
| 237 | | for (; opline < end; opline++) { |
|---|
| | 194 | if (from->arg_types != NULL) |
|---|
| | 195 | calc_string((char *) from->arg_types, (from->arg_types[0] + 1) * sizeof(zend_uchar) TSRMLS_CC); |
|---|
| | 196 | #endif |
|---|
| | 197 | if (from->function_name != NULL) |
|---|
| | 198 | calc_string(from->function_name, strlen(from->function_name) + 1 TSRMLS_CC); |
|---|
| | 199 | #ifdef ZEND_ENGINE_2 |
|---|
| | 200 | if (from->scope != NULL) { |
|---|
| | 201 | // HOESH: the same problem? |
|---|
| | 202 | Bucket *q = CG(class_table)->pListHead; |
|---|
| | 203 | while (q != NULL) { |
|---|
| | 204 | if (*(zend_class_entry **) q->pData == from->scope) { |
|---|
| | 205 | calc_string(q->arKey, q->nKeyLength TSRMLS_CC); |
|---|
| | 206 | break; |
|---|
| | 207 | } |
|---|
| | 208 | q = q->pListNext; |
|---|
| | 209 | } |
|---|
| | 210 | } |
|---|
| | 211 | #endif |
|---|
| | 212 | if (from->type == ZEND_INTERNAL_FUNCTION) |
|---|
| | 213 | return; |
|---|
| | 214 | |
|---|
| | 215 | if (from->opcodes != NULL) { |
|---|
| | 216 | EACCELERATOR_ALIGN(EAG(mem)); |
|---|
| | 217 | EAG(mem) += from->last * sizeof(zend_op); |
|---|
| | 218 | |
|---|
| | 219 | opline = from->opcodes; |
|---|
| | 220 | end = opline + from->last; |
|---|
| | 221 | EAG(compress) = 0; |
|---|
| | 222 | for (; opline < end; opline++) { |
|---|
| 241 | | if (opline->op1.op_type == IS_CONST) |
|---|
| 242 | | calc_zval (&opline->op1.u.constant TSRMLS_CC); |
|---|
| 243 | | if (opline->op2.op_type == IS_CONST) |
|---|
| 244 | | calc_zval (&opline->op2.u.constant TSRMLS_CC); |
|---|
| 245 | | } |
|---|
| 246 | | EAG (compress) = 1; |
|---|
| 247 | | } |
|---|
| 248 | | if (from->brk_cont_array != NULL) { |
|---|
| 249 | | EACCELERATOR_ALIGN (EAG (mem)); |
|---|
| 250 | | EAG (mem) += sizeof (zend_brk_cont_element) * from->last_brk_cont; |
|---|
| 251 | | } |
|---|
| 252 | | #ifdef ZEND_ENGINE_2 |
|---|
| 253 | | /* HOESH: try & catch support */ |
|---|
| 254 | | if (from->try_catch_array != NULL) { |
|---|
| 255 | | EACCELERATOR_ALIGN (EAG (mem)); |
|---|
| 256 | | EAG (mem) += sizeof (zend_try_catch_element) * from->last_try_catch; |
|---|
| 257 | | } |
|---|
| 258 | | #endif |
|---|
| 259 | | if (from->static_variables != NULL) { |
|---|
| 260 | | EACCELERATOR_ALIGN (EAG (mem)); |
|---|
| 261 | | EAG (mem) += sizeof (HashTable); |
|---|
| 262 | | calc_zval_hash (from->static_variables); |
|---|
| 263 | | } |
|---|
| 264 | | if (from->filename != NULL) { |
|---|
| 265 | | calc_string (from->filename, strlen (from->filename) + 1 TSRMLS_CC); |
|---|
| 266 | | } |
|---|
| 267 | | #ifdef ZEND_ENGINE_2 |
|---|
| 268 | | if (from->doc_comment != NULL) { |
|---|
| 269 | | calc_string (from->doc_comment, from->doc_comment_len + 1 TSRMLS_CC); |
|---|
| 270 | | } |
|---|
| | 226 | if (opline->op1.op_type == IS_CONST) |
|---|
| | 227 | calc_zval(&opline->op1.u.constant TSRMLS_CC); |
|---|
| | 228 | if (opline->op2.op_type == IS_CONST) |
|---|
| | 229 | calc_zval(&opline->op2.u.constant TSRMLS_CC); |
|---|
| | 230 | } |
|---|
| | 231 | EAG(compress) = 1; |
|---|
| | 232 | } |
|---|
| | 233 | if (from->brk_cont_array != NULL) { |
|---|
| | 234 | EACCELERATOR_ALIGN(EAG(mem)); |
|---|
| | 235 | EAG(mem) += sizeof(zend_brk_cont_element) * from->last_brk_cont; |
|---|
| | 236 | } |
|---|
| | 237 | #ifdef ZEND_ENGINE_2 |
|---|
| | 238 | /* HOESH: try & catch support */ |
|---|
| | 239 | if (from->try_catch_array != NULL) { |
|---|
| | 240 | EACCELERATOR_ALIGN(EAG(mem)); |
|---|
| | 241 | EAG(mem) += sizeof(zend_try_catch_element) * from->last_try_catch; |
|---|
| | 242 | } |
|---|
| | 243 | #endif |
|---|
| | 244 | if (from->static_variables != NULL) { |
|---|
| | 245 | EACCELERATOR_ALIGN(EAG(mem)); |
|---|
| | 246 | EAG(mem) += sizeof(HashTable); |
|---|
| | 247 | calc_zval_hash(from->static_variables); |
|---|
| | 248 | } |
|---|
| | 249 | if (from->filename != NULL) |
|---|
| | 250 | calc_string(from->filename, strlen(from->filename) + 1 TSRMLS_CC); |
|---|
| | 251 | #ifdef ZEND_ENGINE_2 |
|---|
| | 252 | if (from->doc_comment != NULL) |
|---|
| | 253 | calc_string(from->doc_comment, from->doc_comment_len + 1 TSRMLS_CC); |
|---|
| 294 | | // what's problem. why from->interfaces[i] == 0x5a5a5a5a ? |
|---|
| 295 | | for (i = 0; i < from->num_interfaces; i++) { |
|---|
| 296 | | if (from->interfaces[i]) { |
|---|
| 297 | | calc_string (from->interfaces[i]->name, |
|---|
| 298 | | from->interfaces[i]->name_length); |
|---|
| 299 | | } |
|---|
| 300 | | } |
|---|
| 301 | | #endif |
|---|
| 302 | | if (from->filename != NULL) { |
|---|
| 303 | | calc_string (from->filename, strlen (from->filename) + 1 TSRMLS_CC); |
|---|
| 304 | | } |
|---|
| 305 | | if (from->doc_comment != NULL) { |
|---|
| 306 | | calc_string (from->doc_comment, from->doc_comment_len + 1 TSRMLS_CC); |
|---|
| 307 | | } |
|---|
| 308 | | |
|---|
| 309 | | calc_zval_hash (&from->constants_table); |
|---|
| 310 | | calc_zval_hash (&from->default_properties); |
|---|
| 311 | | calc_hash (&from->properties_info, (calc_bucket_t) calc_property_info); |
|---|
| 312 | | if (from->static_members != NULL) { |
|---|
| 313 | | EACCELERATOR_ALIGN (EAG (mem)); |
|---|
| 314 | | EAG (mem) += sizeof (HashTable); |
|---|
| 315 | | calc_zval_hash (from->static_members); |
|---|
| 316 | | } |
|---|
| | 273 | // what's problem. why from->interfaces[i] == 0x5a5a5a5a ? |
|---|
| | 274 | for (i = 0; i < from->num_interfaces; i++) { |
|---|
| | 275 | if (from->interfaces[i]) { |
|---|
| | 276 | calc_string(from->interfaces[i]->name, |
|---|
| | 277 | from->interfaces[i]->name_length); |
|---|
| | 278 | } |
|---|
| | 279 | } |
|---|
| | 280 | #endif |
|---|
| | 281 | if (from->filename != NULL) |
|---|
| | 282 | calc_string(from->filename, strlen(from->filename) + 1 TSRMLS_CC); |
|---|
| | 283 | if (from->doc_comment != NULL) |
|---|
| | 284 | calc_string(from->doc_comment, from->doc_comment_len + 1 TSRMLS_CC); |
|---|
| | 285 | |
|---|
| | 286 | calc_zval_hash(&from->constants_table); |
|---|
| | 287 | calc_zval_hash(&from->default_properties); |
|---|
| | 288 | calc_hash(&from->properties_info, (calc_bucket_t) calc_property_info); |
|---|
| | 289 | if (from->static_members != NULL) { |
|---|
| | 290 | EACCELERATOR_ALIGN(EAG(mem)); |
|---|
| | 291 | EAG(mem) += sizeof(HashTable); |
|---|
| | 292 | calc_zval_hash(from->static_members); |
|---|
| | 293 | } |
|---|
| 325 | | int calc_size (char *key, zend_op_array * op_array, |
|---|
| 326 | | Bucket * f, Bucket * c TSRMLS_DC) |
|---|
| 327 | | { |
|---|
| 328 | | Bucket *b; |
|---|
| 329 | | char *x; |
|---|
| 330 | | int len = strlen (key); |
|---|
| 331 | | EAG (compress) = 1; |
|---|
| 332 | | EAG (mem) = NULL; |
|---|
| 333 | | |
|---|
| 334 | | zend_hash_init (&EAG (strings), 0, NULL, NULL, 0); |
|---|
| 335 | | EAG (mem) += offsetof (mm_cache_entry, realfilename) + len + 1; |
|---|
| 336 | | zend_hash_add (&EAG (strings), key, len + 1, &key, sizeof (char *), NULL); |
|---|
| 337 | | b = c; |
|---|
| 338 | | while (b != NULL) { |
|---|
| 339 | | EACCELERATOR_ALIGN (EAG (mem)); |
|---|
| 340 | | EAG (mem) += offsetof (mm_fc_entry, htabkey) + b->nKeyLength; |
|---|
| 341 | | x = b->arKey; |
|---|
| 342 | | zend_hash_add (&EAG (strings), b->arKey, b->nKeyLength, &x, |
|---|
| 343 | | sizeof (char *), NULL); |
|---|
| 344 | | b = b->pListNext; |
|---|
| 345 | | } |
|---|
| 346 | | b = f; |
|---|
| 347 | | while (b != NULL) { |
|---|
| 348 | | EACCELERATOR_ALIGN (EAG (mem)); |
|---|
| 349 | | EAG (mem) += offsetof (mm_fc_entry, htabkey) + b->nKeyLength; |
|---|
| 350 | | x = b->arKey; |
|---|
| 351 | | zend_hash_add (&EAG (strings), b->arKey, b->nKeyLength, &x, |
|---|
| 352 | | sizeof (char *), NULL); |
|---|
| 353 | | b = b->pListNext; |
|---|
| 354 | | } |
|---|
| 355 | | while (c != NULL) { |
|---|
| 356 | | #ifdef ZEND_ENGINE_2 |
|---|
| 357 | | calc_class_entry (*(zend_class_entry **) c->pData TSRMLS_CC); |
|---|
| | 302 | int calc_size(char *key, zend_op_array * op_array, |
|---|
| | 303 | Bucket * f, Bucket * c TSRMLS_DC) |
|---|
| | 304 | { |
|---|
| | 305 | Bucket *b; |
|---|
| | 306 | char *x; |
|---|
| | 307 | int len = strlen(key); |
|---|
| | 308 | EAG(compress) = 1; |
|---|
| | 309 | EAG(mem) = NULL; |
|---|
| | 310 | |
|---|
| | 311 | zend_hash_init(&EAG(strings), 0, NULL, NULL, 0); |
|---|
| | 312 | EAG(mem) += offsetof(mm_cache_entry, realfilename) + len + 1; |
|---|
| | 313 | zend_hash_add(&EAG(strings), key, len + 1, &key, sizeof(char *), NULL); |
|---|
| | 314 | b = c; |
|---|
| | 315 | while (b != NULL) { |
|---|
| | 316 | EACCELERATOR_ALIGN(EAG(mem)); |
|---|
| | 317 | EAG(mem) += offsetof(mm_fc_entry, htabkey) + b->nKeyLength; |
|---|
| | 318 | x = b->arKey; |
|---|
| | 319 | zend_hash_add(&EAG(strings), b->arKey, b->nKeyLength, &x, sizeof(char *), NULL); |
|---|
| | 320 | b = b->pListNext; |
|---|
| | 321 | } |
|---|
| | 322 | b = f; |
|---|
| | 323 | while (b != NULL) { |
|---|
| | 324 | EACCELERATOR_ALIGN(EAG(mem)); |
|---|
| | 325 | EAG(mem) += offsetof(mm_fc_entry, htabkey) + b->nKeyLength; |
|---|
| | 326 | x = b->arKey; |
|---|
| | 327 | zend_hash_add(&EAG(strings), b->arKey, b->nKeyLength, &x, sizeof(char *), NULL); |
|---|
| | 328 | b = b->pListNext; |
|---|
| | 329 | } |
|---|
| | 330 | while (c != NULL) { |
|---|
| | 331 | #ifdef ZEND_ENGINE_2 |
|---|
| | 332 | calc_class_entry(*(zend_class_entry **) c->pData TSRMLS_CC); |
|---|
| 410 | | static zval *store_zval_ptr (zval * from TSRMLS_DC) |
|---|
| 411 | | { |
|---|
| 412 | | zval *to; |
|---|
| 413 | | EACCELERATOR_ALIGN (EAG (mem)); |
|---|
| 414 | | to = (zval *) EAG (mem); |
|---|
| 415 | | EAG (mem) += sizeof (zval); |
|---|
| 416 | | memcpy (to, from, sizeof (zval)); |
|---|
| 417 | | store_zval (to TSRMLS_CC); |
|---|
| 418 | | return to; |
|---|
| 419 | | } |
|---|
| 420 | | |
|---|
| 421 | | static void store_hash_int (HashTable * target, HashTable * source, |
|---|
| 422 | | Bucket * start, |
|---|
| 423 | | store_bucket_t copy_bucket TSRMLS_DC) |
|---|
| 424 | | { |
|---|
| 425 | | Bucket *p, *np, *prev_p; |
|---|
| 426 | | |
|---|
| 427 | | memcpy (target, source, sizeof (HashTable)); |
|---|
| 428 | | |
|---|
| 429 | | if (source->nNumOfElements > 0) { |
|---|
| 430 | | if (!EAG (compress)) { |
|---|
| 431 | | EACCELERATOR_ALIGN (EAG (mem)); |
|---|
| 432 | | target->arBuckets = (Bucket **) EAG (mem); |
|---|
| 433 | | EAG (mem) += target->nTableSize * sizeof (Bucket *); |
|---|
| 434 | | memset (target->arBuckets, 0, |
|---|
| 435 | | target->nTableSize * sizeof (Bucket *)); |
|---|
| 436 | | } |
|---|
| 437 | | |
|---|
| 438 | | target->pDestructor = NULL; |
|---|
| 439 | | target->persistent = 1; |
|---|
| 440 | | target->pListHead = NULL; |
|---|
| 441 | | target->pListTail = NULL; |
|---|
| 442 | | |
|---|
| 443 | | p = start; |
|---|
| 444 | | prev_p = NULL; |
|---|
| 445 | | np = NULL; |
|---|
| 446 | | while (p) { |
|---|
| 447 | | EACCELERATOR_ALIGN (EAG (mem)); |
|---|
| 448 | | np = (Bucket *) EAG (mem); |
|---|
| 449 | | EAG (mem) += offsetof (Bucket, arKey) + p->nKeyLength; |
|---|
| 450 | | |
|---|
| 451 | | if (!EAG (compress)) { |
|---|
| 452 | | int nIndex = p->h % source->nTableSize; |
|---|
| 453 | | if (target->arBuckets[nIndex]) { |
|---|
| 454 | | np->pNext = target->arBuckets[nIndex]; |
|---|
| 455 | | np->pLast = NULL; |
|---|
| 456 | | np->pNext->pLast = np; |
|---|
| 457 | | } else { |
|---|
| 458 | | np->pNext = NULL; |
|---|
| 459 | | np->pLast = NULL; |
|---|
| 460 | | } |
|---|
| 461 | | target->arBuckets[nIndex] = np; |
|---|
| 462 | | } |
|---|
| 463 | | np->h = p->h; |
|---|
| 464 | | np->nKeyLength = p->nKeyLength; |
|---|
| 465 | | |
|---|
| 466 | | if (p->pDataPtr == NULL) { |
|---|
| 467 | | np->pData = copy_bucket (p->pData TSRMLS_CC); |
|---|
| 468 | | np->pDataPtr = NULL; |
|---|
| 469 | | } else { |
|---|
| 470 | | np->pDataPtr = copy_bucket (p->pDataPtr TSRMLS_CC); |
|---|
| 471 | | np->pData = &np->pDataPtr; |
|---|
| 472 | | } |
|---|
| 473 | | |
|---|
| 474 | | np->pListLast = prev_p; |
|---|
| 475 | | np->pListNext = NULL; |
|---|
| 476 | | |
|---|
| 477 | | memcpy (np->arKey, p->arKey, p->nKeyLength); |
|---|
| 478 | | |
|---|
| 479 | | if (prev_p) { |
|---|
| 480 | | prev_p->pListNext = np; |
|---|
| 481 | | } else { |
|---|
| 482 | | target->pListHead = np; |
|---|
| 483 | | } |
|---|
| 484 | | prev_p = np; |
|---|
| 485 | | p = p->pListNext; |
|---|
| 486 | | } |
|---|
| 487 | | target->pListTail = np; |
|---|
| 488 | | target->pInternalPointer = target->pListHead; |
|---|
| | 383 | static zval *store_zval_ptr(zval * from TSRMLS_DC) |
|---|
| | 384 | { |
|---|
| | 385 | zval *to; |
|---|
| | 386 | EACCELERATOR_ALIGN(EAG(mem)); |
|---|
| | 387 | to = (zval *) EAG(mem); |
|---|
| | 388 | EAG(mem) += sizeof(zval); |
|---|
| | 389 | memcpy(to, from, sizeof(zval)); |
|---|
| | 390 | store_zval(to TSRMLS_CC); |
|---|
| | 391 | return to; |
|---|
| | 392 | } |
|---|
| | 393 | |
|---|
| | 394 | static void store_hash_int(HashTable * target, HashTable * source, |
|---|
| | 395 | Bucket * start, store_bucket_t copy_bucket TSRMLS_DC) |
|---|
| | 396 | { |
|---|
| | 397 | Bucket *p, *np, *prev_p; |
|---|
| | 398 | |
|---|
| | 399 | memcpy(target, source, sizeof(HashTable)); |
|---|
| | 400 | |
|---|
| | 401 | if (source->nNumOfElements > 0) { |
|---|
| | 402 | if (!EAG(compress)) { |
|---|
| | 403 | EACCELERATOR_ALIGN(EAG(mem)); |
|---|
| | 404 | target->arBuckets = (Bucket **) EAG(mem); |
|---|
| | 405 | EAG(mem) += target->nTableSize * sizeof(Bucket *); |
|---|
| | 406 | memset(target->arBuckets, 0, target->nTableSize * sizeof(Bucket *)); |
|---|
| | 407 | } |
|---|
| | 408 | |
|---|
| | 409 | target->pDestructor = NULL; |
|---|
| | 410 | target->persistent = 1; |
|---|
| | 411 | target->pListHead = NULL; |
|---|
| | 412 | target->pListTail = NULL; |
|---|
| | 413 | |
|---|
| | 414 | p = start; |
|---|
| | 415 | prev_p = NULL; |
|---|
| | 416 | np = NULL; |
|---|
| | 417 | while (p) { |
|---|
| | 418 | EACCELERATOR_ALIGN(EAG(mem)); |
|---|
| | 419 | np = (Bucket *) EAG(mem); |
|---|
| | 420 | EAG(mem) += offsetof(Bucket, arKey) + p->nKeyLength; |
|---|
| | 421 | |
|---|
| | 422 | if (!EAG(compress)) { |
|---|
| | 423 | int nIndex = p->h % source->nTableSize; |
|---|
| | 424 | if (target->arBuckets[nIndex]) { |
|---|
| | 425 | np->pNext = target->arBuckets[nIndex]; |
|---|
| | 426 | np->pLast = NULL; |
|---|
| | 427 | np->pNext->pLast = np; |
|---|
| | 428 | } else { |
|---|
| | 429 | np->pNext = NULL; |
|---|
| | 430 | np->pLast = NULL; |
|---|
| | 431 | } |
|---|
| | 432 | target->arBuckets[nIndex] = np; |
|---|
| | 433 | } |
|---|
| | 434 | np->h = p->h; |
|---|
| | 435 | np->nKeyLength = p->nKeyLength; |
|---|
| | 436 | |
|---|
| | 437 | if (p->pDataPtr == NULL) { |
|---|
| | 438 | np->pData = copy_bucket(p->pData TSRMLS_CC); |
|---|
| | 439 | np->pDataPtr = NULL; |
|---|
| | 440 | } else { |
|---|
| | 441 | np->pDataPtr = copy_bucket(p->pDataPtr TSRMLS_CC); |
|---|
| | 442 | np->pData = &np->pDataPtr; |
|---|
| | 443 | } |
|---|
| | 444 | |
|---|
| | 445 | np->pListLast = prev_p; |
|---|
| | 446 | np->pListNext = NULL; |
|---|
| | 447 | |
|---|
| | 448 | memcpy(np->arKey, p->arKey, p->nKeyLength); |
|---|
| | 449 | |
|---|
| | 450 | if (prev_p) { |
|---|
| | 451 | prev_p->pListNext = np; |
|---|
| | 452 | } else { |
|---|
| | 453 | target->pListHead = np; |
|---|
| | 454 | } |
|---|
| | 455 | prev_p = np; |
|---|
| | 456 | p = p->pListNext; |
|---|
| | 457 | } |
|---|
| | 458 | target->pListTail = np; |
|---|
| | 459 | target->pInternalPointer = target->pListHead; |
|---|
| | 460 | } |
|---|
| | 461 | } |
|---|
| | 462 | |
|---|
| | 463 | void store_zval(zval * zv TSRMLS_DC) |
|---|
| | 464 | { |
|---|
| | 465 | switch (zv->type & ~IS_CONSTANT_INDEX) { |
|---|
| | 466 | case IS_CONSTANT: |
|---|
| | 467 | case IS_STRING: |
|---|
| | 468 | if (zv->value.str.val == NULL || |
|---|
| | 469 | zv->value.str.val == empty_string || zv->value.str.len == 0) { |
|---|
| | 470 | zv->value.str.val = empty_string; |
|---|
| | 471 | zv->value.str.len = 0; |
|---|
| | 472 | } else { |
|---|
| | 473 | zv->value.str.val = store_string(zv->value.str.val, zv->value.str.len + 1 TSRMLS_CC); |
|---|
| | 474 | } |
|---|
| | 475 | break; |
|---|
| | 476 | case IS_ARRAY: |
|---|
| | 477 | case IS_CONSTANT_ARRAY: |
|---|
| | 478 | if (zv->value.ht != NULL && zv->value.ht != &EG(symbol_table)) { |
|---|
| | 479 | HashTable *p; |
|---|
| | 480 | EACCELERATOR_ALIGN(EAG(mem)); |
|---|
| | 481 | p = (HashTable *) EAG(mem); |
|---|
| | 482 | EAG(mem) += sizeof(HashTable); |
|---|
| | 483 | store_zval_hash(p, zv->value.ht); |
|---|
| | 484 | zv->value.ht = p; |
|---|
| | 485 | } |
|---|
| | 486 | break; |
|---|
| | 487 | case IS_OBJECT: |
|---|
| | 488 | if (!EAG(compress)) { |
|---|
| | 489 | return; |
|---|
| | 490 | } |
|---|
| | 491 | #ifndef ZEND_ENGINE_2 |
|---|
| | 492 | if (zv->value.obj.ce != NULL) { |
|---|
| | 493 | char *s = store_string(zv->value.obj.ce->name, zv->value.obj.ce->name_length + 1 TSRMLS_CC); |
|---|
| | 494 | zend_str_tolower(s, zv->value.obj.ce->name_length); |
|---|
| | 495 | zv->value.obj.ce = (zend_class_entry *) s; |
|---|
| | 496 | } |
|---|
| | 497 | if (zv->value.obj.properties != NULL) { |
|---|
| | 498 | HashTable *p; |
|---|
| | 499 | EACCELERATOR_ALIGN(EAG(mem)); |
|---|
| | 500 | p = (HashTable *) EAG(mem); |
|---|
| | 501 | EAG(mem) += sizeof(HashTable); |
|---|
| | 502 | store_zval_hash(p, zv->value.obj.properties); |
|---|
| | 503 | zv->value.obj.properties = p; |
|---|
| | 504 | } |
|---|
| | 505 | #endif |
|---|
| | 506 | default: |
|---|
| | 507 | break; |
|---|
| | 508 | } |
|---|
| | 509 | } |
|---|
| | 510 | |
|---|
| | 511 | eaccelerator_op_array *store_op_array(zend_op_array * from TSRMLS_DC) |
|---|
| | 512 | { |
|---|
| | 513 | eaccelerator_op_array *to; |
|---|
| | 514 | zend_op *opline; |
|---|
| | 515 | zend_op *end; |
|---|
| | 516 | |
|---|
| | 517 | ea_debug_pad(EA_DEBUG TSRMLS_CC); |
|---|
| | 518 | ea_debug_printf(EA_DEBUG, "[%d] store_op_array: %s [scope=%s]\n", |
|---|
| | 519 | getpid(), from->function_name ? from->function_name : "(top)", |
|---|
| | 520 | #ifdef ZEND_ENGINE_2 |
|---|
| | 521 | from->scope ? from->scope->name : "NULL" |
|---|
| | 522 | #else |
|---|
| | 523 | "NULL" |
|---|
| | 524 | #endif |
|---|
| | 525 | ); |
|---|
| | 526 | |
|---|
| | 527 | if (from->type == ZEND_INTERNAL_FUNCTION) { |
|---|
| | 528 | EACCELERATOR_ALIGN(EAG(mem)); |
|---|
| | 529 | to = (eaccelerator_op_array *) EAG(mem); |
|---|
| | 530 | EAG(mem) += offsetof(eaccelerator_op_array, opcodes); |
|---|
| | 531 | } else if (from->type == ZEND_USER_FUNCTION) { |
|---|
| | 532 | EACCELERATOR_ALIGN(EAG(mem)); |
|---|
| | 533 | to = (eaccelerator_op_array *) EAG(mem); |
|---|
| | 534 | EAG(mem) += sizeof(eaccelerator_op_array); |
|---|
| | 535 | } else { |
|---|
| | 536 | return NULL; |
|---|
| | 537 | } |
|---|
| | 538 | |
|---|
| | 539 | to->type = from->type; |
|---|
| | 540 | #ifdef ZEND_ENGINE_2 |
|---|
| | 541 | to->num_args = from->num_args; |
|---|
| | 542 | to->required_num_args = from->required_num_args; |
|---|
| | 543 | if (from->num_args > 0) { |
|---|
| | 544 | zend_uint i; |
|---|
| | 545 | EACCELERATOR_ALIGN(EAG(mem)); |
|---|
| | 546 | to->arg_info = (zend_arg_info *) EAG(mem); |
|---|
| | 547 | EAG(mem) += from->num_args * sizeof(zend_arg_info); |
|---|
| | 548 | for (i = 0; i < from->num_args; i++) { |
|---|
| | 549 | if (from->arg_info[i].name) { |
|---|
| | 550 | to->arg_info[i].name = store_string(from->arg_info[i].name, from->arg_info[i].name_len + 1 TSRMLS_CC); |
|---|
| | 551 | to->arg_info[i].name_len = from->arg_info[i].name_len; |
|---|
| | 552 | } |
|---|
| | 553 | if (from->arg_info[i].class_name) { |
|---|
| | 554 | to->arg_info[i].class_name = store_string(from->arg_info[i].class_name, from->arg_info[i].class_name_len + 1 TSRMLS_CC); |
|---|
| | 555 | to->arg_info[i].class_name_len = from->arg_info[i].class_name_len; |
|---|
| | 556 | } |
|---|
| | 557 | to->arg_info[i].allow_null = from->arg_info[i].allow_null; |
|---|
| | 558 | to->arg_info[i].pass_by_reference = from->arg_info[i].pass_by_reference; |
|---|
| | 559 | to->arg_info[i].return_reference = from->arg_info[i].return_reference; |
|---|
| | 560 | } |
|---|
| | 561 | } |
|---|
| | 562 | to->pass_rest_by_reference = from->pass_rest_by_reference; |
|---|
| | 563 | #else |
|---|
| | 564 | if (from->arg_types != NULL) |
|---|
| | 565 | to->arg_types = (unsigned char *) store_string((char *) from->arg_types, (from->arg_types[0] + 1) * sizeof(zend_uchar) TSRMLS_CC); |
|---|
| | 566 | #endif |
|---|
| | 567 | if (from->function_name != NULL) |
|---|
| | 568 | to->function_name = store_string(from->function_name, strlen(from->function_name) + 1 TSRMLS_CC); |
|---|
| | 569 | #ifdef ZEND_ENGINE_2 |
|---|
| | 570 | to->fn_flags = from->fn_flags; |
|---|
| | 571 | to->scope_name = NULL; |
|---|
| | 572 | to->scope_name_len = 0; |
|---|
| | 573 | if (from->scope != NULL) { |
|---|
| | 574 | Bucket *q = CG(class_table)->pListHead; |
|---|
| | 575 | while (q != NULL) { |
|---|
| | 576 | if (*(zend_class_entry **) q->pData == from->scope) { |
|---|
| | 577 | to->scope_name = store_string(q->arKey, q->nKeyLength TSRMLS_CC); |
|---|
| | 578 | to->scope_name_len = q->nKeyLength - 1; |
|---|
| | 579 | |
|---|
| | 580 | ea_debug_pad(EA_DEBUG TSRMLS_CC); |
|---|
| | 581 | ea_debug_printf(EA_DEBUG, |
|---|
| | 582 | "[%d] find scope '%s' in CG(class_table) save hashkey '%s' [%08x] as to->scope_name\n", |
|---|
| | 583 | getpid(), from->scope->name ? from->scope->name : "NULL", q->arKey, to->scope_name); |
|---|
| | 584 | break; |
|---|
| | 585 | } |
|---|
| | 586 | q = q->pListNext; |
|---|
| | 587 | } |
|---|
| | 588 | if (to->scope_name == NULL) { |
|---|
| | 589 | ea_debug_pad(EA_DEBUG TSRMLS_CC); |
|---|
| | 590 | ea_debug_printf(EA_DEBUG, |
|---|
| | 591 | "[%d] could not find scope '%s' in CG(class_table), saving it to NULL\n", |
|---|
| | 592 | getpid(), from->scope->name ? from->scope->name : "NULL"); |
|---|
| | 593 | } |
|---|