Exemplo n.º 1
0
static zend_function *oop_get_indirection_func(
    zend_class_entry *ce, zend_function *fbc, zval *method, zval *obj
) {
    indirection_function *ind = emalloc(sizeof(indirection_function));
    zend_function *fn = (zend_function *) &ind->fn;
    long keep_flags = ZEND_ACC_RETURN_REFERENCE;

    ind->fn.type = ZEND_INTERNAL_FUNCTION;
    ind->fn.module = (ce->type == ZEND_INTERNAL_CLASS) ? ce->info.internal.module : NULL;
    ind->fn.handler = oop_indirection_func;
    ind->fn.scope = ce;
    ind->fn.fn_flags = ZEND_ACC_CALL_VIA_HANDLER | (fbc->common.fn_flags & keep_flags);
    ind->fn.num_args = fbc->common.num_args - 1;

    ind->fbc = fbc;
    if (fbc->common.arg_info) {
        fn->common.arg_info = &fbc->common.arg_info[1];
    } else {
        fn->common.arg_info = NULL;
    }

    ind->fn.function_name = zend_string_copy(Z_STR_P(method));
    zend_set_function_arg_flags(fn);
    ZVAL_COPY_VALUE(&ind->obj, obj);

    return fn;
}
Exemplo n.º 2
0
static zend_function *zend_test_class_static_method_get(zend_class_entry *ce, zend_string *name) /* {{{ */ {
	zend_internal_function *fptr = emalloc(sizeof(zend_internal_function));
	fptr->type = ZEND_OVERLOADED_FUNCTION;
	fptr->num_args = 1;
	fptr->arg_info = NULL;
	fptr->scope = ce;
	fptr->fn_flags = ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_STATIC;
	fptr->function_name = name;
	fptr->handler = ZEND_FN(zend_test_func);
	zend_set_function_arg_flags((zend_function*)fptr);

	return (zend_function*)fptr;
}
Exemplo n.º 3
0
static zend_function *zend_test_class_method_get(zend_object **object, zend_string *name, const zval *key) /* {{{ */ {
	zend_internal_function *fptr = emalloc(sizeof(zend_internal_function));
	fptr->type = ZEND_OVERLOADED_FUNCTION_TEMPORARY;
	fptr->num_args = 1;
	fptr->arg_info = NULL;
	fptr->scope = (*object)->ce;
	fptr->fn_flags = ZEND_ACC_CALL_VIA_HANDLER;
	fptr->function_name = zend_string_copy(name);
	fptr->handler = ZEND_FN(zend_test_func);
	zend_set_function_arg_flags((zend_function*)fptr);

	return (zend_function*)fptr;
}
Exemplo n.º 4
0
static union _zend_function *com_method_get(zend_object **object_ptr, zend_string *name, const zval *key)
{
	zend_internal_function f, *fptr = NULL;
	union _zend_function *func;
	DISPID dummy;
	php_com_dotnet_object *obj = (php_com_dotnet_object*)*object_ptr;

	if (V_VT(&obj->v) != VT_DISPATCH) {
		return NULL;
	}

	if (FAILED(php_com_get_id_of_name(obj, name->val, name->len, &dummy))) {
		return NULL;
	}

	/* check cache */
	if (obj->method_cache == NULL || NULL == (fptr = zend_hash_find_ptr(obj->method_cache, name))) {
		f.type = ZEND_OVERLOADED_FUNCTION;
		f.num_args = 0;
		f.arg_info = NULL;
		f.scope = obj->ce;
		f.fn_flags = ZEND_ACC_CALL_VIA_HANDLER;
		f.function_name = zend_string_copy(name);
		f.handler = PHP_FN(com_method_handler);

		fptr = &f;

		if (obj->typeinfo) {
			/* look for byref params */
			ITypeComp *comp;
			ITypeInfo *TI = NULL;
			DESCKIND kind;
			BINDPTR bindptr;
			OLECHAR *olename;
			ULONG lhash;
			int i;

			if (SUCCEEDED(ITypeInfo_GetTypeComp(obj->typeinfo, &comp))) {
				olename = php_com_string_to_olestring(name->val, name->len, obj->code_page);
				lhash = LHashValOfNameSys(SYS_WIN32, LOCALE_SYSTEM_DEFAULT, olename);

				if (SUCCEEDED(ITypeComp_Bind(comp, olename, lhash, INVOKE_FUNC, &TI, &kind, &bindptr))) {
					switch (kind) {
						case DESCKIND_FUNCDESC:
							f.arg_info = ecalloc(bindptr.lpfuncdesc->cParams, sizeof(zend_arg_info));

							for (i = 0; i < bindptr.lpfuncdesc->cParams; i++) {
								f.arg_info[i].allow_null = 1;
								if (bindptr.lpfuncdesc->lprgelemdescParam[i].paramdesc.wParamFlags & PARAMFLAG_FOUT) {
									f.arg_info[i].pass_by_reference = ZEND_SEND_BY_REF;
								}
							}

							f.num_args = bindptr.lpfuncdesc->cParams;

							ITypeInfo_ReleaseFuncDesc(TI, bindptr.lpfuncdesc);
							break;

							/* these should not happen, but *might* happen if the user
							 * screws up; lets avoid a leak in that case */
						case DESCKIND_VARDESC:
							ITypeInfo_ReleaseVarDesc(TI, bindptr.lpvardesc);
							break;
						case DESCKIND_TYPECOMP:
							ITypeComp_Release(bindptr.lptcomp);
							break;

						case DESCKIND_NONE:
							break;
					}
					if (TI) {
						ITypeInfo_Release(TI);
					}
				}
				ITypeComp_Release(comp);
				efree(olename);
			}
		}

		zend_set_function_arg_flags((zend_function*)&f);
		/* save this method in the cache */
		if (!obj->method_cache) {
			ALLOC_HASHTABLE(obj->method_cache);
			zend_hash_init(obj->method_cache, 2, NULL, function_dtor, 0);
		}

		zend_hash_update_mem(obj->method_cache, name, &f, sizeof(f));
	}

	if (fptr) {
		/* duplicate this into a new chunk of emalloc'd memory,
		 * since the engine will efree it */
		func = emalloc(sizeof(*fptr));
		memcpy(func, fptr, sizeof(*fptr));

		return func;
	}

	return NULL;
}