2678
Start using type names from the type tree rather than the property tree in most places. Hopefully the only occurrences of 'properties.at(0).second' left are ones where we're managing it. Next we can stop writing to it.
This commit is contained in:
parent
343bc5359b
commit
65c905fe84
3
010vm.cc
3
010vm.cc
|
@ -269,7 +269,7 @@ type_tree* new_type_tree(const string_tree* properties) {
|
|||
if (!properties) return NULL;
|
||||
type_tree* result = new type_tree("", 0);
|
||||
if (!properties->value.empty()) {
|
||||
const string& type_name = properties->value;
|
||||
const string& type_name = result->name = properties->value;
|
||||
if (contains_key(Type_ordinal, type_name))
|
||||
result->value = get(Type_ordinal, type_name);
|
||||
else if (is_integer(type_name)) // sometimes types will contain non-type tags, like numbers for the size of an array
|
||||
|
@ -298,6 +298,7 @@ reagent::reagent(const reagent& old) {
|
|||
}
|
||||
|
||||
type_tree::type_tree(const type_tree& old) {
|
||||
name = old.name;
|
||||
value = old.value;
|
||||
left = old.left ? new type_tree(*old.left) : NULL;
|
||||
right = old.right ? new type_tree(*old.right) : NULL;
|
||||
|
|
|
@ -124,7 +124,7 @@ if (s.at(0) == '[') {
|
|||
|
||||
:(code)
|
||||
bool is_literal_string(const reagent& x) {
|
||||
return x.properties.at(0).second && x.properties.at(0).second->value == "literal-string";
|
||||
return x.type && x.type->name == "literal-string";
|
||||
}
|
||||
|
||||
string emit_literal_string(string name) {
|
||||
|
|
|
@ -181,8 +181,8 @@ bool is_mu_number(reagent r) {
|
|||
if (!r.type) return false;
|
||||
if (is_literal(r)) {
|
||||
if (!r.properties.at(0).second) return false;
|
||||
return r.properties.at(0).second->value == "literal-number"
|
||||
|| r.properties.at(0).second->value == "literal";
|
||||
return r.type->name == "literal-number"
|
||||
|| r.type->name == "literal";
|
||||
}
|
||||
if (r.type->value == get(Type_ordinal, "character")) return true; // permit arithmetic on unicode code points
|
||||
return r.type->value == get(Type_ordinal, "number");
|
||||
|
@ -191,7 +191,7 @@ bool is_mu_number(reagent r) {
|
|||
bool is_mu_scalar(reagent r) {
|
||||
if (!r.type) return false;
|
||||
if (is_literal(r))
|
||||
return !r.properties.at(0).second || r.properties.at(0).second->value != "literal-string";
|
||||
return !r.properties.at(0).second || r.type->name != "literal-string";
|
||||
if (is_mu_array(r)) return false;
|
||||
return size_of(r) == 1;
|
||||
}
|
||||
|
|
|
@ -437,7 +437,7 @@ type_tree* new_type_tree_with_new_types_for_unknown(const string_tree* propertie
|
|||
if (!properties) return NULL;
|
||||
type_tree* result = new type_tree("", 0);
|
||||
if (!properties->value.empty()) {
|
||||
const string& type_name = properties->value;
|
||||
const string& type_name = result->name = properties->value;
|
||||
if (contains_key(Type_ordinal, type_name)) {
|
||||
result->value = get(Type_ordinal, type_name);
|
||||
}
|
||||
|
|
|
@ -106,8 +106,8 @@ void drop_from_type(reagent& r, string expected_type) {
|
|||
raise_error << "can't drop " << expected_type << " from " << to_string(r) << '\n' << end();
|
||||
return;
|
||||
}
|
||||
if (r.properties.at(0).second->value != expected_type) {
|
||||
raise_error << "can't drop " << expected_type << " from " << to_string(r) << '\n' << end();
|
||||
if (r.type->name != expected_type) {
|
||||
raise_error << "can't drop2 " << expected_type << " from " << to_string(r) << '\n' << end();
|
||||
return;
|
||||
}
|
||||
type_tree* tmp = r.type;
|
||||
|
|
|
@ -34,13 +34,13 @@
|
|||
type_ordinal shared = put(Type_ordinal, "shared", Next_type_ordinal++);
|
||||
get_or_insert(Type, shared).name = "shared";
|
||||
:(before "End Drop Address In lookup_memory(x)")
|
||||
if (x.properties.at(0).second->value == "shared") {
|
||||
if (x.type->name == "shared") {
|
||||
trace(9999, "mem") << "skipping refcount at " << x.value << end();
|
||||
x.set_value(x.value+1); // skip refcount
|
||||
drop_from_type(x, "shared");
|
||||
}
|
||||
:(before "End Drop Address In canonize_type(r)")
|
||||
if (r.properties.at(0).second->value == "shared") {
|
||||
if (r.type->name == "shared") {
|
||||
drop_from_type(r, "shared");
|
||||
}
|
||||
|
||||
|
@ -655,5 +655,5 @@ string read_mu_string(long long int address) {
|
|||
bool is_mu_type_literal(reagent r) {
|
||||
//? if (!r.properties.empty())
|
||||
//? dump_property(r.properties.at(0).second, cerr);
|
||||
return is_literal(r) && !r.properties.empty() && r.properties.at(0).second && r.properties.at(0).second->value == "type";
|
||||
return is_literal(r) && !r.properties.empty() && r.properties.at(0).second && r.type->name == "type";
|
||||
}
|
||||
|
|
|
@ -121,7 +121,7 @@ void append_fragment(vector<instruction>& base, const vector<instruction>& patch
|
|||
for (long long int j = 0; j < SIZE(inst.ingredients); ++j) {
|
||||
reagent& x = inst.ingredients.at(j);
|
||||
if (!is_literal(x)) continue;
|
||||
if (x.properties.at(0).second->value == "label" && contains_key(jump_targets, x.name))
|
||||
if (x.type->name == "label" && contains_key(jump_targets, x.name))
|
||||
x.name = prefix+x.name;
|
||||
}
|
||||
base.push_back(inst);
|
||||
|
|
|
@ -273,10 +273,12 @@ void replace_type_ingredients(type_tree* element_type, string_tree* element_type
|
|||
// rather than {foo: (number)}
|
||||
// We'd also like to use it with multiple types: foo:address:number.
|
||||
replacement = curr;
|
||||
if (!final_type_ingredient(type_ingredient_index, container_info))
|
||||
if (!final_type_ingredient(type_ingredient_index, container_info)) {
|
||||
splice_right = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
element_type->name = replacement->name;
|
||||
element_type->value = replacement->value;
|
||||
assert(!element_type->left); // since value is set
|
||||
element_type->left = replacement->left ? new type_tree(*replacement->left) : NULL;
|
||||
|
@ -346,8 +348,8 @@ void test_replace_type_ingredients_entire() {
|
|||
reagent callsite("x:foo:point");
|
||||
reagent element = element_type(callsite, 0);
|
||||
CHECK_EQ(element.name, "x");
|
||||
CHECK_EQ(element.properties.at(0).second->value, "point");
|
||||
CHECK(!element.properties.at(0).second->right);
|
||||
CHECK_EQ(element.type->name, "point");
|
||||
CHECK(!element.type->right);
|
||||
}
|
||||
|
||||
void test_replace_type_ingredients_tail() {
|
||||
|
@ -360,9 +362,9 @@ void test_replace_type_ingredients_tail() {
|
|||
reagent callsite("x:bar:point");
|
||||
reagent element = element_type(callsite, 0);
|
||||
CHECK_EQ(element.name, "x");
|
||||
CHECK_EQ(element.properties.at(0).second->value, "foo");
|
||||
CHECK_EQ(element.properties.at(0).second->right->value, "point");
|
||||
CHECK(!element.properties.at(0).second->right->right);
|
||||
CHECK_EQ(element.type->name, "foo");
|
||||
CHECK_EQ(element.type->right->name, "point");
|
||||
CHECK(!element.type->right->right);
|
||||
}
|
||||
|
||||
void test_replace_type_ingredients_head_tail_multiple() {
|
||||
|
@ -375,12 +377,12 @@ void test_replace_type_ingredients_head_tail_multiple() {
|
|||
reagent callsite("x:bar:address:shared:array:character");
|
||||
reagent element = element_type(callsite, 0);
|
||||
CHECK_EQ(element.name, "x");
|
||||
CHECK_EQ(element.properties.at(0).second->value, "foo");
|
||||
CHECK_EQ(element.properties.at(0).second->right->value, "address");
|
||||
CHECK_EQ(element.properties.at(0).second->right->right->value, "shared");
|
||||
CHECK_EQ(element.properties.at(0).second->right->right->right->value, "array");
|
||||
CHECK_EQ(element.properties.at(0).second->right->right->right->right->value, "character");
|
||||
CHECK(!element.properties.at(0).second->right->right->right->right->right);
|
||||
CHECK_EQ(element.type->name, "foo");
|
||||
CHECK_EQ(element.type->right->name, "address");
|
||||
CHECK_EQ(element.type->right->right->name, "shared");
|
||||
CHECK_EQ(element.type->right->right->right->name, "array");
|
||||
CHECK_EQ(element.type->right->right->right->right->name, "character");
|
||||
CHECK(!element.type->right->right->right->right->right);
|
||||
}
|
||||
|
||||
void test_replace_type_ingredients_head_middle() {
|
||||
|
@ -393,13 +395,13 @@ void test_replace_type_ingredients_head_middle() {
|
|||
reagent callsite("x:bar:address");
|
||||
reagent element = element_type(callsite, 0);
|
||||
CHECK_EQ(element.name, "x");
|
||||
CHECK(element.properties.at(0).second)
|
||||
CHECK_EQ(element.properties.at(0).second->value, "foo");
|
||||
CHECK(element.properties.at(0).second->right)
|
||||
CHECK_EQ(element.properties.at(0).second->right->value, "address");
|
||||
CHECK(element.properties.at(0).second->right->right)
|
||||
CHECK_EQ(element.properties.at(0).second->right->right->value, "number");
|
||||
CHECK(!element.properties.at(0).second->right->right->right);
|
||||
CHECK(element.type)
|
||||
CHECK_EQ(element.type->name, "foo");
|
||||
CHECK(element.type->right)
|
||||
CHECK_EQ(element.type->right->name, "address");
|
||||
CHECK(element.type->right->right)
|
||||
CHECK_EQ(element.type->right->right->name, "number");
|
||||
CHECK(!element.type->right->right->right);
|
||||
}
|
||||
|
||||
void test_replace_last_type_ingredient_with_multiple() {
|
||||
|
@ -410,15 +412,15 @@ void test_replace_last_type_ingredient_with_multiple() {
|
|||
reagent callsite("{f: (foo number (address shared array character))}");
|
||||
reagent element1 = element_type(callsite, 0);
|
||||
CHECK_EQ(element1.name, "x");
|
||||
CHECK_EQ(element1.properties.at(0).second->value, "number");
|
||||
CHECK(!element1.properties.at(0).second->right);
|
||||
CHECK_EQ(element1.type->name, "number");
|
||||
CHECK(!element1.type->right);
|
||||
reagent element2 = element_type(callsite, 1);
|
||||
CHECK_EQ(element2.name, "y");
|
||||
CHECK_EQ(element2.properties.at(0).second->value, "address");
|
||||
CHECK_EQ(element2.properties.at(0).second->right->value, "shared");
|
||||
CHECK_EQ(element2.properties.at(0).second->right->right->value, "array");
|
||||
CHECK_EQ(element2.properties.at(0).second->right->right->right->value, "character");
|
||||
CHECK(!element2.properties.at(0).second->right->right->right->right);
|
||||
CHECK_EQ(element2.type->name, "address");
|
||||
CHECK_EQ(element2.type->right->name, "shared");
|
||||
CHECK_EQ(element2.type->right->right->name, "array");
|
||||
CHECK_EQ(element2.type->right->right->right->name, "character");
|
||||
CHECK(!element2.type->right->right->right->right);
|
||||
}
|
||||
|
||||
void test_replace_middle_type_ingredient_with_multiple() {
|
||||
|
@ -430,19 +432,19 @@ void test_replace_middle_type_ingredient_with_multiple() {
|
|||
reagent callsite("{f: (foo number (address shared array character) boolean)}");
|
||||
reagent element1 = element_type(callsite, 0);
|
||||
CHECK_EQ(element1.name, "x");
|
||||
CHECK_EQ(element1.properties.at(0).second->value, "number");
|
||||
CHECK(!element1.properties.at(0).second->right);
|
||||
CHECK_EQ(element1.type->name, "number");
|
||||
CHECK(!element1.type->right);
|
||||
reagent element2 = element_type(callsite, 1);
|
||||
CHECK_EQ(element2.name, "y");
|
||||
CHECK_EQ(element2.properties.at(0).second->value, "address");
|
||||
CHECK_EQ(element2.properties.at(0).second->right->value, "shared");
|
||||
CHECK_EQ(element2.properties.at(0).second->right->right->value, "array");
|
||||
CHECK_EQ(element2.properties.at(0).second->right->right->right->value, "character");
|
||||
CHECK(!element2.properties.at(0).second->right->right->right->right);
|
||||
CHECK_EQ(element2.type->name, "address");
|
||||
CHECK_EQ(element2.type->right->name, "shared");
|
||||
CHECK_EQ(element2.type->right->right->name, "array");
|
||||
CHECK_EQ(element2.type->right->right->right->name, "character");
|
||||
CHECK(!element2.type->right->right->right->right);
|
||||
reagent element3 = element_type(callsite, 2);
|
||||
CHECK_EQ(element3.name, "z");
|
||||
CHECK_EQ(element3.properties.at(0).second->value, "boolean");
|
||||
CHECK(!element3.properties.at(0).second->right);
|
||||
CHECK_EQ(element3.type->name, "boolean");
|
||||
CHECK(!element3.type->right);
|
||||
}
|
||||
|
||||
bool has_nth_type(const type_tree* base, long long int n) {
|
||||
|
|
|
@ -121,14 +121,14 @@ bool all_concrete_header_reagents_strictly_match(const instruction& inst, const
|
|||
return false;
|
||||
}
|
||||
for (long long int i = 0; i < SIZE(variant.ingredients); ++i) {
|
||||
if (!concrete_types_strictly_match(variant.ingredients.at(i), inst.ingredients.at(i))) {
|
||||
if (!concrete_type_names_strictly_match(variant.ingredients.at(i), inst.ingredients.at(i))) {
|
||||
trace(9993, "transform") << "concrete-type match failed: ingredient " << i << end();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (long long int i = 0; i < SIZE(inst.products); ++i) {
|
||||
if (is_dummy(inst.products.at(i))) continue;
|
||||
if (!concrete_types_strictly_match(variant.products.at(i), inst.products.at(i))) {
|
||||
if (!concrete_type_names_strictly_match(variant.products.at(i), inst.products.at(i))) {
|
||||
trace(9993, "transform") << "strict match failed: product " << i << end();
|
||||
return false;
|
||||
}
|
||||
|
@ -142,7 +142,7 @@ recipe_ordinal best_shape_shifting_variant(const instruction& inst, vector<recip
|
|||
// primary score
|
||||
long long int max_score = -1;
|
||||
for (long long int i = 0; i < SIZE(candidates); ++i) {
|
||||
long long int score = number_of_concrete_types(candidates.at(i));
|
||||
long long int score = number_of_concrete_type_names(candidates.at(i));
|
||||
assert(score > -1);
|
||||
if (score > max_score) max_score = score;
|
||||
}
|
||||
|
@ -150,7 +150,7 @@ recipe_ordinal best_shape_shifting_variant(const instruction& inst, vector<recip
|
|||
long long int min_score2 = 999;
|
||||
long long int best_index = 0;
|
||||
for (long long int i = 0; i < SIZE(candidates); ++i) {
|
||||
long long int score1 = number_of_concrete_types(candidates.at(i));
|
||||
long long int score1 = number_of_concrete_type_names(candidates.at(i));
|
||||
assert(score1 <= max_score);
|
||||
if (score1 != max_score) continue;
|
||||
const recipe& candidate = get(Recipe, candidates.at(i));
|
||||
|
@ -178,63 +178,63 @@ bool any_type_ingredient_in_header(recipe_ordinal variant) {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool concrete_types_strictly_match(reagent to, reagent from) {
|
||||
bool concrete_type_names_strictly_match(reagent to, reagent from) {
|
||||
canonize_type(to);
|
||||
canonize_type(from);
|
||||
return concrete_types_strictly_match(to.properties.at(0).second, from.properties.at(0).second, from);
|
||||
return concrete_type_names_strictly_match(to.type, from.type, from);
|
||||
}
|
||||
|
||||
long long int number_of_concrete_types(recipe_ordinal r) {
|
||||
long long int number_of_concrete_type_names(recipe_ordinal r) {
|
||||
const recipe& caller = get(Recipe, r);
|
||||
long long int result = 0;
|
||||
for (long long int i = 0; i < SIZE(caller.ingredients); ++i)
|
||||
result += number_of_concrete_types(caller.ingredients.at(i));
|
||||
result += number_of_concrete_type_names(caller.ingredients.at(i));
|
||||
for (long long int i = 0; i < SIZE(caller.products); ++i)
|
||||
result += number_of_concrete_types(caller.products.at(i));
|
||||
result += number_of_concrete_type_names(caller.products.at(i));
|
||||
return result;
|
||||
}
|
||||
|
||||
long long int number_of_concrete_types(const reagent& r) {
|
||||
return number_of_concrete_types(r.properties.at(0).second);
|
||||
long long int number_of_concrete_type_names(const reagent& r) {
|
||||
return number_of_concrete_type_names(r.type);
|
||||
}
|
||||
|
||||
long long int number_of_concrete_types(const string_tree* type) {
|
||||
long long int number_of_concrete_type_names(const type_tree* type) {
|
||||
if (!type) return 0;
|
||||
long long int result = 0;
|
||||
if (!type->value.empty() && !is_type_ingredient_name(type->value))
|
||||
if (!type->name.empty() && !is_type_ingredient_name(type->name))
|
||||
result++;
|
||||
result += number_of_concrete_types(type->left);
|
||||
result += number_of_concrete_types(type->right);
|
||||
result += number_of_concrete_type_names(type->left);
|
||||
result += number_of_concrete_type_names(type->right);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool concrete_types_strictly_match(const string_tree* to, const string_tree* from, const reagent& rhs_reagent) {
|
||||
bool concrete_type_names_strictly_match(const type_tree* to, const type_tree* from, const reagent& rhs_reagent) {
|
||||
if (!to) return !from;
|
||||
if (!from) return !to;
|
||||
if (is_type_ingredient_name(to->value)) return true; // type ingredient matches anything
|
||||
if (to->value == "literal" && from->value == "literal")
|
||||
if (is_type_ingredient_name(to->name)) return true; // type ingredient matches anything
|
||||
if (to->name == "literal" && from->name == "literal")
|
||||
return true;
|
||||
if (to->value == "literal"
|
||||
&& Literal_type_names.find(from->value) != Literal_type_names.end())
|
||||
if (to->name == "literal"
|
||||
&& Literal_type_names.find(from->name) != Literal_type_names.end())
|
||||
return true;
|
||||
if (from->value == "literal"
|
||||
&& Literal_type_names.find(to->value) != Literal_type_names.end())
|
||||
if (from->name == "literal"
|
||||
&& Literal_type_names.find(to->name) != Literal_type_names.end())
|
||||
return true;
|
||||
if (from->value == "literal" && to->value == "address")
|
||||
if (from->name == "literal" && to->name == "address")
|
||||
return rhs_reagent.name == "0";
|
||||
//? cerr << to->value << " vs " << from->value << '\n';
|
||||
return to->value == from->value
|
||||
&& concrete_types_strictly_match(to->left, from->left, rhs_reagent)
|
||||
&& concrete_types_strictly_match(to->right, from->right, rhs_reagent);
|
||||
//? cerr << to->name << " vs " << from->name << '\n';
|
||||
return to->name == from->name
|
||||
&& concrete_type_names_strictly_match(to->left, from->left, rhs_reagent)
|
||||
&& concrete_type_names_strictly_match(to->right, from->right, rhs_reagent);
|
||||
}
|
||||
|
||||
bool contains_type_ingredient_name(const reagent& x) {
|
||||
return contains_type_ingredient_name(x.properties.at(0).second);
|
||||
return contains_type_ingredient_name(x.type);
|
||||
}
|
||||
|
||||
bool contains_type_ingredient_name(const string_tree* type) {
|
||||
bool contains_type_ingredient_name(const type_tree* type) {
|
||||
if (!type) return false;
|
||||
if (is_type_ingredient_name(type->value)) return true;
|
||||
if (is_type_ingredient_name(type->name)) return true;
|
||||
return contains_type_ingredient_name(type->left) || contains_type_ingredient_name(type->right);
|
||||
}
|
||||
|
||||
|
@ -301,7 +301,7 @@ void save_or_deduce_type_name(reagent& x, map<string, string_tree*>& type_name,
|
|||
return;
|
||||
}
|
||||
if (contains_key(type_name, x.name)) return;
|
||||
if (x.properties.at(0).second->value == "offset" || x.properties.at(0).second->value == "variant") return; // special-case for container-access instructions
|
||||
if (x.type->name == "offset" || x.type->name == "variant") return; // special-case for container-access instructions
|
||||
put(type_name, x.name, x.properties.at(0).second);
|
||||
trace(9993, "transform") << "type of " << x.name << " is " << to_string(x.properties.at(0).second) << end();
|
||||
}
|
||||
|
@ -390,7 +390,7 @@ void replace_type_ingredients(recipe& new_recipe, const map<string, const string
|
|||
for (long long int j = 0; j < SIZE(inst.products); ++j)
|
||||
replace_type_ingredients(inst.products.at(j), mappings, new_recipe);
|
||||
// special-case for new: replace type ingredient in first ingredient *value*
|
||||
if (inst.name == "new" && inst.ingredients.at(0).properties.at(0).second->value != "literal-string") {
|
||||
if (inst.name == "new" && inst.ingredients.at(0).type->name != "literal-string") {
|
||||
string_tree* type_name = parse_string_tree(inst.ingredients.at(0).name);
|
||||
replace_type_ingredients(type_name, mappings);
|
||||
inst.ingredients.at(0).name = inspect(type_name);
|
||||
|
|
19
061recipe.cc
19
061recipe.cc
|
@ -32,7 +32,7 @@ type_ordinal recipe = put(Type_ordinal, "recipe", Next_type_ordinal++);
|
|||
get_or_insert(Type, recipe).name = "recipe";
|
||||
|
||||
:(before "End Null-type is_disqualified Exceptions")
|
||||
if (!x.properties.at(0).second && contains_key(Recipe_ordinal, x.name)) {
|
||||
if (!x.type && contains_key(Recipe_ordinal, x.name)) {
|
||||
x.properties.at(0).second = new string_tree("recipe-literal");
|
||||
x.type = new type_tree("recipe-literal", get(Type_ordinal, "recipe-literal"));
|
||||
x.set_value(get(Recipe_ordinal, x.name));
|
||||
|
@ -126,27 +126,26 @@ void check_indirect_calls_against_header(const recipe_ordinal r) {
|
|||
}
|
||||
|
||||
recipe from_reagent(const reagent& r) {
|
||||
assert(r.properties.at(0).second->value == "recipe");
|
||||
assert(r.type->name == "recipe");
|
||||
recipe result_header; // will contain only ingredients and products, nothing else
|
||||
result_header.has_header = true;
|
||||
const string_tree* curr = r.properties.at(0).second->right;
|
||||
const type_tree* curr = r.type->right;
|
||||
for (; curr; curr=curr->right) {
|
||||
if (curr->value == "->") {
|
||||
if (curr->name == "->") {
|
||||
curr = curr->right; // skip delimiter
|
||||
break;
|
||||
}
|
||||
result_header.ingredients.push_back("recipe:"+curr->value);
|
||||
}
|
||||
for (; curr; curr=curr->right) {
|
||||
result_header.products.push_back("recipe:"+curr->value);
|
||||
result_header.ingredients.push_back("recipe:"+curr->name);
|
||||
}
|
||||
for (; curr; curr=curr->right)
|
||||
result_header.products.push_back("recipe:"+curr->name);
|
||||
return result_header;
|
||||
}
|
||||
|
||||
bool is_mu_recipe(reagent r) {
|
||||
if (!r.type) return false;
|
||||
if (r.properties.at(0).second->value == "recipe") return true;
|
||||
if (r.properties.at(0).second->value == "recipe-literal") return true;
|
||||
if (r.type->name == "recipe") return true;
|
||||
if (r.type->name == "recipe-literal") return true;
|
||||
// End is_mu_recipe Cases
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ size_t hash_mu_address(size_t h, reagent& r) {
|
|||
if (r.value == 0) return 0;
|
||||
r.value = get_or_insert(Memory, r.value);
|
||||
drop_from_type(r, "address");
|
||||
if (r.properties.at(0).second->value == "shared") {
|
||||
if (r.type->name == "shared") {
|
||||
++r.value;
|
||||
drop_from_type(r, "shared");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue