Exemple #1
0
PHP_METHOD(Struct, getOffset) {
	zval *zoffset;
	php_jit_struct_t *pstruct;
	zend_ulong of = 0;
	
	if (php_jit_parameters("z", &zoffset) != SUCCESS || !zoffset) {
		php_jit_exception("unexpected parameters, expected (string|integer field)");
		return;
	}
	
	pstruct = PHP_JIT_FETCH_STRUCT(getThis());
	
	switch (Z_TYPE_P(zoffset)) {
		case IS_STRING:
			if (!pstruct->names) {
				php_jit_exception("no names available");
			}
			
			of = jit_type_find_name
				(pstruct->type, Z_STRVAL_P(zoffset));
		break;
		
		case IS_LONG:	
			of = Z_LVAL_P(zoffset);
		break;
		
		default:
			php_jit_exception("unexpected parameters, expected (string|integer field)");
			return;
	}
	
	if (of < pstruct->nfields) {
		RETURN_LONG(jit_type_get_offset(pstruct->type, of));
	}
	
	php_jit_exception("failed to find offset of requested field");
}
Exemple #2
0
/*
 * On X86_64 the alignment of native types matches their size.
 * This leads to the result that all types except nfloats and aggregates
 * (structs and unions) must start and end in an eightbyte (or the part
 * we are looking at).
 */
static int
_jit_classify_structpart(jit_type_t struct_type, unsigned int start,
						 unsigned int start_offset, unsigned int end_offset)
{
	int arg_class = X86_64_ARG_NO_CLASS;
	unsigned int num_fields = jit_type_num_fields(struct_type);
	unsigned int current_field;
	
	for(current_field = 0; current_field < num_fields; ++current_field)
	{
		jit_nuint field_offset = jit_type_get_offset(struct_type,
													 current_field);

		if(field_offset <= end_offset)
		{
			/* The field starts at a place that's inerresting for us */
			jit_type_t field_type = jit_type_get_field(struct_type,
													   current_field);
			jit_nuint field_size = jit_type_get_size(field_type); 

			if(field_offset + field_size > start_offset)
			{
				/* The field is at least partially in the part we are */
				/* looking at */
				int arg_class2 = X86_64_ARG_NO_CLASS;

				if(is_struct_or_union(field_type))
				{
					/* We have to check this struct recursively */
					unsigned int current_start;
					unsigned int nested_struct_start;
					unsigned int nested_struct_end;

					current_start = start + start_offset;
					if(field_offset < current_start)
					{
						nested_struct_start = current_start - field_offset;
					}
					else
					{
						nested_struct_start = 0;
					}
					if(field_offset + field_size - 1 > end_offset)
					{
						/* The struct ends beyond the part we are looking at */
						nested_struct_end = field_offset + field_size -
												(nested_struct_start + 1);
					}
					else
					{
						nested_struct_end = field_size - 1;
					}
					arg_class2 = _jit_classify_structpart(field_type,
														  start + field_offset,
														  nested_struct_start,
														  nested_struct_end);
				}
				else
				{
					if((start + start_offset) & (field_size - 1))
					{
						/* The field is misaligned */
						return X86_64_ARG_MEMORY;
					}
					arg_class2 = _jit_classify_arg(field_type, 0);
				}
				if(arg_class == X86_64_ARG_NO_CLASS)
				{
					arg_class = arg_class2;
				}
				else if(arg_class != arg_class2)
				{
					if(arg_class == X86_64_ARG_MEMORY ||
					   arg_class2 == X86_64_ARG_MEMORY)
					{
						arg_class = X86_64_ARG_MEMORY;
					}
					else if(arg_class == X86_64_ARG_INTEGER ||
					   arg_class2 == X86_64_ARG_INTEGER)
					{
						arg_class = X86_64_ARG_INTEGER;
					}
					else if(arg_class == X86_64_ARG_X87 ||
					   arg_class2 == X86_64_ARG_X87)
					{
						arg_class = X86_64_ARG_MEMORY;
					}
					else
					{
						arg_class = X86_64_ARG_SSE;
					}
				}
			}
		}
	}
	return arg_class;
}