From b2566a847948ba808d4ca93d02bcc62ee6487255 Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Tue, 2 Feb 2016 09:59:40 -0800 Subject: 2625 --- html/038new.cc.html | 99 ++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 90 insertions(+), 9 deletions(-) (limited to 'html/038new.cc.html') diff --git a/html/038new.cc.html b/html/038new.cc.html index 1ba4365a..07a6d9ec 100644 --- a/html/038new.cc.html +++ b/html/038new.cc.html @@ -22,7 +22,6 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; } .Special { color: #ff6060; } .Identifier { color: #804000; } .Constant { color: #00a0a0; } -.Todo { color: #000000; background-color: #ffff00; padding-bottom: 1px; } --> @@ -130,21 +129,28 @@ case NEW: { raise_error << maybe(caller.name) << "result of 'new' should never be ignored\n" << end(); break; } - reagent product(inst.products.at(0)); + if (!product_of_new_is_valid(inst)) { + raise_error << maybe(caller.name) << "product of 'new' has incorrect type: " << inst.to_string() << '\n' << end(); + break; + } + break; +} +:(code) +bool product_of_new_is_valid(const instruction& inst) { + reagent product = inst.products.at(0); canonize_type(product); + if (!product.type || product.type->value != get(Type_ordinal, "address")) return false; drop_from_type(product, "address"); + if (!product.type || product.type->value != get(Type_ordinal, "shared")) return false; drop_from_type(product, "shared"); if (SIZE(inst.ingredients) > 1) { // array allocation + if (!product.type || product.type->value != get(Type_ordinal, "array")) return false; drop_from_type(product, "array"); } - reagent expected_product("x:"+type.name); + reagent expected_product("x:"+inst.ingredients.at(0).name); // End Post-processing(expected_product) When Checking 'new' - if (!types_strictly_match(product, expected_product)) { - raise_error << maybe(caller.name) << "product of 'new' has incorrect type: " << inst.to_string() << '\n' << end(); - break; - } - break; + return types_strictly_match(product, expected_product); } //:: translate 'new' to 'allocate' instructions that take a size instead of a type @@ -265,6 +271,13 @@ recipe main [ ] +mem: storing 0 in location 2 +:(scenario new_error) +% Hide_errors = true; +recipe main [ + 1:address:number/raw <- new number:type +] ++error: main: product of 'new' has incorrect type: 1:address:number/raw <- new number:type + :(scenario new_array) recipe main [ 1:address:shared:array:number/raw <- new number:type, 5 @@ -457,6 +470,7 @@ if (x.type(Memory, old_address, old_refcount-1); } // perform the write +//? trace(9999, "mem") << "038new.cc:424: location " << x.value << " contains " << old_address << " with refcount " << get_or_insert(Memory, old_address) << end(); trace(9999, "mem") << "storing " << no_scientific(data.at(0)) << " in location " << base << end(); put(Memory, base, new_address); // increment refcount of new address @@ -468,7 +482,9 @@ if (x.type} // abandon old address if necessary // do this after all refcount updates are done just in case old and new are identical - // TODO: doesn't work yet +//? if (get_or_insert(Memory, old_address) < 0) { +//? DUMP(""); +//? } assert(get_or_insert(Memory, old_address) >= 0); if (old_address && get_or_insert(Memory, old_address) == 0) { // lookup_memory without drop_one_lookup { @@ -478,11 +494,76 @@ if (x.type(x, "address"); drop_from_type(x, "shared"); // } +//? cerr << "ABANDON\n"; abandon(old_address, size_of(x)+/*refcount*/1); } return; } +:(scenario refcounts_2) +recipe main [ + 1:address:shared:number <- new number:type + # over-writing one allocation with another + 1:address:shared:number <- new number:type + 1:address:shared:number <- copy 0 +] ++run: 1:address:shared:number <- new number:type ++mem: incrementing refcount of 1000: 0 -> 1 ++run: 1:address:shared:number <- new number:type ++mem: automatically abandoning 1000 + +:(scenario refcounts_3) +recipe main [ + 1:address:shared:number <- new number:type + # passing in addresses to recipes increments refcount + foo 1:address:shared:number + 1:address:shared:number <- copy 0 +] +recipe foo [ + 2:address:shared:number <- next-ingredient + # return does NOT yet decrement refcount; memory must be explicitly managed + 2:address:shared:number <- copy 0 +] ++run: 1:address:shared:number <- new number:type ++mem: incrementing refcount of 1000: 0 -> 1 ++run: 2:address:shared:number <- next-ingredient ++mem: incrementing refcount of 1000: 1 -> 2 ++run: 2:address:shared:number <- copy 0 ++mem: decrementing refcount of 1000: 2 -> 1 ++run: 1:address:shared:number <- copy 0 ++mem: decrementing refcount of 1000: 1 -> 0 ++mem: automatically abandoning 1000 + +:(scenario refcounts_4) +recipe main [ + 1:address:shared:number <- new number:type + # idempotent copies leave refcount unchanged + 1:address:shared:number <- copy 1:address:shared:number +] ++run: 1:address:shared:number <- new number:type ++mem: incrementing refcount of 1000: 0 -> 1 ++run: 1:address:shared:number <- copy 1:address:shared:number ++mem: decrementing refcount of 1000: 1 -> 0 ++mem: incrementing refcount of 1000: 0 -> 1 + +:(scenario refcounts_5) +recipe main [ + 1:address:shared:number <- new number:type + # passing in addresses to recipes increments refcount + foo 1:address:shared:number + # return does NOT yet decrement refcount; memory must be explicitly managed + 1:address:shared:number <- new number:type +] +recipe foo [ + 2:address:shared:number <- next-ingredient +] ++run: 1:address:shared:number <- new number:type ++mem: incrementing refcount of 1000: 0 -> 1 ++run: 2:address:shared:number <- next-ingredient ++mem: incrementing refcount of 1000: 1 -> 2 ++run: 1:address:shared:number <- new number:type ++mem: decrementing refcount of 1000: 2 -> 1 + //:: Extend 'new' to handle a unicode string literal argument. :(scenario new_string) -- cgit 1.4.1-2-gfad0