Example #1
0
static value_t heap_object_identity_compare(value_t a, value_t b,
    cycle_detector_t *detector) {
  CHECK_DOMAIN(vdHeapObject, a);
  CHECK_DOMAIN(vdHeapObject, b);
  // Fast case when a and b are the same object.
  if (is_same_value(a, b))
    return yes();
  heap_object_family_t a_family = get_heap_object_family(a);
  heap_object_family_t b_family = get_heap_object_family(b);
  if (a_family != b_family)
    return no();
  family_behavior_t *behavior = get_heap_object_family_behavior(a);
  return (behavior->identity_compare)(a, b, detector);
}
Example #2
0
static value_t custom_tagged_ordering_compare(value_t a, value_t b) {
  CHECK_DOMAIN(vdCustomTagged, a);
  CHECK_DOMAIN(vdCustomTagged, b);
  custom_tagged_phylum_t a_phylum = get_custom_tagged_phylum(a);
  custom_tagged_phylum_t b_phylum = get_custom_tagged_phylum(b);
  if (a_phylum != b_phylum)
    return compare_signed_integers(a_phylum, b_phylum);
  phylum_behavior_t *behavior = get_custom_tagged_phylum_behavior(a_phylum);
  value_t (*ordering_compare)(value_t a, value_t b) = behavior->ordering_compare;
  if (ordering_compare == NULL) {
    return unordered();
  } else {
    return ordering_compare(a, b);
  }
}
Example #3
0
static value_t integer_transient_identity_hash(value_t self,
    hash_stream_t *stream) {
  CHECK_DOMAIN(vdInteger, self);
  hash_stream_write_tags(stream, vdInteger, __ofUnknown__);
  hash_stream_write_int64(stream, get_integer_value(self));
  return success();
}
Example #4
0
// Checks whether to fire the next barrier on the way to the given destination.
// If there is a barrier to fire, fire it. Returns false iff a barrier was fired,
// true if we've arrived at the destination.
static bool maybe_fire_next_barrier(code_cache_t *cache, frame_t *frame,
                                    runtime_t *runtime, value_t stack, value_t destination) {
    CHECK_DOMAIN(vdDerivedObject, destination);
    value_t next_barrier = get_stack_top_barrier(stack);
    if (is_same_value(next_barrier, destination)) {
        // We've arrived.
        return true;
    }
    // Grab the next barrier's handler.
    value_t payload = get_barrier_state_payload(next_barrier);
    value_t previous = get_barrier_state_previous(next_barrier);
    // Unhook the barrier from the barrier stack.
    set_stack_top_barrier(stack, previous);
    // Fire the exit action for the handler object.
    if (in_genus(dgEnsureSection, next_barrier)) {
        // Pop any previous state off the stack. If we've executed any
        // code shards before the first will be the result from the shard
        // the second will be the shard itself.
        frame_pop_value(frame);
        frame_pop_value(frame);
        // Push the shard onto the stack as the subject since we may need it
        // to refract access to outer variables.
        frame_push_value(frame, next_barrier);
        value_t argmap = ROOT(runtime, array_of_zero);
        value_t code_block = payload;
        push_stack_frame(runtime, stack, frame,
                         get_code_block_high_water_mark(code_block), argmap);
        frame_set_code_block(frame, code_block);
        code_cache_refresh(cache, frame);
    } else {
        on_derived_object_exit(next_barrier);
    }
    return false;
}
Example #5
0
static value_t object_ordering_compare(value_t a, value_t b) {
  CHECK_DOMAIN(vdHeapObject, a);
  CHECK_DOMAIN(vdHeapObject, b);
  heap_object_family_t a_family = get_heap_object_family(a);
  heap_object_family_t b_family = get_heap_object_family(b);
  if (a_family != b_family)
    // This may cause us to return a valid result even when a and b are not
    // comparable.
    return compare_signed_integers(a_family, b_family);
  family_behavior_t *behavior = get_heap_object_family_behavior(a);
  value_t (*ordering_compare)(value_t a, value_t b) = behavior->ordering_compare;
  if (ordering_compare == NULL) {
    return unordered();
  } else {
    return ordering_compare(a, b);
  }
}
Example #6
0
static value_t custom_tagged_transient_identity_hash(value_t self,
    hash_stream_t *stream) {
  CHECK_DOMAIN(vdCustomTagged, self);
  hash_stream_write_tags(stream, vdCustomTagged, __ofUnknown__);
  hash_stream_write_int64(stream, get_custom_tagged_phylum(self));
  hash_stream_write_int64(stream, get_custom_tagged_payload(self));
  return success();
}
Example #7
0
value_t finalize_heap_object(value_t garbage) {
  CHECK_DOMAIN(vdHeapObject, garbage);
  value_t header = get_heap_object_header(garbage);
  CHECK_FALSE("finalizing live object", in_domain(vdMovedObject, header));
  family_behavior_t *behavior = get_species_family_behavior(header);
  garbage_value_t wrapper = {garbage};
  CHECK_FALSE("finalizing object without finalizer", behavior->finalize == NULL);
  return (behavior->finalize(wrapper));
}
Example #8
0
void get_heap_object_layout(value_t self, heap_object_layout_t *layout_out) {
  // This has to work during gc so some of the normal behavior checks are
  // disabled.
  CHECK_DOMAIN(vdHeapObject, self);
  // We only get the layout of objects that have already been moved so this
  // gives a proper species.
  value_t species = get_heap_object_species(self);
  // The species itself may have been moved but in any its memory will still be
  // intact enough that we can get the behavior out.
  family_behavior_t *behavior = get_species_family_behavior(species);
  (behavior->get_heap_object_layout)(self, layout_out);
}
Example #9
0
phylum_behavior_t *get_custom_tagged_behavior(value_t value) {
  CHECK_DOMAIN(vdCustomTagged, value);
  custom_tagged_phylum_t phylum = get_custom_tagged_phylum(value);
  return get_custom_tagged_phylum_behavior(phylum);
}
Example #10
0
void on_derived_object_exit(value_t self) {
  CHECK_DOMAIN(vdDerivedObject, self);
  genus_descriptor_t *descriptor = get_derived_object_descriptor(self);
  CHECK_TRUE("derived object not scoped", descriptor->on_scope_exit != NULL);
  (descriptor->on_scope_exit)(self);
}
Example #11
0
static void derived_object_print_on(value_t value, print_on_context_t *context) {
  CHECK_DOMAIN(vdDerivedObject, value);
  derived_object_genus_t genus = get_derived_object_genus(value);
  genus_descriptor_t *descriptor = get_genus_descriptor(genus);
  (descriptor->print_on)(value, context);
}
Example #12
0
static void custom_tagged_print_on(value_t value, print_on_context_t *context) {
  CHECK_DOMAIN(vdCustomTagged, value);
  phylum_behavior_t *behavior = get_custom_tagged_behavior(value);
  (behavior->print_on)(value, context);
}
Example #13
0
static void heap_object_print_on(value_t value, print_on_context_t *context) {
  CHECK_DOMAIN(vdHeapObject, value);
  family_behavior_t *behavior = get_heap_object_family_behavior(value);
  (behavior->print_on)(value, context);
}
Example #14
0
static void condition_print_on(value_t value, string_buffer_t *buf) {
  CHECK_DOMAIN(vdCondition, value);
  condition_cause_t cause = get_condition_cause(value);
  const char *cause_name = get_condition_cause_name(cause);
  string_buffer_printf(buf, "%%<condition: %s(", cause_name);
  uint32_t details = get_condition_details(value);
  switch (cause) {
    case ccInvalidSyntax: {
      invalid_syntax_cause_t cause = (invalid_syntax_cause_t) details;
      string_buffer_printf(buf, "%s", get_invalid_syntax_cause_name(cause));
      break;
    }
    case ccUnsupportedBehavior: {
      unsupported_behavior_details_codec_t codec;
      codec.encoded = details;
      unsupported_behavior_cause_t cause = (unsupported_behavior_cause_t) codec.decoded.cause;
      string_buffer_printf(buf, "%s", get_unsupported_behavior_cause_name(cause));
      value_type_info_t type = value_type_info_decode(codec.decoded.type_info);
      string_buffer_printf(buf, " of %s", value_type_info_name(type));
      break;
    }
    case ccLookupError: {
      lookup_error_cause_t cause = (lookup_error_cause_t) details;
      string_buffer_printf(buf, "%s", get_lookup_error_cause_name(cause));
      break;
    }
    case ccSystemError: {
      system_error_cause_t cause = (system_error_cause_t) details;
      string_buffer_printf(buf, "%s", get_system_error_cause_name(cause));
      break;
    }
    case ccInvalidInput: {
      if (details != 0) {
        // If no hint is given (or the hint it the empty string) the details
        // field will be 0.
        invalid_input_details_codec_t codec;
        codec.encoded = details;
        char hint[7];
        string_hint_to_c_str(codec.decoded, hint);
        string_buffer_printf(buf, "%s", hint);
      }
      break;
    }
    case ccNotSerializable: {
      value_type_info_t type = value_type_info_decode((uint16_t) details);
      string_buffer_printf(buf, "%s", value_type_info_name(type));
      break;
    }
    case ccUnexpectedType: {
      unexpected_type_info_codec_t codec;
      codec.encoded = details;
      value_type_info_t expected = value_type_info_decode(codec.decoded.expected);
      if (!value_type_info_is_empty(expected))
        // It's okay to leave out the expected type, we skip printing it if it's
        // not there.
        string_buffer_printf(buf, "expected: %s, ", value_type_info_name(expected));
      value_type_info_t found = value_type_info_decode(codec.decoded.found);
      string_buffer_printf(buf, "found: %s", value_type_info_name(found));
      break;
    }
    case ccUncaughtSignal: {
      string_buffer_printf(buf, is_uncaught_signal_escape(value) ? "escape" : "non-escape");
      break;
    }
    default: {
      string_buffer_printf(buf, "dt@%i", details);
      break;
    }
  }
  string_buffer_printf(buf, ")>");
}
Example #15
0
static void integer_print_on(value_t value, print_on_context_t *context) {
  CHECK_DOMAIN(vdInteger, value);
  const char *fmt = (context->flags & pfHex) ? "%llx" : "%lli";
  string_buffer_printf(context->buf, fmt, get_integer_value(value));
}