Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /* -*- c++ -*- */
  2. /*
  3.  * Copyright © 2010 Intel Corporation
  4.  *
  5.  * Permission is hereby granted, free of charge, to any person obtaining a
  6.  * copy of this software and associated documentation files (the "Software"),
  7.  * to deal in the Software without restriction, including without limitation
  8.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  9.  * and/or sell copies of the Software, and to permit persons to whom the
  10.  * Software is furnished to do so, subject to the following conditions:
  11.  *
  12.  * The above copyright notice and this permission notice (including the next
  13.  * paragraph) shall be included in all copies or substantial portions of the
  14.  * Software.
  15.  *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  19.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  21.  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  22.  * DEALINGS IN THE SOFTWARE.
  23.  */
  24.  
  25. #include "glsl_symbol_table.h"
  26.  
  27. class symbol_table_entry {
  28. public:
  29.    DECLARE_RALLOC_CXX_OPERATORS(symbol_table_entry);
  30.  
  31.    bool add_interface(const glsl_type *i, enum ir_variable_mode mode)
  32.    {
  33.       const glsl_type **dest;
  34.  
  35.       switch (mode) {
  36.       case ir_var_uniform:
  37.          dest = &ibu;
  38.          break;
  39.       case ir_var_shader_in:
  40.          dest = &ibi;
  41.          break;
  42.       case ir_var_shader_out:
  43.          dest = &ibo;
  44.          break;
  45.       default:
  46.          assert(!"Unsupported interface variable mode!");
  47.          return false;
  48.       }
  49.  
  50.       if (*dest != NULL) {
  51.          return false;
  52.       } else {
  53.          *dest = i;
  54.          return true;
  55.       }
  56.    }
  57.  
  58.    const glsl_type *get_interface(enum ir_variable_mode mode)
  59.    {
  60.       switch (mode) {
  61.       case ir_var_uniform:
  62.          return ibu;
  63.       case ir_var_shader_in:
  64.          return ibi;
  65.       case ir_var_shader_out:
  66.          return ibo;
  67.       default:
  68.          assert(!"Unsupported interface variable mode!");
  69.          return NULL;
  70.       }
  71.    }
  72.  
  73.    symbol_table_entry(ir_variable *v)               :
  74.       v(v), f(0), t(0), ibu(0), ibi(0), ibo(0), a(0) {}
  75.    symbol_table_entry(ir_function *f)               :
  76.       v(0), f(f), t(0), ibu(0), ibi(0), ibo(0), a(0) {}
  77.    symbol_table_entry(const glsl_type *t)           :
  78.       v(0), f(0), t(t), ibu(0), ibi(0), ibo(0), a(0) {}
  79.    symbol_table_entry(const glsl_type *t, enum ir_variable_mode mode) :
  80.       v(0), f(0), t(0), ibu(0), ibi(0), ibo(0), a(0)
  81.    {
  82.       assert(t->is_interface());
  83.       add_interface(t, mode);
  84.    }
  85.    symbol_table_entry(const class ast_type_specifier *a):
  86.       v(0), f(0), t(0), ibu(0), ibi(0), ibo(0), a(a) {}
  87.  
  88.    ir_variable *v;
  89.    ir_function *f;
  90.    const glsl_type *t;
  91.    const glsl_type *ibu;
  92.    const glsl_type *ibi;
  93.    const glsl_type *ibo;
  94.    const class ast_type_specifier *a;
  95. };
  96.  
  97. glsl_symbol_table::glsl_symbol_table()
  98. {
  99.    this->separate_function_namespace = false;
  100.    this->table = _mesa_symbol_table_ctor();
  101.    this->mem_ctx = ralloc_context(NULL);
  102. }
  103.  
  104. glsl_symbol_table::~glsl_symbol_table()
  105. {
  106.    _mesa_symbol_table_dtor(table);
  107.    ralloc_free(mem_ctx);
  108. }
  109.  
  110. void glsl_symbol_table::push_scope()
  111. {
  112.    _mesa_symbol_table_push_scope(table);
  113. }
  114.  
  115. void glsl_symbol_table::pop_scope()
  116. {
  117.    _mesa_symbol_table_pop_scope(table);
  118. }
  119.  
  120. bool glsl_symbol_table::name_declared_this_scope(const char *name)
  121. {
  122.    return _mesa_symbol_table_symbol_scope(table, -1, name) == 0;
  123. }
  124.  
  125. bool glsl_symbol_table::add_variable(ir_variable *v)
  126. {
  127.    assert(v->data.mode != ir_var_temporary);
  128.  
  129.    if (this->separate_function_namespace) {
  130.       /* In 1.10, functions and variables have separate namespaces. */
  131.       symbol_table_entry *existing = get_entry(v->name);
  132.       if (name_declared_this_scope(v->name)) {
  133.          /* If there's already an existing function (not a constructor!) in
  134.           * the current scope, just update the existing entry to include 'v'.
  135.           */
  136.          if (existing->v == NULL && existing->t == NULL) {
  137.             existing->v = v;
  138.             return true;
  139.          }
  140.       } else {
  141.          /* If not declared at this scope, add a new entry.  But if an existing
  142.           * entry includes a function, propagate that to this block - otherwise
  143.           * the new variable declaration would shadow the function.
  144.           */
  145.          symbol_table_entry *entry = new(mem_ctx) symbol_table_entry(v);
  146.          if (existing != NULL)
  147.             entry->f = existing->f;
  148.          int added = _mesa_symbol_table_add_symbol(table, -1, v->name, entry);
  149.          assert(added == 0);
  150.          (void)added;
  151.          return true;
  152.       }
  153.       return false;
  154.    }
  155.  
  156.    /* 1.20+ rules: */
  157.    symbol_table_entry *entry = new(mem_ctx) symbol_table_entry(v);
  158.    return _mesa_symbol_table_add_symbol(table, -1, v->name, entry) == 0;
  159. }
  160.  
  161. bool glsl_symbol_table::add_type(const char *name, const glsl_type *t)
  162. {
  163.    symbol_table_entry *entry = new(mem_ctx) symbol_table_entry(t);
  164.    return _mesa_symbol_table_add_symbol(table, -1, name, entry) == 0;
  165. }
  166.  
  167. bool glsl_symbol_table::add_interface(const char *name, const glsl_type *i,
  168.                                       enum ir_variable_mode mode)
  169. {
  170.    assert(i->is_interface());
  171.    symbol_table_entry *entry = get_entry(name);
  172.    if (entry == NULL) {
  173.       symbol_table_entry *entry =
  174.          new(mem_ctx) symbol_table_entry(i, mode);
  175.       bool add_interface_symbol_result =
  176.          _mesa_symbol_table_add_symbol(table, -1, name, entry) == 0;
  177.       assert(add_interface_symbol_result);
  178.       return add_interface_symbol_result;
  179.    } else {
  180.       return entry->add_interface(i, mode);
  181.    }
  182. }
  183.  
  184. bool glsl_symbol_table::add_function(ir_function *f)
  185. {
  186.    if (this->separate_function_namespace && name_declared_this_scope(f->name)) {
  187.       /* In 1.10, functions and variables have separate namespaces. */
  188.       symbol_table_entry *existing = get_entry(f->name);
  189.       if ((existing->f == NULL) && (existing->t == NULL)) {
  190.          existing->f = f;
  191.          return true;
  192.       }
  193.    }
  194.    symbol_table_entry *entry = new(mem_ctx) symbol_table_entry(f);
  195.    return _mesa_symbol_table_add_symbol(table, -1, f->name, entry) == 0;
  196. }
  197.  
  198. void glsl_symbol_table::add_global_function(ir_function *f)
  199. {
  200.    symbol_table_entry *entry = new(mem_ctx) symbol_table_entry(f);
  201.    int added = _mesa_symbol_table_add_global_symbol(table, -1, f->name, entry);
  202.    assert(added == 0);
  203.    (void)added;
  204. }
  205.  
  206. ir_variable *glsl_symbol_table::get_variable(const char *name)
  207. {
  208.    symbol_table_entry *entry = get_entry(name);
  209.    return entry != NULL ? entry->v : NULL;
  210. }
  211.  
  212. const glsl_type *glsl_symbol_table::get_type(const char *name)
  213. {
  214.    symbol_table_entry *entry = get_entry(name);
  215.    return entry != NULL ? entry->t : NULL;
  216. }
  217.  
  218. const glsl_type *glsl_symbol_table::get_interface(const char *name,
  219.                                                   enum ir_variable_mode mode)
  220. {
  221.    symbol_table_entry *entry = get_entry(name);
  222.    return entry != NULL ? entry->get_interface(mode) : NULL;
  223. }
  224.  
  225. ir_function *glsl_symbol_table::get_function(const char *name)
  226. {
  227.    symbol_table_entry *entry = get_entry(name);
  228.    return entry != NULL ? entry->f : NULL;
  229. }
  230.  
  231. symbol_table_entry *glsl_symbol_table::get_entry(const char *name)
  232. {
  233.    return (symbol_table_entry *)
  234.       _mesa_symbol_table_find_symbol(table, -1, name);
  235. }
  236.  
  237. void
  238. glsl_symbol_table::disable_variable(const char *name)
  239. {
  240.    /* Ideally we would remove the variable's entry from the symbol table, but
  241.     * that would be difficult.  Fortunately, since this is only used for
  242.     * built-in variables, it won't be possible for the shader to re-introduce
  243.     * the variable later, so all we really need to do is to make sure that
  244.     * further attempts to access it using get_variable() will return NULL.
  245.     */
  246.    symbol_table_entry *entry = get_entry(name);
  247.    if (entry != NULL) {
  248.       entry->v = NULL;
  249.    }
  250. }
  251.