/** * @brief Create a new container * @param type Type of element inside container * @param data Data pointer for contained element * @param inlist Input links list if any (else it will be created empty) * @param outlist Output links list if any (else it will be created empty) * @param uniqid Unique ID to be put into name * @return Container newly created */ container_t *container_create(u_int type, void *data, list_t *inlist, list_t *outlist, u_int uniqid) { container_t *newcntnr; aspectype_t *rtype; PROFILER_IN(__FILE__, __FUNCTION__, __LINE__); rtype = aspect_type_get_by_id(type); if (!rtype) PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Unknown container element type", NULL); /* Make sure meta-data is initialized and contiguous with pointed data */ #if defined(DEBUG_LIBASPECT) fprintf(stderr, "Allocating sizeof(container) + (%s type->size = %u) \n", rtype->name, rtype->size); #endif XALLOC(__FILE__, __FUNCTION__, __LINE__, newcntnr, sizeof(container_t) + rtype->size, NULL); newcntnr->data = (char *) newcntnr + sizeof(container_t); newcntnr->type = type; memcpy((char *) newcntnr->data, (char *) data, rtype->size); /* Create lists if not specified */ if (inlist) newcntnr->inlinks = elist_copy(inlist); else container_linklists_create(newcntnr, CONTAINER_LINK_IN, uniqid); if (outlist) newcntnr->outlinks = elist_copy(outlist); else container_linklists_create(newcntnr, CONTAINER_LINK_OUT, uniqid); /* Make sure the container and contained data are contiguous */ PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, newcntnr); }
/** * Perform the transformation (can be called from case or into commands) * @param matchme * @param destvalue * @return */ static int revm_case_transform(revmexpr_t *matchme, char *destvalue) { u_int dstnbr; char *curptr; char *foundptr; u_int curidx; list_t *exprlist; aspectype_t *type; char namebuf[BUFSIZ]; char *rname; revmexpr_t *candid; list_t *looplist; int ret; PROFILER_IN(__FILE__, __FUNCTION__, __LINE__); /* We matched : first find how many elements there is in the target (list) type */ exprlist = world.curjob->recur[world.curjob->curscope].rwrt.transformed; dstnbr = 1; for (curidx = world.curjob->iter[world.curjob->curloop].elmidx - 1, curptr = destvalue; curptr && *curptr; curptr = foundptr + 2, curidx++, dstnbr++) { foundptr = strstr(curptr, "::"); if (!foundptr && dstnbr == 1) break; if (foundptr) *foundptr = 0x00; type = revm_exprtype_get(curptr); snprintf(namebuf, BUFSIZ, "%s-%u", world.curjob->iter[world.curjob->curloop].curkey, curidx); rname = strdup(namebuf); candid = revm_expr_create(type, rname, curptr); if (!candid || !candid->annot) PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Invalid target type(s) for transformation", -1); candid->annot->inhash = 1; elist_append(exprlist, rname, candid); if (!foundptr) break; } /* XXX: Case where the rewritten element is not part of an iterated list -- unsupported */ looplist = (list_t *) world.curjob->iter[world.curjob->curloop].container; if (!looplist) PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Rewriting of non-list element unimplemented", -1); else if (looplist->type != ASPECT_TYPE_EXPR) PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Rewrite of non-expression variables unimplemented", -1); /* Simply replace the current list element now */ /* The type of the list (list_t->type) does not change : it still is a list of revmexpr_t */ /* Just one element to swap */ else if (dstnbr == 1) { /* No transformation, keep the original expression */ if (!strcmp(destvalue, ".")) candid = matchme; else { /* Case where we did not have a simple value here but a real expression */ rname = revm_tmpvar_create(); type = revm_exprtype_get(destvalue); candid = revm_expr_create(type, rname, destvalue); if (!candid || !candid->annot) PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Malformed destination type", -1); candid->annot->inhash = 1; /** ** ** XXX: Disabled -- do not remove -- to enable when SSA transform is ready ** if (revm_links_propagate(candid, matchme) < 0) ** PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, ** "Error while propagating dataflow links", -1); ** ** XXX: Also address the propagate for the case where dstnbr != 1 */ ret = elist_set(looplist, world.curjob->iter[world.curjob->curloop].curkey, candid); if (ret < 0) PROFILER_ERR(__FILE__, __FUNCTION__, __LINE__, "Failed to store transformed expr in input list", -1); /* ** We reuse the same key for transform list, so that any change in transform list ** can be recorded back to the element of the original list. We also refresh the ** induction variable of current loop context. ** ** XXX: we should probably update context hashes too */ elist_append(exprlist, strdup(world.curjob->iter[world.curjob->curloop].curkey), candid); char *name = world.curjob->iter[world.curjob->curloop].curind->label; world.curjob->iter[world.curjob->curloop].curind = candid; world.curjob->iter[world.curjob->curloop].curind->label = name; } } /* Insert a list at a certain offset of the list and remove matched element */ else { elist_replace(looplist, world.curjob->iter[world.curjob->curloop].curkey, elist_copy(exprlist, ELIST_DATA_NOCOPY)); world.curjob->iter[world.curjob->curloop].elmidx += exprlist->elmnbr - 1; } PROFILER_ROUT(__FILE__, __FUNCTION__, __LINE__, 0); }