[svn:parrot] r40219 - branches/orderedhash_revamp/src/pmc
bacek at svn.parrot.org
bacek at svn.parrot.org
Wed Jul 22 23:14:42 UTC 2009
Author: bacek
Date: Wed Jul 22 23:14:41 2009
New Revision: 40219
URL: https://trac.parrot.org/parrot/changeset/40219
Log:
[pmc] Totally broke OrderedHash.
- Remove old methods.
- Add stubs for new methods.
- Build is broken.
- But 2 first OrderedHash tests are passed!
Modified:
branches/orderedhash_revamp/src/pmc/orderedhash.pmc
Modified: branches/orderedhash_revamp/src/pmc/orderedhash.pmc
==============================================================================
--- branches/orderedhash_revamp/src/pmc/orderedhash.pmc Wed Jul 22 23:14:19 2009 (r40218)
+++ branches/orderedhash_revamp/src/pmc/orderedhash.pmc Wed Jul 22 23:14:41 2009 (r40219)
@@ -96,12 +96,12 @@
VTABLE_set_pmc_keyed_int(interp, ret, ORDERED_HASH_ITEM_KEY, key);
VTABLE_set_pmc_keyed_int(interp, ret, ORDERED_HASH_ITEM_VALUE, value);
return ret;
-}
+};
-pmclass OrderedHash need_ext provides array provides hash {
- ATTR PMC* hash; /* key -> (value, prev, next) tuple */
- ATTR PMC* first; /* Pointer to first inserted value */
- ATTR PMC* last; /* Pointer to last inserted value */
+pmclass OrderedHash need_ext provides array {
+ ATTR PMC *hash; /* key to item tuple */
+ ATTR PMC *first; /* Pointer to first inserted value */
+ ATTR PMC *last; /* Pointer to last inserted value */
/*
@@ -118,11 +118,17 @@
mem_allocate_zeroed_typed(Parrot_OrderedHash_attributes);
PMC_data(SELF) = attrs;
- attrs->lookup = pmc_new(INTERP, enum_class_Hash);
+ attrs->hash = pmc_new(INTERP, enum_class_Hash);
+ attrs->first = PMCNULL;
+ attrs->last = PMCNULL;
PObj_custom_mark_destroy_SETALL(SELF);
}
+ VTABLE void init_pmc() {
+ PARROT_ASSERT(!"Bah");
+ }
+
/*
=item C<void mark()>
@@ -137,8 +143,8 @@
Parrot_OrderedHash_attributes * const attrs =
PARROT_ORDEREDHASH(SELF);
- if (attrs->lookup)
- Parrot_gc_mark_PObj_alive(INTERP, attrs->lookup);
+ if (attrs->hash)
+ Parrot_gc_mark_PObj_alive(INTERP, (PObj *)attrs->hash);
/* Don't mark C<first> and C<last>. They are in lookup hash anyway */
}
@@ -164,6 +170,67 @@
/*
+=item C<INTVAL elements()>
+
+=item C<INTVAL get_integer()>
+
+=item C<FLOATVAL get_number()>
+
+Returns the size of the hash.
+
+=cut
+
+*/
+
+ VTABLE INTVAL get_integer() {
+ return STATICSELF.elements();
+ }
+
+ VTABLE FLOATVAL get_number() {
+ return SELF.get_integer();
+ }
+
+ VTABLE INTVAL elements() {
+ return VTABLE_elements(INTERP, PARROT_ORDEREDHASH(SELF)->hash);
+ }
+
+ VTABLE void set_pmc_keyed_str(STRING *key, PMC *value) {
+ PMC *pkey = pmc_new(interp, Parrot_get_ctx_HLL_type(interp, enum_class_String));
+ VTABLE_set_string_native(INTERP, pkey, key);
+ VTABLE_set_pmc_keyed(INTERP, SELF, pkey, value);
+ }
+
+ VTABLE void set_pmc_keyed(PMC *key, PMC *value) {
+ Parrot_OrderedHash_attributes *attrs =
+ PARROT_ORDEREDHASH(SELF);
+ /* Check for old entry */
+ PMC *list_entry = VTABLE_get_pmc_keyed(INTERP, attrs->hash, key);
+ if (!PMC_IS_NULL(list_entry)) {
+ /* We have old entry. Just update value */
+ VTABLE_set_pmc_keyed_int(INTERP, list_entry, ORDERED_HASH_ITEM_VALUE, value);
+ return;
+ }
+
+ /* Create new entry */
+ list_entry = pmc_new(INTERP, enum_class_FixedPMCArray);
+ VTABLE_set_integer_native(INTERP, list_entry, ORDERED_HASH_ITEM_MAX);
+ VTABLE_set_pmc_keyed_int(INTERP, list_entry, ORDERED_HASH_ITEM_VALUE, value);
+ VTABLE_set_pmc_keyed_int(INTERP, list_entry, ORDERED_HASH_ITEM_KEY, key);
+
+ /* .. and link it */
+ if (!PMC_IS_NULL(attrs->last)) {
+ VTABLE_set_pmc_keyed_int(INTERP, list_entry, ORDERED_HASH_ITEM_PREV, attrs->last);
+ VTABLE_set_pmc_keyed_int(INTERP, attrs->last, ORDERED_HASH_ITEM_NEXT, list_entry);
+ }
+ attrs->last = list_entry;
+ if (PMC_IS_NULL(attrs->first))
+ attrs->first = list_entry;
+
+ /* .. and store it */
+ VTABLE_set_pmc_keyed(INTERP, attrs->hash, key, list_entry);
+ }
+/*
+
=item C<PMC *get_pmc_keyed(PMC *key)>
=item C<PMC *get_pmc_keyed_int(INTVAL key)>
@@ -175,27 +242,24 @@
*/
VTABLE PMC *get_pmc_keyed_int(INTVAL idx) {
- Hash * const h = (Hash *)SELF.get_pointer();
- const INTVAL n = h->entries;
- HashBucket *b;
-
- if (idx < 0)
- idx += n;
+ Parrot_OrderedHash_attributes *attrs = PARROT_ORDEREDHASH(SELF);
+ INTVAL pos;
+ PMC *list_entry = attrs->first;
- if (idx < 0 || idx >= n)
- Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_KEY_NOT_FOUND,
- "OrderedHash: index out of bounds!");
+ if (idx < 0 || idx >= STATICSELF.elements())
+ return PMCNULL;
- b = h->bs + idx;
-
- if (b->key)
- return (PMC *)b->value;
+ /* Iterate over linked list to get value */
+ for (pos = 0; pos < idx; ++pos) {
+ list_entry = VTABLE_get_pmc_keyed_int(INTERP, list_entry, ORDERED_HASH_ITEM_NEXT);
+ }
- Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_KEY_NOT_FOUND,
- "OrderedHash: No such key");
+ PARROT_ASSERT(!PMC_IS_NULL(list_entry));
+ return VTABLE_get_pmc_keyed_int(INTERP, list_entry, ORDERED_HASH_ITEM_VALUE);
}
VTABLE PMC *get_pmc_keyed(PMC *key) {
+ PMC * item;
if ((PObj_get_FLAGS(key) & KEY_type_FLAGS) == KEY_integer_FLAG) {
PMC * const item = SELF.get_pmc_keyed_int(VTABLE_get_integer(INTERP, key));
PMC * const next = VTABLE_shift_pmc(INTERP, key);
@@ -206,9 +270,17 @@
return VTABLE_get_pmc_keyed(INTERP, item, next);
}
- return INTERP->vtables[enum_class_Hash]->get_pmc_keyed(INTERP, SELF, key);
+ item = VTABLE_get_pmc_keyed(INTERP, PARROT_ORDEREDHASH(SELF)->hash, key);
+ if (PMC_IS_NULL(item))
+ return PMCNULL;
+ return VTABLE_get_pmc_keyed_int(INTERP, item, ORDERED_HASH_ITEM_VALUE);
}
+ VTABLE PMC *get_pmc_keyed_str(STRING *key) {
+ PMC *pkey = pmc_new(interp, Parrot_get_ctx_HLL_type(interp, enum_class_String));
+ VTABLE_set_string_native(INTERP, pkey, key);
+ return STATICSELF.get_pmc_keyed(pkey);
+ }
/*
=item C<STRING *get_string_keyed(PMC *key)>
@@ -222,39 +294,13 @@
*/
VTABLE STRING *get_string_keyed_int(INTVAL idx) {
- Hash * const h = (Hash *)SELF.get_pointer();
- const INTVAL n = h->entries;
-
- HashBucket *b;
-
- if (idx < 0)
- idx += n;
-
- if (idx < 0 || idx >= n)
- Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_KEY_NOT_FOUND,
- "OrderedHash: index out of bounds!");
-
- b = h->bs + idx;
-
- if (b->key)
- return VTABLE_get_string(INTERP, (PMC *)b->value);
-
- Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_KEY_NOT_FOUND,
- "OrderedHash: No such key");
+ PMC * const item = VTABLE_get_pmc_keyed_int(INTERP, SELF, idx);
+ return VTABLE_get_string(INTERP, item);
}
VTABLE STRING *get_string_keyed(PMC *key) {
- if ((PObj_get_FLAGS(key) & KEY_type_FLAGS) == KEY_integer_FLAG) {
- PMC * const item = SELF.get_pmc_keyed_int(VTABLE_get_integer(INTERP, key));
- PMC * const next = VTABLE_shift_pmc(INTERP, key);
-
- if (!next)
- return VTABLE_get_string(INTERP, item);
-
- return VTABLE_get_string_keyed(INTERP, item, next);
- }
-
- return INTERP->vtables[enum_class_Hash]->get_string_keyed(INTERP, SELF, key);
+ PMC * const item = VTABLE_get_pmc_keyed(INTERP, SELF, key);
+ return VTABLE_get_string(INTERP, item);
}
/*
@@ -271,39 +317,13 @@
*/
VTABLE INTVAL get_integer_keyed_int(INTVAL idx) {
- Hash * const h = (Hash *)SELF.get_pointer();
- const INTVAL n = h->entries;
- HashBucket *b;
-
- if (idx < 0)
- idx += n;
-
- if (idx < 0 || idx >= n)
- Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
- "OrderedHash: index out of bounds!");
-
- b = h->bs + idx;
-
- if (b->key)
- return VTABLE_get_integer(INTERP, (PMC *)b->value);
-
- Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_KEY_NOT_FOUND,
- "OrderedHash: No such key");
+ PMC * const item = VTABLE_get_pmc_keyed_int(INTERP, SELF, idx);
+ return VTABLE_get_integer(INTERP, item);
}
VTABLE INTVAL get_integer_keyed(PMC *key) {
-
- if ((PObj_get_FLAGS(key) & KEY_type_FLAGS) == KEY_integer_FLAG) {
- PMC * const item = SELF.get_pmc_keyed_int(VTABLE_get_integer(INTERP, key));
- PMC * const next = VTABLE_shift_pmc(INTERP, key);
-
- if (!next)
- return VTABLE_get_integer(INTERP, item);
-
- return VTABLE_get_integer_keyed(INTERP, item, next);
- }
-
- return INTERP->vtables[enum_class_Hash]->get_integer_keyed(INTERP, SELF, key);
+ PMC * const item = VTABLE_get_pmc_keyed(INTERP, SELF, key);
+ return VTABLE_get_integer(INTERP, item);
}
/*
@@ -321,38 +341,13 @@
*/
VTABLE FLOATVAL get_number_keyed_int(INTVAL idx) {
- Hash * const h = (Hash *)SELF.get_pointer();
- const INTVAL n = h->entries;
- HashBucket *b;
-
- if (idx < 0)
- idx += n;
-
- if (idx < 0 || idx >= n)
- Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
- "OrderedHash: index out of bounds!");
-
- b = h->bs + idx;
-
- if (b->key)
- return VTABLE_get_number(INTERP, (PMC *)b->value);
-
- Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_KEY_NOT_FOUND,
- "OrderedHash: No such key");
+ PMC * const item = VTABLE_get_pmc_keyed_int(INTERP, SELF, idx);
+ return VTABLE_get_number(INTERP, item);
}
VTABLE FLOATVAL get_number_keyed(PMC *key) {
- if ((PObj_get_FLAGS(key) & KEY_type_FLAGS) == KEY_integer_FLAG) {
- PMC * const item = SELF.get_pmc_keyed_int(VTABLE_get_integer(INTERP, key));
- PMC * const next = VTABLE_shift_pmc(INTERP, key);
-
- if (!next)
- return VTABLE_get_number(INTERP, item);
-
- return VTABLE_get_number_keyed(INTERP, item, next);
- }
-
- return SUPER(key);
+ PMC * const item = VTABLE_get_pmc_keyed(INTERP, SELF, key);
+ return VTABLE_get_number(INTERP, item);
}
/*
@@ -373,28 +368,7 @@
*/
VTABLE void set_pmc_keyed_int(INTVAL idx, PMC *val) {
- Hash * const h = (Hash *)SELF.get_pointer();
- const INTVAL n = h->entries;
- STRING * const fmt = CONST_STRING(INTERP, "\1%d");
-
- if (idx < -n)
- idx = -idx - n - 1;
- else if (idx < 0)
- idx += n;
-
- if (idx >= n) {
- /* TODO warn or fill if there are holes */
- STRING * const key = Parrot_sprintf_s(INTERP, fmt, idx);
- SELF.set_pmc_keyed_str(key, val);
- }
- else {
- HashBucket * const b = h->bs + idx;
-
- if (!b->key)
- b->key = Parrot_sprintf_s(INTERP, fmt, idx);
-
- b->value = val;
- }
+ PARROT_ASSERT(!"Bah");
}
VTABLE void set_integer_keyed_int(INTVAL idx, INTVAL value) {
@@ -464,60 +438,16 @@
*/
VTABLE INTVAL exists_keyed_int(INTVAL idx) {
- Hash * const h = (Hash *)SELF.get_pointer();
- const INTVAL n = h->entries;
- HashBucket *b;
-
- if (idx < 0)
- idx += n;
-
- if (idx < 0 || idx >= n)
- return 0;
-
- b = h->bs + idx;
-
- if (b->key)
- return 1;
-
- return 0;
+ return (idx >= 0) && (idx < STATICSELF.elements());
}
VTABLE INTVAL exists_keyed(PMC *key) {
- if (PObj_get_FLAGS(key) & KEY_integer_FLAG) {
- PMC *item, *next;
- HashBucket *b;
- Hash * const h = (Hash *)SELF.get_pointer();
- INTVAL idx = VTABLE_get_integer(INTERP, key);
- const INTVAL n = h->entries;
-
- if (idx < 0)
- idx += n;
-
- if (idx < 0 || idx >= n)
- return 0;
-
- b = h->bs + idx;
-
- if (!b->key)
- return 0;
-
- item = (PMC *)b->value;
- next = VTABLE_shift_pmc(INTERP, key);
-
- if (!next)
- return 1;
-
- return VTABLE_exists_keyed(INTERP, item, next);
- }
-
- return SUPER(key);
+ /* TODO Handle Key PMC */
+ return VTABLE_exists_keyed_str(INTERP, SELF, VTABLE_get_string(INTERP, key));
}
VTABLE INTVAL exists_keyed_str(STRING *key) {
- const Hash * const h = (Hash *)SELF.get_pointer();
- const HashBucket * const b = parrot_hash_get_bucket(INTERP, h, key);
-
- return (b && b->key);
+ return VTABLE_exists_keyed_str(INTERP, PARROT_ORDEREDHASH(SELF)->hash, key);
}
/*
@@ -533,55 +463,11 @@
*/
VTABLE INTVAL defined_keyed(PMC *key) {
- if (PObj_get_FLAGS(key) & KEY_integer_FLAG) {
- Hash * const h = (Hash *)SELF.get_pointer();
- INTVAL idx = VTABLE_get_integer(INTERP, key);
- const INTVAL n = h->entries;
-
- HashBucket *b;
- PMC *item, *next;
-
- if (idx < 0)
- idx += n;
-
- /* XXX non-existent is undefined - is this correct */
- if (idx < 0 || idx >= n)
- return 0;
-
- b = h->bs + idx;
-
- if (!b->key)
- return 0;
-
- item = (PMC *)b->value;
- next = VTABLE_shift_pmc(INTERP, key);
-
- if (!next)
- return VTABLE_defined(INTERP, item);
-
- return VTABLE_defined_keyed(INTERP, item, next);
- }
-
- return SUPER(key);
+ PARROT_ASSERT(!"Bah");
}
VTABLE INTVAL defined_keyed_int(INTVAL idx) {
- Hash * const h = (Hash *)SELF.get_pointer();
- const INTVAL n = h->entries;
- HashBucket *b;
-
- if (idx < 0)
- idx += n;
-
- if (idx < 0 || idx >= n)
- return 0;
-
- b = h->bs + idx;
-
- if (b->key)
- return VTABLE_defined(INTERP, (PMC *)b->value);
-
- return 0;
+ PARROT_ASSERT(!"Bah");
}
/*
@@ -599,56 +485,15 @@
*/
VTABLE void delete_keyed(PMC *key) {
- PMC * const next = key_next(INTERP, key);
-
- if (PObj_get_FLAGS(key) & KEY_integer_FLAG) {
- if (next) {
- PMC * const item = SELF.get_pmc_keyed_int(VTABLE_get_integer(INTERP, key));
- VTABLE_delete_keyed(INTERP, item, next);
- return;
- }
-
- SELF.delete_keyed_int(VTABLE_get_integer(INTERP, key));
- }
- else {
- if (next) {
- PMC * const item = SELF.get_pmc_keyed_str(VTABLE_get_string(INTERP, key));
- VTABLE_delete_keyed(INTERP, item, next);
- return;
- }
- SELF.delete_keyed_str(VTABLE_get_string(INTERP, key));
- }
+ PARROT_ASSERT(!"Bah");
}
VTABLE void delete_keyed_int(INTVAL idx) {
- Hash * const h = (Hash *)SELF.get_pointer();
- const INTVAL n = h->entries;
- HashBucket *b;
-
- if (idx < 0)
- idx += n;
-
- if (idx < 0 || idx >= n)
- return;
-
- b = h->bs + idx;
-
- if (!b)
- return;
-
- b->key = NULL;
- b->value = NULL;
+ PARROT_ASSERT(!"Bah");
}
VTABLE void delete_keyed_str(STRING *key) {
- const Hash * const h = (Hash *)SELF.get_pointer();
- HashBucket * const b = parrot_hash_get_bucket(INTERP, h, key);
-
- if (!b)
- return;
-
- b->key = NULL;
- b->value = NULL;
+ PARROT_ASSERT(!"Bah");
}
/*
@@ -664,18 +509,6 @@
VTABLE PMC *clone() {
PMC * const dest = pmc_new(INTERP, SELF->vtable->base_type);
- Hash * const hash = (Hash *)SELF.get_pointer();
- Hash * const h_dest = (Hash *)VTABLE_get_pointer(INTERP, dest);
- UINTVAL i;
-
- for (i = 0; i <= N_BUCKETS(hash->mask-1); i++) {
- HashBucket * const b = hash->bs + i;
- void * const key = b->key;
-
- if (key)
- parrot_hash_put(INTERP, h_dest, key,
- (void *)VTABLE_clone(INTERP, (PMC *)b->value));
- }
return dest;
}
@@ -701,40 +534,10 @@
*/
VTABLE void visit(visit_info *info) {
- info->container = SELF;
-
- switch (info->what) {
- case VISIT_THAW_NORMAL:
- case VISIT_THAW_CONSTANTS:
- SUPER(info);
- break;
-
- case VISIT_FREEZE_NORMAL:
- case VISIT_FREEZE_AT_DESTRUCT:
- {
- Hash * const hash = (Hash *)SELF.get_pointer();
- IMAGE_IO * const io = info->image_io;
- const UINTVAL entries = hash->entries;
- UINTVAL i;
-
- for (i = 0; i < entries; i++) {
- HashBucket * const b = hash->bs + i;
-
- if (b) {
- STRING * const key = (STRING *)b->key;
- if (key) {
- VTABLE_push_string(interp, io, key);
- (info->visit_pmc_now)(interp, (PMC *)b->value, info);
- }
- }
- }
- }
- break;
- default:
- Parrot_ex_throw_from_c_args(interp, NULL,
- EXCEPTION_INVALID_OPERATION,
- "unhandled visit action (%d)", info->what);
- }
+ PMC **hash = &(PARROT_ORDEREDHASH(SELF)->hash);
+ info->thaw_ptr = hash;
+ (info->visit_pmc_now)(INTERP, *hash, info);
+ SUPER(info);
}
}
More information about the parrot-commits
mailing list