mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-25 13:11:00 +00:00
[qfcc] Implement generic type computation
I had already implemented the code generation side (though using type ids instead of encodings is a nice change), but I hadn't implemented the actual evaluation or even called it. Now return types can be computed from generic parameters (eg, ivecN from vecN).
This commit is contained in:
parent
4db018ee47
commit
6e004e9baa
9 changed files with 163 additions and 37 deletions
|
@ -69,7 +69,8 @@ typedef struct expr_s expr_t;
|
||||||
typedef struct gentype_s gentype_t;
|
typedef struct gentype_s gentype_t;
|
||||||
typeeval_t *build_type_function (const expr_t *te, int num_types,
|
typeeval_t *build_type_function (const expr_t *te, int num_types,
|
||||||
gentype_t *types);
|
gentype_t *types);
|
||||||
|
const type_t *evaluate_type (const typeeval_t *typeeval, int num_types,
|
||||||
|
const type_t **types, const expr_t *expr);
|
||||||
///@}
|
///@}
|
||||||
|
|
||||||
#endif//__evaluate_type_h
|
#endif//__evaluate_type_h
|
||||||
|
|
|
@ -1052,7 +1052,7 @@ symbol_t *type_parameter (symbol_t *sym, const expr_t *type);
|
||||||
const type_t *resolve_type (const expr_t *te, rua_ctx_t *ctx);
|
const type_t *resolve_type (const expr_t *te, rua_ctx_t *ctx);
|
||||||
const expr_t *process_type (const expr_t *te, rua_ctx_t *ctx);
|
const expr_t *process_type (const expr_t *te, rua_ctx_t *ctx);
|
||||||
const type_t **expand_type (const expr_t *te, rua_ctx_t *ctx);
|
const type_t **expand_type (const expr_t *te, rua_ctx_t *ctx);
|
||||||
const expr_t *evaluate_type (const expr_t *te, rua_ctx_t *ctx);
|
const expr_t *eval_type (const expr_t *te, rua_ctx_t *ctx);
|
||||||
|
|
||||||
expr_t *append_expr (expr_t *block, const expr_t *e);
|
expr_t *append_expr (expr_t *block, const expr_t *e);
|
||||||
expr_t *prepend_expr (expr_t *block, const expr_t *e);
|
expr_t *prepend_expr (expr_t *block, const expr_t *e);
|
||||||
|
|
|
@ -276,7 +276,9 @@ void clear_typedefs (void);
|
||||||
typedef struct def_s def_t;
|
typedef struct def_s def_t;
|
||||||
|
|
||||||
typedef struct defset_s DARRAY_TYPE (def_t *) defset_t;
|
typedef struct defset_s DARRAY_TYPE (def_t *) defset_t;
|
||||||
|
typedef struct typeset_s DARRAY_TYPE (const type_t *) typeset_t;
|
||||||
extern defset_t type_encodings; ///< qfo encodoing
|
extern defset_t type_encodings; ///< qfo encodoing
|
||||||
|
extern typeset_t type_registry;
|
||||||
|
|
||||||
extern const type_t *ev_types[];
|
extern const type_t *ev_types[];
|
||||||
extern int type_cast_map[];
|
extern int type_cast_map[];
|
||||||
|
|
|
@ -62,7 +62,7 @@ evaluate_debug_handler (prdebug_t event, void *param, void *data)
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case prd_trace:
|
case prd_trace:
|
||||||
st = pr->pr_statements + pr->pr_xstatement;
|
st = pr->pr_statements + pr->pr_xstatement;
|
||||||
PR_PrintStatement (pr, st, 0);
|
PR_PrintStatement (pr, st, 3);
|
||||||
break;
|
break;
|
||||||
case prd_breakpoint:
|
case prd_breakpoint:
|
||||||
case prd_subenter:
|
case prd_subenter:
|
||||||
|
|
|
@ -50,6 +50,9 @@
|
||||||
#include "tools/qfcc/include/type.h"
|
#include "tools/qfcc/include/type.h"
|
||||||
#include "tools/qfcc/include/value.h"
|
#include "tools/qfcc/include/value.h"
|
||||||
|
|
||||||
|
#undef P_PACKED
|
||||||
|
#define P_PACKED(p,t,n) (*(t *) &(p)->pr_globals[1+n])
|
||||||
|
|
||||||
typedef struct typectx_s {
|
typedef struct typectx_s {
|
||||||
const type_t **types;
|
const type_t **types;
|
||||||
int num_types;
|
int num_types;
|
||||||
|
@ -57,74 +60,158 @@ typedef struct typectx_s {
|
||||||
sys_jmpbuf jmpbuf;
|
sys_jmpbuf jmpbuf;
|
||||||
} typectx_t;
|
} typectx_t;
|
||||||
|
|
||||||
|
static const type_t *
|
||||||
|
fetch_type (unsigned id, typectx_t *ctx)
|
||||||
|
{
|
||||||
|
const type_t *type = nullptr;
|
||||||
|
if (id < type_registry.size) {
|
||||||
|
type = type_registry.a[id];
|
||||||
|
}
|
||||||
|
if (!type) {
|
||||||
|
internal_error (ctx->expr, "invalid type id");
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
tf_function_func (progs_t *pr, void *data)
|
tf_function_func (progs_t *pr, void *data)
|
||||||
{
|
{
|
||||||
|
auto ctx = *(typectx_t **) data;
|
||||||
|
internal_error (ctx->expr, "not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
tf_field_func (progs_t *pr, void *data)
|
tf_field_func (progs_t *pr, void *data)
|
||||||
{
|
{
|
||||||
|
auto ctx = *(typectx_t **) data;
|
||||||
|
unsigned id = P_UINT (pr, 0);
|
||||||
|
auto type = fetch_type (id, ctx);
|
||||||
|
type = pointer_type (type);
|
||||||
|
type = find_type (type);
|
||||||
|
R_UINT (pr) = type->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
tf_pointer_func (progs_t *pr, void *data)
|
tf_pointer_func (progs_t *pr, void *data)
|
||||||
{
|
{
|
||||||
|
auto ctx = *(typectx_t **) data;
|
||||||
|
unsigned id = P_UINT (pr, 0);
|
||||||
|
auto type = fetch_type (id, ctx);
|
||||||
|
type = pointer_type (type);
|
||||||
|
type = find_type (type);
|
||||||
|
R_UINT (pr) = type->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
tf_array_func (progs_t *pr, void *data)
|
tf_array_func (progs_t *pr, void *data)
|
||||||
{
|
{
|
||||||
|
auto ctx = *(typectx_t **) data;
|
||||||
|
unsigned id = P_UINT (pr, 0);
|
||||||
|
unsigned count = P_UINT (pr, 1);
|
||||||
|
auto type = fetch_type (id, ctx);
|
||||||
|
type = array_type (type, count);
|
||||||
|
type = find_type (type);
|
||||||
|
R_UINT (pr) = type->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
tf_base_func (progs_t *pr, void *data)
|
tf_base_func (progs_t *pr, void *data)
|
||||||
{
|
{
|
||||||
|
auto ctx = *(typectx_t **) data;
|
||||||
|
unsigned id = P_UINT (pr, 0);
|
||||||
|
auto type = fetch_type (id, ctx);
|
||||||
|
type = base_type (type);
|
||||||
|
R_UINT (pr) = type->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
tf_width_func (progs_t *pr, void *data)
|
tf_width_func (progs_t *pr, void *data)
|
||||||
{
|
{
|
||||||
|
auto ctx = *(typectx_t **) data;
|
||||||
|
unsigned id = P_UINT (pr, 0);
|
||||||
|
auto type = fetch_type (id, ctx);
|
||||||
|
R_UINT (pr) = type_width (type);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
tf_vector_func (progs_t *pr, void *data)
|
tf_vector_func (progs_t *pr, void *data)
|
||||||
{
|
{
|
||||||
|
auto ctx = *(typectx_t **) data;
|
||||||
|
unsigned id = P_UINT (pr, 0);
|
||||||
|
unsigned width = P_UINT (pr, 1);
|
||||||
|
auto base = fetch_type (id, ctx);
|
||||||
|
auto type = vector_type (base, width);
|
||||||
|
R_UINT (pr) = type->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
tf_rows_func (progs_t *pr, void *data)
|
tf_rows_func (progs_t *pr, void *data)
|
||||||
{
|
{
|
||||||
|
auto ctx = *(typectx_t **) data;
|
||||||
|
unsigned id = P_UINT (pr, 0);
|
||||||
|
auto type = fetch_type (id, ctx);
|
||||||
|
R_UINT (pr) = type_rows (type);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
tf_cols_func (progs_t *pr, void *data)
|
tf_cols_func (progs_t *pr, void *data)
|
||||||
{
|
{
|
||||||
|
auto ctx = *(typectx_t **) data;
|
||||||
|
unsigned id = P_UINT (pr, 0);
|
||||||
|
auto type = fetch_type (id, ctx);
|
||||||
|
R_UINT (pr) = type_cols (type);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
tf_matrix_func (progs_t *pr, void *data)
|
tf_matrix_func (progs_t *pr, void *data)
|
||||||
{
|
{
|
||||||
|
auto ctx = *(typectx_t **) data;
|
||||||
|
unsigned id = P_UINT (pr, 0);
|
||||||
|
unsigned cols = P_UINT (pr, 1);
|
||||||
|
unsigned rows = P_UINT (pr, 2);
|
||||||
|
auto base = fetch_type (id, ctx);
|
||||||
|
auto type = matrix_type (base, cols, rows);
|
||||||
|
R_UINT (pr) = type->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
tf_int_func (progs_t *pr, void *data)
|
tf_int_func (progs_t *pr, void *data)
|
||||||
{
|
{
|
||||||
|
auto ctx = *(typectx_t **) data;
|
||||||
|
unsigned id = P_UINT (pr, 0);
|
||||||
|
auto type = fetch_type (id, ctx);
|
||||||
|
type = int_type (type);
|
||||||
|
R_UINT (pr) = type->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
tf_uint_func (progs_t *pr, void *data)
|
tf_uint_func (progs_t *pr, void *data)
|
||||||
{
|
{
|
||||||
|
auto ctx = *(typectx_t **) data;
|
||||||
|
unsigned id = P_UINT (pr, 0);
|
||||||
|
auto type = fetch_type (id, ctx);
|
||||||
|
type = uint_type (type);
|
||||||
|
R_UINT (pr) = type->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
tf_bool_func (progs_t *pr, void *data)
|
tf_bool_func (progs_t *pr, void *data)
|
||||||
{
|
{
|
||||||
|
auto ctx = *(typectx_t **) data;
|
||||||
|
unsigned id = P_UINT (pr, 0);
|
||||||
|
auto type = fetch_type (id, ctx);
|
||||||
|
type = bool_type (type);
|
||||||
|
R_UINT (pr) = type->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
tf_float_func (progs_t *pr, void *data)
|
tf_float_func (progs_t *pr, void *data)
|
||||||
{
|
{
|
||||||
|
auto ctx = *(typectx_t **) data;
|
||||||
|
unsigned id = P_UINT (pr, 0);
|
||||||
|
auto type = fetch_type (id, ctx);
|
||||||
|
type = float_type (type);
|
||||||
|
R_UINT (pr) = type->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -140,8 +227,7 @@ tf_gentype_func (progs_t *pr, void *data)
|
||||||
error (ctx->expr, "refernce to unresolved type");
|
error (ctx->expr, "refernce to unresolved type");
|
||||||
Sys_longjmp (ctx->jmpbuf);
|
Sys_longjmp (ctx->jmpbuf);
|
||||||
}
|
}
|
||||||
auto type_def = type_encodings.a[type->id];
|
R_UINT (pr) = type->id;
|
||||||
R_POINTER (pr) = type_def->offset;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define BASE(b, base) (((base) & 3) << OP_##b##_SHIFT)
|
#define BASE(b, base) (((base) & 3) << OP_##b##_SHIFT)
|
||||||
|
@ -213,3 +299,26 @@ setup_type_progs (void)
|
||||||
PR_Init (&type_pr);
|
PR_Init (&type_pr);
|
||||||
PR_Debug_Init (&type_pr);
|
PR_Debug_Init (&type_pr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const type_t *
|
||||||
|
evaluate_type (const typeeval_t *typeeval, int num_types, const type_t **types,
|
||||||
|
const expr_t *expr)
|
||||||
|
{
|
||||||
|
typectx_t ctx = {
|
||||||
|
types = types,
|
||||||
|
num_types = num_types,
|
||||||
|
expr = expr,
|
||||||
|
};
|
||||||
|
int err;
|
||||||
|
if ((err = Sys_setjmp (ctx.jmpbuf))) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
type_genfunc = &ctx;
|
||||||
|
type_pr.pr_statements = typeeval->code;
|
||||||
|
type_pr.pr_globals = typeeval->data;
|
||||||
|
type_pr.globals_size = typeeval->data_size;
|
||||||
|
type_pr.pr_trace = options.verbosity > 1;
|
||||||
|
PR_ExecuteProgram (&type_pr, tf_eval);
|
||||||
|
unsigned id = R_UINT (&type_pr);
|
||||||
|
return fetch_type (id, &ctx);
|
||||||
|
}
|
||||||
|
|
|
@ -517,10 +517,10 @@ static def_t *
|
||||||
compute_type_array (int arg_count, const expr_t **args, comp_ctx_t *ctx)
|
compute_type_array (int arg_count, const expr_t **args, comp_ctx_t *ctx)
|
||||||
{
|
{
|
||||||
auto type = compute_type (args[0], ctx);
|
auto type = compute_type (args[0], ctx);
|
||||||
auto size = compute_val (args[1], ctx);
|
auto count = compute_val (args[1], ctx);
|
||||||
auto res = compute_tmp (ctx);
|
auto res = compute_tmp (ctx);
|
||||||
C (OP_STORE_A_1, ctx->args[0], nullptr, type);
|
C (OP_STORE_A_1, ctx->args[0], nullptr, type);
|
||||||
C (OP_STORE_A_1, ctx->args[1], nullptr, size);
|
C (OP_STORE_A_1, ctx->args[1], nullptr, count);
|
||||||
C (OP_CALL_B, ctx->funcs[tf_array], nullptr, res);
|
C (OP_CALL_B, ctx->funcs[tf_array], nullptr, res);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -810,7 +810,7 @@ expand_type (const expr_t *te, rua_ctx_t *ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
const expr_t *
|
const expr_t *
|
||||||
evaluate_type (const expr_t *te, rua_ctx_t *ctx)
|
eval_type (const expr_t *te, rua_ctx_t *ctx)
|
||||||
{
|
{
|
||||||
if (te->type != ex_type) {
|
if (te->type != ex_type) {
|
||||||
internal_error (te, "not a type expression");
|
internal_error (te, "not a type expression");
|
||||||
|
@ -927,8 +927,7 @@ compute_type (const expr_t *arg, comp_ctx_t *ctx)
|
||||||
internal_error (arg, "no type in reference");
|
internal_error (arg, "no type in reference");
|
||||||
}
|
}
|
||||||
auto val = compute_tmp (ctx);
|
auto val = compute_tmp (ctx);
|
||||||
auto type_def = type_encodings.a[arg->typ.type->id];
|
D_INT (val) = arg->typ.type->id;
|
||||||
D_INT (val) = type_def->offset;
|
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
int op = arg->typ.op;
|
int op = arg->typ.op;
|
||||||
|
|
|
@ -564,6 +564,7 @@ typedef struct {
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int num_params;
|
int num_params;
|
||||||
callparm_t *params;
|
callparm_t *params;
|
||||||
|
const type_t **types;
|
||||||
} calltype_t;
|
} calltype_t;
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
@ -687,36 +688,43 @@ find_generic_function (genfunc_t **genfuncs, const expr_t *fexpr,
|
||||||
return genfuncs[best_ind];
|
return genfuncs[best_ind];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const type_t *
|
||||||
|
compute_param_type (const genparam_t *param, int param_ind,
|
||||||
|
const genfunc_t *genfunc, calltype_t *calltype,
|
||||||
|
const expr_t *fexpr)
|
||||||
|
{
|
||||||
|
auto call_types = calltype->types;
|
||||||
|
auto call_params = calltype->params;
|
||||||
|
if (param->fixed_type) {
|
||||||
|
return param->fixed_type;
|
||||||
|
}
|
||||||
|
if (param->compute) {
|
||||||
|
return evaluate_type (param->compute, genfunc->num_types,
|
||||||
|
calltype->types, fexpr);
|
||||||
|
}
|
||||||
|
int ind = param->gentype;
|
||||||
|
if (!call_types[ind] && param_ind >= 0) {
|
||||||
|
call_types[ind] = select_type (&genfunc->types[ind],
|
||||||
|
call_params[param_ind]);
|
||||||
|
}
|
||||||
|
return call_types[ind];
|
||||||
|
}
|
||||||
|
|
||||||
static symbol_t *
|
static symbol_t *
|
||||||
create_generic_sym (genfunc_t *g, const expr_t *fexpr, calltype_t *calltype,
|
create_generic_sym (genfunc_t *g, const expr_t *fexpr, calltype_t *calltype)
|
||||||
const type_t **types)
|
|
||||||
{
|
{
|
||||||
int num_params = calltype->num_params;
|
int num_params = calltype->num_params;
|
||||||
auto call_params = calltype->params;
|
|
||||||
const type_t *param_types[num_params];
|
const type_t *param_types[num_params];
|
||||||
param_qual_t param_quals[num_params];
|
param_qual_t param_quals[num_params];
|
||||||
const type_t *return_type;
|
const type_t *return_type;
|
||||||
for (int i = 0; i < num_params; i++) {
|
for (int i = 0; i < num_params; i++) {
|
||||||
auto p = &g->params[i];
|
auto p = &g->params[i];
|
||||||
if (!p->fixed_type) {
|
param_types[i] = compute_param_type (p, i, g, calltype, fexpr);
|
||||||
int ind = p->gentype;
|
|
||||||
if (!types[ind]) {
|
|
||||||
types[ind] = select_type (&g->types[ind], call_params[i]);
|
|
||||||
}
|
|
||||||
param_types[i] = types[ind];
|
|
||||||
} else {
|
|
||||||
param_types[i] = p->fixed_type;
|
|
||||||
}
|
|
||||||
param_quals[i] = p->qual;
|
param_quals[i] = p->qual;
|
||||||
}
|
}
|
||||||
if (!g->ret_type->fixed_type) {
|
return_type = compute_param_type (g->ret_type, -1, g, calltype, fexpr);
|
||||||
int ind = g->ret_type->gentype;
|
if (!return_type) {
|
||||||
if (!types[ind]) {
|
internal_error (0, "return type not determined");
|
||||||
internal_error (0, "return type not determined");
|
|
||||||
}
|
|
||||||
return_type = types[ind];
|
|
||||||
} else {
|
|
||||||
return_type = g->ret_type->fixed_type;
|
|
||||||
}
|
}
|
||||||
param_t *params = nullptr;
|
param_t *params = nullptr;
|
||||||
for (int i = 0; i < num_params; i++) {
|
for (int i = 0; i < num_params; i++) {
|
||||||
|
@ -796,13 +804,15 @@ get_function (const char *name, specifier_t spec, rua_ctx_t *ctx)
|
||||||
auto gen = find_generic_function (genfuncs, &fexpr, &calltype, false);
|
auto gen = find_generic_function (genfuncs, &fexpr, &calltype, false);
|
||||||
if (gen) {
|
if (gen) {
|
||||||
const type_t *ref_types[gen->num_types] = {};
|
const type_t *ref_types[gen->num_types] = {};
|
||||||
auto sym = create_generic_sym (gen, &fexpr, &calltype, ref_types);
|
calltype.types = ref_types;
|
||||||
|
auto sym = create_generic_sym (gen, &fexpr, &calltype);
|
||||||
if (sym == fexpr.symbol
|
if (sym == fexpr.symbol
|
||||||
|| sym->metafunc == fexpr.symbol->metafunc) {
|
|| sym->metafunc == fexpr.symbol->metafunc) {
|
||||||
internal_error (0, "genfunc oops");
|
internal_error (0, "genfunc oops");
|
||||||
}
|
}
|
||||||
func = sym->metafunc;
|
func = sym->metafunc;
|
||||||
overload = true;
|
overload = true;
|
||||||
|
calltype.types = nullptr;
|
||||||
} else {
|
} else {
|
||||||
func = nullptr;
|
func = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -1004,7 +1014,8 @@ find_function (const expr_t *fexpr, const expr_t *params)
|
||||||
return new_error_expr ();
|
return new_error_expr ();
|
||||||
}
|
}
|
||||||
const type_t *ref_types[gen->num_types] = {};
|
const type_t *ref_types[gen->num_types] = {};
|
||||||
auto sym = create_generic_sym (gen, fexpr, &calltype, ref_types);
|
calltype.types = ref_types;
|
||||||
|
auto sym = create_generic_sym (gen, fexpr, &calltype);
|
||||||
if (gen->can_inline) {
|
if (gen->can_inline) {
|
||||||
// the call will be inlined, so a new scope is needed every
|
// the call will be inlined, so a new scope is needed every
|
||||||
// time
|
// time
|
||||||
|
|
|
@ -481,10 +481,10 @@ SRC_LINE
|
||||||
"genBType isnan(genDType x);" "\n"
|
"genBType isnan(genDType x);" "\n"
|
||||||
"genBType isinf(genFType x);" "\n"
|
"genBType isinf(genFType x);" "\n"
|
||||||
"genBType isinf(genDType x);" "\n"
|
"genBType isinf(genDType x);" "\n"
|
||||||
"genIType floatBitsToInt(highp genFType value);" "\n"
|
"@vector(int,@width(genFType)) floatBitsToInt(highp genFType value) = " SPV(124) ";" "\n"
|
||||||
"genUType floatBitsToUint(highp genFType value);" "\n"
|
"@vector(uint,@width(genFType)) floatBitsToUint(highp genFType value) = " SPV(124) ";" "\n"
|
||||||
"genFType intBitsToFloat(highp genIType value);" "\n"
|
"@vector(float,@width(genIType)) intBitsToFloat(highp genIType value) = " SPV(124) ";" "\n"
|
||||||
"genFType uintBitsToFloat(highp genUType value);" "\n"
|
"@vector(float,@width(genUType)) uintBitsToFloat(highp genUType value) = " SPV(124) ";" "\n"
|
||||||
"genFType fma(genFType a, genFType b, genFType c);" "\n"
|
"genFType fma(genFType a, genFType b, genFType c);" "\n"
|
||||||
"genDType fma(genDType a, genDType b, genDType c);" "\n"
|
"genDType fma(genDType a, genDType b, genDType c);" "\n"
|
||||||
"genFType frexp(highp genFType x, out highp genIType exp);" "\n"
|
"genFType frexp(highp genFType x, out highp genIType exp);" "\n"
|
||||||
|
|
|
@ -265,6 +265,7 @@ int type_cast_map[ev_type_count] = {
|
||||||
//[ev_bool64] = 7,
|
//[ev_bool64] = 7,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typeset_t type_registry = DARRAY_STATIC_INIT (64);
|
||||||
defset_t type_encodings = DARRAY_STATIC_INIT (64);
|
defset_t type_encodings = DARRAY_STATIC_INIT (64);
|
||||||
|
|
||||||
ALLOC_STATE (type_t, types);
|
ALLOC_STATE (type_t, types);
|
||||||
|
@ -309,7 +310,8 @@ chain_type (type_t *type)
|
||||||
if (type->id) {
|
if (type->id) {
|
||||||
internal_error (0, "type already has id");
|
internal_error (0, "type already has id");
|
||||||
}
|
}
|
||||||
type->id = type_encodings.size;
|
type->id = type_registry.size;
|
||||||
|
DARRAY_APPEND (&type_registry, type);
|
||||||
DARRAY_APPEND (&type_encodings, nullptr);
|
DARRAY_APPEND (&type_encodings, nullptr);
|
||||||
type->next = pr.types;
|
type->next = pr.types;
|
||||||
pr.types = type;
|
pr.types = type;
|
||||||
|
@ -2027,7 +2029,9 @@ type_aligned_size (const type_t *type)
|
||||||
static void
|
static void
|
||||||
chain_basic_types (void)
|
chain_basic_types (void)
|
||||||
{
|
{
|
||||||
|
type_registry.size = 0;
|
||||||
type_encodings.size = 0;
|
type_encodings.size = 0;
|
||||||
|
DARRAY_APPEND (&type_registry, nullptr);
|
||||||
DARRAY_APPEND (&type_encodings, nullptr);
|
DARRAY_APPEND (&type_encodings, nullptr);
|
||||||
|
|
||||||
type_entity.symtab = pr.entity_fields;
|
type_entity.symtab = pr.entity_fields;
|
||||||
|
|
Loading…
Reference in a new issue