Example #1
0
  Object* LookupTable::store(STATE, Object* key, Object* val) {
    unsigned int num_entries, num_bins, bin;
    LookupTableBucket* entry;
    LookupTableBucket* last = NULL;

    num_entries = entries_->to_native();
    num_bins = bins_->to_native();

    if(max_density_p(num_entries, num_bins)) {
      redistribute(state, num_bins <<= 1);
    }

    key_to_sym(key);
    bin = find_bin(key_hash(key), num_bins);
    entry = try_as<LookupTableBucket>(values_->at(state, bin));

    while(entry) {
      if(entry->key() == key) {
        entry->value(state, val);
        return val;
      }
      last = entry;
      entry = try_as<LookupTableBucket>(entry->next());
    }

    if(last) {
      last->next(state, LookupTableBucket::create(state, key, val));
    } else {
      values_->put(state, bin, LookupTableBucket::create(state, key, val));
    }

    entries(state, Fixnum::from(num_entries + 1));
    return val;
  }
Example #2
0
  Object* MethodTable::alias(STATE, Symbol* name, Symbol* vis,
                             Symbol* orig_name, Object* orig_method,
                             Module* orig_mod)
  {
    check_frozen(state);

    utilities::thread::SpinLock::LockGuard lg(lock_);

    Executable* orig_exec;

    if(Alias* alias = try_as<Alias>(orig_method)) {
      orig_exec = alias->original_exec();
      orig_mod = alias->original_module();
      orig_name = alias->original_name();
    } else if(orig_method->nil_p()) {
      orig_exec = nil<Executable>();
    } else {
      orig_exec = as<Executable>(orig_method);
    }

    Alias* method = Alias::create(state, orig_name, orig_mod, orig_exec);

    native_int num_entries = entries_->to_native();
    native_int num_bins = bins_->to_native();

    if(max_density_p(num_entries, num_bins)) {
      redistribute(state, num_bins <<= 1);
    }

    native_int bin = find_bin(key_hash(name), num_bins);

    MethodTableBucket* entry = try_as<MethodTableBucket>(values_->at(state, bin));
    MethodTableBucket* last = NULL;

    while(entry) {
      if(entry->name() == name) {
        entry->method_id(state, nil<String>());
        entry->method(state, method);
        entry->scope(state, cNil);
        entry->serial(state, Fixnum::from(0));
        entry->visibility(state, vis);
        return name;
      }

      last = entry;
      entry = try_as<MethodTableBucket>(entry->next());
    }

    if(last) {
      last->next(state, MethodTableBucket::create(
            state, name, nil<String>(), method, cNil, Fixnum::from(0), vis));
    } else {
      values_->put(state, bin, MethodTableBucket::create(
            state, name, nil<String>(), method, cNil, Fixnum::from(0), vis));
    }

    entries(state, Fixnum::from(num_entries + 1));
    return name;
  }
Example #3
0
  Object* MethodTable::store(STATE, Symbol* name, Object* exec, Symbol* vis)
  {
    check_frozen(state);

    utilities::thread::SpinLock::LockGuard lg(lock_);

    Executable* method;
    if(exec->nil_p()) {
      method = nil<Executable>();
    } else {
      if(Alias* stored_alias = try_as<Alias>(exec)) {
        lock_.unlock();
        Object* res = alias(state, name, vis,
                           stored_alias->original_name(),
                           stored_alias->original_exec(),
                           stored_alias->original_module());
        lock_.lock();
        return res;
      } else {
        method = as<Executable>(exec);
      }
    }

    native_int num_entries = entries_->to_native();
    native_int num_bins = bins_->to_native();

    if(max_density_p(num_entries, num_bins)) {
      redistribute(state, num_bins <<= 1);
    }

    native_int bin = find_bin(key_hash(name), num_bins);

    MethodTableBucket* entry = try_as<MethodTableBucket>(values_->at(state, bin));
    MethodTableBucket* last = NULL;

    while(entry) {
      if(entry->name() == name) {
        entry->method(state, method);
        entry->visibility(state, vis);
        return name;
      }

      last = entry;
      entry = try_as<MethodTableBucket>(entry->next());
    }

    if(last) {
      last->next(state, MethodTableBucket::create(state, name, method, vis));
    } else {
      values_->put(state, bin,
                         MethodTableBucket::create(state, name, method, vis));
    }

    entries(state, Fixnum::from(num_entries + 1));

    return name;
  }
Example #4
0
  Object* MethodTable::store(STATE, Symbol* name, Object* exec, Symbol* vis) {
    unsigned int num_entries, num_bins, bin;
    MethodTableBucket* entry;
    MethodTableBucket* last = NULL;

    Executable* method;
    if(exec->nil_p()) {
      method = reinterpret_cast<Executable*>(Qnil);
    } else {
      if(Alias* alias = try_as<Alias>(exec)) {
        method = alias->original_exec();
      } else {
        method = as<Executable>(exec);
      }
    }

    num_entries = entries_->to_native();
    num_bins = bins_->to_native();

    if(max_density_p(num_entries, num_bins)) {
      redistribute(state, num_bins <<= 1);
    }

    bin = find_bin(key_hash(name), num_bins);
    entry = try_as<MethodTableBucket>(values_->at(state, bin));

    while(entry) {
      if(entry->name() == name) {
        entry->method(state, method);
        entry->visibility(state, vis);
        return name;
      }
      last = entry;
      entry = try_as<MethodTableBucket>(entry->next());
    }

    if(last) {
      last->next(state, MethodTableBucket::create(state, name, method, vis));
    } else {
      values_->put(state, bin, MethodTableBucket::create(state, name, method, vis));
    }

    entries(state, Fixnum::from(num_entries + 1));
    return name;
  }
Example #5
0
  Object* MethodTable::alias(STATE, Symbol* name, Symbol* vis,
                             Symbol* orig_name, Executable* orig_method,
                             Module* orig_mod)
  {
    unsigned int num_entries, num_bins, bin;
    MethodTableBucket* entry;
    MethodTableBucket* last = NULL;

    if(Alias* alias = try_as<Alias>(orig_method)) {
      orig_method = alias->original_exec();
      orig_mod = alias->original_module();
      orig_name = alias->original_name();
    }

    Alias* method = Alias::create(state, orig_name, orig_mod, orig_method);

    num_entries = entries_->to_native();
    num_bins = bins_->to_native();

    if(max_density_p(num_entries, num_bins)) {
      redistribute(state, num_bins <<= 1);
    }

    bin = find_bin(key_hash(name), num_bins);
    entry = try_as<MethodTableBucket>(values_->at(state, bin));

    while(entry) {
      if(entry->name() == name) {
        entry->method(state, method);
        entry->visibility(state, vis);
        return name;
      }
      last = entry;
      entry = try_as<MethodTableBucket>(entry->next());
    }

    if(last) {
      last->next(state, MethodTableBucket::create(state, name, method, vis));
    } else {
      values_->put(state, bin, MethodTableBucket::create(state, name, method, vis));
    }

    entries(state, Fixnum::from(num_entries + 1));
    return name;
  }
Example #6
0
  Object* LookupTable::store(STATE, Object* key, Object* val) {
    unsigned int num_entries, num_bins, bin;
    Object* new_ent;
    Tuple* cur;
    Tuple* entry;

    key_to_sym(key);
    num_entries = entries_->to_native();
    num_bins = bins_->to_native();

    if(max_density_p(num_entries, num_bins)) {
      redistribute(state, num_bins <<= 1);
    }

    bin = find_bin(key_hash(key), num_bins);
    cur = entry = try_as<Tuple>(values_->at(state, bin));

    while(entry) {
      if(entry->at(state, 0) == key) {
        entry->put(state, 1, val);
        return val;
      }
      cur = entry;
      entry = try_as<Tuple>(entry->at(state, 2));
    }

    new_ent = entry_new(state, key, val);
    if(cur) {
      cur->put(state, 2, new_ent);
    } else {
      values_->put(state, bin, new_ent);
    }

    entries(state, Fixnum::from(num_entries + 1));
    return val;
  }