예제 #1
0
파일: qb_interpreter.c 프로젝트: 3CTO/qb
static int32_t qb_release_object_instances(qb_interpreter_context *cxt) {
	USE_TSRM
	uint32_t i;
	for(i = 0; i < QB_G(scope_count); i++) {
		qb_import_scope *scope = QB_G(scopes)[i];
		if(scope->type == QB_IMPORT_SCOPE_OBJECT) {
			// release the object
			zval_ptr_dtor(&scope->object);
			scope->type = QB_IMPORT_SCOPE_FREED_OBJECT;
		}
	}
	return TRUE;
}
예제 #2
0
파일: qb_interpreter.c 프로젝트: 3CTO/qb
static void qb_refresh_imported_variables(qb_interpreter_context *cxt) {
	USE_TSRM
	uint32_t i, j;
	for(i = 0; i < QB_G(scope_count); i++) {
		qb_import_scope *scope = QB_G(scopes)[i];
		if(scope->type != QB_IMPORT_SCOPE_ABSTRACT_OBJECT) {
			for(j = 0; j < scope->variable_count; j++) {
				qb_variable *ivar = scope->variables[j];
				qb_transfer_value_from_import_source(cxt, ivar, scope);
			}
		}
	}
}
예제 #3
0
파일: qb_interpreter.c 프로젝트: 3CTO/qb
static int32_t qb_release_imported_segments(qb_interpreter_context *cxt) {
	USE_TSRM
	uint32_t i, j;
	for(i = 0; i < QB_G(scope_count); i++) {
		qb_import_scope *scope = QB_G(scopes)[i];
		if(scope->type != QB_IMPORT_SCOPE_ABSTRACT_OBJECT) {
			for(j = QB_SELECTOR_ARRAY_START; j < scope->storage->segment_count; j++) {
				qb_memory_segment *segment = &scope->storage->segments[j];
				qb_release_segment(segment);
			}
		}
	}
	return TRUE;
}
예제 #4
0
파일: qb_build.c 프로젝트: remicollet/qb
void qb_generate_executables(qb_build_context *cxt) {
	USE_TSRM
	int32_t native_compile = FALSE;
	uint32_t i;
	for(i = 0; i < cxt->compiler_context_count; i++) {
		qb_compiler_context *compiler_cxt = cxt->compiler_contexts[i];
		qb_encoder_context _encoder_cxt, *encoder_cxt = &_encoder_cxt;

		qb_initialize_encoder_context(encoder_cxt, compiler_cxt, TRUE TSRMLS_CC);

		// encode the instruction stream
		compiler_cxt->compiled_function = qb_encode_function(encoder_cxt);

		if(!compiler_cxt->compiled_function) {
			qb_dispatch_exceptions(TSRMLS_C);
		}

		// relocate the function now, so the base function won't be in the middle of relcoation while it's being copied
		qb_relocate_function(compiler_cxt->compiled_function, TRUE);

		// attach the function to the op array
		qb_attach_compiled_function(compiler_cxt->compiled_function, compiler_cxt->zend_op_array TSRMLS_CC);

		if(compiler_cxt->function_flags & QB_FUNCTION_NATIVE_IF_POSSIBLE) {
			native_compile = TRUE;
		}
	}

#ifdef NATIVE_COMPILE_ENABLED
	// compile all functions inside build in one go
	if(native_compile) {
		if(QB_G(allow_native_compilation)) {
			qb_native_compiler_context _native_compiler_cxt, *native_compiler_cxt = &_native_compiler_cxt;
			qb_initialize_native_compiler_context(native_compiler_cxt, cxt TSRMLS_CC);
			qb_compile_to_native_code(native_compiler_cxt);
			qb_free_native_compiler_context(native_compiler_cxt);
		}
	}
	if(!QB_G(allow_bytecode_interpretation)) {
		for(i = 0; i < cxt->compiler_context_count; i++) {
			qb_compiler_context *compiler_cxt = cxt->compiler_contexts[i];
			if(!compiler_cxt->compiled_function->native_proc) {
				qb_report_native_compilation_exception(compiler_cxt->compiled_function->line_id, compiler_cxt->compiled_function->name);
				qb_dispatch_exceptions(TSRMLS_C);
			}
		}
	}
#endif
}
예제 #5
0
파일: qb_interpreter.c 프로젝트: 3CTO/qb
static int32_t qb_sync_imported_variables(qb_interpreter_context *cxt) {
	USE_TSRM
	uint32_t i, j;
	for(i = 0; i < QB_G(scope_count); i++) {
		qb_import_scope *scope = QB_G(scopes)[i];
		if(scope->type != QB_IMPORT_SCOPE_ABSTRACT_OBJECT && scope->type != QB_IMPORT_SCOPE_FREED_OBJECT) {
			for(j = 0; j < scope->variable_count; j++) {
				qb_variable *ivar = scope->variables[j];
				if(!qb_transfer_value_to_import_source(cxt, ivar, scope)) {
					return FALSE;
				}
			}
		}
	}
	return TRUE;
}
예제 #6
0
static int32_t qb_validate_operands_matrix_current_mode(qb_compiler_context *cxt, qb_op_factory *f, qb_primitive_type expr_type, uint32_t flags, qb_operand *operands, uint32_t operand_count, qb_result_destination *result_destination) {
	USE_TSRM
	qb_matrix_op_factory_selector *s = (qb_matrix_op_factory_selector *) f;
	if(QB_G(column_major_matrix)) {
		f = s->cm_factory;
	} else {
		f = s->rm_factory;
	}
	return f->validate_operands(cxt, f, expr_type, flags, operands, operand_count, result_destination);
}
예제 #7
0
static int32_t qb_transfer_operands_matrix_current_mode(qb_compiler_context *cxt, qb_op_factory *f, uint32_t flags, qb_operand *operands, uint32_t operand_count, qb_operand *result, qb_operand *dest, uint32_t dest_count) {
	USE_TSRM
	qb_matrix_op_factory_selector *s = (qb_matrix_op_factory_selector *) f;
	if(QB_G(column_major_matrix)) {
		f = s->cm_factory;
	} else {
		f = s->rm_factory;
	}
	return f->transfer_operands(cxt, f, flags, operands, operand_count, result, dest, dest_count);
}
예제 #8
0
파일: qb.c 프로젝트: WaseemCake/qb
NO_RETURN void qb_abort(const char *format, ...) {
	const char *filename;
	uint32_t lineno;
	va_list args;
	TSRMLS_FETCH();

	if(QB_G(current_filename)) {
		filename = QB_G(current_filename);
	} else {
		filename = zend_get_executed_filename(TSRMLS_C);
	}
	if(QB_G(current_line_number)) {
		lineno = QB_G(current_line_number);
	} else {
		lineno = zend_get_executed_lineno(TSRMLS_C);
	}

	va_start(args, format);
	zend_error_cb(E_ERROR, filename, lineno, format, args);
	va_end(args);
}
예제 #9
0
static int32_t qb_inline_function(qb_compiler_context *cxt, void *factory, qb_operand *operands, uint32_t operand_count, qb_operand *result, uint32_t *jump_target_indices, uint32_t jump_target_count, qb_result_prototype *result_prototype) {
	USE_TSRM
	qb_operand *func = &operands[0], *arguments = &operands[1], *argument_count = &operands[2];
	qb_function *qfunc = qb_find_compiled_function(func->zend_function TSRMLS_CC);
	qb_compiler_context *callee_cxt = qb_find_compiler_context(QB_G(build_context), qfunc);
	qb_function_inliner_context _inliner_cxt, *inliner_cxt = &_inliner_cxt;
	int32_t succeeded;

	qb_initialize_function_inliner_context(inliner_cxt, cxt, callee_cxt, arguments->arguments, argument_count->number, result, result_prototype TSRMLS_CC);
	succeeded = qb_transfer_inlined_function_ops(inliner_cxt);
	qb_free_function_inliner_context(inliner_cxt);
	return succeeded;
}
예제 #10
0
파일: qb_build.c 프로젝트: remicollet/qb
void qb_perform_translation(qb_build_context *cxt) {
	USE_TSRM
	uint32_t i;
	for(i = 0; i < cxt->compiler_context_count; i++) {
		qb_compiler_context *compiler_cxt = cxt->compiler_contexts[i];

		switch(compiler_cxt->translation) {
			case QB_TRANSLATION_PHP: {
				qb_php_translator_context *translator_cxt = compiler_cxt->translator_context;
				// translate the zend ops to intermediate qb ops
				qb_translate_instructions(translator_cxt);
			}	break;
			case QB_TRANSLATION_PBJ: {
				qb_pbj_translator_context *translator_cxt = compiler_cxt->translator_context;
				// create the main loop and translate the PB instructions
				qb_translate_pbj_instructions(translator_cxt);

				// free the binary
				qb_free_external_code(compiler_cxt);
			}	break;
		}

		// display warning and bail out on fatal errors
		qb_dispatch_exceptions(TSRMLS_C);

		// make all jump target indices absolute
		qb_resolve_jump_targets(compiler_cxt);

		// fuse basic instructions into compound ones
		qb_fuse_instructions(compiler_cxt, 1);

		// assign storage space to variables
		qb_assign_storage_space(compiler_cxt);

		// make opcodes address-mode-specific
		qb_resolve_address_modes(compiler_cxt);

		// try to fuse more instructions
		qb_fuse_instructions(compiler_cxt, 2);

		// figure out how many references to relocatable segments there are
		qb_resolve_reference_counts(compiler_cxt);

		// show the qb opcodes if turned on
		if(QB_G(show_opcodes)) {
			qb_printer_context _printer_cxt, *printer_cxt = &_printer_cxt;
			qb_initialize_printer_context(printer_cxt, compiler_cxt TSRMLS_CC);
			qb_print_ops(printer_cxt);
		}
	}
}
예제 #11
0
static qb_matrix_order qb_get_matrix_order(qb_compiler_context *cxt, qb_op_factory *f) {
	if(f->result_flags & QB_RESULT_IS_COLUMN_MAJOR) {
		return QB_MATRIX_ORDER_COLUMN_MAJOR;
	} else if(f->result_flags & QB_RESULT_IS_ROW_MAJOR) {
		return QB_MATRIX_ORDER_ROW_MAJOR;
	} else {
		USE_TSRM
		if(QB_G(column_major_matrix)) { 
			return QB_MATRIX_ORDER_COLUMN_MAJOR;
		} else {
			return QB_MATRIX_ORDER_ROW_MAJOR;
		}
	}
}
예제 #12
0
파일: qb_build.c 프로젝트: remicollet/qb
static void qb_initialize_build_environment(qb_build_context *cxt) {
	USE_TSRM
	uint32_t i;

	cxt->compiler_contexts = emalloc(sizeof(qb_compiler_context *) * cxt->function_declaration_count);
	for(i = 0; i < cxt->function_declaration_count; i++) {
		qb_compiler_context *compiler_cxt = cxt->compiler_contexts[cxt->compiler_context_count++] = emalloc(sizeof(qb_compiler_context));
		qb_initialize_compiler_context(compiler_cxt, cxt->pool, cxt->function_declarations[i], i, cxt->function_declaration_count TSRMLS_CC);

		// add variables used within function
		if(!qb_add_variables(compiler_cxt)) {
			qb_dispatch_exceptions(TSRMLS_C);
		}

		// set up function prototypes so the functions can resolved against each other
		qb_initialize_function_prototype(compiler_cxt);

		// attach the appropriate translator
		if(!compiler_cxt->function_declaration->import_path) {
			qb_php_translator_context *translator_cxt = emalloc(sizeof(qb_php_translator_context));
			qb_initialize_php_translator_context(translator_cxt, compiler_cxt TSRMLS_CC);
			compiler_cxt->translation = QB_TRANSLATION_PHP;
			compiler_cxt->translator_context = translator_cxt;
		} else {
			qb_pbj_translator_context *translator_cxt = emalloc(sizeof(qb_pbj_translator_context));
			qb_initialize_pbj_translator_context(translator_cxt, compiler_cxt TSRMLS_CC);
			compiler_cxt->translation = QB_TRANSLATION_PBJ;
			compiler_cxt->translator_context = translator_cxt;

			// load the code into memory and decode the pbj data
			if(!qb_load_external_code(compiler_cxt, compiler_cxt->function_declaration->import_path)
			|| !qb_decode_pbj_binary(translator_cxt)) {
				qb_dispatch_exceptions(TSRMLS_C);
			}
		}

		// show the zend/pbj opcodes if turned on
		if(QB_G(show_source_opcodes)) {
			qb_printer_context _printer_cxt, *printer_cxt = &_printer_cxt;
			qb_initialize_printer_context(printer_cxt, compiler_cxt TSRMLS_CC);
			qb_print_source_ops(printer_cxt);
			qb_free_printer_context(printer_cxt);
		}
	}

	for(i = 0; i < cxt->compiler_context_count; i++) {
		qb_compiler_context *compiler_cxt = cxt->compiler_contexts[i];

		switch(compiler_cxt->translation) {
			case QB_TRANSLATION_PHP: {
				// run an initial pass over the opcode to gather info
				qb_php_translator_context *translator_cxt = compiler_cxt->translator_context;
				qb_survey_instructions(translator_cxt);
			}	break;
			case QB_TRANSLATION_PBJ: {
				qb_pbj_translator_context *translator_cxt = compiler_cxt->translator_context;
				qb_survey_pbj_instructions(translator_cxt);
			}	break;
		}
	}

	// display warning and bail out on fatal errors
	qb_dispatch_exceptions(TSRMLS_C);
}