void InterpreterRuntime::SignatureHandlerGenerator::generate(uint64_t fingerprint) {
  __ emit_fd();

  // generate code to handle arguments
  iterate(fingerprint);
  pass_prev(-BytesPerWord);

  // return result handler
  __ movl(GR_RET, (uint64_t)AbstractInterpreter::result_handler(method()->result_type()));
  __ ret();

  __ flush();
}
void InterpreterRuntime::SignatureHandlerGenerator::pass_float() {
  pass_prev(0);
  pass_curr(Argument::float_sig);
}
void InterpreterRuntime::SignatureHandlerGenerator::pass_double() {
  pass_prev(BytesPerWord);
  pass_curr(Argument::double_sig);
}
Ejemplo n.º 4
0
ast_t* package_load(ast_t* from, const char* path, pass_opt_t* options)
{
  const char* magic = find_magic_package(path);
  const char* full_path = path;
  const char* qualified_name = path;
  ast_t* program = ast_nearest(from, TK_PROGRAM);

  if(magic == NULL)
  {
    // Lookup (and hence normalise) path
    bool is_relative = false;
    full_path = find_path(from, path, &is_relative);

    if(full_path == NULL)
      return NULL;

    if((from != NULL) && is_relative)
    {
      // Package to load is relative to from, build the qualified name
      // The qualified name should be relative to the program being built
      package_t* from_pkg = (package_t*)ast_data(ast_child(program));

      if(from_pkg != NULL)
      {
        const char* base_name = from_pkg->qualified_name;
        size_t base_name_len = strlen(base_name);
        size_t path_len = strlen(path);
        size_t len = base_name_len + path_len + 2;
        char* q_name = (char*)pool_alloc_size(len);
        memcpy(q_name, base_name, base_name_len);
        q_name[base_name_len] = '/';
        memcpy(q_name + base_name_len + 1, path, path_len);
        q_name[len - 1] = '\0';
        qualified_name = stringtab_consume(q_name, len);
      }
    }
  }

  ast_t* package = ast_get(program, full_path, NULL);

  // Package already loaded
  if(package != NULL)
    return package;

  package = create_package(program, full_path, qualified_name);

  if(report_build)
    printf("Building %s -> %s\n", path, full_path);

  if(magic != NULL)
  {
    if(!parse_source_code(package, magic, options))
      return NULL;
  }
  else
  {
    if(!parse_files_in_dir(package, full_path, options))
      return NULL;
  }

  if(ast_child(package) == NULL)
  {
    ast_error(package, "no source files in package '%s'", path);
    return NULL;
  }

  // We add new packages to the end of the program, so they will be reached by
  // the current pass processing. This means we need to catch up the new
  // package to the previous pass
  if(!ast_passes_subtree(&package, options,
    pass_prev(options->type_catchup_pass)))
    return NULL;

  return package;
}