diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2015-07-29 18:40:36 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2015-07-29 18:40:36 -0700 |
commit | 89b87bc7c493670ecb598784e1073a09f691d43e (patch) | |
tree | b645853bb524a9a57a897a729269786aad8c4ce6 | |
parent | 9570363aec35e187e2395b1760a4b94e71580ac9 (diff) | |
download | mu-89b87bc7c493670ecb598784e1073a09f691d43e.tar.gz |
1886 - gracefully handle malformed ingredients
For example: x:number <- index y:address:array:number, 3 (forgetting to do a lookup) Thanks Caleb Couch.
-rw-r--r-- | 021arithmetic.cc | 6 | ||||
-rw-r--r-- | 024compare.cc | 10 | ||||
-rw-r--r-- | 029tools.cc | 2 | ||||
-rw-r--r-- | 030container.cc | 6 | ||||
-rw-r--r-- | 032array.cc | 7 | ||||
-rw-r--r-- | 033exclusive_container.cc | 2 | ||||
-rw-r--r-- | 035call_ingredient.cc | 3 | ||||
-rw-r--r-- | 038scheduler.cc | 2 | ||||
-rw-r--r-- | 043new.cc | 3 | ||||
-rw-r--r-- | 053continuation.cc | 2 | ||||
-rw-r--r-- | 064random.cc | 2 | ||||
-rw-r--r-- | 081run_interactive.cc | 4 | ||||
-rw-r--r-- | 082persist.cc | 6 |
13 files changed, 32 insertions, 23 deletions
diff --git a/021arithmetic.cc b/021arithmetic.cc index 1485e194..2a21c2cf 100644 --- a/021arithmetic.cc +++ b/021arithmetic.cc @@ -43,6 +43,7 @@ SUBTRACT, Recipe_ordinal["subtract"] = SUBTRACT; :(before "End Primitive Recipe Implementations") case SUBTRACT: { + products.resize(1); if (ingredients.empty()) { raise << current_recipe_name() << ": 'subtract' has no ingredients\n" << end(); break; @@ -53,7 +54,6 @@ case SUBTRACT: { assert(scalar(ingredients.at(i))); result -= ingredients.at(i).at(0); } - products.resize(1); products.at(0).push_back(result); break; } @@ -120,6 +120,7 @@ DIVIDE, Recipe_ordinal["divide"] = DIVIDE; :(before "End Primitive Recipe Implementations") case DIVIDE: { + products.resize(1); if (ingredients.empty()) { raise << current_recipe_name() << ": 'divide' has no ingredients\n" << end(); break; @@ -130,7 +131,6 @@ case DIVIDE: { assert(scalar(ingredients.at(i))); result /= ingredients.at(i).at(0); } - products.resize(1); products.at(0).push_back(result); break; } @@ -163,13 +163,13 @@ DIVIDE_WITH_REMAINDER, Recipe_ordinal["divide-with-remainder"] = DIVIDE_WITH_REMAINDER; :(before "End Primitive Recipe Implementations") case DIVIDE_WITH_REMAINDER: { + products.resize(2); if (SIZE(ingredients) != 2) { raise << current_recipe_name() << ": 'divide-with-remainder' requires exactly two ingredients, but got " << current_instruction().to_string() << '\n' << end(); break; } long long int quotient = ingredients.at(0).at(0) / ingredients.at(1).at(0); long long int remainder = static_cast<long long int>(ingredients.at(0).at(0)) % static_cast<long long int>(ingredients.at(1).at(0)); - products.resize(2); // very large integers will lose precision products.at(0).push_back(quotient); products.at(1).push_back(remainder); diff --git a/024compare.cc b/024compare.cc index fb3481fd..7fb8c2e8 100644 --- a/024compare.cc +++ b/024compare.cc @@ -6,6 +6,7 @@ EQUAL, Recipe_ordinal["equal"] = EQUAL; :(before "End Primitive Recipe Implementations") case EQUAL: { + products.resize(1); if (SIZE(ingredients) <= 1) { raise << current_recipe_name() << ": 'equal' needs at least two ingredients to compare in '" << current_instruction().to_string() << "'\n" << end(); break; @@ -18,7 +19,6 @@ case EQUAL: { break; } } - products.resize(1); products.at(0).push_back(result); break; } @@ -61,6 +61,7 @@ GREATER_THAN, Recipe_ordinal["greater-than"] = GREATER_THAN; :(before "End Primitive Recipe Implementations") case GREATER_THAN: { + products.resize(1); bool result = true; if (SIZE(ingredients) <= 1) { raise << current_recipe_name() << ": 'greater-than' needs at least two ingredients to compare in '" << current_instruction().to_string() << "'\n" << end(); @@ -78,7 +79,6 @@ case GREATER_THAN: { } } finish_greater_than: - products.resize(1); products.at(0).push_back(result); break; } @@ -117,6 +117,7 @@ LESSER_THAN, Recipe_ordinal["lesser-than"] = LESSER_THAN; :(before "End Primitive Recipe Implementations") case LESSER_THAN: { + products.resize(1); bool result = true; if (SIZE(ingredients) <= 1) { raise << current_recipe_name() << ": 'lesser-than' needs at least two ingredients to compare in '" << current_instruction().to_string() << "'\n" << end(); @@ -134,7 +135,6 @@ case LESSER_THAN: { } } finish_lesser_than: - products.resize(1); products.at(0).push_back(result); break; } @@ -173,6 +173,7 @@ GREATER_OR_EQUAL, Recipe_ordinal["greater-or-equal"] = GREATER_OR_EQUAL; :(before "End Primitive Recipe Implementations") case GREATER_OR_EQUAL: { + products.resize(1); bool result = true; if (SIZE(ingredients) <= 1) { raise << current_recipe_name() << ": 'greater-or-equal' needs at least two ingredients to compare in '" << current_instruction().to_string() << "'\n" << end(); @@ -190,7 +191,6 @@ case GREATER_OR_EQUAL: { } } finish_greater_or_equal: - products.resize(1); products.at(0).push_back(result); break; } @@ -237,6 +237,7 @@ LESSER_OR_EQUAL, Recipe_ordinal["lesser-or-equal"] = LESSER_OR_EQUAL; :(before "End Primitive Recipe Implementations") case LESSER_OR_EQUAL: { + products.resize(1); bool result = true; if (SIZE(ingredients) <= 1) { raise << current_recipe_name() << ": 'lesser-or-equal' needs at least two ingredients to compare in '" << current_instruction().to_string() << "'\n" << end(); @@ -254,7 +255,6 @@ case LESSER_OR_EQUAL: { } } finish_lesser_or_equal: - products.resize(1); products.at(0).push_back(result); break; } diff --git a/029tools.cc b/029tools.cc index 9e25f16f..cd4123fa 100644 --- a/029tools.cc +++ b/029tools.cc @@ -182,11 +182,11 @@ _SYSTEM, Recipe_ordinal["$system"] = _SYSTEM; :(before "End Primitive Recipe Implementations") case _SYSTEM: { + products.resize(1); if (current_instruction().ingredients.empty()) { raise << current_recipe_name() << ": '$system' requires exactly one ingredient, but got none\n" << end(); break; } - products.resize(1); int status = system(current_instruction().ingredients.at(0).name.c_str()); products.at(0).push_back(status); break; diff --git a/030container.cc b/030container.cc index 46314d00..15a6eb6f 100644 --- a/030container.cc +++ b/030container.cc @@ -109,6 +109,7 @@ Recipe_ordinal["get"] = GET; case GET: { if (SIZE(ingredients) != 2) { raise << current_recipe_name() << ": 'get' expects exactly 2 ingredients in '" << current_instruction().to_string() << "'\n" << end(); + products.resize(1); break; } reagent base = current_instruction().ingredients.at(0); @@ -116,10 +117,12 @@ case GET: { type_ordinal base_type = base.types.at(0); if (Type[base_type].kind != container) { raise << current_recipe_name () << ": first ingredient of 'get' should be a container, but got " << base.original_string << '\n' << end(); + products.resize(1); break; } if (!is_literal(current_instruction().ingredients.at(1))) { raise << current_recipe_name() << ": second ingredient of 'get' should have type 'offset', but got " << current_instruction().ingredients.at(1).original_string << '\n' << end(); + products.resize(1); break; } assert(scalar(ingredients.at(1))); @@ -188,6 +191,7 @@ GET_ADDRESS, Recipe_ordinal["get-address"] = GET_ADDRESS; :(before "End Primitive Recipe Implementations") case GET_ADDRESS: { + products.resize(1); reagent base = current_instruction().ingredients.at(0); long long int base_address = base.value; type_ordinal base_type = base.types.at(0); @@ -203,7 +207,6 @@ case GET_ADDRESS: { long long int offset = ingredients.at(1).at(0); if (offset < 0 || offset >= SIZE(Type[base_type].elements)) { raise << "invalid offset " << offset << " for " << Type[base_type].name << '\n' << end(); - products.resize(1); break; } long long int result = base_address; @@ -211,7 +214,6 @@ case GET_ADDRESS: { result += size_of(Type[base_type].elements.at(i)); } trace(Primitive_recipe_depth, "run") << "address to copy is " << result << end(); - products.resize(1); products.at(0).push_back(result); break; } diff --git a/032array.cc b/032array.cc index 9f816ceb..5911f1c3 100644 --- a/032array.cc +++ b/032array.cc @@ -81,12 +81,14 @@ Recipe_ordinal["index"] = INDEX; case INDEX: { if (SIZE(ingredients) != 2) { raise << current_recipe_name() << ": 'index' expects exactly 2 ingredients in '" << current_instruction().to_string() << "'\n" << end(); + products.resize(1); break; } reagent base = canonize(current_instruction().ingredients.at(0)); long long int base_address = base.value; if (base.types.at(0) != Type_ordinal["array"]) { raise << current_recipe_name () << ": 'index' on a non-array " << base.original_string << '\n' << end(); + products.resize(1); break; } reagent offset = canonize(current_instruction().ingredients.at(1)); @@ -171,6 +173,7 @@ INDEX_ADDRESS, Recipe_ordinal["index-address"] = INDEX_ADDRESS; :(before "End Primitive Recipe Implementations") case INDEX_ADDRESS: { + products.resize(1); if (SIZE(ingredients) != 2) { raise << current_recipe_name() << ": 'index-address' expects exactly 2 ingredients in '" << current_instruction().to_string() << "'\n" << end(); break; @@ -186,11 +189,9 @@ case INDEX_ADDRESS: { vector<type_ordinal> element_type = array_element(base.types); if (offset_val.at(0) < 0 || offset_val.at(0) >= Memory[base_address]) { raise << current_recipe_name() << ": invalid index " << offset_val.at(0) << '\n' << end(); - 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; } @@ -243,6 +244,7 @@ LENGTH, Recipe_ordinal["length"] = LENGTH; :(before "End Primitive Recipe Implementations") case LENGTH: { + products.resize(1); if (SIZE(ingredients) != 1) { raise << current_recipe_name() << ": 'length' expects exactly 2 ingredients in '" << current_instruction().to_string() << "'\n" << end(); break; @@ -252,7 +254,6 @@ case LENGTH: { raise << "tried to calculate length of non-array " << x.original_string << '\n' << end(); break; } - products.resize(1); products.at(0).push_back(Memory[x.value]); break; } diff --git a/033exclusive_container.cc b/033exclusive_container.cc index 3893d46f..65995b14 100644 --- a/033exclusive_container.cc +++ b/033exclusive_container.cc @@ -83,6 +83,7 @@ MAYBE_CONVERT, Recipe_ordinal["maybe-convert"] = MAYBE_CONVERT; :(before "End Primitive Recipe Implementations") case MAYBE_CONVERT: { + products.resize(1); if (SIZE(ingredients) != 2) { raise << current_recipe_name() << ": 'maybe-convert' expects exactly 2 ingredients in '" << current_instruction().to_string() << "'\n" << end(); break; @@ -106,7 +107,6 @@ case MAYBE_CONVERT: { else { result = 0; } - products.resize(1); products.at(0).push_back(result); break; } diff --git a/035call_ingredient.cc b/035call_ingredient.cc index 599906da..a2dd97ad 100644 --- a/035call_ingredient.cc +++ b/035call_ingredient.cc @@ -39,6 +39,7 @@ Recipe_ordinal["next-ingredient"] = NEXT_INGREDIENT; case NEXT_INGREDIENT: { if (!ingredients.empty()) { raise << current_recipe_name() << ": 'next-ingredient' didn't expect any ingredients in '" << current_instruction().to_string() << "'\n" << end(); + products.resize(2); break; } assert(!Current_routine->calls.empty()); @@ -101,10 +102,12 @@ Recipe_ordinal["ingredient"] = INGREDIENT; case INGREDIENT: { if (SIZE(ingredients) != 1) { raise << current_recipe_name() << ": 'ingredient' expects exactly one ingredient, but got '" << current_instruction().to_string() << "'\n" << end(); + products.resize(2); break; } if (!is_literal(current_instruction().ingredients.at(0))) { raise << current_recipe_name() << ": 'ingredient' expects a literal ingredient, but got " << current_instruction().ingredients.at(0).original_string << '\n' << end(); + products.resize(2); break; } assert(scalar(ingredients.at(0))); diff --git a/038scheduler.cc b/038scheduler.cc index d32fb76a..5925abab 100644 --- a/038scheduler.cc +++ b/038scheduler.cc @@ -281,6 +281,7 @@ ROUTINE_STATE, Recipe_ordinal["routine-state"] = ROUTINE_STATE; :(before "End Primitive Recipe Implementations") case ROUTINE_STATE: { + products.resize(1); if (SIZE(ingredients) != 1) { raise << current_recipe_name() << ": 'routine-state' requires exactly one ingredient, but got " << current_instruction().to_string() << '\n' << end(); break; @@ -297,7 +298,6 @@ case ROUTINE_STATE: { break; } } - products.resize(1); products.at(0).push_back(result); break; } diff --git a/043new.cc b/043new.cc index 191d9e87..c324bff7 100644 --- a/043new.cc +++ b/043new.cc @@ -56,12 +56,14 @@ NEW, Recipe_ordinal["new"] = NEW; :(before "End Primitive Recipe Implementations") case NEW: { + products.resize(1); if (ingredients.empty() || SIZE(ingredients) > 2) { raise << current_recipe_name() << ": 'new' requires one or two ingredients, but got " << current_instruction().to_string() << '\n' << end(); break; } if (!scalar(ingredients.at(0))) { raise << current_recipe_name() << ": first ingredient of 'new' should be a type, but got " << current_instruction().ingredients.at(0).original_string << '\n' << end(); + break; } // compute the space we need long long int size = 0; @@ -88,7 +90,6 @@ case NEW: { const long long int result = Current_routine->alloc; trace(Primitive_recipe_depth, "mem") << "new alloc: " << result << end(); // save result - products.resize(1); products.at(0).push_back(result); // initialize allocated space for (long long int address = result; address < result+size; ++address) { diff --git a/053continuation.cc b/053continuation.cc index 20cf1b05..5885fd40 100644 --- a/053continuation.cc +++ b/053continuation.cc @@ -193,6 +193,7 @@ REPLY_DELIMITED_CONTINUATION, Recipe_ordinal["reply-delimited-continuation"] = REPLY_DELIMITED_CONTINUATION; :(before "End Primitive Recipe Implementations") case REPLY_DELIMITED_CONTINUATION: { + products.resize(1); // first clear any existing ingredients, to isolate the creation of the // continuation from its calls Current_routine->calls.front().ingredient_atoms.clear(); @@ -210,7 +211,6 @@ case REPLY_DELIMITED_CONTINUATION: { Current_routine->calls.pop_front(); } // return it as the result of the 'reset' call - products.resize(1); products.at(0).push_back(Next_delimited_continuation_id); ++Next_delimited_continuation_id; break; // continue to process rest of 'reset' call diff --git a/064random.cc b/064random.cc index bd171132..cdc519c9 100644 --- a/064random.cc +++ b/064random.cc @@ -27,6 +27,7 @@ ROUND, Recipe_ordinal["round"] = ROUND; :(before "End Primitive Recipe Implementations") case ROUND: { + products.resize(1); if (SIZE(ingredients) != 1) { raise << current_recipe_name() << ": 'round' requires exactly one ingredient, but got " << current_instruction().to_string() << '\n' << end(); break; @@ -35,7 +36,6 @@ case ROUND: { raise << current_recipe_name() << ": first ingredient of 'round' should be a number, but got " << current_instruction().ingredients.at(0).original_string << '\n' << end(); break; } - products.resize(1); products.at(0).push_back(rint(ingredients.at(0).at(0))); break; } diff --git a/081run_interactive.cc b/081run_interactive.cc index 242578c7..1f6c0407 100644 --- a/081run_interactive.cc +++ b/081run_interactive.cc @@ -26,6 +26,7 @@ Recipe_ordinal["run-interactive"] = RUN_INTERACTIVE; //? cerr << "run-interactive: " << RUN_INTERACTIVE << '\n'; //? 1 :(before "End Primitive Recipe Implementations") case RUN_INTERACTIVE: { + products.resize(3); if (SIZE(ingredients) != 1) { raise << current_recipe_name() << ": 'run-interactive' requires exactly one ingredient, but got " << current_instruction().to_string() << '\n' << end(); break; @@ -34,7 +35,6 @@ case RUN_INTERACTIVE: { raise << current_recipe_name() << ": first ingredient of 'run-interactive' should be a literal string, but got " << current_instruction().ingredients.at(0).original_string << '\n' << end(); break; } - products.resize(3); bool new_code_pushed_to_stack = run_interactive(ingredients.at(0).at(0)); if (!new_code_pushed_to_stack) { products.at(0).push_back(0); @@ -269,6 +269,7 @@ RELOAD, Recipe_ordinal["reload"] = RELOAD; :(before "End Primitive Recipe Implementations") case RELOAD: { + products.resize(1); if (SIZE(ingredients) != 1) { raise << current_recipe_name() << ": 'reload' requires exactly one ingredient, but got " << current_instruction().to_string() << '\n' << end(); break; @@ -289,7 +290,6 @@ case RELOAD: { Trace_stream->newline(); // flush trace Disable_redefine_warnings = false; Hide_warnings = false; - products.resize(1); products.at(0).push_back(warnings_from_trace()); if (Trace_stream->collect_layer == "warn") { delete Trace_stream; diff --git a/082persist.cc b/082persist.cc index d663773c..d63176bd 100644 --- a/082persist.cc +++ b/082persist.cc @@ -8,13 +8,15 @@ RESTORE, Recipe_ordinal["restore"] = RESTORE; :(before "End Primitive Recipe Implementations") case RESTORE: { + products.resize(1); if (SIZE(ingredients) != 1) { raise << current_recipe_name() << ": 'restore' requires exactly one ingredient, but got " << current_instruction().to_string() << '\n' << end(); break; } - if (!scalar(ingredients.at(0))) + if (!scalar(ingredients.at(0))) { raise << current_recipe_name() << ": first ingredient of 'restore' should be a literal string, but got " << current_instruction().ingredients.at(0).to_string() << '\n' << end(); - products.resize(1); + break; + } if (Current_scenario) break; // do nothing in tests string filename = current_instruction().ingredients.at(0).name; if (!is_literal(current_instruction().ingredients.at(0))) |