diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2016-07-01 22:39:45 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2016-07-01 22:39:45 -0700 |
commit | 703a73722cd3e2843bb7e2e11f2881c84f20cac0 (patch) | |
tree | b7b57d9800502c860080d973481fb2dcf5cc0857 | |
parent | 3259784417ceb4e81156f708eaccf417cd048ea2 (diff) | |
download | mu-703a73722cd3e2843bb7e2e11f2881c84f20cac0.tar.gz |
3084
-rw-r--r-- | 073deep_copy.cc | 50 |
1 files 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<double> deep_copy(reagent/*copy*/ in, reagent& tmp) { +vector<double> deep_copy(reagent/*copy*/ in, const reagent& tmp) { canonize(in); vector<double> result; map<int, int> 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<int, int>& 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<int, int>& addresses_copied, vector<double>& out) { +void deep_copy(const reagent& canonized_in, map<int, int>& addresses_copied, const reagent& tmp, vector<double>& 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<int, int>& addresses_copied, vec out.push_back(result.at(0)); return; } - if (get(Container_metadata, canonized_in.type).address.empty()) { - vector<double> result = read_memory(canonized_in); - out.insert(out.end(), result.begin(), result.end()); - return; + vector<double> 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<tag_condition_info>, set<address_element_info> >::const_iterator p = metadata.address.begin(); p != metadata.address.end(); ++p) { + if (!all_match(data, p->first)) continue; + for (set<address_element_info>::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<string, string_tree*>("raw", NULL)); + trace(9991, "run") << "deep-copy: copying address " << curr.value << end(); + out.at(info->offset) = deep_copy_address(curr, addresses_copied, tmp); + } } } |