bcompiler php,php_bcompiler.c

本文档详细介绍了PHP的bcompiler模块,包括其功能、初始化全局变量、加载和解析类、读写文件、设置文件名处理器等功能。bcompiler模块允许将PHP代码编译为字节码并进行序列化,以便于存储和传输。此外,还涉及了如何与APC扩展集成,用于替代默认的编译过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/*

+----------------------------------------------------------------------+

| PHP bcompiler |

+----------------------------------------------------------------------+

| Copyright (c) 1997-2010 The PHP Group |

+----------------------------------------------------------------------+

| This source file is subject to version 2.02 of the PHP license, |

| that is bundled with this package in the file LICENSE, and is |

| available at through the world-wide-web at |

| http://www.php.net/license/2_02.txt. |

| If you did not receive a copy of the PHP license and are unable to |

| obtain it through the world-wide-web, please send a note to |

| license@php.net so we can mail you a copy immediately. |

+----------------------------------------------------------------------+

| Authors: Alan Knowles |

| val khokhlov |

+----------------------------------------------------------------------+

*/

/* $Id: php_bcompiler.c 305930 2010-12-03 00:49:25Z val $ */

#include "php_bcompiler.h"

PHP_MINIT_FUNCTION(bcompiler);

PHP_MSHUTDOWN_FUNCTION(bcompiler);

PHP_RINIT_FUNCTION(bcompiler);

PHP_RSHUTDOWN_FUNCTION(bcompiler);

PHP_MINFO_FUNCTION(bcompiler);

/* {{{ PHP_FUNCTION declarations */

PHP_FUNCTION(bcompiler_load); /* load a file */

PHP_FUNCTION(bcompiler_load_exe); /* loads an exe style file */

PHP_FUNCTION(bcompiler_parse_class); /* callback opcodes for a class */

PHP_FUNCTION(bcompiler_read); /* Read a file handle */

PHP_FUNCTION(bcompiler_set_filename_handler); /* Set a filename handler */

PHP_FUNCTION(bcompiler_write_class); /* Write a class */

PHP_FUNCTION(bcompiler_write_constant); /* Write a constant */

PHP_FUNCTION(bcompiler_write_exe_footer); /* Write the end zero byte */

PHP_FUNCTION(bcompiler_write_file); /* Write file opcodes */

PHP_FUNCTION(bcompiler_write_footer); /* Write the tail for a exe type file*/

PHP_FUNCTION(bcompiler_write_function); /* Write a function */

PHP_FUNCTION(bcompiler_write_functions_from_file); /* Write a bunch of functions */

PHP_FUNCTION(bcompiler_write_header); /* Write the header */

PHP_FUNCTION(bcompiler_write_included_filename); /* Add an entry to the included filename list*/

/* }}} */

/* Globals */

ZEND_DECLARE_MODULE_GLOBALS(bcompiler)

zend_op_array *(*bcompiler_saved_zend_compile_file)(zend_file_handle *file_handle, int type TSRMLS_DC);

static void* (*apc_hook)(void *) = NULL;

/* {{{ bcompiler_functions[]

*

* All the functions in bcompiler

*/

zend_function_entry bcompiler_functions[] = {

PHP_FE(bcompiler_load, NULL)

PHP_FE(bcompiler_load_exe, NULL)

PHP_FE(bcompiler_parse_class, NULL)

PHP_FE(bcompiler_read, NULL)

PHP_FE(bcompiler_set_filename_handler, NULL)

PHP_FE(bcompiler_write_class, NULL)

PHP_FE(bcompiler_write_constant, NULL)

PHP_FE(bcompiler_write_exe_footer, NULL)

PHP_FE(bcompiler_write_file, NULL)

PHP_FE(bcompiler_write_footer, NULL)

PHP_FE(bcompiler_write_function, NULL)

PHP_FE(bcompiler_write_functions_from_file, NULL)

PHP_FE(bcompiler_write_header, NULL)

PHP_FE(bcompiler_write_included_filename, NULL)

{NULL, NULL, NULL}

};

/* }}} */

/* {{{ bcompiler_module_entry

*/

zend_module_entry bcompiler_module_entry = {

#if ZEND_MODULE_API_NO >= 20010901

STANDARD_MODULE_HEADER,

#endif

"bcompiler",

bcompiler_functions,

PHP_MINIT(bcompiler),

PHP_MSHUTDOWN(bcompiler),

PHP_RINIT(bcompiler),

PHP_RSHUTDOWN(bcompiler),

PHP_MINFO(bcompiler),

#if ZEND_MODULE_API_NO >= 20010901

BCOMPILER_VERSION BCOMPILER_STREAMS, /* Replace with version number for your extension */

#endif

STANDARD_MODULE_PROPERTIES

};

/* }}} */

#ifdef COMPILE_DL_BCOMPILER

ZEND_GET_MODULE(bcompiler)

#endif

/* ran out of other ideas on how to make these work */

ZEND_DLEXPORT int bcompiler_zend_startup(zend_extension *extension)

{

return zend_startup_module(&bcompiler_module_entry);

}

ZEND_DLEXPORT void bcompiler_zend_shutdown(zend_extension *extension)

{

}

#ifndef ZEND_EXT_API

#define ZEND_EXT_API ZEND_DLEXPORT

#endif

ZEND_EXTENSION();

ZEND_DLEXPORT zend_extension zend_extension_entry = {

"bcompiler",

BCOMPILER_VERSION,

"Alan Knowles and val khokhlov",

"http://www.php.net",

"Copyright (c) 1997-2010 The PHP Group",

bcompiler_zend_startup,

bcompiler_zend_shutdown,

NULL, /* activate_func_t */

NULL, /* deactivate_func_t */

NULL, /* message_handler_func_t */

NULL, /* op_array_handler_func_t */

NULL, /* statement_handler_func_t */

NULL, /* fcall_begin_handler_func_t */

NULL, /* fcall_end_handler_func_t */

NULL, /* op_array_ctor_func_t */

NULL, /* op_array_dtor_func_t */

#ifdef COMPAT_ZEND_EXTENSION_PROPERTIES

NULL, /* api_no_check */

COMPAT_ZEND_EXTENSION_PROPERTIES

#else

STANDARD_ZEND_EXTENSION_PROPERTIES

#endif

};

#ifdef ZEND_ENGINE_2

#define OnUpdateInt OnUpdateLong

#endif

/* {{{ PHP_INI */

PHP_INI_BEGIN()

STD_PHP_INI_BOOLEAN("bcompiler.enabled", "1", PHP_INI_ALL, OnUpdateBool, enabled, zend_bcompiler_globals, bcompiler_globals)

STD_PHP_INI_BOOLEAN("bcompiler.detect_filedir", "1", PHP_INI_ALL, OnUpdateBool, detect_filedir, zend_bcompiler_globals, bcompiler_globals)

STD_PHP_INI_ENTRY("bcompiler.debug", "0", PHP_INI_ALL, OnUpdateInt, debug_lvl, zend_bcompiler_globals, bcompiler_globals)

STD_PHP_INI_ENTRY("bcompiler.debugfile", NULL, PHP_INI_ALL, OnUpdateString, debug_file, zend_bcompiler_globals, bcompiler_globals)

PHP_INI_END()

/* }}} */

#ifdef ZEND_ENGINE_2

static void zend_destroy_property_info(zend_property_info *property_info)

{

efree(ZS2S(property_info->name));

}

#endif

/* {{{ php_bcompiler_init_globals

*/

static void php_bcompiler_init_globals(zend_bcompiler_globals *bcompiler_globals)

{

#ifdef ZEND_ENGINE_2

HashTable ht;

zend_hash_init(&ht, 0, NULL, (dtor_func_t)&zend_destroy_property_info, 0);

zend_hash_destroy(&ht);

#endif

bcompiler_globals->stream = NULL;

bcompiler_globals->callback = NULL;

bcompiler_globals->callback_value = NULL;

bcompiler_globals->callback_key = "NONE";

bcompiler_globals->current_version = BCOMPILER_CUR_VER;

bcompiler_globals->is_unicode = 0;

bcompiler_globals->current_write = BCOMPILER_CUR_VER;

bcompiler_globals->current_include = 0;

bcompiler_globals->parsing_error = 0;

bcompiler_set_stdsize(BCOMPILER_CUR_VER, &(bcompiler_globals->bcompiler_stdsize));

bcompiler_globals->cur_zc = NULL;

bcompiler_globals->current_filename = NULL;

bcompiler_globals->filename_handler = NULL;

bcompiler_globals->filename_handler_name = NULL;

}

/* }}} */

/* {{{ PHP_MINIT_FUNCTION

*/

PHP_MINIT_FUNCTION(bcompiler)

{

zend_module_entry *apc_lookup;

zend_constant *apc_magic;

ZEND_INIT_MODULE_GLOBALS(bcompiler, php_bcompiler_init_globals, NULL);

REGISTER_INI_ENTRIES();

if (BCOMPILERG(enabled)) {

if (zend_hash_find(&module_registry, "apc", sizeof("apc"), (void**)&apc_lookup) != FAILURE &&

zend_hash_find(EG(zend_constants), "\000apc_magic", 11, (void**)&apc_magic) != FAILURE) {

apc_hook = (void* (*)(void*))apc_magic->value.value.lval;

bcompiler_saved_zend_compile_file = apc_hook(NULL);

apc_hook(bcompiler_compile_file);

} else {

bcompiler_saved_zend_compile_file = zend_compile_file;

zend_compile_file = bcompiler_compile_file;

}

}

return SUCCESS;

}

/* }}} */

/* {{{ PHP_MSHUTDOWN_FUNCTION

*/

PHP_MSHUTDOWN_FUNCTION(bcompiler)

{

if (BCOMPILERG(enabled)) {

if (apc_hook)

apc_hook(bcompiler_saved_zend_compile_file);

else

zend_compile_file = bcompiler_saved_zend_compile_file;

#if BCOMPILER_DEBUG_ON || BCOMPILER_DEBUGFULL_ON

/* close debug log */

bcompiler_debug(NULL);

#endif

}

UNREGISTER_INI_ENTRIES();

return SUCCESS;

}

/* }}} */

/* {{{ PHP_RINIT_FUNCTION

*/

PHP_RINIT_FUNCTION(bcompiler)

{

if (BCOMPILERG(enabled)) {

/* looks like init_globals is supposed to do this, but it's not? */

BCOMPILERG(buffer_size) = 1024;

BCOMPILERG(buffer) = (char*) emalloc( BCOMPILERG(buffer_size) );

BCOMPILERG(current_filename) = NULL;

BCOMPILERG(filename_handler) = NULL;

BCOMPILERG(filename_handler_name) = NULL;

}

return SUCCESS;

}

/* }}} */

/* {{{ PHP_RSHUTDOWN_FUNCTION

*/

PHP_RSHUTDOWN_FUNCTION(bcompiler)

{

if (BCOMPILERG(enabled)) {

efree(BCOMPILERG(buffer));

if (BCOMPILERG(current_filename)) efree(BCOMPILERG(current_filename));

#if PHP_MAJOR_VERSION >= 6

if (BCOMPILERG(filename_handler_name)) zval_ptr_dtor(&BCOMPILERG(filename_handler_name));

#else

if (BCOMPILERG(filename_handler_name)) efree(BCOMPILERG(filename_handler_name));

#endif

if (BCOMPILERG(filename_handler)) zval_ptr_dtor(&BCOMPILERG(filename_handler));

}

return SUCCESS;

}

/* }}} */

/* {{{ PHP_MINFO_FUNCTION

*/

PHP_MINFO_FUNCTION(bcompiler)

{

char *tmp;

php_info_print_table_start();

php_info_print_table_header(2, "bcompiler support", BCOMPILERG(enabled) ? "enabled" : "disabled");

php_info_print_table_row(2, "bcompiler version", BCOMPILER_VERSION BCOMPILER_STREAMS);

#ifdef BCOMPILER_DEBUG_ON

{

char buf[8];

snprintf(buf, sizeof(buf)-1, "%d", BCOMPILERG(debug_lvl));

php_info_print_table_row(2, "bcompiler debug level", buf);

}

#endif

tmp = bcompiler_bc_version(BCOMPILER_CUR_VER);

php_info_print_table_row(2, "current bytecode version", tmp);

tmp = bcompiler_bc_version(0);

php_info_print_table_row(2, "can parse bytecode version", tmp);

efree(tmp);

php_info_print_table_end();

DISPLAY_INI_ENTRIES();

}

/* }}} */

/* === FUNCTIONS =========================================================== */

/* --- class --------------------------------------------------------------- */

/* {{{ proto boolean bcompiler_write_class(stream out | filehandle, string class_name [, string extends] )

Writes compiled data to stream*/

PHP_FUNCTION(bcompiler_write_class)

{

char *class_name = NULL;

char *extends_name = NULL;

int class_len,extends_len = 0;

#ifdef ZEND_ENGINE_2

zend_class_entry **pce = NULL;

#endif

zend_class_entry *ce = NULL;

zend_class_entry *cee = NULL;

zval *rsrc;

php_stream *stream;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs|s",

&rsrc, &class_name, &class_len,&extends_name, &extends_len)

== FAILURE) {

return;

}

php_stream_from_zval(stream, &rsrc);

/* DANGER! This modifies the class_name string passed by the script */

#ifdef ZEND_ENGINE_2

if (FAILURE == zend_lookup_class(class_name, class_len, &pce TSRMLS_CC))

#else

zend_str_tolower(class_name, class_len);

if (SUCCESS != zend_hash_find(EG(class_table), class_name, class_len+1, (void **)&ce))

#endif

{

php_error(E_WARNING, "Could not find class %s", class_name);

RETURN_NULL();

}

BCOMPILER_DEBUG(("EXTENDS LEN: %d",extends_len));

if (extends_len > 0) {

zend_str_tolower(extends_name, extends_len);

if (SUCCESS != zend_hash_find(EG(class_table), extends_name, extends_len+1, (void **)&cee)) {

php_error(E_WARNING, "Could not find extended class");

RETURN_NULL();

}

}

BCOMPILERG(stream) = stream;

BCOMPILERG(callback) = NULL;

SERIALIZE_SCALAR(BCOMPILER_CLASS_ENTRY, char)

#ifdef ZEND_ENGINE_2

ce = *pce;

#endif

apc_serialize_zend_class_entry(ce, extends_name, extends_len, NULL, 0 TSRMLS_CC);

RETURN_TRUE;

}

/* }}} */

/* --- included_filename --------------------------------------------------- */

/* {{{ proto boolean bcompiler_write_included_filename(stream out | filehandle, string filename)

Writes compiled data to stream*/

PHP_FUNCTION(bcompiler_write_included_filename)

{

char *file_name = NULL;

int file_len;

zval *rsrc;

php_stream *stream;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &rsrc,&file_name, &file_len) == FAILURE) {

return;

}

php_stream_from_zval(stream, &rsrc);

BCOMPILERG(stream) = stream;

BCOMPILERG(callback) = NULL;

SERIALIZE_SCALAR(BCOMPILER_INCTABLE_ENTRY, char);

apc_serialize_string(file_name TSRMLS_CC);

RETURN_TRUE;

}

/* }}} */

/* --- function ------------------------------------------------------------ */

/* {{{ proto boolean bcompiler_write_function(stream out | filehandle, string function_name)

Writes compiled data to stream*/

PHP_FUNCTION(bcompiler_write_function)

{

char *function_name = NULL;

int function_len;

zend_function *fe = NULL;

zval *rsrc;

php_stream *stream;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &rsrc, &function_name, &function_len) == FAILURE) {

return;

}

php_stream_from_zval(stream, &rsrc);

/* DANGER! modifies function_name */

zend_str_tolower(function_name, function_len);

zend_hash_find(CG(function_table), function_name, function_len+1, (void **)&fe);

if (!fe) {

php_error(E_WARNING, "Could not find function");

RETURN_NULL();

}

BCOMPILERG(stream) = stream;

BCOMPILERG(callback) = NULL;

SERIALIZE_SCALAR(BCOMPILER_FUNCTION_ENTRY, char)

apc_serialize_zend_function(fe TSRMLS_CC);

RETURN_TRUE;

}

/* }}} */

/* --- constant ------------------------------------------------------------ */

/* {{{ proto boolean bcompiler_write_constant(stream out | filehandle, string constant)

Writes compiled data to stream*/

PHP_FUNCTION(bcompiler_write_constant)

{

char *constant_name = NULL;

int constant_len;

zend_constant *zc = NULL;

zval *rsrc;

php_stream *stream;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &rsrc, &constant_name, &constant_len) == FAILURE) {

return;

}

php_stream_from_zval(stream, &rsrc);

zend_hash_find(EG(zend_constants), constant_name, constant_len + 1, (void **)&zc);

if (!zc) {

php_error(E_WARNING, "Could not find constant");

RETURN_NULL();

}

BCOMPILERG(stream) = stream;

BCOMPILERG(callback) = NULL;

SERIALIZE_SCALAR(BCOMPILER_CONSTANT, char)

apc_serialize_zend_constant(zc TSRMLS_CC);

RETURN_TRUE;

}

/* }}} */

/* --- functions from file ------------------------------------------------- */

/* write functions defined in file `real_path' to stream */

static void _bcompiler_write_functions_from_file(char *real_path TSRMLS_DC)

{

zend_function *zf = NULL;

HashPosition pos;

/* Cycle through the functions HashTable looking for user defined functions */

zend_hash_internal_pointer_reset_ex(EG(function_table), &pos);

while (zend_hash_get_current_data_ex(EG(function_table), (void **)&zf, &pos) == SUCCESS)

{

if (zf->type == ZEND_USER_FUNCTION) {

if (strcmp(zf->op_array.filename, real_path) == 0) {

if (BCOMPILERG(current_write) < 0x0010) {

SERIALIZE_SCALAR(BCOMPILER_FUNCTION_ENTRY, char)

} else {

SERIALIZE_SCALAR(BCOMPILER_FUNCTION_ENTRY_EX, char)

SERIALIZE_SCALAR(pos->nKeyLength, int);

#if PHP_MAJOR_VERSION >= 6

apc_serialize_zstring(pos->key.arKey.s, pos->key.type == IS_UNICODE ? UBYTES(pos->nKeyLength) : pos->nKeyLength TSRMLS_CC);

#else

apc_serialize_zstring(pos->arKey, pos->nKeyLength TSRMLS_CC);

#endif

}

apc_serialize_zend_function(zf TSRMLS_CC);

}

}

zend_hash_move_forward_ex(EG(function_table), &pos);

}

}

/* {{{ proto boolean bcompiler_write_functions_from_file(stream out | filehandle, string filename)

Writes compiled data from procedural code to stream */

PHP_FUNCTION(bcompiler_write_functions_from_file)

{

zval *rsrc;

char *filename = NULL;

int filename_length;

char *real_path = NULL;

php_stream *stream;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &rsrc, &filename, &filename_length) == FAILURE) {

return;

}

php_stream_from_zval(stream, &rsrc);

BCOMPILERG(stream) = stream;

BCOMPILERG(callback) = NULL;

real_path = expand_filepath(filename, NULL TSRMLS_CC);

if (!real_path) {

RETURN_FALSE;

}

_bcompiler_write_functions_from_file(real_path TSRMLS_CC);

efree(real_path);

RETURN_TRUE;

}

/* }}} */

/* --- file ---------------------------------------------------------------- */

/* {{{ proto boolean bcompiler_write_file(stream out | filehandle, string filename)

Writes compiled file data to stream */

PHP_FUNCTION(bcompiler_write_file)

{

zend_file_handle file_handle = {0};

zval *rsrc;

char *filename = NULL;

int filename_length;

char *real_path = NULL;

php_stream *stream;

zend_op_array *op_array = NULL;

#ifndef ZEND_ENGINE_2

int i = 0;

int n_old_class;

#endif

HashPosition pos;

zend_class_entry *zc;

zend_function *zf = NULL;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &rsrc, &filename, &filename_length) == FAILURE) {

return;

}

php_stream_from_zval(stream, &rsrc);

BCOMPILERG(stream) = stream;

BCOMPILERG(callback) = NULL;

real_path = expand_filepath(filename, NULL TSRMLS_CC);

if (!real_path) {

RETURN_FALSE;

}

file_handle.filename = real_path;

file_handle.free_filename = 0;

file_handle.type = ZEND_HANDLE_FILENAME;

file_handle.opened_path = NULL;

#ifndef ZEND_ENGINE_2

n_old_class = zend_hash_num_elements(CG(class_table));

#endif

CG(zend_lineno) = 0; /* Damjan Cvetko: to prevent -1 lineno offset */

/* compile (as include) */

op_array = bcompiler_saved_zend_compile_file(&file_handle, ZEND_INCLUDE/*type*/ TSRMLS_CC);

zend_destroy_file_handle(&file_handle TSRMLS_CC);

/* check for errors */

if (!op_array) {

efree(real_path);

RETURN_FALSE;

}

/* following line will execute just compiled script */

/*zend_execute(op_array TSRMLS_CC);*/

/* write classes */

zend_hash_internal_pointer_reset_ex(CG(class_table), &pos);

while (zend_hash_get_current_data_ex(CG(class_table), (void **)&zc, &pos) == SUCCESS)

{

#ifdef ZEND_ENGINE_2

zc = *((zend_class_entry**)zc);

#else

i++;

#endif

if (zc->type == ZEND_USER_CLASS) {

#ifndef ZEND_ENGINE_2

if (i > n_old_class)

#else

if (zc->info.user.filename && strcmp(zc->info.user.filename, real_path) == 0)

#endif

{

SERIALIZE_SCALAR(BCOMPILER_CLASS_ENTRY, char)

#if PHP_MAJOR_VERSION >= 6

apc_serialize_zend_class_entry(zc, NULL, 0, pos->key.arKey.s, pos->key.type == IS_UNICODE ? -pos->nKeyLength : pos->nKeyLength TSRMLS_CC);

#else

apc_serialize_zend_class_entry(zc, NULL, 0, pos->arKey, pos->nKeyLength TSRMLS_CC);

#endif

}

}

zend_hash_move_forward_ex(CG(class_table), &pos);

}

/* write functions */

_bcompiler_write_functions_from_file(real_path TSRMLS_CC);

/* write script body opcodes */

SERIALIZE_SCALAR(BCOMPILER_OP_ARRAY, char);

apc_serialize_zend_op_array(op_array TSRMLS_CC);

/* free opcode array */

#ifdef ZEND_ENGINE_2

destroy_op_array(op_array TSRMLS_CC);

#else

destroy_op_array(op_array);

#endif

efree(op_array);

/* clean-up created functions */

zend_hash_internal_pointer_reset_ex(CG(function_table), &pos);

while (zend_hash_get_current_data_ex(CG(function_table), (void **)&zf, &pos) == SUCCESS)

{

if (zf->type == ZEND_USER_FUNCTION) {

if (strcmp(zf->op_array.filename, real_path) == 0) {

#if PHP_MAJOR_VERSION >= 6

zend_u_hash_del(CG(function_table), pos->key.type, ZSTR(pos->key.arKey.s), pos->nKeyLength);

#else

zend_hash_del(CG(function_table), pos->arKey, pos->nKeyLength);

#endif

}

}

zend_hash_move_forward_ex(CG(function_table), &pos);

}

/* clean-up created classes */

#ifndef ZEND_ENGINE_2

i = 0;

#endif

zend_hash_internal_pointer_reset_ex(CG(class_table), &pos);

while (zend_hash_get_current_data_ex(CG(class_table), (void **)&zc, &pos) == SUCCESS)

{

#ifdef ZEND_ENGINE_2

zc = *((zend_class_entry**)zc);

#else

i++;

#endif

if (zc->type == ZEND_USER_CLASS) {

#ifndef ZEND_ENGINE_2

if (i > n_old_class)

#else

if (zc->info.user.filename && strcmp(zc->info.user.filename, real_path) == 0)

#endif

{

#if PHP_MAJOR_VERSION >= 6

zend_u_hash_del(CG(class_table), pos->key.type, ZSTR(pos->key.arKey.s), pos->nKeyLength);

#else

zend_hash_del(CG(class_table), pos->arKey, pos->nKeyLength);

#endif

}

}

zend_hash_move_forward_ex(CG(class_table), &pos);

}

efree(real_path);

RETURN_TRUE;

}

/* }}} */

/* --- parse_class --------------------------------------------------------- */

/* {{{ proto boolean bcompiler_parse_class(callback, string class_name)

Writes compiled data to g*/

PHP_FUNCTION(bcompiler_parse_class)

{

char *class_name = NULL;

int class_len;

zend_class_entry *ce = NULL;

zval *callback = NULL;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zs", &callback, &class_name, &class_len) == FAILURE) {

return;

}

zend_str_tolower(class_name, class_len);

zend_hash_find(EG(class_table), class_name, class_len+1, (void **)&ce);

if (!ce) {

RETURN_NULL();

}

BCOMPILERG(callback) = callback;

BCOMPILERG(stream) = NULL;

apc_serialize_zend_class_entry(ce, NULL, 0, NULL, 0 TSRMLS_CC);

RETURN_TRUE;

}

/* }}} */

/* --- header -------------------------------------------------------------- */

/* {{{ proto boolean bcompiler_write_header(stream out[, string write_ver])

Writes the start flag*/

PHP_FUNCTION(bcompiler_write_header)

{

zval *rsrc;

char *s = NULL;

int slen = 0, ver = BCOMPILER_CUR_VER;

php_stream *stream;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|s", &rsrc, &s, &slen) == FAILURE) {

return;

}

php_stream_from_zval(stream, &rsrc);

/* check desired bytecode version */

if (s) {

unsigned int rc, hi, lo;

rc = sscanf(s, "%u.%u", &hi, &lo);

if (rc == 2) {

ver = ((hi & 0xff) << 8) + (lo & 0xff);

if (!bcompiler_can_read(ver)) {

zend_error(E_WARNING, "unsupported version, using defaults");

ver = BCOMPILER_CUR_VER;

}

}

}

BCOMPILERG(current_write) = ver;

bcompiler_set_stdsize(ver, &BCOMPILERG(bcompiler_stdsize));

BCOMPILERG(stream) = stream;

serialize_magic(ver TSRMLS_CC);

RETURN_TRUE;

}

/* }}} */

/* --- footer -------------------------------------------------------------- */

/* {{{ proto boolean bcompiler_write_footer(stream out)

Writes the end zero*/

PHP_FUNCTION(bcompiler_write_footer)

{

zval *rsrc;

php_stream *stream;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &rsrc) == FAILURE) {

return;

}

php_stream_from_zval(stream, &rsrc);

BCOMPILERG(stream) = stream;

SERIALIZE_SCALAR(0, char);

RETURN_TRUE;

}

/* }}} */

/* --- exe_footer ---------------------------------------------------------- */

/* {{{ proto boolean bcompiler_write_exe_footer(stream out, int start_pos)

Writes compiled data to stream*/

PHP_FUNCTION(bcompiler_write_exe_footer)

{

zval *rsrc;

int start;

php_stream *stream;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &rsrc, &start) == FAILURE) {

return;

}

php_stream_from_zval(stream, &rsrc);

BCOMPILERG(stream) = stream;

SERIALIZE_SCALAR(start, int);

serialize_magic(0 TSRMLS_CC);

RETURN_TRUE;

}

/* }}} */

/* --- read ---------------------------------------------------------------- */

/* {{{ proto boolean bcompiler_read(stream in)

Reads compiled data from stream*/

PHP_FUNCTION(bcompiler_read)

{

zval *rsrc;

int test =0;

php_stream *stream;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &rsrc) == FAILURE) {

return;

}

php_stream_from_zval(stream, &rsrc);

BCOMPILERG(stream) = stream;

test = deserialize_magic(TSRMLS_C);

if (test != 0) {

php_error(E_WARNING, "Could not find Magic header in stream");

return;

}

BCOMPILERG(current_include) = 0;

bcompiler_read(TSRMLS_C);

RETURN_TRUE;

}

/* }}} */

/* --- load ---------------------------------------------------------------- */

/* {{{ proto boolean bcompiler_load(string bziped_file)

Reads compiled data bziped file*/

PHP_FUNCTION(bcompiler_load)

{

int test =0;

char *filename;

int filename_len;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename,&filename_len) == FAILURE) {

return;

}

BCOMPILERG(stream) = bz2_aware_stream_open(filename, 1, NULL TSRMLS_CC);

if (!BCOMPILERG(stream)) {

php_error(E_WARNING, "Could not open stream");

}

test = deserialize_magic(TSRMLS_C);

if (test != 0) {

php_error(E_WARNING, "Could not find Magic header in stream");

return;

}

if (BCOMPILERG(current_filename)) efree(BCOMPILERG(current_filename));

BCOMPILERG(current_filename) = estrdup(filename);

BCOMPILERG(current_include) = 0;

bcompiler_read(TSRMLS_C);

php_stream_close( BCOMPILERG(stream) );

RETURN_TRUE;

}

/* }}} */

/* --- load_exe ------------------------------------------------------------ */

/* {{{ proto boolean bcompiler_load_exe(string bziped_file)

Reads compiled data bziped file*/

PHP_FUNCTION(bcompiler_load_exe)

{

php_stream *stream = NULL;

int test =0;

int seekreturn = 0;

char *filename;

int filename_len;

long pos; /* offset to use */

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename,&filename_len) == FAILURE) {

return;

}

stream = bz2_aware_stream_open(filename, 0, NULL TSRMLS_CC);

if (!stream) {

BCOMPILER_DEBUG(("could not open stream: %s\n", filename));

php_error(E_WARNING, "Failed to open %s",filename);

return;

}

pos = (long) ((strlen(BCOMPILER_MAGIC_HEADER)+4) * -1); /* +4 cause we need to read the string size */

BCOMPILER_DEBUG(("move to start: %d\n", pos));

php_stream_seek(stream, pos , SEEK_END);

BCOMPILER_DEBUG(("done seek - try deserialize\n"));

BCOMPILERG(stream) = stream;

test = deserialize_magic(TSRMLS_C);

#if DISABLED_EXE

if (test != 0) {

BCOMPILER_DEBUG(("No magic header found\n"));

php_error(E_WARNING, "Could not find Magic header in stream");

php_stream_close(stream);

return;

}

#endif

/* now read the length */

pos = pos - 4;

BCOMPILER_DEBUG(("move to end: %d\n", pos));

php_stream_seek(stream, pos , SEEK_END);

DESERIALIZE_SCALAR(&pos, int);

/* seek the beginning of the bytecodes */

BCOMPILER_DEBUG(("move to start: %d\n", pos));

seekreturn = php_stream_seek(stream, pos , SEEK_SET);

if (seekreturn != 0) {

php_error(E_WARNING, "Failed to seek to stored position");

php_stream_close(stream);

return;

}

BCOMPILERG(stream) = stream;

test = deserialize_magic(TSRMLS_C);

if (test != 0) {

php_error(E_ERROR, "Could not find Magic header in stream");

php_stream_close(stream);

return;

}

if (BCOMPILERG(current_filename)) efree(BCOMPILERG(current_filename));

BCOMPILERG(current_filename) = estrdup(filename);

BCOMPILERG(current_include) = 0;

bcompiler_read( TSRMLS_C);

php_stream_close(stream);

RETURN_TRUE;

}

/* }}} */

/* --- set_filename_handler ------------------------------------------------ */

/* {{{ proto boolean bcompiler_set_filename_handler(callback handler)

Reads compiled data bziped file*/

PHP_FUNCTION(bcompiler_set_filename_handler)

{

zval *func = NULL;

#if PHP_MAJOR_VERSION >= 6

zval *name = NULL;

#else

char *name = NULL;

#endif

if (ZEND_NUM_ARGS() == 0) {

#if PHP_MAJOR_VERSION >= 6

if (BCOMPILERG(filename_handler_name)) zval_ptr_dtor(&BCOMPILERG(filename_handler_name));

#else

if (BCOMPILERG(filename_handler_name)) efree(BCOMPILERG(filename_handler_name));

#endif

if (BCOMPILERG(filename_handler)) zval_ptr_dtor(&BCOMPILERG(filename_handler));

BCOMPILERG(filename_handler_name) = NULL;

BCOMPILERG(filename_handler) = NULL;

RETURN_TRUE;

}

else if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &func) != FAILURE) {

#if PHP_MAJOR_VERSION < 6

if (Z_TYPE_P(func) != IS_STRING && Z_TYPE_P(func) != IS_ARRAY) {

SEPARATE_ZVAL(&func);

convert_to_string_ex(&func);

}

#endif

}

else {

WRONG_PARAM_COUNT;

}

#if PHP_MAJOR_VERSION >= 6

MAKE_STD_ZVAL(name);

if (!zend_is_callable(func, 0, name TSRMLS_CC)) {

if (name && Z_UNILEN(*name) == 0) {

func = NULL;

} else {

php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument is expected to be a valid callback, '%R' was given", Z_TYPE_P(name), Z_UNIVAL_P(name));

if (name) zval_ptr_dtor(&name);

RETURN_FALSE;

}

}

#else

if (!zend_is_callable(func, 0, &name TSRMLS_CC)) {

if (name && *name == 0) {

func = NULL;

} else {

php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument is expected to be a valid callback, '%s' was given", name);

if (name) efree(name);

RETURN_FALSE;

}

}

#endif

#if PHP_MAJOR_VERSION >= 6

if (BCOMPILERG(filename_handler_name)) zval_ptr_dtor(&BCOMPILERG(filename_handler_name));

#else

if (BCOMPILERG(filename_handler_name)) efree(BCOMPILERG(filename_handler_name));

#endif

if (BCOMPILERG(filename_handler)) zval_ptr_dtor(&BCOMPILERG(filename_handler));

BCOMPILERG(filename_handler_name) = name;

BCOMPILERG(filename_handler) = func;

if (func) zval_add_ref(&func);

RETURN_TRUE;

}

/* }}} */

/*

* Local variables:

* tab-width: 4

* c-basic-offset: 4

* End:

* vim>600: expandtab sw=4 ts=4 sts=4 fdm=marker

* vim<600: expandtab sw=4 ts=4 sts=4

*/

一键复制

编辑

Web IDE

原始数据

按行查看

历史

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值