⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 slang_compile.c

📁 mesa-6.5-minigui源码
💻 C
📖 第 1 页 / 共 4 页
字号:
	/* restore the old assembly */	if (!slang_assembly_file_restore_point_load (A->file, &point))		return GL_FALSE;	A->local = save_local;	/* now we copy the contents of the initialized variable back to the original machine */	_mesa_memcpy ((GLubyte *) A->mach->mem + var->address, (GLubyte *) mach.mem + var->address,		var->size);	return GL_TRUE;}/* init declarator list */#define DECLARATOR_NONE 0#define DECLARATOR_NEXT 1/* variable declaration */#define VARIABLE_NONE 0#define VARIABLE_IDENTIFIER 1#define VARIABLE_INITIALIZER 2#define VARIABLE_ARRAY_EXPLICIT 3#define VARIABLE_ARRAY_UNKNOWN 4static int parse_init_declarator (slang_parse_ctx *C, slang_output_ctx *O,	const slang_fully_specified_type *type){	slang_variable *var;	/* empty init declatator (without name, e.g. "float ;") */	if (*C->I++ == VARIABLE_NONE)		return 1;	/* make room for the new variable and initialize it */	O->vars->variables = (slang_variable *) slang_alloc_realloc (O->vars->variables,		O->vars->num_variables * sizeof (slang_variable),		(O->vars->num_variables + 1) * sizeof (slang_variable));	if (O->vars->variables == NULL)	{		slang_info_log_memory (C->L);		return 0;	}	var = &O->vars->variables[O->vars->num_variables];	if (!slang_variable_construct (var))		return 0;	O->vars->num_variables++;	/* copy the declarator qualifier type, parse the identifier */	var->global = C->global_scope;	var->type.qualifier = type->qualifier;	var->a_name = parse_identifier (C);	if (var->a_name == SLANG_ATOM_NULL)		return 0;	switch (*C->I++)	{	case VARIABLE_NONE:		/* simple variable declarator - just copy the specifier */		if (!slang_type_specifier_copy (&var->type.specifier, &type->specifier))			return 0;		break;	case VARIABLE_INITIALIZER:		/* initialized variable - copy the specifier and parse the expression */		if (!slang_type_specifier_copy (&var->type.specifier, &type->specifier))			return 0;		var->initializer = (slang_operation *) slang_alloc_malloc (sizeof (slang_operation));		if (var->initializer == NULL)		{			slang_info_log_memory (C->L);			return 0;		}		if (!slang_operation_construct (var->initializer))		{			slang_alloc_free (var->initializer);			var->initializer = NULL;			slang_info_log_memory (C->L);			return 0;		}		if (!parse_expression (C, O, var->initializer))			return 0;		break;#if 0	case VARIABLE_ARRAY_UNKNOWN:		/* unsized array - mark it as array and copy the specifier to the array element */		if (!convert_to_array (C, var, &type->specifier))			return GL_FALSE;		break;#endif	case VARIABLE_ARRAY_EXPLICIT:		if (!convert_to_array (C, var, &type->specifier))			return GL_FALSE;		if (!parse_array_len (C, O, &var->array_len))			return GL_FALSE;		break;	default:		return 0;	}	/* allocate global address space for a variable with a known size */	if (C->global_scope && !(var->type.specifier.type == slang_spec_array && var->array_len == 0))	{		if (!calculate_var_size (C, O, var))			return GL_FALSE;		var->address = slang_var_pool_alloc (O->global_pool, var->size);	}	/* initialize global variable */	if (C->global_scope && var->initializer != NULL)	{		slang_assemble_ctx A;		A.file = O->assembly;		A.mach = O->machine;		A.atoms = C->atoms;		A.space.funcs = O->funs;		A.space.structs = O->structs;		A.space.vars = O->vars;		if (!initialize_global (&A, var))			return 0;	}	return 1;}static int parse_init_declarator_list (slang_parse_ctx *C, slang_output_ctx *O){	slang_fully_specified_type type;	/* parse the fully specified type, common to all declarators */	if (!slang_fully_specified_type_construct (&type))		return 0;	if (!parse_fully_specified_type (C, O, &type))	{		slang_fully_specified_type_destruct (&type);		return 0;	}	/* parse declarators, pass-in the parsed type */	do	{		if (!parse_init_declarator (C, O, &type))		{			slang_fully_specified_type_destruct (&type);			return 0;		}	}	while (*C->I++ == DECLARATOR_NEXT);	slang_fully_specified_type_destruct (&type);	return 1;}static int parse_function (slang_parse_ctx *C, slang_output_ctx *O, int definition,	slang_function **parsed_func_ret){	slang_function parsed_func, *found_func;	/* parse function definition/declaration */	if (!slang_function_construct (&parsed_func))		return 0;	if (definition)	{		if (!parse_function_definition (C, O, &parsed_func))		{			slang_function_destruct (&parsed_func);			return 0;		}	}	else	{		if (!parse_function_prototype (C, O, &parsed_func))		{			slang_function_destruct (&parsed_func);			return 0;		}	}	/* find a function with a prototype matching the parsed one - only the current scope	 * is being searched to allow built-in function overriding */	found_func = slang_function_scope_find (O->funs, &parsed_func, 0);	if (found_func == NULL)	{		/* add the parsed function to the function list */		O->funs->functions = (slang_function *) slang_alloc_realloc (O->funs->functions,			O->funs->num_functions * sizeof (slang_function),			(O->funs->num_functions + 1) * sizeof (slang_function));		if (O->funs->functions == NULL)		{			slang_info_log_memory (C->L);			slang_function_destruct (&parsed_func);			return 0;		}		O->funs->functions[O->funs->num_functions] = parsed_func;		O->funs->num_functions++;		/* return the newly parsed function */		*parsed_func_ret = &O->funs->functions[O->funs->num_functions - 1];	}	else	{		/* TODO: check function return type qualifiers and specifiers */		if (definition)		{			if (found_func->body != NULL)			{				slang_info_log_error (C->L, "%s: function already has a body",					slang_atom_pool_id (C->atoms, parsed_func.header.a_name));				slang_function_destruct (&parsed_func);				return 0;			}			/* destroy the existing function declaration and replace it with the new one,			 * remember to save the fixup table */			parsed_func.fixups = found_func->fixups;			slang_fixup_table_init (&found_func->fixups);			slang_function_destruct (found_func);			*found_func = parsed_func;		}		else		{			/* another declaration of the same function prototype - ignore it */			slang_function_destruct (&parsed_func);		}		/* return the found function */		*parsed_func_ret = found_func;	}	/* assemble the parsed function */	{		slang_assemble_ctx A;		A.file = O->assembly;		A.mach = O->machine;		A.atoms = C->atoms;		A.space.funcs = O->funs;		A.space.structs = O->structs;		A.space.vars = O->vars;		if (!_slang_assemble_function (&A, *parsed_func_ret))			return 0;	}	return 1;}/* declaration */#define DECLARATION_FUNCTION_PROTOTYPE 1#define DECLARATION_INIT_DECLARATOR_LIST 2static int parse_declaration (slang_parse_ctx *C, slang_output_ctx *O){	switch (*C->I++)	{	case DECLARATION_INIT_DECLARATOR_LIST:		if (!parse_init_declarator_list (C, O))			return 0;		break;	case DECLARATION_FUNCTION_PROTOTYPE:		{			slang_function *dummy_func;			if (!parse_function (C, O, 0, &dummy_func))				return 0;		}		break;	default:		return 0;	}	return 1;}/* external declaration */#define EXTERNAL_NULL 0#define EXTERNAL_FUNCTION_DEFINITION 1#define EXTERNAL_DECLARATION 2static int parse_translation_unit (slang_parse_ctx *C, slang_translation_unit *unit){	slang_output_ctx o;	/* setup output context */	o.funs = &unit->functions;	o.structs = &unit->structs;	o.vars = &unit->globals;	o.assembly = unit->assembly;	o.global_pool = unit->global_pool;	o.machine = unit->machine;	/* parse individual functions and declarations */	while (*C->I != EXTERNAL_NULL)	{		switch (*C->I++)		{		case EXTERNAL_FUNCTION_DEFINITION:			{				slang_function *func;				if (!parse_function (C, &o, 1, &func))					return 0;			}			break;		case EXTERNAL_DECLARATION:			if (!parse_declaration (C, &o))				return 0;			break;		default:			return 0;		}	}	C->I++;	return 1;}#define BUILTIN_CORE 0#define BUILTIN_COMMON 1#define BUILTIN_TARGET 2#define BUILTIN_TOTAL 3static int compile_binary (const byte *prod, slang_translation_unit *unit, slang_unit_type type,	slang_info_log *log, slang_translation_unit *builtins, slang_assembly_file *file,	slang_var_pool *pool, slang_machine *mach, slang_translation_unit *downlink,	slang_atom_pool *atoms){	slang_parse_ctx C;	/* create translation unit object */	if (file != NULL)	{		if (!slang_translation_unit_construct2 (unit, file, pool, mach, atoms))			return 0;		unit->type = type;	}	/* set-up parse context */	C.I = prod;	C.L = log;	C.parsing_builtin = builtins == NULL;	C.global_scope = 1;	C.atoms = unit->atom_pool;	if (!check_revision (&C))	{		slang_translation_unit_destruct (unit);		return 0;	}	if (downlink != NULL)	{		unit->functions.outer_scope = &downlink->functions;		unit->globals.outer_scope = &downlink->globals;		unit->structs.outer_scope = &downlink->structs;	}	/* parse translation unit */	if (!parse_translation_unit (&C, unit))	{		slang_translation_unit_destruct (unit);		return 0;	}	return 1;}static int compile_with_grammar (grammar id, const char *source, slang_translation_unit *unit,	slang_unit_type type, slang_info_log *log, slang_translation_unit *builtins){	byte *prod;	unsigned int size, start, version;	/* retrieve version */	if (!_slang_preprocess_version (source, &version, &start, log))		return 0;	/* check the syntax and generate its binary representation */	if (!grammar_fast_check (id, (const byte *) source + start, &prod, &size, 65536))	{		char buf[1024];		unsigned int pos;		grammar_get_last_error ( (unsigned char*) buf, 1024, (int*) &pos);		slang_info_log_error (log, buf);		return 0;	}	/* syntax is okay - translate it to internal representation */	if (!compile_binary (prod, unit, type, log, builtins, NULL, NULL, NULL,			&builtins[BUILTIN_TARGET], NULL))	{		grammar_alloc_free (prod);		return 0;	}	grammar_alloc_free (prod);	return 1;}static const char *slang_shader_syn =#include "library/slang_shader_syn.h";static const byte slang_core_gc[] = {#include "library/slang_core_gc.h"};static const byte slang_common_builtin_gc[] = {#include "library/slang_common_builtin_gc.h"};static const byte slang_fragment_builtin_gc[] = {#include "library/slang_fragment_builtin_gc.h"};static const byte slang_vertex_builtin_gc[] = {#include "library/slang_vertex_builtin_gc.h"};static int compile (grammar *id, slang_translation_unit *builtin_units, int *compiled,	const char *source, slang_translation_unit *unit, slang_unit_type type, slang_info_log *log){	slang_translation_unit *builtins = NULL;	/* load slang grammar */	*id = grammar_load_from_text ((const byte *) (slang_shader_syn));	if (*id == 0)	{		byte buf[1024];		int pos;		grammar_get_last_error (buf, 1024, &pos);		slang_info_log_error (log, (const char *) (buf));		return 0;	}	/* set shader type - the syntax is slightly different for different shaders */	if (type == slang_unit_fragment_shader || type == slang_unit_fragment_builtin)		grammar_set_reg8 (*id, (const byte *) "shader_type", 1);	else		grammar_set_reg8 (*id, (const byte *) "shader_type", 2);	/* enable language extensions */	grammar_set_reg8 (*id, (const byte *) "parsing_builtin", 1);	/* if parsing user-specified shader, load built-in library */	if (type == slang_unit_fragment_shader || type == slang_unit_vertex_shader)	{		/* compile core functionality first */		if (!compile_binary (slang_core_gc, &builtin_units[BUILTIN_CORE],				slang_unit_fragment_builtin, log, NULL, unit->assembly, unit->global_pool,				unit->machine, NULL, unit->atom_pool))			return 0;		compiled[BUILTIN_CORE] = 1;		/* compile common functions and variables, link to core */		if (!compile_binary (slang_common_builtin_gc, &builtin_units[BUILTIN_COMMON],				slang_unit_fragment_builtin, log, NULL, unit->assembly, unit->global_pool,				unit->machine, &builtin_units[BUILTIN_CORE], unit->atom_pool))			return 0;		compiled[BUILTIN_COMMON] = 1;		/* compile target-specific functions and variables, link to common */		if (type == slang_unit_fragment_shader)		{			if (!compile_binary (slang_fragment_builtin_gc, &builtin_units[BUILTIN_TARGET],					slang_unit_fragment_builtin, log, NULL, unit->assembly, unit->global_pool,					unit->machine, &builtin_units[BUILTIN_COMMON], unit->atom_pool))				return 0;		}		else if (type == slang_unit_vertex_shader)		{			if (!compile_binary (slang_vertex_builtin_gc, &builtin_units[BUILTIN_TARGET],					slang_unit_vertex_builtin, log, NULL, unit->assembly, unit->global_pool,					unit->machine, &builtin_units[BUILTIN_COMMON], unit->atom_pool))				return 0;		}		compiled[BUILTIN_TARGET] = 1;		/* disable language extensions */		grammar_set_reg8 (*id, (const byte *) "parsing_builtin", 0);		builtins = builtin_units;	}	/* compile the actual shader - pass-in built-in library for external shader */	if (!compile_with_grammar (*id, source, unit, type, log, builtins))		return 0;	return 1;}int _slang_compile (const char *source, slang_translation_unit *unit, slang_unit_type type,	slang_info_log *log){	int success;	grammar id = 0;/*	slang_translation_unit builtin_units[BUILTIN_TOTAL];*/	slang_translation_unit *builtin_units;	int compiled[BUILTIN_TOTAL] = { 0 };	/* create the main unit first */	if (!slang_translation_unit_construct (unit))		return 0;	unit->type = type;	builtin_units = (slang_translation_unit *) slang_alloc_malloc (BUILTIN_TOTAL * sizeof (slang_translation_unit));	success = compile (&id, builtin_units, compiled, source, unit, type, log);	/* destroy built-in library */	/* XXX: free with the unit */	/*if (type == slang_unit_fragment_shader || type == slang_unit_vertex_shader)	{		int i;		for (i = 0; i < BUILTIN_TOTAL; i++)			if (compiled[i] != 0)				slang_translation_unit_destruct (&builtin_units[i]);	}*/	if (id != 0)		grammar_destroy (id);	if (!success)		return 0;	unit->exp_data.atoms = unit->atom_pool;	if (!_slang_build_export_data_table (&unit->exp_data, &unit->globals))		return 0;	unit->exp_code.atoms = unit->atom_pool;	if (!_slang_build_export_code_table (&unit->exp_code, &unit->functions, unit))		return 0;#if defined(USE_X86_ASM) || defined(SLANG_X86)	/* XXX: lookup the @main label */	if (!_slang_x86_codegen (unit->machine, unit->assembly, unit->exp_code.entries[0].address))		return 0;#endif	return 1;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -