int equal(struct tree *lhs, struct tree *rhs) { int retval; inc_refcount(lhs); inc_refcount(rhs); if (lhs->type != rhs->type) { retval = 0; } else { switch(lhs->type) { case CHAR: retval = lhs->data.c == rhs->data.c; break; case INT: retval = lhs->data.i == rhs->data.i; break; case DOUBLE: retval = lhs->data.d == rhs->data.d; break; default: retval = 0; } } dec_refcount(rhs); dec_refcount(lhs); return retval; }
int lt(struct tree *lhs, struct tree *rhs) { int retval; inc_refcount(lhs); inc_refcount(rhs); if (lhs->type != rhs->type) { fprintf(stderr, "TYPE MISMATCH!\n"); retval = 0; } else { switch(lhs->type) { case CHAR: retval = lhs->data.c < rhs->data.c; break; case INT: retval = lhs->data.i < rhs->data.i; break; case DOUBLE: retval = lhs->data.d < rhs->data.d; break; default: retval = 0; } } dec_refcount(rhs); dec_refcount(lhs); return retval; }
struct tree *get_branch_t(struct tree *root, struct tree *branch) { struct tree *child; inc_refcount(branch); child = (struct tree *)get_branch(root, branch->data.i); dec_refcount(branch); return child; }
int add_child (struct tree *root, struct tree *child) { if (root == NULL) { return -1; } inc_refcount(child); append(root->children, child); root->width += 1; return root->width; }
struct tree *treemake(data_type type, union data_u data, struct tree *child, va_list args) { struct tree *root = malloc(sizeof(struct tree)); init_tree(root); root->type = type; root->data = data; while (child != NULL) { add_child(root, child); inc_refcount(child); child = va_arg(args, struct tree *); } return root; }
struct tree *cast(data_type type, struct tree *t) { if (type == INT) { switch (t->type) { case INT: break; case DOUBLE: t->data.i = (int)t->data.d; break; case CHAR: t->data.i = (int)t->data.c; break; default: t->data.i = 0; } t->type = INT; } struct tree* inc_refcount(struct tree *t) { if (t) { t->refcount++; } return t; } struct tree *dec_refcount(struct tree *t) { if (t) { if (--(t->refcount) <= 0) { free_tree(t); t = NULL; } } return t; } struct tree *sub(struct tree *lhs, struct tree *rhs) { struct tree *retval; inc_refcount(lhs); inc_refcount(rhs); if (lhs->type != rhs->type) { retval = NULL; } else { switch (lhs->type) { case CHAR: retval = char_treemake(lhs->data.c - rhs->data.c, NULL); break; case INT: retval = int_treemake(lhs->data.i - rhs->data.i, NULL); break; case DOUBLE: retval = double_treemake(lhs->data.d - rhs->data.d, NULL); break; default: retval = NULL; } } dec_refcount(rhs); dec_refcount(lhs); return retval; } struct tree *add(struct tree *lhs, struct tree *rhs) { struct tree *retval; inc_refcount(lhs); inc_refcount(rhs); if (lhs->type != rhs->type) { retval = NULL; } else { switch (lhs->type) { case CHAR: retval = char_treemake(lhs->data.c + rhs->data.c, NULL); break; case INT: retval = int_treemake(lhs->data.i + rhs->data.i, NULL); break; case DOUBLE: retval = double_treemake(lhs->data.d + rhs->data.d, NULL); break; default: retval = NULL; } } dec_refcount(rhs); dec_refcount(lhs); return retval; } struct tree *mult(struct tree *lhs, struct tree *rhs) { struct tree *retval; inc_refcount(lhs); inc_refcount(rhs); if (lhs->type != rhs->type) { retval = NULL; } else { switch (lhs->type) { case CHAR: retval = char_treemake(lhs->data.c * rhs->data.c, NULL); break; case INT: retval = int_treemake(lhs->data.i * rhs->data.i, NULL); break; case DOUBLE: retval = double_treemake(lhs->data.d * rhs->data.d, NULL); break; default: retval = NULL; } } dec_refcount(rhs); dec_refcount(lhs); return retval; } struct tree *divd(struct tree *lhs, struct tree *rhs) { struct tree *retval; inc_refcount(lhs); inc_refcount(rhs); if (lhs->type != rhs->type) { retval = NULL; } else { switch (lhs->type) { case CHAR: retval = char_treemake(lhs->data.c / rhs->data.c, NULL); break; case INT: retval = int_treemake(lhs->data.i / rhs->data.i, NULL); break; case DOUBLE: retval = double_treemake(lhs->data.d / rhs->data.d, NULL); break; default: retval = NULL; } } dec_refcount(rhs); dec_refcount(lhs); return retval; } struct tree *mod(struct tree *lhs, struct tree *rhs) { struct tree *retval; inc_refcount(lhs); inc_refcount(rhs); if (lhs->type != rhs->type) { retval = NULL; } else { switch (lhs->type) { case CHAR: retval = char_treemake(lhs->data.c % rhs->data.c, NULL); break; case INT: retval = int_treemake(lhs->data.i % rhs->data.i, NULL); break; default: retval = NULL; } } dec_refcount(rhs); dec_refcount(lhs); return retval; } void init_tree(struct tree *root) { root->children = malloc(sizeof(struct List)); root->type = VOID; root->width = 0; root->refcount = 0; init_list(root->children); }
/* Increase reference count of segment name identified by IX. */ void ML_(am_inc_refcount)(Int ix) { if (ix != -1) inc_refcount(ix); }
/* Searches the string table to find an index for the given name. If none is found, an index is allocated and the name stored. If running ouf of memory, return -1. */ Int ML_(am_allocate_segname)(const HChar *name) { UInt len, ix, size, next_freeslot; aspacem_assert(name); if (0) VG_(debugLog)(0, "aspacem", "allocate_segname %s\n", name); len = VG_(strlen)(name); /* First see if we already have the name. */ for (ix = overhead; (size = get_slotsize(ix)) != 0; ix += size + overhead) { if (is_freeslot(ix)) continue; if (VG_(strcmp)(name, segnames + ix) == 0) { inc_refcount(ix); return ix; } } /* Is there a free slot in the string table from a previously "freed" segment name ? */ Int prev; for (prev = -1, ix = freeslot_chain; ix != end_of_chain; prev = ix, ix = next_freeslot) { next_freeslot = get_slotindex(ix); // next in chain size = get_slotsize(ix); if (size >= len + 1) { /* Note, if the size of the slot is a lot larger than the length of the string we're about to store in it, we could split the slot into two. But that complicates matters and as we're not doing any coalescing of adjacent free slots this could lead to fragmentation. */ if (prev == -1) freeslot_chain = next_freeslot; else put_slotindex(prev, next_freeslot); put_refcount(ix, 1); put_slotsize(ix, size); VG_(strcpy)(segnames + ix, name); ++num_segnames; return ix; } } /* We need to add a new name. */ /* Note, that we need at least two bytes in the payload. The reason is that the payload area will be used to store the size of the slot when the slot is on the freelist. */ if (len == 0) len = 1; /* Is there enough room in the string table? The OVERHEAD is for the sentinel following the payload of new slot. */ SizeT need = len + 1 + overhead; if (need > (sizeof segnames) - segnames_used) { return -1; } ++num_segnames; ++num_slots; /* copy it in */ ix = segnames_used; put_refcount(ix, 1); put_slotsize(ix, len + 1); VG_(strcpy)(segnames + ix, name); segnames_used += need; /* Add sentinel at end of segment name list */ put_sentinel(segnames_used); return ix; }
void inc_buf_refcount(char *buf) { inc_refcount(get_buffer(buf)); }