From 9f7f62eda3d591eb66db6ddc2c9a646a1a9fd6d1 Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Mon, 7 Nov 2016 09:59:51 -0800 Subject: 3645 Extract a helper to compute the element type of an array. As a side effect, the hack for disambiguating array:address:number and array:number:3 is now in just one place. --- 030container.cc | 6 ++---- 032array.cc | 43 +++++++++++++++++-------------------------- 036refcount.cc | 15 ++++++--------- 037abandon.cc | 2 +- 4 files changed, 26 insertions(+), 40 deletions(-) diff --git a/030container.cc b/030container.cc index 6d16d689..626587f8 100644 --- a/030container.cc +++ b/030container.cc @@ -209,18 +209,16 @@ void compute_container_sizes(const type_tree* type, set& pending_meta pending_metadata.insert(*type); if (!type->atom) { assert(type->left->atom); - if (type->left->name == "address") { + if (type->left->name == "address") compute_container_sizes(type->right, pending_metadata, location_for_error_messages); - } // End compute_container_sizes Non-atom Special-cases return; } assert(type->atom); if (!contains_key(Type, type->value)) return; // error raised elsewhere type_info& info = get(Type, type->value); - if (info.kind == CONTAINER) { + if (info.kind == CONTAINER) compute_container_sizes(info, type, pending_metadata, location_for_error_messages); - } // End compute_container_sizes Atom Special-cases } diff --git a/032array.cc b/032array.cc index d2b6c698..7344ffe1 100644 --- a/032array.cc +++ b/032array.cc @@ -104,10 +104,7 @@ if (!r.type->atom && r.type->left->atom && r.type->left->value == get(Type_ordin raise << maybe(current_recipe_name()) << "'" << r.original_string << "' is an array of what?\n" << end(); return 1; } - type_tree* element_type = copy_array_element(r.type); - int result = 1 + array_length(r)*size_of(element_type); - delete element_type; - return result; + return /*space for length*/1 + array_length(r)*size_of(array_element(r.type)); } //: disable the size mismatch check for arrays since the destination array @@ -190,13 +187,8 @@ def foo [ //: make sure we compute container sizes inside arrays :(before "End compute_container_sizes Non-atom Special-cases") -else if (type->left->name == "array") { - const type_tree* element_type = type->right; - // hack: support both array:num:3 and array:address:num - if (!element_type->atom && element_type->right && element_type->right->atom && is_integer(element_type->right->name)) - element_type = element_type->left; - compute_container_sizes(element_type, pending_metadata, location_for_error_messages); -} +else if (type->left->name == "array") + compute_container_sizes(array_element(type), pending_metadata, location_for_error_messages); :(before "End Unit Tests") void test_container_sizes_from_array() { @@ -318,7 +310,7 @@ case INDEX: { if (inst.products.empty()) break; reagent/*copy*/ product = inst.products.at(0); // Update INDEX product in Check - reagent element; + reagent/*local*/ element; element.type = copy_array_element(base.type); if (!types_coercible(product, element)) { raise << maybe(get(Recipe, r).name) << "'index' on '" << base.original_string << "' can't be saved in '" << product.original_string << "'; type should be '" << names_to_string_without_quotes(element.type) << "'\n" << end(); @@ -343,13 +335,11 @@ case INDEX: { raise << maybe(current_recipe_name()) << "invalid index " << no_scientific(index_val.at(0)) << " in '" << to_original_string(current_instruction()) << "'\n" << end(); break; } - type_tree* element_type = copy_array_element(base.type); - int src = base_address + 1 + index_val.at(0)*size_of(element_type); - trace(9998, "run") << "address to copy is " << src << end(); - trace(9998, "run") << "its type is " << to_string(element_type) << end(); - reagent element; - element.set_value(src); - element.type = element_type; + reagent/*local*/ element; + element.type = copy_array_element(base.type); + element.set_value(base_address + /*skip length*/1 + index_val.at(0)*size_of(element.type)); + trace(9998, "run") << "address to copy is " << element.value << end(); + trace(9998, "run") << "its type is " << to_string(element.type) << end(); // Read element products.push_back(read_memory(element)); break; @@ -357,11 +347,15 @@ case INDEX: { :(code) type_tree* copy_array_element(const type_tree* type) { + return new type_tree(*array_element(type)); +} + +type_tree* array_element(const type_tree* type) { assert(type->right); // hack: don't require parens for either array:num:3 array:address:num if (!type->right->atom && type->right->right && type->right->right->atom && is_integer(type->right->right->name)) - return new type_tree(*type->right->left); - return new type_tree(*type->right); + return type->right->left; + return type->right; } int array_length(const reagent& x) { @@ -486,7 +480,7 @@ case PUT_INDEX: { } reagent/*copy*/ value = inst.ingredients.at(2); // Update PUT_INDEX value in Check - reagent element; + reagent/*local*/ element; element.type = copy_array_element(base.type); if (!types_coercible(element, value)) { raise << maybe(get(Recipe, r).name) << "'put-index " << base.original_string << ", " << inst.ingredients.at(1).original_string << "' should store " << names_to_string_without_quotes(element.type) << " but '" << value.name << "' has type " << names_to_string_without_quotes(value.type) << '\n' << end(); @@ -516,10 +510,7 @@ case PUT_INDEX: { raise << maybe(current_recipe_name()) << "invalid index " << no_scientific(index_val.at(0)) << " in '" << to_original_string(current_instruction()) << "'\n" << end(); break; } - reagent element; - element.type = copy_array_element(base.type); - int address = base_address + 1 + index_val.at(0)*size_of(element.type); - element.set_value(address); + int address = base_address + /*skip length*/1 + index_val.at(0)*size_of(array_element(base.type)); trace(9998, "run") << "address to copy to is " << address << end(); // optimization: directly write the element rather than updating 'product' // and writing the entire array diff --git a/036refcount.cc b/036refcount.cc index ba0f3560..213cbf36 100644 --- a/036refcount.cc +++ b/036refcount.cc @@ -158,6 +158,9 @@ def main [ +mem: incrementing refcount of 1000: 1 -> 2 :(after "Write Memory in PUT_INDEX in Run") +reagent/*local*/ element; +element.set_value(address); +element.type = copy_array_element(base.type); update_any_refcounts(element, value); :(scenario refcounts_maybe_convert) @@ -309,16 +312,10 @@ void compute_container_address_offsets(const type_tree* type, const string& loca if (!type) return; if (!type->atom) { assert(type->left->atom); - if (type->left->name == "address") { + if (type->left->name == "address") compute_container_address_offsets(type->right, location_for_error_messages); - } - else if (type->left->name == "array") { - const type_tree* element_type = type->right; - // hack: support both array:num:3 and array:address:num - if (!element_type->atom && element_type->right && element_type->right->atom && is_integer(element_type->right->name)) - element_type = element_type->left; - compute_container_address_offsets(element_type, location_for_error_messages); - } + else if (type->left->name == "array") + compute_container_address_offsets(array_element(type), location_for_error_messages); // End compute_container_address_offsets Non-atom Special-cases } if (!contains_key(Type, root_type(type)->value)) return; // error raised elsewhere diff --git a/037abandon.cc b/037abandon.cc index 567e7e97..d29d624a 100644 --- a/037abandon.cc +++ b/037abandon.cc @@ -32,7 +32,7 @@ void abandon(int address, const type_tree* payload_type, int payload_size) { //? cerr << "abandon: " << size << '\n'; // decrement any contained refcounts if (is_mu_array(payload_type)) { - reagent element; + reagent/*local*/ element; element.type = copy_array_element(payload_type); int array_length = get_or_insert(Memory, address+/*skip refcount*/1); assert(element.type->name != "array"); -- cgit 1.4.1-2-gfad0