示例#1
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();
}
示例#2
0
文件: method.c 项目: tundra/neutrino
value_t add_to_signature_map(runtime_t *runtime, value_t map, value_t signature,
    value_t value) {
  CHECK_FAMILY(ofSignatureMap, map);
  CHECK_FAMILY(ofSignature, signature);
  value_t entries = get_signature_map_entries(map);
  TRY(add_to_pair_array_buffer(runtime, entries, signature, value));
  return success();
}
示例#3
0
文件: method.c 项目: tundra/neutrino
value_t add_methodspace_method(runtime_t *runtime, value_t self,
    value_t method) {
  CHECK_FAMILY(ofMethodspace, self);
  CHECK_MUTABLE(self);
  CHECK_FAMILY(ofMethod, method);
  invalidate_methodspace_caches(self);
  value_t signature = get_method_signature(method);
  return add_to_signature_map(runtime, get_methodspace_methods(self), signature,
      method);
}
示例#4
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();
}
示例#5
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();
}
示例#6
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;
}
示例#7
0
文件: bind.c 项目: plesner/neutrino
// Binds an individual module fragment.
static value_t bind_module_fragment(binding_context_t *context,
    value_t entry, value_t bound_fragment) {
  CHECK_FAMILY(ofModuleFragment, bound_fragment);
  value_t unbound_fragment = get_fragment_entry_fragment(entry);
  value_t imports = get_fragment_entry_imports(entry);
  if (!is_nothing(unbound_fragment)) {
    // This is a real fragment so we have to apply the entries.
    CHECK_FAMILY(ofUnboundModuleFragment, unbound_fragment);
    CHECK_EQ("fragment already bound", feUnbound,
        get_module_fragment_epoch(bound_fragment));
    set_module_fragment_epoch(bound_fragment, feBinding);
    TRY(bind_module_fragment_imports(context, imports, bound_fragment));
    TRY(apply_module_fragment_elements(context, unbound_fragment, bound_fragment));
  }
  set_module_fragment_epoch(bound_fragment, feComplete);
  return success();
}
示例#8
0
文件: method.c 项目: tundra/neutrino
void parameter_print_on(value_t self, print_on_context_t *context) {
  CHECK_FAMILY(ofParameter, self);
  string_buffer_printf(context->buf, "#<parameter: gd@");
  // We know the guard is a guard, not a parameter, so this can't cause a cycle.
  value_print_inner_on(get_parameter_guard(self), context, -1);
  string_buffer_printf(context->buf, ", op@%i, ix@%i>",
      get_parameter_is_optional(self), get_parameter_index(self));
}
示例#9
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);
}
示例#10
0
文件: bind.c 项目: plesner/neutrino
value_t module_loader_process_options(runtime_t *runtime, value_t self,
    value_t options) {
  CHECK_FAMILY(ofIdHashMap, options);
  value_t libraries = get_id_hash_map_at_with_default(options, RSTR(runtime, libraries),
      ROOT(runtime, empty_array));
  for (size_t i = 0; i < get_array_length(libraries); i++) {
    value_t library_path = get_array_at(libraries, i);
    TRY(module_loader_read_library(runtime, self, library_path));
  }
  return success();
}
示例#11
0
文件: method.c 项目: tundra/neutrino
value_t add_methodspace_inheritance(runtime_t *runtime, value_t self,
    value_t subtype, value_t supertype) {
  CHECK_FAMILY(ofMethodspace, self);
  CHECK_MUTABLE(self);
  CHECK_FAMILY(ofType, subtype);
  CHECK_FAMILY(ofType, supertype);
  value_t inheritance = get_methodspace_inheritance(self);
  value_t parents = get_id_hash_map_at(inheritance, subtype);
  if (in_condition_cause(ccNotFound, parents)) {
    // Make the parents buffer small since most types don't have many direct
    // parents. If this fails nothing has happened.
    TRY_SET(parents, new_heap_array_buffer(runtime, 4));
    // If this fails we've wasted some space allocating the parents array but
    // otherwise nothing has happened.
    TRY(set_id_hash_map_at(runtime, inheritance, subtype, parents));
  }
  // If this fails we may have set the parents array of the subtype to an empty
  // array which is awkward but okay.
  invalidate_methodspace_caches(self);
  return add_to_array_buffer(runtime, parents, supertype);
}
示例#12
0
文件: method.c 项目: tundra/neutrino
static value_t call_data_get(builtin_arguments_t *args) {
  value_t self = get_builtin_subject(args);
  CHECK_FAMILY(ofCallData, self);
  value_t needle = get_builtin_argument(args, 0);
  value_t tags = get_call_data_tags(self);
  for (int64_t i = 0; i < get_call_tags_entry_count(tags); i++) {
    value_t tag = get_call_tags_tag_at(tags, i);
    if (value_identity_compare(needle, tag))
      return get_call_data_value_at(self, i);
  }
  ESCAPE_BUILTIN(args, no_such_tag, needle);
}
示例#13
0
文件: bind.c 项目: plesner/neutrino
// Returns true iff the given identifier is $:core.
static bool is_present_core(runtime_t *runtime, value_t ident) {
  CHECK_FAMILY(ofIdentifier, ident);
  value_t path = get_identifier_path(ident);
  value_t stage = get_identifier_stage(ident);
  if (get_stage_offset_value(stage) != 0)
    // Not present.
    return false;
  if (is_path_empty(path) || !is_path_empty(get_path_tail(path)))
    // Not length 1.
    return false;
  value_t head = get_path_head(path);
  return value_identity_compare(head, RSTR(runtime, core));
}
示例#14
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);
}
示例#15
0
文件: bind.c 项目: plesner/neutrino
// Performs the appropriate action for a fragment element to the given fragment.
static value_t apply_unbound_fragment_element(value_t ambience, value_t element,
    value_t fragment) {
  CHECK_FAMILY(ofAmbience, ambience);
  heap_object_family_t family = get_heap_object_family(element);
  switch (family) {
    case ofNamespaceDeclarationAst:
      return apply_namespace_declaration(ambience, element, fragment);
    case ofMethodDeclarationAst:
      return apply_method_declaration(ambience, element, fragment);
    case ofIsDeclarationAst:
      return apply_is_declaration(get_ambience_runtime(ambience), element, fragment);
    default:
      ERROR("Invalid toplevel element %s", get_heap_object_family_name(family));
      return success();
  }
}
示例#16
0
文件: method.c 项目: tundra/neutrino
void guard_print_on(value_t self, print_on_context_t *context) {
  CHECK_FAMILY(ofGuard, self);
  switch (get_guard_type(self)) {
    case gtEq:
      string_buffer_printf(context->buf, "eq(");
      value_print_inner_on(get_guard_value(self), context, -1);
      string_buffer_printf(context->buf, ")");
      break;
    case gtIs:
      string_buffer_printf(context->buf, "is(");
      value_print_inner_on(get_guard_value(self), context, -1);
      string_buffer_printf(context->buf, ")");
      break;
    case gtAny:
      string_buffer_printf(context->buf, "any()");
      break;
  }
}
示例#17
0
value_t push_stack_frame(runtime_t *runtime, value_t stack, frame_t *frame,
    size_t frame_capacity, value_t arg_map) {
  CHECK_FAMILY(ofStack, stack);
  value_t top_piece = get_stack_top_piece(stack);
  CHECK_FALSE("stack piece closed", is_stack_piece_closed(top_piece));
  if (!try_push_new_frame(frame, frame_capacity, ffOrganic, false)) {
    // There wasn't room to push this frame onto the top stack piece so
    // allocate a new top piece that definitely has room.
    size_t default_capacity = get_stack_default_piece_capacity(stack);
    size_t transfer_arg_count = get_array_length(arg_map);
    size_t required_capacity
        = frame_capacity          // the new frame's locals
        + kFrameHeaderSize        // the new frame's header
        + 1                       // the synthetic bottom frame's one local
        + kFrameHeaderSize        // the synthetic bottom frame's header
        + transfer_arg_count;     // any arguments to be copied onto the piece
    size_t new_capacity = max_size(default_capacity, required_capacity);

    // Create and initialize the new stack segment. The frame struct is still
    // pointing to the old frame.
    TRY_DEF(new_piece, new_heap_stack_piece(runtime, new_capacity, top_piece,
        stack));
    push_stack_piece_bottom_frame(runtime, new_piece, arg_map);
    transfer_top_arguments(new_piece, frame, transfer_arg_count);
    set_stack_top_piece(stack, new_piece);

    // Close the previous stack piece, recording the frame state.
    close_frame(frame);

    // Finally, create a new frame on the new stack which includes updating the
    // struct. The required_capacity calculation ensures that this call will
    // succeed.
    open_stack_piece(new_piece, frame);
    bool pushed_stack_piece = try_push_new_frame(frame, frame_capacity,
        ffOrganic, false);
    if (!pushed_stack_piece)
      try_push_new_frame(frame, frame_capacity,
              ffOrganic, false);
    CHECK_TRUE("pushing on new piece failed", pushed_stack_piece);
  }
  frame_set_argument_map(frame, arg_map);
  return success();
}
示例#18
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);
}
示例#19
0
文件: bind.c 项目: plesner/neutrino
// Ensures that the given unbound module is in the given array buffer, as well
// as any other modules imported by the module.
static value_t ensure_module_in_array(runtime_t *runtime, value_t array,
    value_t unbound_module) {
  CHECK_FAMILY(ofUnboundModule, unbound_module);
  if (in_array_buffer(array, unbound_module))
    // If it's already there there's nothing to do.
    return success();
  // Add the module.
  TRY(add_to_array_buffer(runtime, array, unbound_module));
  // Scan through the imports and recursively add imported modules. Which
  // stage the module is imported into doesn't matter at this point, we just
  // have to enumerate them.
  value_t unbound_fragments = get_unbound_module_fragments(unbound_module);
  for (size_t fi = 0; fi < get_array_length(unbound_fragments); fi++) {
    value_t unbound_fragment = get_array_at(unbound_fragments, fi);
    value_t imports = get_unbound_module_fragment_imports(unbound_fragment);
    for (size_t ii = 0; ii < get_array_length(imports); ii++) {
      value_t import = get_array_at(imports, ii);
      TRY_DEF(imported_module, module_loader_lookup_module(
          deref(runtime->module_loader), import));
      TRY(ensure_module_in_array(runtime, array, imported_module));
    }
  }
  return success();
}
示例#20
0
文件: method.c 项目: tundra/neutrino
value_t guard_match(value_t guard, value_t value, runtime_t *runtime,
    value_t space, value_t *score_out) {
  CHECK_FAMILY(ofGuard, guard);
  switch (get_guard_type(guard)) {
    case gtEq: {
      value_t guard_value = get_guard_value(guard);
      bool match = value_identity_compare(guard_value, value);
      *score_out = match ? new_identical_match_score() : new_no_match_score();
      return success();
    }
    case gtIs: {
      TRY_DEF(primary, get_primary_type(value, runtime));
      value_t target = get_guard_value(guard);
      return find_best_match(runtime, primary, target,
          new_perfect_is_match_score(), space, score_out);
    }
    case gtAny:
      *score_out = new_any_match_score();
      return success();
    default:
      UNREACHABLE("Unknown guard type");
      return new_condition(ccWat);
  }
}
示例#21
0
文件: method.c 项目: tundra/neutrino
void builtin_implementation_print_on(value_t self, print_on_context_t *context) {
  CHECK_FAMILY(ofBuiltinImplementation, self);
  string_buffer_printf(context->buf, "#<builtin_implementation ");
  value_print_inner_on(get_builtin_implementation_name(self), context, -1);
  string_buffer_printf(context->buf, ">");
}
示例#22
0
void stack_piece_print_on(value_t value, print_on_context_t *context) {
  CHECK_FAMILY(ofStackPiece, value);
  string_buffer_printf(context->buf, "#<stack piece ~%w: st@%i>", value,
      get_stack_piece_capacity(value));
}
示例#23
0
文件: method.c 项目: tundra/neutrino
void builtin_marker_print_on(value_t self, print_on_context_t *context) {
  CHECK_FAMILY(ofBuiltinMarker, self);
  string_buffer_printf(context->buf, "#<builtin_marker ");
  value_print_inner_on(get_builtin_marker_name(self), context, -1);
  string_buffer_printf(context->buf, ">");
}
示例#24
0
文件: method.c 项目: tundra/neutrino
value_t get_signature_parameter_at(value_t self, int64_t index) {
  CHECK_FAMILY(ofSignature, self);
  return get_pair_array_second_at(get_signature_tags(self), index);
}
示例#25
0
文件: method.c 项目: tundra/neutrino
static value_t call_data_length(builtin_arguments_t *args) {
  value_t self = get_builtin_subject(args);
  CHECK_FAMILY(ofCallData, self);
  value_t values = get_call_data_values(self);
  return new_integer(get_array_length(values));
}
示例#26
0
文件: method.c 项目: tundra/neutrino
value_t get_signature_tag_at(value_t self, int64_t index) {
  CHECK_FAMILY(ofSignature, self);
  return get_pair_array_first_at(get_signature_tags(self), index);
}
示例#27
0
文件: method.c 项目: tundra/neutrino
int64_t get_call_tags_entry_count(value_t self) {
  CHECK_FAMILY(ofCallTags, self);
  value_t entries = get_call_tags_entries(self);
  return get_pair_array_length(entries);
}
示例#28
0
文件: method.c 项目: tundra/neutrino
int64_t get_call_tags_offset_at(value_t self, int64_t index) {
  CHECK_FAMILY(ofCallTags, self);
  value_t entries = get_call_tags_entries(self);
  return get_integer_value(get_pair_array_second_at(entries, index));
}
示例#29
0
文件: method.c 项目: tundra/neutrino
value_t get_call_tags_tag_at(value_t self, int64_t index) {
  CHECK_FAMILY(ofCallTags, self);
  value_t entries = get_call_tags_entries(self);
  return get_pair_array_first_at(entries, index);
}
示例#30
0
文件: method.c 项目: tundra/neutrino
int64_t get_signature_tag_count(value_t self) {
  CHECK_FAMILY(ofSignature, self);
  return get_pair_array_length(get_signature_tags(self));
}