X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=ir_reader.cpp;h=2c942914aefc5e933990c85b23cc0064493616ae;hb=7ee79fb6b78012abd0ae8e874a7c64550b1cb707;hp=e14f5c85796232a2ff7229321677812eb4e8eb2f;hpb=09cad1339d8e6eebe5b13d95a9e1d2a1da2fce29;p=mesa.git diff --git a/ir_reader.cpp b/ir_reader.cpp index e14f5c85796..2c942914aef 100644 --- a/ir_reader.cpp +++ b/ir_reader.cpp @@ -33,9 +33,10 @@ static const glsl_type *read_type(_mesa_glsl_parse_state *, s_expression *); static void scan_for_prototypes(_mesa_glsl_parse_state *, exec_list *, s_expression *); -static void read_prototypes(_mesa_glsl_parse_state *, exec_list *, s_list *); -static ir_function_signature *read_prototype(_mesa_glsl_parse_state *, - s_list *); +static ir_function *read_function(_mesa_glsl_parse_state *, s_list *, + bool skip_body); +static void read_function_sig(_mesa_glsl_parse_state *, ir_function *, + s_list *, bool skip_body); static void read_instructions(_mesa_glsl_parse_state *, exec_list *, s_expression *, ir_loop *); @@ -49,6 +50,7 @@ static ir_return *read_return(_mesa_glsl_parse_state *, s_list *); static ir_rvalue *read_rvalue(_mesa_glsl_parse_state *, s_expression *); static ir_assignment *read_assignment(_mesa_glsl_parse_state *, s_list *); static ir_expression *read_expression(_mesa_glsl_parse_state *, s_list *); +static ir_call *read_call(_mesa_glsl_parse_state *, s_list *); static ir_swizzle *read_swizzle(_mesa_glsl_parse_state *, s_list *); static ir_constant *read_constant(_mesa_glsl_parse_state *, s_list *); static ir_dereference *read_var_ref(_mesa_glsl_parse_state *, s_list *); @@ -64,9 +66,6 @@ _mesa_glsl_read_ir(_mesa_glsl_parse_state *state, exec_list *instructions, ir_read_error(state, NULL, "couldn't parse S-Expression."); return; } - printf("S-Expression:\n"); - expr->print(); - printf("\n-------------\n"); _mesa_glsl_initialize_types(state); @@ -86,19 +85,22 @@ static void ir_read_error(_mesa_glsl_parse_state *state, s_expression *expr, const char *fmt, ...) { - char buf[1024]; - int len; va_list ap; state->error = true; - len = snprintf(buf, sizeof(buf), "error: "); + printf("error: "); va_start(ap, fmt); - vsnprintf(buf + len, sizeof(buf) - len, fmt, ap); + vprintf(fmt, ap); va_end(ap); + printf("\n"); - printf("%s\n", buf); + if (expr != NULL) { + printf("...in this context:\n "); + expr->print(); + printf("\n\n"); + } } static const glsl_type * @@ -121,7 +123,7 @@ read_type(_mesa_glsl_parse_state *st, s_expression *expr) s_expression *base_expr = (s_expression*) type_sym->next; const glsl_type *base_type = read_type(st, base_expr); if (base_type == NULL) { - ir_read_error(st, expr, "when reading base type of array"); + ir_read_error(st, NULL, "when reading base type of array"); return NULL; } @@ -175,36 +177,34 @@ scan_for_prototypes(_mesa_glsl_parse_state *st, exec_list *instructions, if (tag == NULL || strcmp(tag->value(), "function") != 0) continue; // not a (function ...); ignore it. - read_prototypes(st, instructions, sub); - if (st->error) + ir_function *f = read_function(st, sub, true); + if (f == NULL) return; + instructions->push_tail(f); } } -static void -read_prototypes(_mesa_glsl_parse_state *st, exec_list *instructions, - s_list *list) +static ir_function * +read_function(_mesa_glsl_parse_state *st, s_list *list, bool skip_body) { if (list->length() < 3) { ir_read_error(st, list, "Expected (function (signature ...) ...)"); - return; + return NULL; } s_symbol *name = SX_AS_SYMBOL(list->subexpressions.head->next); if (name == NULL) { ir_read_error(st, list, "Expected (function ...)"); - return; + return NULL; } - ir_function *f = new ir_function(name->value()); - bool added = st->symbols->add_function(name->value(), f); - if (!added) { - ir_read_error(st, list, "Function %s already exists.", name->value()); - return; + ir_function *f = st->symbols->get_function(name->value()); + if (f == NULL) { + f = new ir_function(name->value()); + bool added = st->symbols->add_function(name->value(), f); + assert(added); } - instructions->push_tail(f); - exec_list_iterator it = list->subexpressions.iterator(); it.next(); // skip "function" tag it.next(); // skip function name @@ -212,64 +212,92 @@ read_prototypes(_mesa_glsl_parse_state *st, exec_list *instructions, s_list *siglist = SX_AS_LIST(it.get()); if (siglist == NULL) { ir_read_error(st, list, "Expected (function (signature ...) ...)"); - return; + return NULL; } s_symbol *tag = SX_AS_SYMBOL(siglist->subexpressions.get_head()); if (tag == NULL || strcmp(tag->value(), "signature") != 0) { ir_read_error(st, siglist, "Expected (signature ...)"); - return; + return NULL; } - ir_function_signature *sig = read_prototype(st, siglist); - if (sig == NULL) - return; - - f->add_signature(sig); + read_function_sig(st, f, siglist, skip_body); } + return f; } -static ir_function_signature * -read_prototype(_mesa_glsl_parse_state *st, s_list *list) +static void +read_function_sig(_mesa_glsl_parse_state *st, ir_function *f, s_list *list, + bool skip_body) { if (list->length() != 4) { ir_read_error(st, list, "Expected (signature (parameters ...) " "( ...))"); - return NULL; + return; } s_expression *type_expr = (s_expression*) list->subexpressions.head->next; const glsl_type *return_type = read_type(st, type_expr); if (return_type == NULL) - return NULL; + return; s_list *paramlist = SX_AS_LIST(type_expr->next); - if (paramlist == NULL) { - ir_read_error(st, list, "Expected (signature %s (parameters ...) ...)", - return_type->name); - return NULL; + s_list *body_list = SX_AS_LIST(paramlist->next); + if (paramlist == NULL || body_list == NULL) { + ir_read_error(st, list, "Expected (signature (parameters ...) " + "( ...))"); + return; } s_symbol *paramtag = SX_AS_SYMBOL(paramlist->subexpressions.get_head()); if (paramtag == NULL || strcmp(paramtag->value(), "parameters") != 0) { ir_read_error(st, paramlist, "Expected (parameters ...)"); - return NULL; + return; } - ir_function_signature *sig = new ir_function_signature(return_type); + // Read the parameters list into a temporary place. + exec_list hir_parameters; + st->symbols->push_scope(); exec_list_iterator it = paramlist->subexpressions.iterator(); for (it.next() /* skip "parameters" */; it.has_next(); it.next()) { s_list *decl = SX_AS_LIST(it.get()); ir_variable *var = read_declaration(st, decl); - if (var == NULL) { - delete sig; - return NULL; + if (var == NULL) + return; + + hir_parameters.push_tail(var); + } + + ir_function_signature *sig = f->exact_matching_signature(&hir_parameters); + if (sig != NULL) { + const char *badvar = sig->qualifiers_match(&hir_parameters); + if (badvar != NULL) { + ir_read_error(st, list, "function `%s' parameter `%s' qualifiers " + "don't match prototype", f->name, badvar); + return; } - sig->parameters.push_tail(var); + if (sig->return_type != return_type) { + ir_read_error(st, list, "function `%s' return type doesn't " + "match prototype", f->name); + return; + } + } else { + sig = new ir_function_signature(return_type); + f->add_signature(sig); + } + + sig->replace_parameters(&hir_parameters); + + if (!skip_body) { + if (sig->is_defined) { + ir_read_error(st, list, "function %s redefined", f->name); + return; + } + read_instructions(st, &sig->body, body_list, NULL); } - return sig; + st->symbols->pop_scope(); } static void @@ -326,10 +354,12 @@ read_instruction(_mesa_glsl_parse_state *st, s_expression *expr, inst = read_loop(st, list); } else if (strcmp(tag->value(), "return") == 0) { inst = read_return(st, list); + } else if (strcmp(tag->value(), "function") == 0) { + inst = read_function(st, list, false); } else { inst = read_rvalue(st, list); if (inst == NULL) - ir_read_error(st, list, "when reading instruction"); + ir_read_error(st, NULL, "when reading instruction"); } return inst; } @@ -418,7 +448,7 @@ read_if(_mesa_glsl_parse_state *st, s_list *list, ir_loop *loop_ctx) s_expression *cond_expr = (s_expression*) list->subexpressions.head->next; ir_rvalue *condition = read_rvalue(st, cond_expr); if (condition == NULL) { - ir_read_error(st, list, "when reading condition of (if ...)"); + ir_read_error(st, NULL, "when reading condition of (if ...)"); return NULL; } @@ -476,7 +506,7 @@ read_return(_mesa_glsl_parse_state *st, s_list *list) ir_rvalue *retval = read_rvalue(st, expr); if (retval == NULL) { - ir_read_error(st, list, "when reading return value"); + ir_read_error(st, NULL, "when reading return value"); return NULL; } @@ -504,7 +534,8 @@ read_rvalue(_mesa_glsl_parse_state *st, s_expression *expr) rvalue = read_assignment(st, list); } else if (strcmp(tag->value(), "expression") == 0) { rvalue = read_expression(st, list); - // FINISHME: ir_call + } else if (strcmp(tag->value(), "call") == 0) { + rvalue = read_call(st, list); } else if (strcmp(tag->value(), "constant") == 0) { rvalue = read_constant(st, list); } else if (strcmp(tag->value(), "var_ref") == 0) { @@ -535,25 +566,68 @@ read_assignment(_mesa_glsl_parse_state *st, s_list *list) // FINISHME: Deal with "true" condition ir_rvalue *condition = read_rvalue(st, cond_expr); if (condition == NULL) { - ir_read_error(st, list, "when reading condition of assignment"); + ir_read_error(st, NULL, "when reading condition of assignment"); return NULL; } ir_rvalue *lhs = read_rvalue(st, lhs_expr); if (lhs == NULL) { - ir_read_error(st, list, "when reading left-hand side of assignment"); + ir_read_error(st, NULL, "when reading left-hand side of assignment"); return NULL; } ir_rvalue *rhs = read_rvalue(st, rhs_expr); if (rhs == NULL) { - ir_read_error(st, list, "when reading right-hand side of assignment"); + ir_read_error(st, NULL, "when reading right-hand side of assignment"); return NULL; } return new ir_assignment(lhs, rhs, condition); } +static ir_call * +read_call(_mesa_glsl_parse_state *st, s_list *list) +{ + if (list->length() != 3) { + ir_read_error(st, list, "expected (call ( ...))"); + return NULL; + } + + s_symbol *name = SX_AS_SYMBOL(list->subexpressions.head->next); + s_list *params = SX_AS_LIST(name->next); + if (name == NULL || params == NULL) { + ir_read_error(st, list, "expected (call ( ...))"); + return NULL; + } + + exec_list parameters; + + foreach_iter(exec_list_iterator, it, params->subexpressions) { + s_expression *expr = (s_expression*) it.get(); + ir_rvalue *param = read_rvalue(st, expr); + if (param == NULL) { + ir_read_error(st, list, "when reading parameter to function call"); + return NULL; + } + parameters.push_tail(param); + } + + ir_function *f = st->symbols->get_function(name->value()); + if (f == NULL) { + ir_read_error(st, list, "found call to undefined function %s", + name->value()); + return NULL; + } + + const ir_function_signature *callee = f->matching_signature(¶meters); + if (callee == NULL) { + ir_read_error(st, list, "couldn't find matching signature for function " + "%s", name->value()); + return NULL; + } + + return new ir_call(callee, ¶meters); +} static ir_expression * read_expression(_mesa_glsl_parse_state *st, s_list *list) @@ -586,13 +660,13 @@ read_expression(_mesa_glsl_parse_state *st, s_list *list) /* Now that we know the operator, check for the right number of operands */ if (ir_expression::get_num_operands(op) == 2) { if (list_length != 5) { - ir_read_error(st, list, "expected (expression %s )", - op_sym->value()); + ir_read_error(st, list, "expected (expression %s " + " )", op_sym->value()); return NULL; } } else { if (list_length != 4) { - ir_read_error(st, list, "expected (expression %s )", + ir_read_error(st, list, "expected (expression %s )", op_sym->value()); return NULL; } @@ -601,7 +675,7 @@ read_expression(_mesa_glsl_parse_state *st, s_list *list) s_expression *exp1 = (s_expression*) (op_sym->next); ir_rvalue *arg1 = read_rvalue(st, exp1); if (arg1 == NULL) { - ir_read_error(st, list, "when reading first operand of %s", + ir_read_error(st, NULL, "when reading first operand of %s", op_sym->value()); return NULL; } @@ -611,7 +685,7 @@ read_expression(_mesa_glsl_parse_state *st, s_list *list) s_expression *exp2 = (s_expression*) (exp1->next); arg2 = read_rvalue(st, exp2); if (arg2 == NULL) { - ir_read_error(st, list, "when reading second operand of %s", + ir_read_error(st, NULL, "when reading second operand of %s", op_sym->value()); return NULL; } @@ -634,8 +708,7 @@ read_swizzle(_mesa_glsl_parse_state *st, s_list *list) return NULL; } - unsigned num_components = strlen(swiz->value()); - if (num_components > 4) { + if (strlen(swiz->value()) > 4) { ir_read_error(st, list, "expected a valid swizzle; found %s", swiz->value()); return NULL; @@ -652,7 +725,12 @@ read_swizzle(_mesa_glsl_parse_state *st, s_list *list) if (rvalue == NULL) return NULL; - return ir_swizzle::create(rvalue, swiz->value(), num_components); + ir_swizzle *ir = ir_swizzle::create(rvalue, swiz->value(), + rvalue->type->vector_elements); + if (ir == NULL) + ir_read_error(st, list, "invalid swizzle"); + + return ir; } static ir_constant *