Vmstack php,zend_vm_stack_push_call_frame

static zend_always_inline zend_execute_data *zend_vm_stack_push_call_frame(uint32_t call_info, zend_function *func, uint32_t num_args, zend_class_entry *called_scope, zend_object *object)

{

//根据参数和方法,计算使用的堆栈

uint32_t used_stack = zend_vm_calc_used_stack(num_args, func);

return zend_vm_stack_push_call_frame_ex(used_stack, call_info,

func, num_args, called_scope, object);

}

1.zend_vm_calc_used_stack

static zend_always_inline uint32_t zend_vm_calc_used_stack(uint32_t num_args, zend_function *func)

{

//槽,加上参数数量个数

uint32_t used_stack = ZEND_CALL_FRAME_SLOT + num_args;

//ZEND_USER_CODE(type) ((type & 1) == 0)

if (EXPECTED(ZEND_USER_CODE(func->type))) {

//加上op_array最后一个定义的变量,加上临时变量和返回值的大小,减去一个重复的变量个数

used_stack += func->op_array.last_var + func->op_array.T - MIN(func->op_array.num_args, num_args);

}

return used_stack * sizeof(zval);

}

//两个结构体的长度除以一个zval的长度,得出占用几个zval的个数,aligned 对其方式

#define ZEND_CALL_FRAME_SLOT \

((int)((ZEND_MM_ALIGNED_SIZE(sizeof(zend_execute_data)) + ZEND_MM_ALIGNED_SIZE(sizeof(zval)) - 1) / ZEND_MM_ALIGNED_SIZE(sizeof(zval))))

2.zend_vm_stack_push_call_frame_ex

static zend_always_inline zend_execute_data *zend_vm_stack_push_call_frame_ex(uint32_t used_stack, uint32_t call_info, zend_function *func, uint32_t num_args, zend_class_entry *called_scope, zend_object *object)

{

zend_execute_data *call = (zend_execute_data*)EG(vm_stack_top);

ZEND_ASSERT_VM_STACK_GLOBAL;

//需要的堆栈空间大于剩余可用的,则扩容

if (UNEXPECTED(used_stack > (size_t)(((char*)EG(vm_stack_end)) - (char*)call))) {

call = (zend_execute_data*)zend_vm_stack_extend(used_stack);

ZEND_ASSERT_VM_STACK_GLOBAL;

//call_info ZEND_CALL_FUNCTION | ZEND_CALL_RELEASE_THIS | ZEND_CALL_CTOR

// func constructor

zend_vm_init_call_frame(call, call_info | ZEND_CALL_ALLOCATED, func, num_args, called_scope, object);

return call;

} else {

EG(vm_stack_top) = (zval*)((char*)call + used_stack);

zend_vm_init_call_frame(call, call_info, func, num_args, called_scope, object);

return call;

}

}

ZEND_API void* zend_vm_stack_extend(size_t size)

{

zend_vm_stack stack;

void *ptr;

stack = EG(vm_stack);

stack->top = EG(vm_stack_top);

EG(vm_stack) = stack = zend_vm_stack_new_page(

EXPECTED(size < ZEND_VM_STACK_FREE_PAGE_SIZE(0)) ?

ZEND_VM_STACK_PAGE_SIZE(0) : ZEND_VM_STACK_PAGE_ALIGNED_SIZE(0, size),

stack);

ptr = stack->top;

EG(vm_stack_top) = (void*)(((char*)ptr) + size);

EG(vm_stack_end) = stack->end;

return ptr;

}

static zend_always_inline void zend_vm_init_call_frame(zend_execute_data *call, uint32_t call_info, zend_function *func, uint32_t num_args, zend_class_entry *called_scope, zend_object *object)

{

call->func = func;

if (object) {

//#define Z_OBJ(zval) (zval).value.obj,this值

Z_OBJ(call->This) = object;

ZEND_SET_CALL_INFO(call, 1, call_info);

} else {

Z_CE(call->This) = called_scope;

//#define ZEND_SET_CALL_INFO(call, object, info) do { \

//Z_TYPE_INFO((call)->This) = ((object) ? IS_OBJECT_EX : IS_UNDEF) | ((info) << //ZEND_CALL_INFO_SHIFT); \

//} while (0)

ZEND_SET_CALL_INFO(call, 0, call_info);

}

//#define ZEND_CALL_NUM_ARGS(call) \

// (call)->This.u2.num_args

ZEND_CALL_NUM_ARGS(call) = num_args;

}

本作品采用《CC 协议》,转载必须注明作者和本文链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值