Example #1
1
void gendesc_table(compile_t* c)
{
  uint32_t len = c->reach->next_type_id;
  size_t size = len * sizeof(LLVMValueRef);
  LLVMValueRef* args = (LLVMValueRef*)ponyint_pool_alloc_size(size);

  reach_type_t* t;
  size_t i = HASHMAP_BEGIN;

  while((t = reach_types_next(&c->reach->types, &i)) != NULL)
  {
    LLVMValueRef desc;

    if(t->desc != NULL)
      desc = LLVMBuildBitCast(c->builder, t->desc, c->descriptor_ptr, "");
    else
      desc = LLVMConstNull(c->descriptor_ptr);

    args[t->type_id] = desc;
  }

  LLVMTypeRef type = LLVMArrayType(c->descriptor_ptr, len);
  LLVMValueRef table = LLVMAddGlobal(c->module, type, "__DescTable");
  LLVMValueRef value = LLVMConstArray(c->descriptor_ptr, args, len);
  LLVMSetInitializer(table, value);
  LLVMSetGlobalConstant(table, true);

  LLVMValueRef table_size = LLVMAddGlobal(c->module, c->intptr,
    "__DescTableSize");
  LLVMSetInitializer(table_size, LLVMConstInt(c->intptr, len, false));
  LLVMSetGlobalConstant(table_size, true);

  ponyint_pool_free_size(size, args);
}
Example #2
0
void pony_serialise(pony_ctx_t* ctx, void* p, void* out)
{
  // This can raise an error.
  assert(ctx->stack == NULL);
  ctx->trace_object = ponyint_serialise_object;
  ctx->trace_actor = ponyint_serialise_actor;
  ctx->serialise_size = 0;

  pony_traceunknown(ctx, p, PONY_TRACE_MUTABLE);
  ponyint_gc_handlestack(ctx);

  ponyint_array_t* r = (ponyint_array_t*)out;
  r->size = ctx->serialise_size;
  r->alloc = r->size;
  r->ptr = (char*)ponyint_pool_alloc_size(r->size);

  size_t i = HASHMAP_BEGIN;
  serialise_t* s;

  while((s = ponyint_serialise_next(&ctx->serialise, &i)) != NULL)
  {
    if(s->t != NULL)
      s->t->serialise(ctx, (void*)s->key, r->ptr, s->value, s->mutability);
  }

  serialise_cleanup(ctx);
}
Example #3
0
pony_ctx_t* ponyint_sched_init(uint32_t threads, bool noyield, bool nopin,
  bool pinasio)
{
  use_yield = !noyield;

  // If no thread count is specified, use the available physical core count.
  if(threads == 0)
    threads = ponyint_cpu_count();

  scheduler_count = threads;
  scheduler = (scheduler_t*)ponyint_pool_alloc_size(
    scheduler_count * sizeof(scheduler_t));
  memset(scheduler, 0, scheduler_count * sizeof(scheduler_t));

  uint32_t asio_cpu = ponyint_cpu_assign(scheduler_count, scheduler, nopin,
    pinasio);

  for(uint32_t i = 0; i < scheduler_count; i++)
  {
    scheduler[i].ctx.scheduler = &scheduler[i];
    scheduler[i].last_victim = &scheduler[i];
    ponyint_messageq_init(&scheduler[i].mq);
    ponyint_mpmcq_init(&scheduler[i].q);
  }

  this_scheduler = &scheduler[0];
  ponyint_mpmcq_init(&inject);
  ponyint_asio_init(asio_cpu);

  return &scheduler[0].ctx;
}
Example #4
0
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);
}
Example #5
0
// https://stackoverflow.com/questions/2736753/how-to-remove-extension-from-file-name
// remove_ext: removes the "extension" from a file spec.
//   path is the string to process.
//   dot is the extension separator.
//   sep is the path separator (0 means to ignore).
// Returns an allocated string identical to the original but
//   with the extension removed. It must be freed when you're
//   finished with it.
// If you pass in NULL or the new string can't be allocated,
//   it returns NULL.
char* remove_ext(const char* path, char dot, char sep, size_t* allocated_size) 
{
    char *retstr, *lastdot, *lastsep;
    // Error checks and allocate string.
    if (path == NULL)
      return NULL;

    *allocated_size = strlen(path) + 1;

    retstr = (char*) ponyint_pool_alloc_size(*allocated_size);

    // Make a copy and find the relevant characters.
    strcpy(retstr, path);
    lastdot = strrchr(retstr, dot);
    lastsep = (sep == 0) ? NULL : strrchr(retstr, sep);

    // If it has an extension separator.
    if (lastdot != NULL) {
      // and it's before the extension separator.
      if (lastsep != NULL) {
        if (lastsep < lastdot) {
          // then remove it.
          *lastdot = '\0';
        }
      }
      else {
        // Has extension separator with no path separator.
        *lastdot = '\0';
      }
    }
    // Return the modified string.
    return retstr;
}
Example #6
0
static void set_method_types(reach_t* r, reach_method_t* m,
  pass_opt_t* opt)
{
  AST_GET_CHILDREN(m->r_fun, cap, id, typeparams, params, result, can_error,
    body);

  m->param_count = ast_childcount(params);
  m->params = (reach_param_t*)ponyint_pool_alloc_size(
    m->param_count * sizeof(reach_param_t));

  ast_t* param = ast_child(params);
  size_t i = 0;

  while(param != NULL)
  {
    AST_GET_CHILDREN(param, p_id, p_type);
    m->params[i].type = add_type(r, p_type, opt);
    if(ast_id(p_type) != TK_NOMINAL && ast_id(p_type) != TK_TYPEPARAMREF)
      m->params[i].cap = TK_REF;
    else
      m->params[i].cap = ast_id(cap_fetch(p_type));
    ++i;
    param = ast_sibling(param);
  }

  m->result = add_type(r, result, opt);
}
Example #7
0
static void handle_stack(reachable_method_stack_t* s, reachable_types_t* r,
  uint32_t* next_type_id)
{
  while(s != NULL)
  {
    reachable_method_t* m;
    s = reachable_method_stack_pop(s, &m);

    AST_GET_CHILDREN(m->r_fun, cap, id, typeparams, params, result, can_error,
      body);

    m->param_count = ast_childcount(params);
    m->params = (reachable_type_t**)ponyint_pool_alloc_size(
      m->param_count * sizeof(reachable_type_t*));

    ast_t* param = ast_child(params);
    size_t i = 0;

    while(param != NULL)
    {
      AST_GET_CHILDREN(param, p_id, p_type);
      m->params[i++] = add_type(&s, r, next_type_id, p_type);
      param = ast_sibling(param);
    }

    m->result = add_type(&s, r, next_type_id, result);
    reachable_expr(&s, r, next_type_id, body);
  }
}
Example #8
0
static LLVMValueRef make_trait_list(compile_t* c, reach_type_t* t,
  uint32_t* final_count)
{
  // The list is an array of integers.
  uint32_t* tid;
  size_t tid_size;
  uint32_t count = trait_count(t, &tid, &tid_size);

  // If we have no traits, return a null pointer to a list.
  if(count == 0)
    return LLVMConstNull(LLVMPointerType(LLVMArrayType(c->i32, 0), 0));

  // Create a constant array of trait identifiers.
  size_t list_size = count * sizeof(LLVMValueRef);
  LLVMValueRef* list = (LLVMValueRef*)ponyint_pool_alloc_size(list_size);

  for(uint32_t i = 0; i < count; i++)
    list[i] = LLVMConstInt(c->i32, tid[i], false);

  LLVMValueRef trait_array = LLVMConstArray(c->i32, list, count);

  // Create a global to hold the array.
  const char* name = genname_traitlist(t->name);
  LLVMTypeRef list_type = LLVMArrayType(c->i32, count);
  LLVMValueRef global = LLVMAddGlobal(c->module, list_type, name);
  LLVMSetGlobalConstant(global, true);
  LLVMSetLinkage(global, LLVMPrivateLinkage);
  LLVMSetInitializer(global, trait_array);

  ponyint_pool_free_size(tid_size, tid);
  ponyint_pool_free_size(list_size, list);

  *final_count = count;
  return global;
}
Example #9
0
// Cat together the given strings into a newly allocated buffer.
// Any unneeded strings should be passed as "", not NULL.
// The returned buffer must be freed with ponyint_pool_free_size() when
// no longer needed.
// The out_buf_size parameter returns the size of the buffer (which is needed
// for freeing), not the length of the string.
static char* doc_cat(const char* a, const char* b, const char* c,
  const char* d, const char* e, size_t* out_buf_size)
{
  assert(a != NULL);
  assert(b != NULL);
  assert(c != NULL);
  assert(d != NULL);
  assert(e != NULL);
  assert(out_buf_size != NULL);

  size_t a_len = strlen(a);
  size_t b_len = strlen(b);
  size_t c_len = strlen(c);
  size_t d_len = strlen(d);
  size_t e_len = strlen(e);
  size_t buf_len = a_len + b_len + c_len + d_len + e_len + 1;

  char* buffer = (char*)ponyint_pool_alloc_size(buf_len);
  char *p = buffer;

  if(a_len > 0) { memcpy(p, a, a_len); p += a_len; }
  if(b_len > 0) { memcpy(p, b, b_len); p += b_len; }
  if(c_len > 0) { memcpy(p, c, c_len); p += c_len; }
  if(d_len > 0) { memcpy(p, d, d_len); p += d_len; }
  if(e_len > 0) { memcpy(p, e, e_len); p += e_len; }

  *(p++) = '\0';

  assert(p == (buffer + buf_len));
  *out_buf_size = buf_len;
  return buffer;
}
Example #10
0
static void print_params(compile_t* c, printbuf_t* buf, ast_t* params)
{
  ast_t* param = ast_child(params);

  while(param != NULL)
  {
    AST_GET_CHILDREN(param, id, ptype);

    // Print the parameter.
    printbuf(buf, ", ");
    print_type_name(c, buf, ptype);

    // Smash trailing primes to underscores.
    const char* name = ast_name(id);
    size_t len = strlen(name) + 1;
    size_t buf_size = len;
    char* buffer = (char*)ponyint_pool_alloc_size(buf_size);
    memcpy(buffer, name, len);

    len--;

    while(buffer[--len] == '\'')
      buffer[len] = '_';

    printbuf(buf, " %s", buffer);

    param = ast_sibling(param);
    ponyint_pool_free_size(buf_size, buffer);
  }
}
Example #11
0
LLVMValueRef gen_numeric_size_table(compile_t* c)
{
  uint32_t len = c->reach->numeric_type_count;
  if(len == 0)
    return NULL;

  size_t size = len * sizeof(LLVMValueRef);
  LLVMValueRef* args = (LLVMValueRef*)ponyint_pool_alloc_size(size);

  uint32_t count = 0;
  reach_type_t* t;
  size_t i = HASHMAP_BEGIN;

  while(count < len)
  {
    t = reach_types_next(&c->reach->types, &i);
    pony_assert(t != NULL);

    if(t->is_trait || (t->underlying == TK_STRUCT))
      continue;

    uint32_t type_id = t->type_id;
    if((type_id % 4) == 0)
    {
      size_t type_size = (size_t)LLVMABISizeOfType(c->target_data, t->use_type);
      args[type_id >> 2] = LLVMConstInt(c->i32, type_size, false);
      count++;
    }
  }
Example #12
0
static const char* symbol_suffix(const char* symbol, size_t suffix)
{
  size_t len = strlen(symbol);
  size_t buf_size = len + 32;
  char* buf = (char*)ponyint_pool_alloc_size(buf_size);
  snprintf(buf, buf_size, "%s" __zu, symbol, suffix);

  return stringtab_consume(buf, buf_size);
}
Example #13
0
LLVMValueRef gen_tuple(compile_t* c, ast_t* ast)
{
  ast_t* child = ast_child(ast);

  if(ast_sibling(child) == NULL)
    return gen_expr(c, child);

  deferred_reification_t* reify = c->frame->reify;

  ast_t* type = deferred_reify(reify, ast_type(ast), c->opt);

  // If we contain '_', we have no usable value.
  if(contains_dontcare(type))
  {
    ast_free_unattached(type);
    return GEN_NOTNEEDED;
  }

  reach_type_t* t = reach_type(c->reach, type);
  compile_type_t* c_t = (compile_type_t*)t->c_type;
  int count = LLVMCountStructElementTypes(c_t->primitive);
  size_t buf_size = count * sizeof(LLVMTypeRef);
  LLVMTypeRef* elements = (LLVMTypeRef*)ponyint_pool_alloc_size(buf_size);
  LLVMGetStructElementTypes(c_t->primitive, elements);

  LLVMValueRef tuple = LLVMGetUndef(c_t->primitive);
  int i = 0;

  while(child != NULL)
  {
    LLVMValueRef value = gen_expr(c, child);

    if(value == NULL)
    {
      ponyint_pool_free_size(buf_size, elements);
      return NULL;
    }

    // We'll have an undefined element if one of our source elements is a
    // variable declaration. This is ok, since the tuple value will never be
    // used.
    if(value == GEN_NOVALUE || value == GEN_NOTNEEDED)
    {
      ponyint_pool_free_size(buf_size, elements);
      return value;
    }

    ast_t* child_type = deferred_reify(reify, ast_type(child), c->opt);
    value = gen_assign_cast(c, elements[i], value, child_type);
    ast_free_unattached(child_type);
    tuple = LLVMBuildInsertValue(c->builder, tuple, value, i++, "");
    child = ast_sibling(child);
  }

  ponyint_pool_free_size(buf_size, elements);
  return tuple;
}
Example #14
0
printbuf_t* printbuf_new()
{
  printbuf_t* buf = POOL_ALLOC(printbuf_t);
  buf->m = (char*)ponyint_pool_alloc_size(32);
  buf->m[0] = '\0';
  buf->size = 32;
  buf->offset = 0;
  return buf;
}
Example #15
0
source_t* source_open_string(const char* source_code)
{
  source_t* source = POOL_ALLOC(source_t);
  source->file = NULL;
  source->len = strlen(source_code);
  source->m = (char*)ponyint_pool_alloc_size(source->len);

  memcpy(source->m, source_code, source->len);

  return source;
}
Example #16
0
// Convert the given ID to a hygenic string. The resulting string should not be
// deleted and is valid indefinitely.
static const char* id_to_string(const char* prefix, size_t id)
{
  if(prefix == NULL)
    prefix = "";

  size_t len = strlen(prefix);
  size_t buf_size = len + 32;
  char* buffer = (char*)ponyint_pool_alloc_size(buf_size);
  snprintf(buffer, buf_size, "%s$" __zu, prefix, id);
  return stringtab_consume(buffer, buf_size);
}
Example #17
0
static void tuple_indices_push(call_tuple_indices_t* ti, size_t idx)
{
  if(ti->count == ti->alloc)
  {
    size_t* tmp_data =
      (size_t*)ponyint_pool_alloc_size(2 * ti->alloc * sizeof(size_t));
    memcpy(tmp_data, ti->data, ti->count * sizeof(size_t));
    ponyint_pool_free_size(ti->alloc * sizeof(size_t), ti->data);
    ti->alloc *= 2;
    ti->data = tmp_data;
  }
  ti->data[ti->count++] = idx;
}
Example #18
0
static LLVMValueRef make_field_list(compile_t* c, reach_type_t* t)
{
  // The list is an array of field descriptors.
  uint32_t count;

  if(t->underlying == TK_TUPLETYPE)
    count = t->field_count;
  else
    count = 0;

  LLVMTypeRef field_type = LLVMArrayType(c->field_descriptor, count);

  // If we aren't a tuple, return a null pointer to a list.
  if(count == 0)
    return LLVMConstNull(LLVMPointerType(field_type, 0));

  // Create a constant array of field descriptors.
  size_t buf_size = count * sizeof(LLVMValueRef);
  LLVMValueRef* list = (LLVMValueRef*)ponyint_pool_alloc_size(buf_size);

  for(uint32_t i = 0; i < count; i++)
  {
    LLVMValueRef fdesc[2];
    fdesc[0] = LLVMConstInt(c->i32,
      LLVMOffsetOfElement(c->target_data, t->primitive, i), false);

    if(t->fields[i].type->desc != NULL)
    {
      // We are a concrete type.
      fdesc[1] = LLVMConstBitCast(t->fields[i].type->desc,
        c->descriptor_ptr);
    } else {
      // We aren't a concrete type.
      fdesc[1] = LLVMConstNull(c->descriptor_ptr);
    }

    list[i] = LLVMConstStructInContext(c->context, fdesc, 2, false);
  }

  LLVMValueRef field_array = LLVMConstArray(c->field_descriptor, list, count);

  // Create a global to hold the array.
  const char* name = genname_fieldlist(t->name);
  LLVMValueRef global = LLVMAddGlobal(c->module, field_type, name);
  LLVMSetGlobalConstant(global, true);
  LLVMSetLinkage(global, LLVMPrivateLinkage);
  LLVMSetInitializer(global, field_array);

  ponyint_pool_free_size(buf_size, list);
  return global;
}
Example #19
0
static const char* name_without_case(const char* name)
{
  size_t len = strlen(name) + 1;
  char* buf = (char*)ponyint_pool_alloc_size(len);

  if(is_name_type(name))
  {
    for(size_t i = 0; i < len; i++)
      buf[i] = (char)toupper(name[i]);
  } else {
    for(size_t i = 0; i < len; i++)
      buf[i] = (char)tolower(name[i]);
  }

  return stringtab_consume(buf, len);
}
Example #20
0
const char* buildflagset_print(buildflagset_t* set)
{
  assert(set != NULL);
  assert(set->flags != NULL);

  char* p = set->text_buffer;

  // First the mutually exclusive flags.
  if(set->have_os_flags)
    print_flag(_os_flags[set->enum_os_flags], true, set, &p);

  if(set->have_arch_flags)
    print_flag(_arch_flags[set->enum_arch_flags], true, set, &p);

  if(set->have_size_flags)
    print_flag(_size_flags[set->enum_size_flags], true, set, &p);

  // Next the normal flags, in any order.
  size_t i = HASHMAP_BEGIN;
  flag_t* flag;

  while((flag = flagtab_next(set->flags, &i)) != NULL)
    print_flag(flag->name, flag->value, set, &p);

  if(p == set->text_buffer) // No flags, all configs match.
    print_str("all configs", set, &p);

  // Check buffer was big enough for it all.
  size_t size_needed = (p - set->text_buffer) + 1; // +1 for terminator.

  if(size_needed > set->buffer_size)
  {
    // Buffer we have isn't big enough, make it bigger then go round again.
    if(set->buffer_size > 0)
      ponyint_pool_free_size(set->buffer_size, set->text_buffer);

    set->text_buffer = (char*)ponyint_pool_alloc_size(size_needed);
    set->buffer_size = size_needed;
    set->text_buffer[0] = '\0';
    buildflagset_print(set);
  }

  // Add terminator.
  assert(set->text_buffer != NULL);
  set->text_buffer[size_needed - 1] = '\0';
  return set->text_buffer;
}
Example #21
0
static const char* suggest_alt_name(ast_t* ast, const char* name)
{
  assert(ast != NULL);
  assert(name != NULL);

  size_t name_len = strlen(name);

  if(is_name_private(name))
  {
    // Try without leading underscore
    const char* try_name = stringtab(name + 1);

    if(ast_get(ast, try_name, NULL) != NULL)
      return try_name;
  }
  else
  {
    // Try with a leading underscore
    char* buf = (char*)ponyint_pool_alloc_size(name_len + 2);
    buf[0] = '_';
    strncpy(buf + 1, name, name_len + 1);
    const char* try_name = stringtab_consume(buf, name_len + 2);

    if(ast_get(ast, try_name, NULL) != NULL)
      return try_name;
  }

  // Try with a different case (without crossing type/value boundary)
  ast_t* case_ast = ast_get_case(ast, name, NULL);
  if(case_ast != NULL)
  {
    ast_t* id = case_ast;

    if(ast_id(id) != TK_ID)
      id = ast_child(id);

    assert(ast_id(id) == TK_ID);
    const char* try_name = ast_name(id);

    if(ast_get(ast, try_name, NULL) != NULL)
      return try_name;
  }

  // Give up
  return NULL;
}
Example #22
0
static void make_debug_fields(compile_t* c, reach_type_t* t)
{
  LLVMMetadataRef fields = NULL;

  if(t->field_count > 0)
  {
    size_t buf_size = t->field_count * sizeof(LLVMMetadataRef);
    LLVMMetadataRef* data = (LLVMMetadataRef*)ponyint_pool_alloc_size(
      buf_size);

    for(uint32_t i = 0; i < t->field_count; i++)
      data[i] = make_debug_field(c, t, i);

    fields = LLVMDIBuilderGetOrCreateArray(c->di, data, t->field_count);
    ponyint_pool_free_size(buf_size, data);
  }

  LLVMTypeRef type;

  if(t->underlying != TK_TUPLETYPE)
    type = t->structure;
  else
    type = t->primitive;

  uint64_t size = 0;
  uint64_t align = 0;

  if(type != NULL)
  {
    size = LLVMABISizeOfType(c->target_data, type);
    align = LLVMABIAlignmentOfType(c->target_data, type);
  }

  LLVMMetadataRef di_type = LLVMDIBuilderCreateStructType(c->di, c->di_unit,
    t->name, t->di_file, (unsigned) ast_line(t->ast), 8 * size, 8 * align,
    fields);

  if(t->underlying != TK_TUPLETYPE)
  {
    LLVMMetadataReplaceAllUsesWith(t->di_type_embed, di_type);
    t->di_type_embed = di_type;
  } else {
    LLVMMetadataReplaceAllUsesWith(t->di_type, di_type);
    t->di_type = di_type;
  }
}
Example #23
0
// Append the given character to the current token text
static void append_to_token(lexer_t* lexer, char c)
{
  if(lexer->buflen >= lexer->alloc)
  {
    size_t new_len = (lexer->alloc > 0) ? lexer->alloc << 1 : 64;
    char* new_buf = (char*)ponyint_pool_alloc_size(new_len);
    memcpy(new_buf, lexer->buffer, lexer->alloc);

    if(lexer->alloc > 0)
      ponyint_pool_free_size(lexer->alloc, lexer->buffer);

    lexer->buffer = new_buf;
    lexer->alloc = new_len;
  }

  lexer->buffer[lexer->buflen] = c;
  lexer->buflen++;
}
Example #24
0
static uint32_t trait_count(reach_type_t* t, uint32_t** list,
  size_t* list_size)
{
  switch(t->underlying)
  {
    case TK_PRIMITIVE:
    case TK_CLASS:
    case TK_ACTOR:
    {
      uint32_t count = (uint32_t)reach_type_cache_size(&t->subtypes);

      if(count == 0)
        return 0;

      // Sort the trait identifiers.
      size_t tid_size = count * sizeof(uint32_t);
      uint32_t* tid = (uint32_t*)ponyint_pool_alloc_size(tid_size);

      size_t i = HASHMAP_BEGIN;
      size_t index = 0;
      reach_type_t* provide;

      while((provide = reach_type_cache_next(&t->subtypes, &i)) != NULL)
        tid[index++] = provide->type_id;

      qsort(tid, index, sizeof(uint32_t), cmp_uint32);
      count = (uint32_t)unique_uint32(tid, index);

      if(list != NULL)
      {
        *list = tid;
        *list_size = tid_size;
      } else {
        ponyint_pool_free_size(tid_size, tid);
      }

      return count;
    }

    default: {}
  }

  return 0;
}
Example #25
0
const char* suffix_filename(compile_t* c, const char* dir, const char* prefix,
  const char* file, const char* extension)
{
  // Copy to a string with space for a suffix.
  size_t len = strlen(dir) + strlen(prefix) + strlen(file) + strlen(extension)
    + 4;
  char* filename = (char*)ponyint_pool_alloc_size(len);

  // Start with no suffix.
#ifdef PLATFORM_IS_WINDOWS
  snprintf(filename, len, "%s\\%s%s%s", dir, prefix, file, extension);
#else
  snprintf(filename, len, "%s/%s%s%s", dir, prefix, file, extension);
#endif

  int suffix = 0;

  while(suffix < 100)
  {
    // Overwrite files but not directories.
    struct stat s;
    int err = stat(filename, &s);

    if((err == -1) || !S_ISDIR(s.st_mode))
      break;

#ifdef PLATFORM_IS_WINDOWS
    snprintf(filename, len, "%s\\%s%s%d%s", dir, prefix, file, ++suffix,
      extension);
#else
    snprintf(filename, len, "%s/%s%s%d%s", dir, prefix, file, ++suffix,
      extension);
#endif
  }

  if(suffix >= 100)
  {
    errorf(c->opt->check.errors, NULL, "couldn't pick an unused file name");
    ponyint_pool_free_size(len, filename);
    return NULL;
  }

  return stringtab_consume(filename, len);
}
Example #26
0
static bool query_registry(HKEY key, bool query_subkeys, query_callback_fn fn,
  search_t* p)
{
  DWORD sub_keys;
  DWORD largest_subkey;

  // Processing a leaf node in the registry, give it to the callback.
  if(!query_subkeys)
  {
    fn(key, NULL, p);
    return true;
  }

  get_child_count(key, &sub_keys, &largest_subkey);

  if(sub_keys == 0)
    return false;

  largest_subkey += 1;

  HKEY node;
  DWORD size = largest_subkey;
  char* name = (char*)ponyint_pool_alloc_size(largest_subkey);
  bool r = true;

  for(DWORD i = 0; i < sub_keys; ++i)
  {
    if(RegEnumKeyEx(key, i, name, &size, NULL, NULL, NULL, NULL)
      != ERROR_SUCCESS ||
      RegOpenKeyEx(key, name, 0, KEY_QUERY_VALUE, &node) != ERROR_SUCCESS)
    {
      r = false;
      break;
    }

    fn(node, name, p);
    RegCloseKey(node);
    size = largest_subkey;
  }

  ponyint_pool_free_size(largest_subkey, name);
  return true;
}
Example #27
0
void* ponyint_heap_alloc_large(pony_actor_t* actor, heap_t* heap, size_t size)
{
  size = ponyint_pool_adjust_size(size);

  chunk_t* chunk = (chunk_t*) POOL_ALLOC(chunk_t);
  chunk->actor = actor;
  chunk->size = size;
  chunk->m = (char*) ponyint_pool_alloc_size(size);
  chunk->slots = 0;
  chunk->shallow = 0;

  large_pagemap(chunk->m, size, chunk);

  chunk->next = heap->large;
  heap->large = chunk;
  heap->used += chunk->size;

  return chunk->m;
}
Example #28
0
source_t* source_open(const char* file, const char** error_msgp)
{
  FILE* fp = fopen(file, "rb");

  if(fp == NULL)
  {
    *error_msgp = "can't open file";
    return NULL;
  }

  fseek(fp, 0, SEEK_END);
  ssize_t size = ftell(fp);
  
  if(size < 0)
  {
    *error_msgp = "can't determine length of file";
    fclose(fp);
    return NULL;
  }

  fseek(fp, 0, SEEK_SET);

  source_t* source = POOL_ALLOC(source_t);
  source->file = stringtab(file);
  source->m = (char*)ponyint_pool_alloc_size(size + 1);
  source->len = size + 1;

  ssize_t read = fread(source->m, sizeof(char), size, fp);
  source->m[size] = '\0';
  
  if(read < size)
  {
    *error_msgp = "failed to read entire file";
    ponyint_pool_free_size(source->len, source->m);
    POOL_FREE(source_t, source);
    fclose(fp);
    return NULL;
  }

  fclose(fp);
  return source;
}
Example #29
0
static const char* quoted_locator(ast_t* use, const char* locator)
{
  assert(locator != NULL);

  if(strpbrk(locator, "\t\r\n\"'`;$|&<>%*?[]{}()") != NULL)
  {
    if(use != NULL)
      ast_error(use, "use URI contains invalid characters");

    return NULL;
  }

  size_t len = strlen(locator);
  char* quoted = (char*)ponyint_pool_alloc_size(len + 3);
  quoted[0] = '"';
  memcpy(quoted + 1, locator, len);
  quoted[len + 1] = '"';
  quoted[len + 2] = '\0';

  return stringtab_consume(quoted, len + 3);
}
Example #30
0
// Append the given text to the program's lib args, handling reallocs.
static void append_to_args(program_t* program, const char* text)
{
  pony_assert(program != NULL);
  pony_assert(text != NULL);

  size_t text_len = strlen(text);
  size_t new_len = program->lib_args_size + text_len + 1; // +1 for terminator

  if(new_len > program->lib_args_alloced)
  {
    size_t new_alloc = 2 * new_len; // 2* so there's spare space for next arg
    char* new_args = (char*)ponyint_pool_alloc_size(new_alloc);
    memcpy(new_args, program->lib_args, program->lib_args_size + 1);
    ponyint_pool_free_size(program->lib_args_alloced, program->lib_args);
    program->lib_args = new_args;
    program->lib_args_alloced = new_alloc;
  }

  strcat(program->lib_args, text);
  program->lib_args_size = new_len - 1; // Don't add terminator to length
}