/* Copyright 2025 Sebastian Peters */ #include #include #include #include "Zend/zend_exceptions.h" #include #include "pwphpwrapper.h" static bool ini_enable_jit=false; static bool ini_enable_jit_full=false; static bool ini_enable_opcache=false; static void ini_enable_settings(HashTable *configuration_hash) { zval ini_value1; ZVAL_NEW_STR(&ini_value1, zend_string_init(ZEND_STRL("PW-Embed SAPI error:"), /* persistent */ 1)); zend_hash_str_update(configuration_hash, ZEND_STRL("error_prepend_string"), &ini_value1); if(ini_enable_opcache){ zval ini_value2; ZVAL_NEW_STR(&ini_value2, zend_string_init(ZEND_STRL("On"), /* persistent */ 1)); zend_hash_str_update(configuration_hash, ZEND_STRL("opcache.enable_cli"), &ini_value2); zval ini_value6; ZVAL_NEW_STR(&ini_value6, zend_string_init(ZEND_STRL("/tmp"), /* persistent */ 1)); zend_hash_str_update(configuration_hash, ZEND_STRL("opcache.file_cache"), &ini_value6); } if(ini_enable_jit){ zval ini_value3; ZVAL_NEW_STR(&ini_value3, zend_string_init(ZEND_STRL("100M"), /* persistent */ 1)); zend_hash_str_update(configuration_hash, ZEND_STRL("opcache.jit_buffer_size"), &ini_value3); } if(ini_enable_jit_full){ zval ini_value5; ZVAL_NEW_STR(&ini_value5, zend_string_init(ZEND_STRL("function"), /* persistent */ 1)); zend_hash_str_update(configuration_hash, ZEND_STRL("opcache.jit"), &ini_value5); } } extern void pw_php_embed_engine_ini_enable_jit_full(){ // Slow startup, fast while executing ini_enable_opcache=true; ini_enable_jit=true; ini_enable_jit_full=true; php_embed_module.name = "cli"; } extern void pw_php_embed_engine_ini_enable_jit(){ // Fast start, slow when found optimazation ini_enable_opcache=true; ini_enable_jit=true; php_embed_module.name = "cli"; } extern void pw_php_embed_engine_ini_enable_opcache_without_jit(){ /* This is necessary for compiling, because JIT will block it! */ ini_enable_opcache=true; php_embed_module.name = "cli"; } extern void pw_php_embed_engine_start(int argc, char **argv){ PG(display_startup_errors)=1; PG(during_request_startup)=0; php_embed_module.ini_defaults = ini_enable_settings; php_embed_init(argc, argv); } extern void pw_php_embed_engine_stop(){ php_embed_shutdown(); } extern void pw_php_embed_engine_exec(char* debugname, char *code){ int ret = 0; zend_try { ret = zend_eval_string(code, NULL, "" TSRMLS_CACHE); // If there was an uncaught error/exception, then report it. zend_object *ex = EG(exception); if (ex != NULL) { zval exception; ZVAL_OBJ(&exception, ex); zend_class_entry *ce_exception = Z_OBJCE(exception); if (ce_exception) { zval rv; zend_string *message = zval_get_string(zend_read_property_ex(instanceof_function(Z_OBJCE_P(&exception), zend_ce_exception) ? zend_ce_exception : zend_ce_error, (Z_OBJ_P(&exception)), ZSTR_KNOWN(ZEND_STR_MESSAGE), 1, &rv)); char exception_str[256]=""; sprintf(exception_str,"%s",ZSTR_VAL(ce_exception->name)); if(strcmp(exception_str,"UnwindExit")==0){ php_embed_shutdown(); exit(EG(exit_status)); } fprintf(stderr, "PWPHP Uncaught (""1"") (%s) Exception '%s': %s""\r\n",debugname, ZSTR_VAL(ce_exception->name), ZSTR_VAL(message)); php_embed_shutdown(); exit(254); } } } zend_catch { zend_object *ex = EG(exception); if (ex != NULL) { EG(exception) = NULL; zval exception; ZVAL_OBJ(&exception, ex); zend_class_entry *ce_exception = Z_OBJCE(exception); if (ce_exception) { zval rv; zend_string *message = zval_get_string(zend_read_property_ex(instanceof_function(Z_OBJCE_P(&exception), zend_ce_exception) ? zend_ce_exception : zend_ce_error, (Z_OBJ_P(&exception)), ZSTR_KNOWN(ZEND_STR_MESSAGE), 1, &rv)); char exception_str[256]=""; sprintf(exception_str,"%s",ZSTR_VAL(ce_exception->name)); if(strcmp(exception_str,"UnwindExit")==0){ php_embed_shutdown(); exit(EG(exit_status)); } fprintf(stderr, "PWPHP Uncaught (""2"") (%s) Exception '%s': %s""\r\n",debugname, ZSTR_VAL(ce_exception->name), ZSTR_VAL(message)); php_embed_shutdown(); exit(253); } EG(exception) = ex; } } zend_end_try(); if(ret == FAILURE){ php_printf("\r\n""ERROR""\r\n"); php_embed_shutdown(); exit(252); } } extern void pw_php_embed_engine_load_compiled_file(char * filename, bool verbose){ pw_main_opcache_load_compiled_file(filename, verbose); } extern void pw_php_embed_engine_load_compiled_chararr(unsigned char *chararr, int charlen, bool verbose){ pw_main_opcache_load_compiled_chararr(chararr, charlen, verbose); }