コード例 #1
0
ファイル: codegen.c プロジェクト: plesner/neutrino
value_t assembler_flush(assembler_t *assm) {
  // Copy the bytecode into a blob object.
  blob_t code_blob;
  short_buffer_flush(&assm->code, &code_blob);
  TRY_DEF(bytecode, new_heap_blob_with_data(assm->runtime, &code_blob));
  // Invert the constant pool map into an array.
  value_t value_pool_map = assm->value_pool;
  size_t value_pool_size = get_id_hash_map_size(value_pool_map);
  TRY_DEF(value_pool, new_heap_array(assm->runtime, value_pool_size));
  id_hash_map_iter_t iter;
  id_hash_map_iter_init(&iter, value_pool_map);
  size_t entries_seen = 0;
  while (id_hash_map_iter_advance(&iter)) {
    value_t key;
    value_t value;
    id_hash_map_iter_get_current(&iter, &key, &value);
    size_t index = get_integer_value(value);
    // Check that the entry hasn't been set already.
    CHECK_PHYLUM(tpNull, get_array_at(value_pool, index));
    set_array_at(value_pool, index, key);
    entries_seen++;
  }
  CHECK_EQ("wrong number of entries", entries_seen, value_pool_size);
  return new_heap_code_block(assm->runtime, bytecode, value_pool,
      assm->high_water_mark);
}
コード例 #2
0
ファイル: bind.c プロジェクト: plesner/neutrino
// Executes a method declaration on the given fragment.
static value_t apply_method_declaration(value_t ambience, value_t decl,
    value_t fragment) {
  CHECK_FAMILY(ofMethodDeclarationAst, decl);
  CHECK_FAMILY(ofModuleFragment, fragment);
  runtime_t *runtime = get_ambience_runtime(ambience);
  // Look for the :builtin annotation on this method.
  value_t annots = get_method_declaration_ast_annotations(decl);
  value_t builtin_name = new_not_found_condition();
  for (size_t i = 0; i < get_array_length(annots); i++) {
    value_t annot = get_array_at(annots, i);
    TRY_DEF(value, run_expression_until_condition(ambience, fragment, annot));
    if (in_family(ofBuiltinMarker, value))
      builtin_name = get_builtin_marker_name(value);
  }
  // Compile the method whether it's a builtin or not. This way we can reuse
  // the compilation code for both cases and just patch up the result after
  // the fact if it's a builtin.
  value_t method_ast = get_method_declaration_ast_method(decl);
  TRY_DEF(method, compile_method_ast_to_method(runtime, method_ast, fragment));
  if (!in_condition_cause(ccNotFound, builtin_name)) {
    // This is a builtin so patch the method with the builtin implementation.
    TRY_DEF(impl, runtime_get_builtin_implementation(runtime, builtin_name));
    value_t impl_code = get_builtin_implementation_code(impl);
    TRY(validate_builtin_method_binding(method, impl));
    set_method_code(method, impl_code);
    value_t impl_flags = get_builtin_implementation_method_flags(impl);
    set_method_flags(method, impl_flags);
  }
  value_t methodspace = get_module_fragment_methodspace(fragment);
  TRY(add_methodspace_method(runtime, methodspace, method));
  return success();
}
コード例 #3
0
ファイル: bind.c プロジェクト: plesner/neutrino
static value_t init_empty_module_fragment(runtime_t *runtime, value_t fragment) {
  TRY_DEF(nspace, new_heap_namespace(runtime, nothing()));
  TRY_DEF(methodspace, new_heap_methodspace(runtime));
  TRY_DEF(imports, new_heap_id_hash_map(runtime, 16));
  set_module_fragment_namespace(fragment, nspace);
  set_module_fragment_methodspace(fragment, methodspace);
  set_module_fragment_imports(fragment, imports);
  return success();
}
コード例 #4
0
ファイル: alloc.c プロジェクト: plesner/neutrino
value_t new_heap_array_buffer(runtime_t *runtime, size_t initial_capacity) {
  size_t size = kArrayBufferSize;
  TRY_DEF(elements, new_heap_array(runtime, initial_capacity));
  TRY_DEF(result, alloc_heap_object(runtime, size,
      ROOT(runtime, mutable_array_buffer_species)));
  set_array_buffer_elements(result, elements);
  set_array_buffer_length(result, 0);
  return post_create_sanity_check(result, size);
}
コード例 #5
0
ファイル: alloc.c プロジェクト: plesner/neutrino
value_t new_heap_mutable_roots(runtime_t *runtime) {
  TRY_DEF(argument_map_trie_root, new_heap_argument_map_trie(runtime,
      ROOT(runtime, empty_array)));
  size_t size = kMutableRootsSize;
  TRY_DEF(result, alloc_heap_object(runtime, size,
      ROOT(runtime, mutable_mutable_roots_species)));
  RAW_MROOT(result, argument_map_trie_root) = argument_map_trie_root;
  return result;
}
コード例 #6
0
ファイル: bind.c プロジェクト: plesner/neutrino
// Executes an is declaration on the given fragment.
static value_t apply_is_declaration(runtime_t *runtime, value_t decl,
    value_t fragment) {
  CHECK_FAMILY(ofIsDeclarationAst, decl);
  CHECK_FAMILY(ofModuleFragment, fragment);
  value_t subtype_ast = get_is_declaration_ast_subtype(decl);
  value_t supertype_ast = get_is_declaration_ast_supertype(decl);
  TRY_DEF(subtype, quick_and_dirty_evaluate_syntax(runtime, fragment, subtype_ast));
  TRY_DEF(supertype, quick_and_dirty_evaluate_syntax(runtime, fragment, supertype_ast));
  value_t methodspace = get_module_fragment_methodspace(fragment);
  TRY(add_methodspace_inheritance(runtime, methodspace, subtype, supertype));
  return success();
}
コード例 #7
0
ファイル: bind.c プロジェクト: plesner/neutrino
value_t build_bound_module(value_t ambience, value_t unbound_module) {
  runtime_t *runtime = get_ambience_runtime(ambience);
  binding_context_t context;
  binding_context_init(&context, ambience);
  TRY_SET(context.bound_module_map, new_heap_id_hash_map(runtime, 16));
  TRY_DEF(modules, build_transitive_module_array(runtime, unbound_module));
  TRY(build_fragment_entry_map(&context, modules));
  TRY_DEF(schedule, build_binding_schedule(&context));
  TRY(execute_binding_schedule(&context, schedule));
  value_t path = get_unbound_module_path(unbound_module);
  value_t result = get_id_hash_map_at(context.bound_module_map, path);
  CHECK_FALSE("module missing", in_condition_cause(ccNotFound, result));
  return result;
}
コード例 #8
0
ファイル: bind.c プロジェクト: plesner/neutrino
// Adds a namespace binding based on the given declaration ast in the given
// fragment's namespace.
static value_t apply_namespace_declaration(value_t ambience, value_t decl,
    value_t fragment) {
  CHECK_FAMILY(ofAmbience, ambience);
  CHECK_FAMILY(ofNamespaceDeclarationAst, decl);
  CHECK_FAMILY(ofModuleFragment, fragment);
  runtime_t *runtime = get_ambience_runtime(ambience);
  value_t value_syntax = get_namespace_declaration_ast_value(decl);
  TRY_DEF(code_block, compile_expression(runtime, value_syntax, fragment,
      scope_get_bottom()));
  TRY_DEF(value, run_code_block_until_condition(ambience, code_block));
  value_t nspace = get_module_fragment_namespace(fragment);
  value_t path = get_namespace_declaration_ast_path(decl);
  TRY(set_namespace_binding_at(runtime, nspace, path, value));
  return success();
}
コード例 #9
0
ファイル: bind.c プロジェクト: plesner/neutrino
value_t build_binding_schedule(binding_context_t *context) {
  runtime_t *runtime = get_ambience_runtime(context->ambience);
  TRY_DEF(schedule, new_heap_array_buffer(runtime, 16));
  TRY_DEF(all_fragments, build_fragment_identifier_array(context));
  loop: do {
    for (size_t i = 0; i < get_array_buffer_length(all_fragments); i++) {
      value_t ident = get_array_buffer_at(all_fragments, i);
      if (should_fragment_be_bound(context, schedule, ident)) {
        TRY(add_to_array_buffer(runtime, schedule, ident));
        goto loop;
      }
    }
  } while (false);
  return schedule;
}
コード例 #10
0
ファイル: bind.c プロジェクト: plesner/neutrino
static value_t run_expression_until_condition(value_t ambience, value_t fragment,
    value_t expr) {
  runtime_t *runtime = get_ambience_runtime(ambience);
  TRY_DEF(code_block, compile_expression(runtime, expr, fragment,
      scope_get_bottom()));
  return run_code_block_until_condition(ambience, code_block);
}
コード例 #11
0
ファイル: bind.c プロジェクト: plesner/neutrino
// Creates a new empty but suitably initialized bound module fragment.
static value_t new_empty_module_fragment(runtime_t *runtime, value_t stage,
    value_t module) {
  TRY_DEF(empty_fragment, new_heap_module_fragment(runtime, module, stage,
      nothing(), nothing(), nothing()));
  TRY(init_empty_module_fragment(runtime, empty_fragment));
  return empty_fragment;
}
コード例 #12
0
ファイル: alloc.c プロジェクト: plesner/neutrino
value_t new_heap_pair(runtime_t *runtime, value_t e0, value_t e1) {
  TRY_DEF(result, new_heap_array(runtime, 2));
  set_array_at(result, 0, e0);
  set_array_at(result, 1, e1);
  TRY(ensure_frozen(runtime, result));
  return result;
}
コード例 #13
0
ファイル: alloc.c プロジェクト: plesner/neutrino
value_t new_heap_reference(runtime_t *runtime, value_t value) {
  size_t size = kReferenceSize;
  TRY_DEF(result, alloc_heap_object(runtime, size,
      ROOT(runtime, mutable_reference_species)));
  set_reference_value(result, value);
  return post_create_sanity_check(result, size);
}
コード例 #14
0
ファイル: alloc.c プロジェクト: plesner/neutrino
value_t new_heap_uninitialized_roots(runtime_t *runtime) {
  size_t size = kRootsSize;
  TRY_DEF(result, alloc_heap_object(runtime, size, whatever()));
  for (size_t i = 0; i < kRootCount; i++)
    *access_heap_object_field(result, HEAP_OBJECT_FIELD_OFFSET(i)) = whatever();
  return result;
}
コード例 #15
0
ファイル: bind.c プロジェクト: plesner/neutrino
// Builds an array buffer containing all the modules that are needed to load
// the given unbound module (which is itself added to the array too).
static value_t build_transitive_module_array(runtime_t *runtime,
    value_t unbound_module) {
  CHECK_FAMILY(ofUnboundModule, unbound_module);
  TRY_DEF(result, new_heap_array_buffer(runtime, 16));
  TRY(ensure_module_in_array(runtime, result, unbound_module));
  return result;
}
コード例 #16
0
ファイル: alloc.c プロジェクト: plesner/neutrino
value_t new_heap_string(runtime_t *runtime, string_t *contents) {
  size_t size = calc_string_size(string_length(contents));
  TRY_DEF(result, alloc_heap_object(runtime, size,
      ROOT(runtime, string_species)));
  set_string_length(result, string_length(contents));
  string_copy_to(contents, get_string_chars(result), string_length(contents) + 1);
  return post_create_sanity_check(result, size);
}
コード例 #17
0
ファイル: alloc.c プロジェクト: plesner/neutrino
value_t new_heap_array(runtime_t *runtime, size_t length) {
  size_t size = calc_array_size(length);
  TRY_DEF(result, alloc_heap_object(runtime, size,
      ROOT(runtime, mutable_array_species)));
  set_array_length(result, length);
  for (size_t i = 0; i < length; i++)
    set_array_at(result, i, null());
  return post_create_sanity_check(result, size);
}
コード例 #18
0
ファイル: alloc.c プロジェクト: plesner/neutrino
value_t new_heap_array_buffer_with_contents(runtime_t *runtime, value_t elements) {
  CHECK_FAMILY(ofArray, elements);
  size_t size = kArrayBufferSize;
  TRY_DEF(result, alloc_heap_object(runtime, size,
      ROOT(runtime, mutable_array_buffer_species)));
  set_array_buffer_elements(result, elements);
  set_array_buffer_length(result, get_array_length(elements));
  return post_create_sanity_check(result, size);
}
コード例 #19
0
ファイル: alloc.c プロジェクト: plesner/neutrino
value_t new_heap_triple(runtime_t *runtime, value_t e0, value_t e1,
    value_t e2) {
  TRY_DEF(result, new_heap_array(runtime, 3));
  set_array_at(result, 0, e0);
  set_array_at(result, 1, e1);
  set_array_at(result, 2, e2);
  TRY(ensure_frozen(runtime, result));
  return result;
}
コード例 #20
0
ファイル: alloc.c プロジェクト: plesner/neutrino
value_t new_heap_compact_species(runtime_t *runtime, family_behavior_t *behavior) {
  size_t bytes = kCompactSpeciesSize;
  TRY_DEF(result, alloc_heap_object(runtime, bytes,
      ROOT(runtime, mutable_species_species)));
  set_species_instance_family(result, behavior->family);
  set_species_family_behavior(result, behavior);
  set_species_division_behavior(result, &kCompactSpeciesBehavior);
  return post_create_sanity_check(result, bytes);
}
コード例 #21
0
ファイル: alloc.c プロジェクト: plesner/neutrino
value_t new_heap_blob_with_data(runtime_t *runtime, blob_t *contents) {
  // Allocate the blob object to hold the data.
  TRY_DEF(blob, new_heap_blob(runtime, blob_byte_length(contents)));
  // Pull out the contents of the heap blob.
  blob_t blob_data;
  get_blob_data(blob, &blob_data);
  // Copy the contents into the heap blob.
  blob_copy_to(contents, &blob_data);
  return blob;
}
コード例 #22
0
ファイル: alloc.c プロジェクト: plesner/neutrino
value_t new_heap_blob(runtime_t *runtime, size_t length) {
  size_t size = calc_blob_size(length);
  TRY_DEF(result, alloc_heap_object(runtime, size,
      ROOT(runtime, blob_species)));
  set_blob_length(result, length);
  blob_t data;
  get_blob_data(result, &data);
  blob_fill(&data, 0);
  return post_create_sanity_check(result, size);
}
コード例 #23
0
ファイル: interp.c プロジェクト: plesner/neutrino
// Runs the given stack until it hits a condition or completes successfully.
static value_t run_stack_until_condition(value_t ambience, value_t stack) {
    value_t result = run_stack_pushing_signals(ambience, stack);
    if (in_condition_cause(ccSignal, result)) {
        runtime_t *runtime = get_ambience_runtime(ambience);
        frame_t frame = open_stack(stack);
        TRY_DEF(trace, capture_backtrace(runtime, &frame));
        print_ln("%9v", trace);
    }
    return result;
}
コード例 #24
0
ファイル: bind.c プロジェクト: plesner/neutrino
// Checks whether a fragment entry for the given stage and path already exists
// and if not creates it.
static value_t binding_context_ensure_fragment_entry(binding_context_t *context,
    value_t stage, value_t path, value_t fragment, bool *created) {
  CHECK_PHYLUM(tpStageOffset, stage);
  CHECK_FAMILY(ofPath, path);
  CHECK_FAMILY_OPT(ofUnboundModuleFragment, fragment);
  value_t path_map = context->fragment_entry_map;
  runtime_t *runtime = get_ambience_runtime(context->ambience);
  if (!has_id_hash_map_at(path_map, path)) {
    TRY_DEF(stage_map, new_heap_id_hash_map(runtime, 16));
    TRY(set_id_hash_map_at(runtime, path_map, path, stage_map));
  }
  value_t stage_map = get_id_hash_map_at(path_map, path);
  if (!has_id_hash_map_at(stage_map, stage)) {
    TRY_DEF(imports, new_heap_array_buffer(runtime, 4));
    TRY_DEF(ident, new_heap_identifier(runtime, stage, path));
    TRY_DEF(entry, new_heap_triple(runtime, fragment, imports, ident));
    TRY(set_id_hash_map_at(runtime, stage_map, stage, entry));
    *created = true;
  }
  return get_id_hash_map_at(stage_map, stage);
}
コード例 #25
0
ファイル: bind.c プロジェクト: plesner/neutrino
// Reads a library from the given library path and adds the modules to this
// loaders set of available modules.
static value_t module_loader_read_library(runtime_t *runtime, value_t self,
    value_t library_path) {
  // Read the library from the file.
  string_t library_path_str;
  get_string_contents(library_path, &library_path_str);
  TRY_DEF(data, read_file_to_blob(runtime, &library_path_str));
  TRY_DEF(library, runtime_plankton_deserialize(runtime, data));
  if (!in_family(ofLibrary, library))
    return new_invalid_input_condition();
  set_library_display_name(library, library_path);
  // Load all the modules from the library into this module loader.
  id_hash_map_iter_t iter;
  id_hash_map_iter_init(&iter, get_library_modules(library));
  while (id_hash_map_iter_advance(&iter)) {
    value_t key;
    value_t value;
    id_hash_map_iter_get_current(&iter, &key, &value);
    TRY(set_id_hash_map_at(runtime, get_module_loader_modules(self), key, value));
  }
  return success();
}
コード例 #26
0
ファイル: alloc.c プロジェクト: plesner/neutrino
value_t new_heap_modal_species_unchecked(runtime_t *runtime,
    family_behavior_t *behavior, value_mode_t mode, root_key_t base_root) {
  size_t size = kModalSpeciesSize;
  TRY_DEF(result, alloc_heap_object(runtime, size,
      ROOT(runtime, mutable_species_species)));
  set_species_instance_family(result, behavior->family);
  set_species_family_behavior(result, behavior);
  set_species_division_behavior(result, &kModalSpeciesBehavior);
  set_modal_species_mode(result, mode);
  set_modal_species_base_root(result, base_root);
  return result;
}
コード例 #27
0
ファイル: alloc.c プロジェクト: plesner/neutrino
value_t new_heap_instance_species(runtime_t *runtime, value_t primary,
    value_t manager) {
  size_t size = kInstanceSpeciesSize;
  CHECK_FAMILY(ofType, primary);
  CHECK_FAMILY_OPT(ofInstanceManager, manager);
  TRY_DEF(result, alloc_heap_object(runtime, size,
      ROOT(runtime, mutable_species_species)));
  set_species_instance_family(result, ofInstance);
  set_species_family_behavior(result, &kInstanceBehavior);
  set_species_division_behavior(result, &kInstanceSpeciesBehavior);
  set_instance_species_primary_type_field(result, primary);
  set_instance_species_manager(result, manager);
  return post_create_sanity_check(result, size);
}
コード例 #28
0
ファイル: bind.c プロジェクト: plesner/neutrino
// Given an array of modules map builds a two-level map from paths to stages to
// fragment entries.
static value_t build_real_fragment_entries(binding_context_t *context,
    value_t modules) {
  runtime_t *runtime = get_ambience_runtime(context->ambience);
  for (size_t mi = 0; mi < get_array_buffer_length(modules); mi++) {
    value_t module = get_array_buffer_at(modules, mi);
    value_t path = get_unbound_module_path(module);
    value_t fragments = get_unbound_module_fragments(module);
    for (size_t fi = 0; fi < get_array_length(fragments); fi++) {
      value_t fragment = get_array_at(fragments, fi);
      value_t stage = get_unbound_module_fragment_stage(fragment);
      bool dummy = false;
      TRY_DEF(entry, binding_context_ensure_fragment_entry(context, stage,
          path, fragment, &dummy));
      value_t imports = get_fragment_entry_imports(entry);
      value_t fragment_imports = get_unbound_module_fragment_imports(fragment);
      for (size_t ii = 0; ii < get_array_length(fragment_imports); ii++) {
        value_t import = get_array_at(fragment_imports, ii);
        TRY_DEF(ident, new_heap_identifier(runtime, present_stage(), import));
        TRY(ensure_array_buffer_contains(runtime, imports, ident));
      }
    }
  }
  return success();
}
コード例 #29
0
ファイル: method.c プロジェクト: tundra/neutrino
value_t build_call_tags_entries(runtime_t *runtime, value_t tags) {
  int64_t tag_count = get_array_length(tags);
  TRY_DEF(result, new_heap_pair_array(runtime, tag_count));
  for (int64_t i = 0; i < tag_count; i++) {
    set_pair_array_first_at(result, i, get_array_at(tags, i));
    // The offset is counted backwards because the argument evaluated last will
    // be at the top of the stack, that is, offset 0, and the first will be at
    // the bottom so has the highest offset.
    int64_t offset = tag_count - i - 1;
    set_pair_array_second_at(result, i, new_integer(offset));
  }
  TRY(co_sort_pair_array(result));
  IF_EXPENSIVE_CHECKS_ENABLED(check_call_tags_entries_unique(result));
  return result;
}
コード例 #30
0
ファイル: method.c プロジェクト: tundra/neutrino
static value_t create_methodspace_selector_slice(runtime_t *runtime, value_t self,
    value_t selector) {
  TRY_DEF(result, new_heap_signature_map(runtime));
  value_t current = self;
  while (!is_nothing(current)) {
    value_t methods = get_methodspace_methods(current);
    value_t entries = get_signature_map_entries(methods);
    for (int64_t i = 0; i < get_pair_array_buffer_length(entries); i++) {
      value_t signature = get_pair_array_buffer_first_at(entries, i);
      if (can_match_eq(signature, ROOT(runtime, selector_key), selector)) {
        value_t method = get_pair_array_buffer_second_at(entries, i);
        TRY(add_to_signature_map(runtime, result, signature, method));
      }
    }
    current = get_methodspace_parent(current);
  }
  return result;
}