示例#1
0
文件: reach.c 项目: Sendence/ponyc
static void add_rmethod_to_subtype(reach_t* r, reach_type_t* t,
  reach_method_name_t* n, reach_method_t* m, pass_opt_t* opt)
{
  // Add the method to the type if it isn't already there.
  reach_method_name_t* n2 = add_method_name(t, n->name);
  add_rmethod(r, t, n2, m->cap, m->typeargs, opt);

  // Add this mangling to the type if it isn't already there.
  reach_method_t* mangled = reach_mangled_get(&n2->r_mangled, m);

  if(mangled != NULL)
    return;

  mangled = POOL_ALLOC(reach_method_t);
  memset(mangled, 0, sizeof(reach_method_t));

  mangled->name = m->name;
  mangled->mangled_name = m->mangled_name;
  mangled->full_name = make_full_name(t, mangled);

  mangled->cap = m->cap;
  mangled->r_fun = ast_dup(m->r_fun);
  mangled->typeargs = ast_dup(m->typeargs);
  mangled->forwarding = true;

  mangled->param_count = m->param_count;
  mangled->params = (reach_param_t*)ponyint_pool_alloc_size(
    mangled->param_count * sizeof(reach_param_t));
  memcpy(mangled->params, m->params, m->param_count * sizeof(reach_param_t));
  mangled->result = m->result;

  // Add to the mangled table only.
  reach_mangled_put(&n2->r_mangled, mangled);
}
示例#2
0
文件: reach.c 项目: Sendence/ponyc
static reach_method_t* add_rmethod(reach_t* r, reach_type_t* t,
  reach_method_name_t* n, token_id cap, ast_t* typeargs, pass_opt_t* opt)
{
  const char* name = genname_fun(cap, n->name, typeargs);
  reach_method_t* m = reach_rmethod(n, name);

  if(m != NULL)
    return m;

  m = POOL_ALLOC(reach_method_t);
  memset(m, 0, sizeof(reach_method_t));
  m->name = name;
  m->cap = cap;
  m->typeargs = ast_dup(typeargs);
  m->vtable_index = (uint32_t)-1;

  ast_t* r_ast = set_cap_and_ephemeral(t->ast, cap, TK_NONE);
  ast_t* fun = lookup(NULL, NULL, r_ast, n->name);
  ast_free_unattached(r_ast);

  if(typeargs != NULL)
  {
    // Reify the method with its typeargs, if it has any.
    AST_GET_CHILDREN(fun, cap, id, typeparams, params, result, can_error,
      body);

    fun = reify(fun, typeparams, typeargs, opt, false);
  }

  m->r_fun = fun;
  set_method_types(r, m, opt);
  m->mangled_name = make_mangled_name(m);
  m->full_name = make_full_name(t, m);

  // Add to both tables.
  reach_methods_put(&n->r_methods, m);
  reach_mangled_put(&n->r_mangled, m);

  // Put on a stack of reachable methods to trace.
  r->stack = reach_method_stack_push(r->stack, m);

  // Add the method to any subtypes.
  add_rmethod_to_subtypes(r, t, n, m, opt);

  return m;
}
示例#3
0
/* size has to be big enough to store a '@', a '\0'
 * and the var or row number.
 */
void lps_makename(
   char*       target,
   int         size,
   const char* name,
   int         no)
{
   char  temp[9];
   int   len;
   int   nlen;

   assert(target != NULL);
   assert(size   >  MIN_NAME_LEN);   /* 8+1, so we have at least '@' + 7 digits + '\0' */
   assert(name   != NULL);
   assert(no     >= -1);
   assert(no     <= 0xFFFFFFF); /* 7 hex digits = 268,435,455 */

   nlen = (int)strlen(name);

   /* There are 3 possibilities:
    *
    *   i) name is smaller than size and does not contain problematic chars
    *      -> just copy it.
    *  ii) as above but contains unvalid chars
    *      -> copy it, transform the chars to '_' and append "@varnum".
    * iii) the name is longer than the size.
    *      -> do as in ii) but only copy as much chars as fit.
    *  iv) no == -1
    *      -> generate a full human readable name
    */      
   if (no == -1)
      make_full_name(target, size, name);
   else if (nlen < size)
   {
      if (lpfstrncpy(target, name, nlen))
      {
         sprintf(temp, "@%x", no);

         len = size - (int)strlen(temp) - 1;

         assert(len >= 0);

         /* Trick: if len > strlen(target) it doesn't matter,
          * lpfstrncmp always appends a '\0' and the strcat below
          * will append temp at the right place.
          * Otherwise it will be appended at len, which is the
          * latest possible position.
          */
         target[len] = '\0';
         strcat(target, temp);
      }
   }
   else
   {
      sprintf(temp, "@%x", no);
      
      len = size - (int)strlen(temp) - 1; /* -1 for '\0' */
      
      assert(len >= 0);
      
      (void)lpfstrncpy(target, name, len);
      strcat(target, temp);
   }
   assert(strlen(target) <= (size_t)size - 1);
}