From 703a73722cd3e2843bb7e2e11f2881c84f20cac0 Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Fri, 1 Jul 2016 22:39:45 -0700 Subject: 3084 --- 073deep_copy.cc | 50 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 42 insertions(+), 8 deletions(-) diff --git a/073deep_copy.cc b/073deep_copy.cc index b281bcb3..0d4607ae 100644 --- a/073deep_copy.cc +++ b/073deep_copy.cc @@ -24,7 +24,7 @@ container foo [ ] def main [ local-scope - a:foo <- merge 34 35 + a:foo <- merge 34, 35 b:foo <- deep-copy a 10:boolean/raw <- equal a, b ] @@ -98,6 +98,28 @@ def main [ # however, the contents are identical +mem: storing 1 in location 11 +:(scenario deep_copy_container_with_address) +container foo [ + x:number + y:address:number +] +def main [ + local-scope + y0:address:number <- new number:type + *y0 <- copy 35 + a:foo <- merge 34, y0 + b:foo <- deep-copy a + 10:boolean/raw <- equal a, b + y1:address:number <- get b, y:offset + 11:boolean/raw <- equal y0, y1 + 12:number/raw <- copy *y1 +] +# containers containing addresses are not identical to their deep copies ++mem: storing 0 in location 10 +# the addresses the contain are not identical either ++mem: storing 0 in location 11 ++mem: storing 35 in location 12 + :(before "End Primitive Recipe Declarations") DEEP_COPY, :(before "End Primitive Recipe Numbers") @@ -126,14 +148,14 @@ case DEEP_COPY: { } :(code) -vector deep_copy(reagent/*copy*/ in, reagent& tmp) { +vector deep_copy(reagent/*copy*/ in, const reagent& tmp) { canonize(in); vector result; map addresses_copied; if (is_mu_address(in)) result.push_back(deep_copy_address(in, addresses_copied, tmp)); else - deep_copy(in, addresses_copied, result); + deep_copy(in, addresses_copied, tmp, result); trace(9991, "run") << "deep-copy: done" << end(); return result; } @@ -191,7 +213,7 @@ int deep_copy_address(const reagent& canonized_in, map& addresses_copi // deep-copy a container and return a container // deep-copy a container and return a vector of locations -void deep_copy(const reagent& canonized_in, map& addresses_copied, vector& out) { +void deep_copy(const reagent& canonized_in, map& addresses_copied, const reagent& tmp, vector& out) { assert(!is_mu_address(canonized_in)); if (!contains_key(Container_metadata, canonized_in.type)) { assert(get(Type, canonized_in.type->value).kind == PRIMITIVE); // not a container @@ -200,9 +222,21 @@ void deep_copy(const reagent& canonized_in, map& addresses_copied, vec out.push_back(result.at(0)); return; } - if (get(Container_metadata, canonized_in.type).address.empty()) { - vector result = read_memory(canonized_in); - out.insert(out.end(), result.begin(), result.end()); - return; + vector data = read_memory(canonized_in); + out.insert(out.end(), data.begin(), data.end()); + trace(9991, "run") << "deep-copy: scanning for addresses in " << to_string(data) << end(); + const container_metadata& metadata = get(Container_metadata, canonized_in.type); + for (map, set >::const_iterator p = metadata.address.begin(); p != metadata.address.end(); ++p) { + if (!all_match(data, p->first)) continue; + for (set::const_iterator info = p->second.begin(); info != p->second.end(); ++info) { + // construct a fake reagent that reads directly from the appropriate + // field of the container + reagent curr; + curr.type = new type_tree("address", new type_tree(*info->payload_type)); + curr.set_value(canonized_in.value + info->offset); + curr.properties.push_back(pair("raw", NULL)); + trace(9991, "run") << "deep-copy: copying address " << curr.value << end(); + out.at(info->offset) = deep_copy_address(curr, addresses_copied, tmp); + } } } -- cgit 1.4.1-2-gfad0