//: Go from an address to the payload it points at using /lookup. //: //: The tests in this layer use unsafe operations so as to stay decoupled from //: 'new'. void test_copy_indirect() { run( "def main [\n" // skip alloc id for 10:&:num " 11:num <- copy 20\n" // skip alloc id for payload " 21:num <- copy 94\n" // Treat locations 10 and 11 as an address to look up, pointing at the // payload in locations 20 and 21. " 30:num <- copy 10:&:num/lookup\n" "]\n" ); CHECK_TRACE_CONTENTS( "mem: storing 94 in location 30\n" ); } :(before "End Preprocess read_memory(x)") canonize(x); //: similarly, write to addresses pointing at other locations using the //: 'lookup' property :(code) void test_store_indirect() { run( "def main [\n" // skip alloc id for 10:&:num " 11:num <- copy 10\n" " 10:&:num/lookup <- copy 94\n" "]\n" ); CHECK_TRACE_CONTENTS( "mem: storing 94 in location 11\n" ); } :(before "End Preprocess write_memory(x, data)") canonize(x); //: writes to address 0 always loudly fail :(code) void test_store_to_0_fails() { Hide_errors = true; run( "def main [\n" " 10:&:num <- copy null\n" " 10:&:num/lookup <- copy 94\n" "]\n" ); CHECK_TRACE_DOESNT_CONTAIN("mem: storing 94 in location 0"); CHECK_TRACE_CONTENTS( "error: main: tried to lookup 0 in '10:&:num/lookup <- copy 94'\n" ); } //: attempts to /lookup address 0 always loudly fail void test_lookup_0_fails() { Hide_errors = true; run( "def main [\n" " 10:&:num <- copy null\n" " 20:num <- copy 10:&:num/lookup\n" "]\n" ); CHECK_TRACE_CONTENTS( "error: main: tried to lookup 0 in '20:num <- copy 10:&:num/lookup'\n" ); } void test_lookup_0_dumps_callstack() { Hide_errors = true; run( "def main [\n" " foo null\n" "]\n" "def foo [\n" " 10:&:num <- next-input\n" " 20:num <- copy 10:&:num/lookup\n" "]\n" ); CHECK_TRACE_CONTENTS( "error: foo: tried to lookup 0 in '20:num <- copy 10:&:num/lookup'\n" "error: called from main: foo null\n" ); } void canonize(reagent& x) { if (is_literal(x)) return; // Begin canonize(x) Lookups while (has_property(x, "lookup")) lookup_memory(x); } void lookup_memory(reagent& x) { if (!x.type || x.type->atom || x.type->left->value != Address_type_ordinal) { raise << maybe(current_recipe_name()) << "tried to lookup '" << x.original_string << "' but it isn't an address\n" << end(); dump_callstack(); return; } // compute value if (x.value == 0) { raise << maybe(current_recipe_name()) << "tried to lookup 0\n" << end(); dump_callstack(); return; } lookup_memory_core(x, /*check_for_null*/true); } void lookup_memory_core(reagent& x, bool check_for_null) { double address = x.value + /*skip alloc id in address*/1; double new_value = get_or_insert(Memory, address); trace(Callstack_depth+1, "mem") << "location " << address << " contains " << no_scientific(new_value) << end(); // check for null if (check_for_null && new_value == 0) { if (Current_routine) { raise << maybe(current_recipe_name()) << "tried to lookup 0 in '" << to_original_string(current_instruction()) << "'\n" << end(); dump_callstack(); } else { raise << "tried to lookup 0\n" << end(); } } // validate alloc-id double alloc_id_in_address =
discard """
disabled: "posix"
"""
# bug 10952, UNC paths
import os
doAssert r"\\hostname\foo\bar" / "baz" == r"\\hostname\foo\bar\baz"
doAssert r"\\?\C:\foo" / "bar" == r"\\?\C:\foo\bar"