about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--036refcount.cc3
-rw-r--r--038new_text.cc3
-rw-r--r--088file.mu12
-rw-r--r--089scenario_filesystem.cc17
-rw-r--r--090scenario_filesystem_test.mu24
5 files changed, 56 insertions, 3 deletions
diff --git a/036refcount.cc b/036refcount.cc
index dca3db90..c6e41471 100644
--- a/036refcount.cc
+++ b/036refcount.cc
@@ -392,12 +392,13 @@ if (is_mu_container(canonized_x) || is_mu_exclusive_container(canonized_x)) {
 
 :(before "End Decrement Refcounts(canonized_x)")
 if (is_mu_container(canonized_x) || is_mu_exclusive_container(canonized_x)) {
-  trace(9999, "mem") << "need to read old value to figure out what refcounts to decrement" << end();
+  trace(9999, "mem") << "need to read old value of '" << to_string(canonized_x) << "' to figure out what refcounts to decrement" << end();
   // read from canonized_x but without canonizing again
   // todo: inline without running canonize all over again
   reagent/*copy*/ tmp = canonized_x;
   tmp.properties.push_back(pair<string, string_tree*>("raw", NULL));
   vector<double> data = read_memory(tmp);
+  trace(9999, "mem") << "done reading old value of '" << to_string(canonized_x) << "'" << end();
   const container_metadata& metadata = get(Container_metadata, canonized_x.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;
diff --git a/038new_text.cc b/038new_text.cc
index c7696a9b..416d2e15 100644
--- a/038new_text.cc
+++ b/038new_text.cc
@@ -40,8 +40,10 @@ int new_mu_string(const string& contents) {
   // initialize string
   int result = Current_routine->alloc;
   // initialize refcount
+  trace(9999, "mem") << "storing string refcount 0 in location " << Current_routine->alloc << end();
   put(Memory, Current_routine->alloc++, 0);
   // store length
+  trace(9999, "mem") << "storing string length " << string_length << " in location " << Current_routine->alloc << end();
   put(Memory, Current_routine->alloc++, string_length);
   int curr = 0;
   const char* raw_contents = contents.c_str();
@@ -49,6 +51,7 @@ int new_mu_string(const string& contents) {
     uint32_t curr_character;
     assert(curr < SIZE(contents));
     tb_utf8_char_to_unicode(&curr_character, &raw_contents[curr]);
+    trace(9999, "mem") << "storing string character " << curr_character << " in location " << Current_routine->alloc << end();
     put(Memory, Current_routine->alloc, curr_character);
     curr += tb_utf8_char_length(raw_contents[curr]);
     ++Current_routine->alloc;
diff --git a/088file.mu b/088file.mu
index 19539b95..012de50a 100644
--- a/088file.mu
+++ b/088file.mu
@@ -117,7 +117,19 @@ def transmit-to-fake-file fs:address:filesystem, filename:address:array:characte
   curr-filename:address:array:character <- copy 0
   data:address:array:file-mapping <- get *fs, data:offset
   # replace file contents if it already exists
+  i:number <- copy 0
   len:number <- length *data
+  {
+    done?:boolean <- greater-or-equal i, len
+    break-if done?
+    tmp:file-mapping <- index *data, i
+    curr-filename <- get tmp, name:offset
+    found?:boolean <- equal filename, curr-filename
+    loop-unless found?
+    put-index *data, i, new-file-mapping
+    reply
+  }
+  # if file didn't already exist, make room for it
   new-len:number <- add len, 1
   new-data:address:array:file-mapping <- new file-mapping:type, new-len
   put *fs, data:offset, new-data
diff --git a/089scenario_filesystem.cc b/089scenario_filesystem.cc
index ef20b159..65b56755 100644
--- a/089scenario_filesystem.cc
+++ b/089scenario_filesystem.cc
@@ -192,18 +192,31 @@ void construct_filesystem_object(const map<string, string>& contents) {
   int curr = filesystem_data_address + /*skip refcount and length*/2;
   for (map<string, string>::const_iterator p = contents.begin(); p != contents.end(); ++p) {
     put(Memory, curr, new_mu_string(p->first));
+    trace(9999, "mem") << "storing file name " << get(Memory, curr) << " in location " << curr << end();
+    put(Memory, get(Memory, curr), 1);
+    trace(9999, "mem") << "storing refcount 1 in location " << get(Memory, curr) << end();
     curr++;
     put(Memory, curr, new_mu_string(p->second));
+    trace(9999, "mem") << "storing file contents " << get(Memory, curr) << " in location " << curr << end();
+    put(Memory, get(Memory, curr), 1);
+    trace(9999, "mem") << "storing refcount 1 in location " << get(Memory, curr) << end();
     curr++;
   }
-  put(Memory, filesystem_data_address+/*skip refcount*/1, SIZE(contents));  // size of array
+  curr = filesystem_data_address+/*skip refcount*/1;
+  put(Memory, curr, SIZE(contents));  // size of array
+  trace(9999, "mem") << "storing filesystem size " << get(Memory, curr) << " in location " << curr << end();
   put(Memory, filesystem_data_address, 1);  // initialize refcount
+  trace(9999, "mem") << "storing refcount 1 in location " << filesystem_data_address << end();
   // wrap the filesystem data in a filesystem object
   int filesystem_address = allocate(size_of_filesystem());
-  put(Memory, filesystem_address+/*skip refcount*/1, filesystem_data_address);
+  curr = filesystem_address+/*skip refcount*/1;
+  put(Memory, curr, filesystem_data_address);
+  trace(9999, "mem") << "storing filesystem data address " << filesystem_data_address << " in location " << curr << end();
   put(Memory, filesystem_address, 1);  // initialize refcount
+  trace(9999, "mem") << "storing refcount 1 in location " << filesystem_address << end();
   // save in product
   put(Memory, FILESYSTEM, filesystem_address);
+  trace(9999, "mem") << "storing filesystem address " << filesystem_address << " in location " << FILESYSTEM << end();
 }
 
 int size_of_filesystem() {
diff --git a/090scenario_filesystem_test.mu b/090scenario_filesystem_test.mu
index 02343cba..b959c141 100644
--- a/090scenario_filesystem_test.mu
+++ b/090scenario_filesystem_test.mu
@@ -55,6 +55,30 @@ scenario write-to-fake-file-that-exists [
   ]
 ]
 
+scenario write-to-existing-file-preserves-other-files [
+  local-scope
+  assume-filesystem [
+    [a] <- []
+    [b] <- [
+      |bcd|
+    ]
+  ]
+  sink:address:sink:character, writer:number/routine <- start-writing filesystem:address:filesystem, [a]
+  sink <- write sink, 120/x
+  sink <- write sink, 121/y
+  close sink
+  wait-for-routine writer
+  contents-read-back:address:array:character <- slurp filesystem, [a]
+  10:boolean/raw <- equal contents-read-back, [xy]
+  other-file-contents:address:array:character <- slurp filesystem, [b]
+  11:boolean/raw <- equal other-file-contents, [bcd
+]
+  memory-should-contain [
+    10 <- 1  # file contents read back exactly match what was written
+    11 <- 1  # other files also continue to persist unchanged
+  ]
+]
+
 def slurp fs:address:filesystem, filename:address:array:character -> contents:address:array:character [
   local-scope
   load-ingredients