diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2016-09-10 10:43:19 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2016-09-10 10:43:19 -0700 |
commit | 44c1aeef226542d692f0002b5cca5a3c30935d18 (patch) | |
tree | 46452902ff779d93e4adcb57cda29d923766a5be /html/036refcount.cc.html | |
parent | c7db6a160a9a43d0905d5dea44e742b47acfa42f (diff) | |
download | mu-44c1aeef226542d692f0002b5cca5a3c30935d18.tar.gz |
3315
Diffstat (limited to 'html/036refcount.cc.html')
-rw-r--r-- | html/036refcount.cc.html | 345 |
1 files changed, 323 insertions, 22 deletions
diff --git a/html/036refcount.cc.html b/html/036refcount.cc.html index 6613fdb8..ef642de8 100644 --- a/html/036refcount.cc.html +++ b/html/036refcount.cc.html @@ -313,7 +313,6 @@ map<set<tag_condition_info><span class="Delimiter">,</span> set<addr <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> <span class="Comment">// equal</span> <span class="Delimiter">}</span> - <span class="Comment">//: populate metadata.address in a separate transform, because it requires</span> <span class="Comment">//: already knowing the sizes of all types</span> @@ -332,45 +331,70 @@ Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</spa compute_container_address_offsets<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> + <span class="Normal">void</span> compute_container_address_offsets<span class="Delimiter">(</span>reagent& r<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>r<span class="Delimiter">)</span> || is_dummy<span class="Delimiter">(</span>r<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span> compute_container_address_offsets<span class="Delimiter">(</span>r<span class="Delimiter">.</span>type<span class="Delimiter">);</span> <span class="Normal">if</span> <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> r<span class="Delimiter">.</span>type<span class="Delimiter">))</span> r<span class="Delimiter">.</span>metadata = get<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> r<span class="Delimiter">.</span>type<span class="Delimiter">);</span> <span class="Delimiter">}</span> -<span class="Normal">void</span> compute_container_address_offsets<span class="Delimiter">(</span>type_tree* type<span class="Delimiter">)</span> <span class="Delimiter">{</span> + +<span class="Comment">// the recursive structure of this function needs to exactly match</span> +<span class="Comment">// compute_container_sizes</span> +<span class="Normal">void</span> compute_container_address_offsets<span class="Delimiter">(</span><span class="Normal">const</span> type_tree* type<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!type<span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>type<span class="Delimiter">-></span>left<span class="Delimiter">)</span> compute_container_address_offsets<span class="Delimiter">(</span>type<span class="Delimiter">-></span>left<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>type<span class="Delimiter">-></span>right<span class="Delimiter">)</span> compute_container_address_offsets<span class="Delimiter">(</span>type<span class="Delimiter">-></span>right<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> type<span class="Delimiter">-></span>value<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Comment">// error raised elsewhere</span> - type_info& info = get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> type<span class="Delimiter">-></span>value<span class="Delimiter">);</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!type<span class="Delimiter">-></span>atom<span class="Delimiter">)</span> <span class="Delimiter">{</span> + assert<span class="Delimiter">(</span>type<span class="Delimiter">-></span>left<span class="Delimiter">-></span>atom<span class="Delimiter">);</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>type<span class="Delimiter">-></span>left<span class="Delimiter">-></span>name == <span class="Constant">"address"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + compute_container_address_offsets<span class="Delimiter">(</span>type<span class="Delimiter">-></span>right<span class="Delimiter">);</span> + <span class="Delimiter">}</span> + <span class="Normal">else</span> <span class="Normal">if</span> <span class="Delimiter">(</span>type<span class="Delimiter">-></span>left<span class="Delimiter">-></span>name == <span class="Constant">"array"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Normal">const</span> type_tree* element_type = type<span class="Delimiter">-></span>right<span class="Delimiter">;</span> + <span class="Comment">// hack: support both array:number:3 and array:address:number</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!element_type<span class="Delimiter">-></span>atom && element_type<span class="Delimiter">-></span>right && element_type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>atom && is_integer<span class="Delimiter">(</span>element_type<span class="Delimiter">-></span>right<span class="Delimiter">-></span>name<span class="Delimiter">))</span> + element_type = element_type<span class="Delimiter">-></span>left<span class="Delimiter">;</span> + compute_container_address_offsets<span class="Delimiter">(</span>element_type<span class="Delimiter">);</span> + <span class="Delimiter">}</span> + <span class="Comment">// End compute_container_address_offsets Non-atom Cases</span> + <span class="Delimiter">}</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> root_type<span class="Delimiter">(</span>type<span class="Delimiter">)-></span>value<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Comment">// error raised elsewhere</span> + type_info& info = get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> root_type<span class="Delimiter">(</span>type<span class="Delimiter">)-></span>value<span class="Delimiter">);</span> <span class="Normal">if</span> <span class="Delimiter">(</span>info<span class="Delimiter">.</span>kind == CONTAINER<span class="Delimiter">)</span> <span class="Delimiter">{</span> - container_metadata& metadata = get<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> type<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>!metadata<span class="Delimiter">.</span>address<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span><span class="Delimiter">;</span> - trace<span class="Delimiter">(</span><span class="Constant">9994</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"compute address offsets for container "</span> << info<span class="Delimiter">.</span>name << end<span class="Delimiter">();</span> - append_addresses<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">,</span> type<span class="Delimiter">,</span> metadata<span class="Delimiter">.</span>address<span class="Delimiter">,</span> set<tag_condition_info><span class="Delimiter">());</span> + compute_container_address_offsets<span class="Delimiter">(</span>info<span class="Delimiter">,</span> type<span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Normal">if</span> <span class="Delimiter">(</span>info<span class="Delimiter">.</span>kind == EXCLUSIVE_CONTAINER<span class="Delimiter">)</span> <span class="Delimiter">{</span> - container_metadata& metadata = get<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> type<span class="Delimiter">);</span> - trace<span class="Delimiter">(</span><span class="Constant">9994</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"compute address offsets for exclusive container "</span> << info<span class="Delimiter">.</span>name << end<span class="Delimiter">();</span> - <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> tag = <span class="Constant">0</span><span class="Delimiter">;</span> tag < SIZE<span class="Delimiter">(</span>info<span class="Delimiter">.</span>elements<span class="Delimiter">);</span> ++tag<span class="Delimiter">)</span> <span class="Delimiter">{</span> - set<tag_condition_info> key<span class="Delimiter">;</span> - key<span class="Delimiter">.</span>insert<span class="Delimiter">(</span>tag_condition_info<span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">tag is at offset</span><span class="Comment">*/</span><span class="Constant">0</span><span class="Delimiter">,</span> tag<span class="Delimiter">));</span> - append_addresses<span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">skip tag offset</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">,</span> variant_type<span class="Delimiter">(</span>type<span class="Delimiter">,</span> tag<span class="Delimiter">).</span>type<span class="Delimiter">,</span> metadata<span class="Delimiter">.</span>address<span class="Delimiter">,</span> key<span class="Delimiter">);</span> - <span class="Delimiter">}</span> + compute_exclusive_container_address_offsets<span class="Delimiter">(</span>info<span class="Delimiter">,</span> type<span class="Delimiter">);</span> + <span class="Delimiter">}</span> +<span class="Delimiter">}</span> + +<span class="Normal">void</span> compute_container_address_offsets<span class="Delimiter">(</span><span class="Normal">const</span> type_info& container_info<span class="Delimiter">,</span> <span class="Normal">const</span> type_tree* full_type<span class="Delimiter">)</span> <span class="Delimiter">{</span> + container_metadata& metadata = get<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> full_type<span class="Delimiter">);</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>!metadata<span class="Delimiter">.</span>address<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span><span class="Delimiter">;</span> + trace<span class="Delimiter">(</span><span class="Constant">9994</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"compute address offsets for container "</span> << container_info<span class="Delimiter">.</span>name << end<span class="Delimiter">();</span> + append_addresses<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">,</span> full_type<span class="Delimiter">,</span> metadata<span class="Delimiter">.</span>address<span class="Delimiter">,</span> set<tag_condition_info><span class="Delimiter">());</span> +<span class="Delimiter">}</span> + +<span class="Normal">void</span> compute_exclusive_container_address_offsets<span class="Delimiter">(</span><span class="Normal">const</span> type_info& exclusive_container_info<span class="Delimiter">,</span> <span class="Normal">const</span> type_tree* full_type<span class="Delimiter">)</span> <span class="Delimiter">{</span> + container_metadata& metadata = get<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> full_type<span class="Delimiter">);</span> + trace<span class="Delimiter">(</span><span class="Constant">9994</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"compute address offsets for exclusive container "</span> << exclusive_container_info<span class="Delimiter">.</span>name << end<span class="Delimiter">();</span> + <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> tag = <span class="Constant">0</span><span class="Delimiter">;</span> tag < SIZE<span class="Delimiter">(</span>exclusive_container_info<span class="Delimiter">.</span>elements<span class="Delimiter">);</span> ++tag<span class="Delimiter">)</span> <span class="Delimiter">{</span> + set<tag_condition_info> key<span class="Delimiter">;</span> + key<span class="Delimiter">.</span>insert<span class="Delimiter">(</span>tag_condition_info<span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">tag is at offset</span><span class="Comment">*/</span><span class="Constant">0</span><span class="Delimiter">,</span> tag<span class="Delimiter">));</span> + append_addresses<span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">skip tag offset</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">,</span> variant_type<span class="Delimiter">(</span>full_type<span class="Delimiter">,</span> tag<span class="Delimiter">).</span>type<span class="Delimiter">,</span> metadata<span class="Delimiter">.</span>address<span class="Delimiter">,</span> key<span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> <span class="Normal">void</span> append_addresses<span class="Delimiter">(</span><span class="Normal">int</span> base_offset<span class="Delimiter">,</span> <span class="Normal">const</span> type_tree* type<span class="Delimiter">,</span> map<set<tag_condition_info><span class="Delimiter">,</span> set<address_element_info> >& out<span class="Delimiter">,</span> <span class="Normal">const</span> set<tag_condition_info>& key<span class="Delimiter">)</span> <span class="Delimiter">{</span> - <span class="Normal">const</span> type_info& info = get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> type<span class="Delimiter">-></span>value<span class="Delimiter">);</span> - <span class="Normal">if</span> <span class="Delimiter">(</span>type<span class="Delimiter">-></span>name == <span class="Constant">"address"</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> + <span class="Normal">if</span> <span class="Delimiter">(</span>is_mu_address<span class="Delimiter">(</span>type<span class="Delimiter">))</span> <span class="Delimiter">{</span> get_or_insert<span class="Delimiter">(</span>out<span class="Delimiter">,</span> key<span class="Delimiter">).</span>insert<span class="Delimiter">(</span>address_element_info<span class="Delimiter">(</span>base_offset<span class="Delimiter">,</span> <span class="Normal">new</span> type_tree<span class="Delimiter">(</span>*type<span class="Delimiter">-></span>right<span class="Delimiter">)));</span> <span class="Identifier">return</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> + <span class="Normal">const</span> type_tree* root = root_type<span class="Delimiter">(</span>type<span class="Delimiter">);</span> + <span class="Normal">const</span> type_info& info = get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> root<span class="Delimiter">-></span>value<span class="Delimiter">);</span> <span class="Normal">if</span> <span class="Delimiter">(</span>info<span class="Delimiter">.</span>kind == CONTAINER<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> curr_index = <span class="Constant">0</span><span class="Delimiter">,</span> curr_offset = base_offset<span class="Delimiter">;</span> curr_index < SIZE<span class="Delimiter">(</span>info<span class="Delimiter">.</span>elements<span class="Delimiter">);</span> ++curr_index<span class="Delimiter">)</span> <span class="Delimiter">{</span> - trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"checking container "</span> << type<span class="Delimiter">-></span>name << <span class="Constant">", element "</span> << curr_index << end<span class="Delimiter">();</span> - reagent<span class="Comment">/*</span><span class="Comment">copy</span><span class="Comment">*/</span> element = element_type<span class="Delimiter">(</span>type<span class="Delimiter">,</span> curr_index<span class="Delimiter">);</span> + trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"checking container "</span> << root<span class="Delimiter">-></span>name << <span class="Constant">", element "</span> << curr_index << end<span class="Delimiter">();</span> + reagent<span class="Comment">/*</span><span class="Comment">copy</span><span class="Comment">*/</span> element = element_type<span class="Delimiter">(</span>type<span class="Delimiter">,</span> curr_index<span class="Delimiter">);</span> <span class="Comment">// not root</span> <span class="Comment">// Compute Container Address Offset(element)</span> <span class="Normal">if</span> <span class="Delimiter">(</span>is_mu_address<span class="Delimiter">(</span>element<span class="Delimiter">))</span> <span class="Delimiter">{</span> trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">"transform"</span><span class="Delimiter">)</span> << <span class="Constant">"address at offset "</span> << curr_offset << end<span class="Delimiter">();</span> @@ -382,7 +406,8 @@ Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</spa curr_offset += size_of<span class="Delimiter">(</span>element<span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Normal">else</span> <span class="Normal">if</span> <span class="Delimiter">(</span>is_mu_exclusive_container<span class="Delimiter">(</span>element<span class="Delimiter">))</span> <span class="Delimiter">{</span> - <span class="Normal">const</span> type_info& element_info = get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> element<span class="Delimiter">.</span>type<span class="Delimiter">-></span>value<span class="Delimiter">);</span> + <span class="Normal">const</span> type_tree* element_root_type = root_type<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<span class="Delimiter">);</span> + <span class="Normal">const</span> type_info& element_info = get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> element_root_type<span class="Delimiter">-></span>value<span class="Delimiter">);</span> <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> tag = <span class="Constant">0</span><span class="Delimiter">;</span> tag < SIZE<span class="Delimiter">(</span>element_info<span class="Delimiter">.</span>elements<span class="Delimiter">);</span> ++tag<span class="Delimiter">)</span> <span class="Delimiter">{</span> set<tag_condition_info> new_key = key<span class="Delimiter">;</span> new_key<span class="Delimiter">.</span>insert<span class="Delimiter">(</span>tag_condition_info<span class="Delimiter">(</span>curr_offset<span class="Delimiter">,</span> tag<span class="Delimiter">));</span> @@ -413,6 +438,280 @@ Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</spa <span class="Identifier">return</span> size_of<span class="Delimiter">(</span>type<span class="Delimiter">-></span>right<span class="Delimiter">)</span> + <span class="Comment">/*</span><span class="Comment">refcount</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> +<span class="Comment">//: for the following unit tests we'll do the work of the transform by hand</span> + +<span class="Delimiter">:(before "End Unit Tests")</span> +<span class="Normal">void</span> test_container_address_offsets_empty<span class="Delimiter">()</span> <span class="Delimiter">{</span> + <span class="Normal">int</span> old_size = SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">);</span> + <span class="Comment">// define a container with no addresses</span> + reagent r<span class="Delimiter">(</span><span class="Constant">"x:point"</span><span class="Delimiter">);</span> + compute_container_sizes<span class="Delimiter">(</span>r<span class="Delimiter">);</span> <span class="Comment">// need to first pre-populate the metadata</span> + <span class="Comment">// scan</span> + compute_container_address_offsets<span class="Delimiter">(</span>r<span class="Delimiter">);</span> + <span class="Comment">// global metadata contains just the entry for foo</span> + <span class="Comment">// no entries for non-container types or other junk</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">)</span>-old_size<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span> + <span class="Comment">// the reagent we scanned knows it has no addresses</span> + CHECK<span class="Delimiter">(</span>r<span class="Delimiter">.</span>metadata<span class="Delimiter">.</span>address<span class="Delimiter">.</span>empty<span class="Delimiter">());</span> + <span class="Comment">// the global table contains an identical entry</span> + CHECK<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> r<span class="Delimiter">.</span>type<span class="Delimiter">));</span> + CHECK<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> r<span class="Delimiter">.</span>type<span class="Delimiter">).</span>address<span class="Delimiter">.</span>empty<span class="Delimiter">());</span> + <span class="Comment">// compute_container_address_offsets creates no new entries</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">)</span>-old_size<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span> +<span class="Delimiter">}</span> + +<span class="Normal">void</span> test_container_address_offsets<span class="Delimiter">()</span> <span class="Delimiter">{</span> + <span class="Normal">int</span> old_size = SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">);</span> + <span class="Comment">// define a container with an address at offset 0 that we have the size for</span> + run<span class="Delimiter">(</span><span class="Constant">"container foo [</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">" x:address:number</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">"]</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">);</span> + reagent r<span class="Delimiter">(</span><span class="Constant">"x:foo"</span><span class="Delimiter">);</span> + compute_container_sizes<span class="Delimiter">(</span>r<span class="Delimiter">);</span> <span class="Comment">// need to first pre-populate the metadata</span> + <span class="Comment">// scan</span> + compute_container_address_offsets<span class="Delimiter">(</span>r<span class="Delimiter">);</span> + <span class="Comment">// global metadata contains just the entry for foo</span> + <span class="Comment">// no entries for non-container types or other junk</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">)</span>-old_size<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span> + <span class="Comment">// the reagent we scanned knows it has an address at offset 0</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>r<span class="Delimiter">.</span>metadata<span class="Delimiter">.</span>address<span class="Delimiter">),</span> <span class="Constant">1</span><span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>r<span class="Delimiter">.</span>metadata<span class="Delimiter">.</span>address<span class="Delimiter">,</span> set<tag_condition_info><span class="Delimiter">()));</span> + <span class="Normal">const</span> set<address_element_info>& address_offsets = get<span class="Delimiter">(</span>r<span class="Delimiter">.</span>metadata<span class="Delimiter">.</span>address<span class="Delimiter">,</span> set<tag_condition_info><span class="Delimiter">());</span> <span class="Comment">// unconditional for containers</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>address_offsets<span class="Delimiter">),</span> <span class="Constant">1</span><span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>address_offsets<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>offset<span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>address_offsets<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>atom<span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>address_offsets<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"number"</span><span class="Delimiter">);</span> + <span class="Comment">// the global table contains an identical entry</span> + CHECK<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> r<span class="Delimiter">.</span>type<span class="Delimiter">));</span> + <span class="Normal">const</span> set<address_element_info>& address_offsets2 = get<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> r<span class="Delimiter">.</span>type<span class="Delimiter">).</span>address<span class="Delimiter">,</span> set<tag_condition_info><span class="Delimiter">());</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">),</span> <span class="Constant">1</span><span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>offset<span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>atom<span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"number"</span><span class="Delimiter">);</span> + <span class="Comment">// compute_container_address_offsets creates no new entries</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">)</span>-old_size<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span> +<span class="Delimiter">}</span> + +<span class="Normal">void</span> test_container_address_offsets_2<span class="Delimiter">()</span> <span class="Delimiter">{</span> + <span class="Normal">int</span> old_size = SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">);</span> + <span class="Comment">// define a container with an address at offset 1 that we have the size for</span> + run<span class="Delimiter">(</span><span class="Constant">"container foo [</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">" x:number</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">" y:address:number</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">"]</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">);</span> + reagent r<span class="Delimiter">(</span><span class="Constant">"x:foo"</span><span class="Delimiter">);</span> + compute_container_sizes<span class="Delimiter">(</span>r<span class="Delimiter">);</span> <span class="Comment">// need to first pre-populate the metadata</span> + <span class="Comment">// global metadata contains just the entry for foo</span> + <span class="Comment">// no entries for non-container types or other junk</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">)</span>-old_size<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span> + <span class="Comment">// scan</span> + compute_container_address_offsets<span class="Delimiter">(</span>r<span class="Delimiter">);</span> + <span class="Comment">// compute_container_address_offsets creates no new entries</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">)</span>-old_size<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span> + <span class="Comment">// the reagent we scanned knows it has an address at offset 1</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>r<span class="Delimiter">.</span>metadata<span class="Delimiter">.</span>address<span class="Delimiter">),</span> <span class="Constant">1</span><span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>r<span class="Delimiter">.</span>metadata<span class="Delimiter">.</span>address<span class="Delimiter">,</span> set<tag_condition_info><span class="Delimiter">()));</span> + <span class="Normal">const</span> set<address_element_info>& address_offsets = get<span class="Delimiter">(</span>r<span class="Delimiter">.</span>metadata<span class="Delimiter">.</span>address<span class="Delimiter">,</span> set<tag_condition_info><span class="Delimiter">());</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>address_offsets<span class="Delimiter">),</span> <span class="Constant">1</span><span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>address_offsets<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>offset<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span> <span class="Comment">//</span> + CHECK<span class="Delimiter">(</span>address_offsets<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>atom<span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>address_offsets<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"number"</span><span class="Delimiter">);</span> + <span class="Comment">// the global table contains an identical entry</span> + CHECK<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> r<span class="Delimiter">.</span>type<span class="Delimiter">));</span> + <span class="Normal">const</span> set<address_element_info>& address_offsets2 = get<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> r<span class="Delimiter">.</span>type<span class="Delimiter">).</span>address<span class="Delimiter">,</span> set<tag_condition_info><span class="Delimiter">());</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">),</span> <span class="Constant">1</span><span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>offset<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span> <span class="Comment">//</span> + CHECK<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>atom<span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"number"</span><span class="Delimiter">);</span> +<span class="Delimiter">}</span> + +<span class="Normal">void</span> test_container_address_offsets_nested<span class="Delimiter">()</span> <span class="Delimiter">{</span> + <span class="Normal">int</span> old_size = SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">);</span> + <span class="Comment">// define a container with a nested container containing an address</span> + run<span class="Delimiter">(</span><span class="Constant">"container foo [</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">" x:address:number</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">" y:number</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">"]</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">"container bar [</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">" p:point</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">" f:foo</span><span class="cSpecial">\n</span><span class="Constant">"</span> <span class="Comment">// nested container containing address</span> + <span class="Constant">"]</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">);</span> + reagent r<span class="Delimiter">(</span><span class="Constant">"x:bar"</span><span class="Delimiter">);</span> + compute_container_sizes<span class="Delimiter">(</span>r<span class="Delimiter">);</span> <span class="Comment">// need to first pre-populate the metadata</span> + <span class="Comment">// global metadata contains entries for bar and included types: point and foo</span> + <span class="Comment">// no entries for non-container types or other junk</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">)</span>-old_size<span class="Delimiter">,</span> <span class="Constant">3</span><span class="Delimiter">);</span> + <span class="Comment">// scan</span> + compute_container_address_offsets<span class="Delimiter">(</span>r<span class="Delimiter">);</span> + <span class="Comment">// the reagent we scanned knows it has an address at offset 2</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>r<span class="Delimiter">.</span>metadata<span class="Delimiter">.</span>address<span class="Delimiter">),</span> <span class="Constant">1</span><span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>r<span class="Delimiter">.</span>metadata<span class="Delimiter">.</span>address<span class="Delimiter">,</span> set<tag_condition_info><span class="Delimiter">()));</span> + <span class="Normal">const</span> set<address_element_info>& address_offsets = get<span class="Delimiter">(</span>r<span class="Delimiter">.</span>metadata<span class="Delimiter">.</span>address<span class="Delimiter">,</span> set<tag_condition_info><span class="Delimiter">());</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>address_offsets<span class="Delimiter">),</span> <span class="Constant">1</span><span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>address_offsets<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>offset<span class="Delimiter">,</span> <span class="Constant">2</span><span class="Delimiter">);</span> <span class="Comment">//</span> + CHECK<span class="Delimiter">(</span>address_offsets<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>atom<span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>address_offsets<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"number"</span><span class="Delimiter">);</span> + <span class="Comment">// the global table also knows its address offset</span> + CHECK<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> r<span class="Delimiter">.</span>type<span class="Delimiter">));</span> + <span class="Normal">const</span> set<address_element_info>& address_offsets2 = get<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> r<span class="Delimiter">.</span>type<span class="Delimiter">).</span>address<span class="Delimiter">,</span> set<tag_condition_info><span class="Delimiter">());</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">),</span> <span class="Constant">1</span><span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>offset<span class="Delimiter">,</span> <span class="Constant">2</span><span class="Delimiter">);</span> <span class="Comment">//</span> + CHECK<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>atom<span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"number"</span><span class="Delimiter">);</span> + <span class="Comment">// compute_container_address_offsets creates no new entries</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">)</span>-old_size<span class="Delimiter">,</span> <span class="Constant">3</span><span class="Delimiter">);</span> +<span class="Delimiter">}</span> + +<span class="Normal">void</span> test_container_address_offsets_from_address<span class="Delimiter">()</span> <span class="Delimiter">{</span> + <span class="Normal">int</span> old_size = SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">);</span> + <span class="Comment">// define a container with an address at offset 0</span> + run<span class="Delimiter">(</span><span class="Constant">"container foo [</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">" x:address:number</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">"]</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">);</span> + reagent r<span class="Delimiter">(</span><span class="Constant">"x:address:foo"</span><span class="Delimiter">);</span> + compute_container_sizes<span class="Delimiter">(</span>r<span class="Delimiter">);</span> <span class="Comment">// need to first pre-populate the metadata</span> + <span class="Comment">// global metadata contains just the entry for foo</span> + <span class="Comment">// no entries for non-container types or other junk</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">)</span>-old_size<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span> + <span class="Comment">// scan an address to the container</span> + compute_container_address_offsets<span class="Delimiter">(</span>r<span class="Delimiter">);</span> + <span class="Comment">// compute_container_address_offsets creates no new entries</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">)</span>-old_size<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span> + <span class="Comment">// scanning precomputed metadata for the container</span> + reagent container<span class="Delimiter">(</span><span class="Constant">"x:foo"</span><span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> container<span class="Delimiter">.</span>type<span class="Delimiter">));</span> + <span class="Normal">const</span> set<address_element_info>& address_offsets2 = get<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> container<span class="Delimiter">.</span>type<span class="Delimiter">).</span>address<span class="Delimiter">,</span> set<tag_condition_info><span class="Delimiter">());</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">),</span> <span class="Constant">1</span><span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>offset<span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>atom<span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"number"</span><span class="Delimiter">);</span> +<span class="Delimiter">}</span> + +<span class="Normal">void</span> test_container_address_offsets_from_array<span class="Delimiter">()</span> <span class="Delimiter">{</span> + <span class="Normal">int</span> old_size = SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">);</span> + <span class="Comment">// define a container with an address at offset 0</span> + run<span class="Delimiter">(</span><span class="Constant">"container foo [</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">" x:address:number</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">"]</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">);</span> + reagent r<span class="Delimiter">(</span><span class="Constant">"x:array:foo"</span><span class="Delimiter">);</span> + compute_container_sizes<span class="Delimiter">(</span>r<span class="Delimiter">);</span> <span class="Comment">// need to first pre-populate the metadata</span> + <span class="Comment">// global metadata contains just the entry for foo</span> + <span class="Comment">// no entries for non-container types or other junk</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">)</span>-old_size<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span> + <span class="Comment">// scan an array of the container</span> + compute_container_address_offsets<span class="Delimiter">(</span>r<span class="Delimiter">);</span> + <span class="Comment">// compute_container_address_offsets creates no new entries</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">)</span>-old_size<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span> + <span class="Comment">// scanning precomputed metadata for the container</span> + reagent container<span class="Delimiter">(</span><span class="Constant">"x:foo"</span><span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> container<span class="Delimiter">.</span>type<span class="Delimiter">));</span> + <span class="Normal">const</span> set<address_element_info>& address_offsets2 = get<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> container<span class="Delimiter">.</span>type<span class="Delimiter">).</span>address<span class="Delimiter">,</span> set<tag_condition_info><span class="Delimiter">());</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">),</span> <span class="Constant">1</span><span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>offset<span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>atom<span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"number"</span><span class="Delimiter">);</span> +<span class="Delimiter">}</span> + +<span class="Normal">void</span> test_container_address_offsets_from_address_to_array<span class="Delimiter">()</span> <span class="Delimiter">{</span> + <span class="Normal">int</span> old_size = SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">);</span> + <span class="Comment">// define a container with an address at offset 0</span> + run<span class="Delimiter">(</span><span class="Constant">"container foo [</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">" x:address:number</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">"]</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">);</span> + reagent r<span class="Delimiter">(</span><span class="Constant">"x:address:array:foo"</span><span class="Delimiter">);</span> + compute_container_sizes<span class="Delimiter">(</span>r<span class="Delimiter">);</span> <span class="Comment">// need to first pre-populate the metadata</span> + <span class="Comment">// global metadata contains just the entry for foo</span> + <span class="Comment">// no entries for non-container types or other junk</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">)</span>-old_size<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span> + <span class="Comment">// scan an address to an array of the container</span> + compute_container_address_offsets<span class="Delimiter">(</span>r<span class="Delimiter">);</span> + <span class="Comment">// compute_container_address_offsets creates no new entries</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">)</span>-old_size<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span> + <span class="Comment">// scanning precomputed metadata for the container</span> + reagent container<span class="Delimiter">(</span><span class="Constant">"x:foo"</span><span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> container<span class="Delimiter">.</span>type<span class="Delimiter">));</span> + <span class="Normal">const</span> set<address_element_info>& address_offsets2 = get<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> container<span class="Delimiter">.</span>type<span class="Delimiter">).</span>address<span class="Delimiter">,</span> set<tag_condition_info><span class="Delimiter">());</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">),</span> <span class="Constant">1</span><span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>offset<span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>atom<span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"number"</span><span class="Delimiter">);</span> +<span class="Delimiter">}</span> + +<span class="Normal">void</span> test_container_address_offsets_from_static_array<span class="Delimiter">()</span> <span class="Delimiter">{</span> + <span class="Normal">int</span> old_size = SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">);</span> + <span class="Comment">// define a container with an address at offset 0</span> + run<span class="Delimiter">(</span><span class="Constant">"container foo [</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">" x:address:number</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">"]</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">);</span> + reagent r<span class="Delimiter">(</span><span class="Constant">"x:array:foo:10"</span><span class="Delimiter">);</span> + compute_container_sizes<span class="Delimiter">(</span>r<span class="Delimiter">);</span> <span class="Comment">// need to first pre-populate the metadata</span> + <span class="Comment">// global metadata contains just the entry for foo</span> + <span class="Comment">// no entries for non-container types or other junk</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">)</span>-old_size<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span> + <span class="Comment">// scan a static array of the container</span> + compute_container_address_offsets<span class="Delimiter">(</span>r<span class="Delimiter">);</span> + <span class="Comment">// compute_container_address_offsets creates no new entries</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">)</span>-old_size<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span> + <span class="Comment">// scanning precomputed metadata for the container</span> + reagent container<span class="Delimiter">(</span><span class="Constant">"x:foo"</span><span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> container<span class="Delimiter">.</span>type<span class="Delimiter">));</span> + <span class="Normal">const</span> set<address_element_info>& address_offsets2 = get<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> container<span class="Delimiter">.</span>type<span class="Delimiter">).</span>address<span class="Delimiter">,</span> set<tag_condition_info><span class="Delimiter">());</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">),</span> <span class="Constant">1</span><span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>offset<span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>atom<span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"number"</span><span class="Delimiter">);</span> +<span class="Delimiter">}</span> + +<span class="Normal">void</span> test_container_address_offsets_from_address_to_static_array<span class="Delimiter">()</span> <span class="Delimiter">{</span> + <span class="Normal">int</span> old_size = SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">);</span> + <span class="Comment">// define a container with an address at offset 0</span> + run<span class="Delimiter">(</span><span class="Constant">"container foo [</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">" x:address:number</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">"]</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">);</span> + reagent r<span class="Delimiter">(</span><span class="Constant">"x:address:array:foo:10"</span><span class="Delimiter">);</span> + compute_container_sizes<span class="Delimiter">(</span>r<span class="Delimiter">);</span> <span class="Comment">// need to first pre-populate the metadata</span> + <span class="Comment">// global metadata contains just the entry for foo</span> + <span class="Comment">// no entries for non-container types or other junk</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">)</span>-old_size<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span> + <span class="Comment">// scan an address to a static array of the container</span> + compute_container_address_offsets<span class="Delimiter">(</span>r<span class="Delimiter">);</span> + <span class="Comment">// compute_container_address_offsets creates no new entries</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">)</span>-old_size<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span> + <span class="Comment">// scanning precomputed metadata for the container</span> + reagent container<span class="Delimiter">(</span><span class="Constant">"x:foo"</span><span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> container<span class="Delimiter">.</span>type<span class="Delimiter">));</span> + <span class="Normal">const</span> set<address_element_info>& address_offsets2 = get<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> container<span class="Delimiter">.</span>type<span class="Delimiter">).</span>address<span class="Delimiter">,</span> set<tag_condition_info><span class="Delimiter">());</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">),</span> <span class="Constant">1</span><span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>offset<span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>atom<span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"number"</span><span class="Delimiter">);</span> +<span class="Delimiter">}</span> + +<span class="Normal">void</span> test_container_address_offsets_from_repeated_address_and_array_types<span class="Delimiter">()</span> <span class="Delimiter">{</span> + <span class="Normal">int</span> old_size = SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">);</span> + <span class="Comment">// define a container with an address at offset 0</span> + run<span class="Delimiter">(</span><span class="Constant">"container foo [</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">" x:address:number</span><span class="cSpecial">\n</span><span class="Constant">"</span> + <span class="Constant">"]</span><span class="cSpecial">\n</span><span class="Constant">"</span><span class="Delimiter">);</span> + <span class="Comment">// scan a deep nest of 'address' and 'array' types modifying a container</span> + reagent r<span class="Delimiter">(</span><span class="Constant">"x:address:array:address:address:array:foo:10"</span><span class="Delimiter">);</span> + compute_container_sizes<span class="Delimiter">(</span>r<span class="Delimiter">);</span> <span class="Comment">// need to first pre-populate the metadata</span> + <span class="Comment">// global metadata contains just the entry for foo</span> + <span class="Comment">// no entries for non-container types or other junk</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">)</span>-old_size<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span> + compute_container_address_offsets<span class="Delimiter">(</span>r<span class="Delimiter">);</span> + <span class="Comment">// compute_container_address_offsets creates no new entries</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">)</span>-old_size<span class="Delimiter">,</span> <span class="Constant">1</span><span class="Delimiter">);</span> + <span class="Comment">// scanning precomputed metadata for the container</span> + reagent container<span class="Delimiter">(</span><span class="Constant">"x:foo"</span><span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> container<span class="Delimiter">.</span>type<span class="Delimiter">));</span> + <span class="Normal">const</span> set<address_element_info>& address_offsets2 = get<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Container_metadata<span class="Delimiter">,</span> container<span class="Delimiter">.</span>type<span class="Delimiter">).</span>address<span class="Delimiter">,</span> set<tag_condition_info><span class="Delimiter">());</span> + CHECK_EQ<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">),</span> <span class="Constant">1</span><span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>offset<span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">);</span> + CHECK<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>atom<span class="Delimiter">);</span> + CHECK_EQ<span class="Delimiter">(</span>address_offsets2<span class="Delimiter">.</span>begin<span class="Delimiter">()-></span>payload_type<span class="Delimiter">-></span>name<span class="Delimiter">,</span> <span class="Constant">"number"</span><span class="Delimiter">);</span> +<span class="Delimiter">}</span> + <span class="Comment">//: use metadata.address to update refcounts within containers, arrays and</span> <span class="Comment">//: exclusive containers</span> @@ -683,6 +982,7 @@ def main [ <span class="Delimiter">}</span> <span class="Normal">bool</span> is_mu_container<span class="Delimiter">(</span><span class="Normal">const</span> type_tree* type<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!type<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> + <span class="Comment">// End is_mu_container(type) Special-cases</span> <span class="Normal">if</span> <span class="Delimiter">(</span>type<span class="Delimiter">-></span>value == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> type_info& info = get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> type<span class="Delimiter">-></span>value<span class="Delimiter">);</span> <span class="Identifier">return</span> info<span class="Delimiter">.</span>kind == CONTAINER<span class="Delimiter">;</span> @@ -693,6 +993,7 @@ def main [ <span class="Delimiter">}</span> <span class="Normal">bool</span> is_mu_exclusive_container<span class="Delimiter">(</span><span class="Normal">const</span> type_tree* type<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!type<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> + <span class="Comment">// End is_mu_exclusive_container(type) Special-cases</span> <span class="Normal">if</span> <span class="Delimiter">(</span>type<span class="Delimiter">-></span>value == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span> type_info& info = get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> type<span class="Delimiter">-></span>value<span class="Delimiter">);</span> <span class="Identifier">return</span> info<span class="Delimiter">.</span>kind == EXCLUSIVE_CONTAINER<span class="Delimiter">;</span> |