static zend_ast *get_ast(zend_string *code, zend_arena **ast_arena, char *filename) { zval code_zv; zend_bool original_in_compilation; zend_lex_state original_lex_state; zend_ast *ast; ZVAL_STR_COPY(&code_zv, code); original_in_compilation = CG(in_compilation); CG(in_compilation) = 1; zend_save_lexical_state(&original_lex_state); if (zend_prepare_string_for_scanning(&code_zv, filename) == SUCCESS) { CG(ast) = NULL; CG(ast_arena) = zend_arena_create(1024 * 32); LANG_SCNG(yy_state) = yycINITIAL; if (zendparse() != 0) { zend_ast_destroy(CG(ast)); zend_arena_destroy(CG(ast_arena)); CG(ast) = NULL; } } /* restore_lexical_state changes CG(ast) and CG(ast_arena) */ ast = CG(ast); *ast_arena = CG(ast_arena); zend_restore_lexical_state(&original_lex_state); CG(in_compilation) = original_in_compilation; zval_dtor(&code_zv); return ast; }
static zend_bool tokenize_parse(zval *return_value, zend_string *source) { zval source_zval; zend_lex_state original_lex_state; zend_bool original_in_compilation; zend_bool success; ZVAL_STR_COPY(&source_zval, source); original_in_compilation = CG(in_compilation); CG(in_compilation) = 1; zend_save_lexical_state(&original_lex_state); if ((success = (zend_prepare_string_for_scanning(&source_zval, "") == SUCCESS))) { zval token_stream; array_init(&token_stream); CG(ast) = NULL; CG(ast_arena) = zend_arena_create(1024 * 32); LANG_SCNG(yy_state) = yycINITIAL; LANG_SCNG(on_event) = on_event; LANG_SCNG(on_event_context) = &token_stream; if((success = (zendparse() == SUCCESS))) { ZVAL_COPY_VALUE(return_value, &token_stream); } else { zval_ptr_dtor(&token_stream); } zend_ast_destroy(CG(ast)); zend_arena_destroy(CG(ast_arena)); } /* restore compiler and scanner global states */ zend_restore_lexical_state(&original_lex_state); CG(in_compilation) = original_in_compilation; zval_dtor(&source_zval); return success; }
int zend_accel_script_optimize(zend_persistent_script *script) { uint idx, j; Bucket *p, *q; zend_class_entry *ce; zend_op_array *op_array; zend_optimizer_ctx ctx; ctx.arena = zend_arena_create(64 * 1024); ctx.script = script; ctx.constants = NULL; zend_accel_optimize(&script->main_op_array, &ctx); for (idx = 0; idx < script->function_table.nNumUsed; idx++) { p = script->function_table.arData + idx; if (Z_TYPE(p->val) == IS_UNDEF) continue; op_array = (zend_op_array*)Z_PTR(p->val); zend_accel_optimize(op_array, &ctx); } for (idx = 0; idx < script->class_table.nNumUsed; idx++) { p = script->class_table.arData + idx; if (Z_TYPE(p->val) == IS_UNDEF) continue; ce = (zend_class_entry*)Z_PTR(p->val); for (j = 0; j < ce->function_table.nNumUsed; j++) { q = ce->function_table.arData + j; if (Z_TYPE(q->val) == IS_UNDEF) continue; op_array = (zend_op_array*)Z_PTR(q->val); if (op_array->scope == ce) { zend_accel_optimize(op_array, &ctx); } else if (op_array->type == ZEND_USER_FUNCTION) { zend_op_array *orig_op_array; if ((orig_op_array = zend_hash_find_ptr(&op_array->scope->function_table, q->key)) != NULL) { HashTable *ht = op_array->static_variables; *op_array = *orig_op_array; op_array->static_variables = ht; } } } } if (ZEND_OPTIMIZER_PASS_12 & OPTIMIZATION_LEVEL) { zend_accel_adjust_fcall_stack_size(&script->main_op_array, &ctx); for (idx = 0; idx < script->function_table.nNumUsed; idx++) { p = script->function_table.arData + idx; if (Z_TYPE(p->val) == IS_UNDEF) continue; op_array = (zend_op_array*)Z_PTR(p->val); zend_accel_adjust_fcall_stack_size(op_array, &ctx); } for (idx = 0; idx < script->class_table.nNumUsed; idx++) { p = script->class_table.arData + idx; if (Z_TYPE(p->val) == IS_UNDEF) continue; ce = (zend_class_entry*)Z_PTR(p->val); for (j = 0; j < ce->function_table.nNumUsed; j++) { q = ce->function_table.arData + j; if (Z_TYPE(q->val) == IS_UNDEF) continue; op_array = (zend_op_array*)Z_PTR(q->val); if (op_array->scope == ce) { zend_accel_adjust_fcall_stack_size(op_array, &ctx); } else if (op_array->type == ZEND_USER_FUNCTION) { zend_op_array *orig_op_array; if ((orig_op_array = zend_hash_find_ptr(&op_array->scope->function_table, q->key)) != NULL) { HashTable *ht = op_array->static_variables; *op_array = *orig_op_array; op_array->static_variables = ht; } } } } } if (ctx.constants) { zend_hash_destroy(ctx.constants); } zend_arena_destroy(ctx.arena); return 1; }