about summary refs log tree commit diff stats
path: root/032array.cc
diff options
context:
space:
mode:
Diffstat (limited to '032array.cc')
-rw-r--r--032array.cc88
1 files changed, 77 insertions, 11 deletions
diff --git a/032array.cc b/032array.cc
index 20cba6fe..e9aef14c 100644
--- a/032array.cc
+++ b/032array.cc
@@ -87,8 +87,11 @@ case INDEX: {
   vector<type_ordinal> element_type = array_element(base.types);
 //?   trace(Primitive_recipe_depth, "run") << "offset: " << offset_val.at(0); //? 1
 //?   trace(Primitive_recipe_depth, "run") << "size of elements: " << size_of(element_type); //? 1
-  assert(offset_val.at(0) >= 0);
-  assert(offset_val.at(0) < Memory[base_address]*size_of(element_type) + 1);
+  if (offset_val.at(0) < 0 || offset_val.at(0) >= Memory[base_address]) {
+    raise << current_recipe_name() << ": invalid index " << offset_val.at(0) << '\n';
+    products.resize(1);
+    break;
+  }
   long long int src = base_address + 1 + offset_val.at(0)*size_of(element_type);
   trace(Primitive_recipe_depth, "run") << "address to copy is " << src;
   trace(Primitive_recipe_depth, "run") << "its type is " << Type[element_type.at(0)].name;
@@ -104,28 +107,58 @@ vector<type_ordinal> array_element(const vector<type_ordinal>& types) {
   return vector<type_ordinal>(++types.begin(), types.end());
 }
 
-:(scenario index_address)
+:(scenario index_indirect)
 recipe main [
   1:number <- copy 3:literal  # length
   2:number <- copy 14:literal
   3:number <- copy 15:literal
   4:number <- copy 16:literal
-  5:number <- index-address 1:array:number/raw, 0:literal  # unsafe
+  5:address:array:number <- copy 1:literal
+  6:number <- index 5:address:array:number/deref, 1:literal
 ]
-+mem: storing 2 in location 5
++mem: storing 15 in location 6
+
+:(scenario index_out_of_bounds)
+% Hide_warnings = true;
+recipe main [
+  1:number <- copy 3:literal  # 3 points
+  2:number <- copy 14:literal
+  3:number <- copy 15:literal
+  4:number <- copy 16:literal
+  5:number <- copy 14:literal
+  6:number <- copy 15:literal
+  7:number <- copy 16:literal
+  8:address:array:point <- copy 1:literal
+  index 8:address:array:point/deref, 4:literal  # less than size of array in locations, but larger than its length in elements
+]
++warn: main: invalid index 4
+
+:(scenario index_out_of_bounds2)
+% Hide_warnings = true;
+recipe main [
+  1:number <- copy 3:literal  # 3 points
+  2:number <- copy 14:literal
+  3:number <- copy 15:literal
+  4:number <- copy 16:literal
+  5:number <- copy 14:literal
+  6:number <- copy 15:literal
+  7:number <- copy 16:literal
+  8:address:array:point <- copy 1:literal
+  index 8:address:array:point/deref, -1:literal
+]
++warn: main: invalid index -1
 
 //:: To write to elements of containers, you need their address.
 
-:(scenario index_indirect)
+:(scenario index_address)
 recipe main [
   1:number <- copy 3:literal  # length
   2:number <- copy 14:literal
   3:number <- copy 15:literal
   4:number <- copy 16:literal
-  5:address:array:number <- copy 1:literal
-  6:number <- index 5:address:array:number/deref, 1:literal
+  5:number <- index-address 1:array:number/raw, 0:literal  # unsafe
 ]
-+mem: storing 15 in location 6
++mem: storing 2 in location 5
 
 :(before "End Primitive Recipe Declarations")
 INDEX_ADDRESS,
@@ -139,14 +172,47 @@ case INDEX_ADDRESS: {
   reagent offset = canonize(current_instruction().ingredients.at(1));
   vector<double> offset_val(read_memory(offset));
   vector<type_ordinal> element_type = array_element(base.types);
-  assert(offset_val.at(0) >= 0);
-  assert(offset_val.at(0) < Memory[base_address]*size_of(element_type) + 1);
+  if (offset_val.at(0) < 0 || offset_val.at(0) >= Memory[base_address]) {
+    raise << current_recipe_name() << ": invalid index " << offset_val.at(0) << '\n';
+    products.resize(1);
+    break;
+  }
   long long int result = base_address + 1 + offset_val.at(0)*size_of(element_type);
   products.resize(1);
   products.at(0).push_back(result);
   break;
 }
 
+:(scenario index_address_out_of_bounds)
+% Hide_warnings = true;
+recipe main [
+  1:number <- copy 3:literal  # 3 points
+  2:number <- copy 14:literal
+  3:number <- copy 15:literal
+  4:number <- copy 16:literal
+  5:number <- copy 14:literal
+  6:number <- copy 15:literal
+  7:number <- copy 16:literal
+  8:address:array:point <- copy 1:literal
+  index-address 8:address:array:point/deref, 4:literal  # less than size of array in locations, but larger than its length in elements
+]
++warn: main: invalid index 4
+
+:(scenario index_address_out_of_bounds2)
+% Hide_warnings = true;
+recipe main [
+  1:number <- copy 3:literal  # 3 points
+  2:number <- copy 14:literal
+  3:number <- copy 15:literal
+  4:number <- copy 16:literal
+  5:number <- copy 14:literal
+  6:number <- copy 15:literal
+  7:number <- copy 16:literal
+  8:address:array:point <- copy 1:literal
+  index-address 8:address:array:point/deref, -1:literal
+]
++warn: main: invalid index -1
+
 //:: compute the length of an array
 
 :(scenario array_length)