diff --git a/design/mvp/CanonicalABI.md b/design/mvp/CanonicalABI.md index 92e01e7f..360af744 100644 --- a/design/mvp/CanonicalABI.md +++ b/design/mvp/CanonicalABI.md @@ -1070,6 +1070,8 @@ host: self.inst.store.invoke(realloc, on_start, on_resolve) self.inst.may_leave = True assert(ptr is not None) + trap_if(ptr != align_to(ptr, alignment)) + trap_if(ptr + new_byte_length > len(self.opts.memory)) return ptr def allocate(self, alignment, byte_length): @@ -2619,8 +2621,6 @@ def store_string_copy(cx, src, src_code_units, dst_code_unit_size, dst_alignment dst_byte_length = dst_code_unit_size * src_code_units assert(dst_byte_length <= REALLOC_I32_MAX) ptr = cx.allocate(dst_alignment, dst_byte_length) - trap_if(ptr != align_to(ptr, dst_alignment)) - trap_if(ptr + dst_byte_length > len(cx.opts.memory)) encoded = src.encode(dst_encoding) assert(dst_byte_length == len(encoded)) cx.opts.memory[ptr : ptr+len(encoded)] = encoded @@ -2642,19 +2642,16 @@ def store_latin1_to_utf8(cx, src, src_code_units): def store_string_to_utf8(cx, src, src_code_units, worst_case_size): assert(src_code_units <= REALLOC_I32_MAX) ptr = cx.allocate(1, src_code_units) - trap_if(ptr + src_code_units > len(cx.opts.memory)) for i,code_point in enumerate(src): if ord(code_point) < 2**7: cx.opts.memory[ptr + i] = ord(code_point) else: assert(worst_case_size <= REALLOC_I32_MAX) ptr = cx.reallocate(ptr, src_code_units, 1, worst_case_size) - trap_if(ptr + worst_case_size > len(cx.opts.memory)) encoded = src.encode('utf-8') cx.opts.memory[ptr+i : ptr+len(encoded)] = encoded[i : ] if worst_case_size > len(encoded): ptr = cx.reallocate(ptr, worst_case_size, 1, len(encoded)) - trap_if(ptr + len(encoded) > len(cx.opts.memory)) return (ptr, len(encoded)) return (ptr, src_code_units) ``` @@ -2668,14 +2665,10 @@ def store_utf8_to_utf16(cx, src, src_code_units): worst_case_size = 2 * src_code_units assert(worst_case_size <= REALLOC_I32_MAX) ptr = cx.allocate(2, worst_case_size) - trap_if(ptr != align_to(ptr, 2)) - trap_if(ptr + worst_case_size > len(cx.opts.memory)) encoded = src.encode('utf-16-le') cx.opts.memory[ptr : ptr+len(encoded)] = encoded if len(encoded) < worst_case_size: ptr = cx.reallocate(ptr, worst_case_size, 2, len(encoded)) - trap_if(ptr != align_to(ptr, 2)) - trap_if(ptr + len(encoded) > len(cx.opts.memory)) code_units = int(len(encoded) / 2) return (ptr, code_units) ``` @@ -2692,8 +2685,6 @@ bytes): def store_string_to_latin1_or_utf16(cx, src, src_code_units): assert(src_code_units <= REALLOC_I32_MAX) ptr = cx.allocate(2, src_code_units) - trap_if(ptr != align_to(ptr, 2)) - trap_if(ptr + src_code_units > len(cx.opts.memory)) dst_byte_length = 0 for usv in src: if ord(usv) < (1 << 8): @@ -2703,8 +2694,6 @@ def store_string_to_latin1_or_utf16(cx, src, src_code_units): worst_case_size = 2 * src_code_units assert(worst_case_size <= REALLOC_I32_MAX) ptr = cx.reallocate(ptr, src_code_units, 2, worst_case_size) - trap_if(ptr != align_to(ptr, 2)) - trap_if(ptr + worst_case_size > len(cx.opts.memory)) for j in range(dst_byte_length-1, -1, -1): cx.opts.memory[ptr + 2*j] = cx.opts.memory[ptr + j] cx.opts.memory[ptr + 2*j + 1] = 0 @@ -2712,14 +2701,10 @@ def store_string_to_latin1_or_utf16(cx, src, src_code_units): cx.opts.memory[ptr+2*dst_byte_length : ptr+len(encoded)] = encoded[2*dst_byte_length : ] if worst_case_size > len(encoded): ptr = cx.reallocate(ptr, worst_case_size, 2, len(encoded)) - trap_if(ptr != align_to(ptr, 2)) - trap_if(ptr + len(encoded) > len(cx.opts.memory)) tagged_code_units = int(len(encoded) / 2) | utf16_tag(cx.opts.memory.ptr_type()) return (ptr, tagged_code_units) if dst_byte_length < src_code_units: ptr = cx.reallocate(ptr, src_code_units, 2, dst_byte_length) - trap_if(ptr != align_to(ptr, 2)) - trap_if(ptr + dst_byte_length > len(cx.opts.memory)) return (ptr, dst_byte_length) ``` @@ -2738,8 +2723,6 @@ def store_probably_utf16_to_latin1_or_utf16(cx, src, src_code_units): src_byte_length = 2 * src_code_units assert(src_byte_length <= REALLOC_I32_MAX) ptr = cx.allocate(2, src_byte_length) - trap_if(ptr != align_to(ptr, 2)) - trap_if(ptr + src_byte_length > len(cx.opts.memory)) encoded = src.encode('utf-16-le') cx.opts.memory[ptr : ptr+len(encoded)] = encoded if any(ord(c) >= (1 << 8) for c in src): @@ -2748,8 +2731,7 @@ def store_probably_utf16_to_latin1_or_utf16(cx, src, src_code_units): latin1_size = int(len(encoded) / 2) for i in range(latin1_size): cx.opts.memory[ptr + i] = cx.opts.memory[ptr + 2*i] - ptr = cx.reallocate(ptr, src_byte_length, 1, latin1_size) - trap_if(ptr + latin1_size > len(cx.opts.memory)) + ptr = cx.reallocate(ptr, src_byte_length, 2, latin1_size) return (ptr, latin1_size) ``` @@ -2780,8 +2762,6 @@ def store_list_into_range(cx, v, elem_type): byte_length = len(v) * elem_size(elem_type, cx.opts.memory.ptr_type()) assert(byte_length <= REALLOC_I32_MAX) ptr = cx.allocate(alignment(elem_type, cx.opts.memory.ptr_type()), byte_length) - trap_if(ptr != align_to(ptr, alignment(elem_type, cx.opts.memory.ptr_type()))) - trap_if(ptr + byte_length > len(cx.opts.memory)) store_list_into_valid_range(cx, v, ptr, elem_type) return (ptr, len(v)) @@ -3317,9 +3297,9 @@ def lower_flat_values(cx, max_flat, vs, ts, out_param = None): flat_vals = [ptr] else: ptr = out_param.next(cx.opts.memory.ptr_type()) + trap_if(ptr != align_to(ptr, alignment(tuple_type, cx.opts.memory.ptr_type()))) + trap_if(ptr + elem_size(tuple_type, cx.opts.memory.ptr_type()) > len(cx.opts.memory)) flat_vals = [] - trap_if(ptr != align_to(ptr, alignment(tuple_type, cx.opts.memory.ptr_type()))) - trap_if(ptr + elem_size(tuple_type, cx.opts.memory.ptr_type()) > len(cx.opts.memory)) store(cx, tuple_value, tuple_type, ptr) else: flat_vals = [] diff --git a/design/mvp/canonical-abi/definitions.py b/design/mvp/canonical-abi/definitions.py index ff2e29e5..70ae3bc4 100644 --- a/design/mvp/canonical-abi/definitions.py +++ b/design/mvp/canonical-abi/definitions.py @@ -638,6 +638,8 @@ def on_resolve(result): self.inst.store.invoke(realloc, on_start, on_resolve) self.inst.may_leave = True assert(ptr is not None) + trap_if(ptr != align_to(ptr, alignment)) + trap_if(ptr + new_byte_length > len(self.opts.memory)) return ptr def allocate(self, alignment, byte_length): @@ -1574,8 +1576,6 @@ def store_string_copy(cx, src, src_code_units, dst_code_unit_size, dst_alignment dst_byte_length = dst_code_unit_size * src_code_units assert(dst_byte_length <= REALLOC_I32_MAX) ptr = cx.allocate(dst_alignment, dst_byte_length) - trap_if(ptr != align_to(ptr, dst_alignment)) - trap_if(ptr + dst_byte_length > len(cx.opts.memory)) encoded = src.encode(dst_encoding) assert(dst_byte_length == len(encoded)) cx.opts.memory[ptr : ptr+len(encoded)] = encoded @@ -1592,19 +1592,16 @@ def store_latin1_to_utf8(cx, src, src_code_units): def store_string_to_utf8(cx, src, src_code_units, worst_case_size): assert(src_code_units <= REALLOC_I32_MAX) ptr = cx.allocate(1, src_code_units) - trap_if(ptr + src_code_units > len(cx.opts.memory)) for i,code_point in enumerate(src): if ord(code_point) < 2**7: cx.opts.memory[ptr + i] = ord(code_point) else: assert(worst_case_size <= REALLOC_I32_MAX) ptr = cx.reallocate(ptr, src_code_units, 1, worst_case_size) - trap_if(ptr + worst_case_size > len(cx.opts.memory)) encoded = src.encode('utf-8') cx.opts.memory[ptr+i : ptr+len(encoded)] = encoded[i : ] if worst_case_size > len(encoded): ptr = cx.reallocate(ptr, worst_case_size, 1, len(encoded)) - trap_if(ptr + len(encoded) > len(cx.opts.memory)) return (ptr, len(encoded)) return (ptr, src_code_units) @@ -1612,22 +1609,16 @@ def store_utf8_to_utf16(cx, src, src_code_units): worst_case_size = 2 * src_code_units assert(worst_case_size <= REALLOC_I32_MAX) ptr = cx.allocate(2, worst_case_size) - trap_if(ptr != align_to(ptr, 2)) - trap_if(ptr + worst_case_size > len(cx.opts.memory)) encoded = src.encode('utf-16-le') cx.opts.memory[ptr : ptr+len(encoded)] = encoded if len(encoded) < worst_case_size: ptr = cx.reallocate(ptr, worst_case_size, 2, len(encoded)) - trap_if(ptr != align_to(ptr, 2)) - trap_if(ptr + len(encoded) > len(cx.opts.memory)) code_units = int(len(encoded) / 2) return (ptr, code_units) def store_string_to_latin1_or_utf16(cx, src, src_code_units): assert(src_code_units <= REALLOC_I32_MAX) ptr = cx.allocate(2, src_code_units) - trap_if(ptr != align_to(ptr, 2)) - trap_if(ptr + src_code_units > len(cx.opts.memory)) dst_byte_length = 0 for usv in src: if ord(usv) < (1 << 8): @@ -1637,8 +1628,6 @@ def store_string_to_latin1_or_utf16(cx, src, src_code_units): worst_case_size = 2 * src_code_units assert(worst_case_size <= REALLOC_I32_MAX) ptr = cx.reallocate(ptr, src_code_units, 2, worst_case_size) - trap_if(ptr != align_to(ptr, 2)) - trap_if(ptr + worst_case_size > len(cx.opts.memory)) for j in range(dst_byte_length-1, -1, -1): cx.opts.memory[ptr + 2*j] = cx.opts.memory[ptr + j] cx.opts.memory[ptr + 2*j + 1] = 0 @@ -1646,22 +1635,16 @@ def store_string_to_latin1_or_utf16(cx, src, src_code_units): cx.opts.memory[ptr+2*dst_byte_length : ptr+len(encoded)] = encoded[2*dst_byte_length : ] if worst_case_size > len(encoded): ptr = cx.reallocate(ptr, worst_case_size, 2, len(encoded)) - trap_if(ptr != align_to(ptr, 2)) - trap_if(ptr + len(encoded) > len(cx.opts.memory)) tagged_code_units = int(len(encoded) / 2) | utf16_tag(cx.opts.memory.ptr_type()) return (ptr, tagged_code_units) if dst_byte_length < src_code_units: ptr = cx.reallocate(ptr, src_code_units, 2, dst_byte_length) - trap_if(ptr != align_to(ptr, 2)) - trap_if(ptr + dst_byte_length > len(cx.opts.memory)) return (ptr, dst_byte_length) def store_probably_utf16_to_latin1_or_utf16(cx, src, src_code_units): src_byte_length = 2 * src_code_units assert(src_byte_length <= REALLOC_I32_MAX) ptr = cx.allocate(2, src_byte_length) - trap_if(ptr != align_to(ptr, 2)) - trap_if(ptr + src_byte_length > len(cx.opts.memory)) encoded = src.encode('utf-16-le') cx.opts.memory[ptr : ptr+len(encoded)] = encoded if any(ord(c) >= (1 << 8) for c in src): @@ -1670,8 +1653,7 @@ def store_probably_utf16_to_latin1_or_utf16(cx, src, src_code_units): latin1_size = int(len(encoded) / 2) for i in range(latin1_size): cx.opts.memory[ptr + i] = cx.opts.memory[ptr + 2*i] - ptr = cx.reallocate(ptr, src_byte_length, 1, latin1_size) - trap_if(ptr + latin1_size > len(cx.opts.memory)) + ptr = cx.reallocate(ptr, src_byte_length, 2, latin1_size) return (ptr, latin1_size) def lower_error_context(cx, v): @@ -1690,8 +1672,6 @@ def store_list_into_range(cx, v, elem_type): byte_length = len(v) * elem_size(elem_type, cx.opts.memory.ptr_type()) assert(byte_length <= REALLOC_I32_MAX) ptr = cx.allocate(alignment(elem_type, cx.opts.memory.ptr_type()), byte_length) - trap_if(ptr != align_to(ptr, alignment(elem_type, cx.opts.memory.ptr_type()))) - trap_if(ptr + byte_length > len(cx.opts.memory)) store_list_into_valid_range(cx, v, ptr, elem_type) return (ptr, len(v)) @@ -2059,9 +2039,9 @@ def lower_flat_values(cx, max_flat, vs, ts, out_param = None): flat_vals = [ptr] else: ptr = out_param.next(cx.opts.memory.ptr_type()) + trap_if(ptr != align_to(ptr, alignment(tuple_type, cx.opts.memory.ptr_type()))) + trap_if(ptr + elem_size(tuple_type, cx.opts.memory.ptr_type()) > len(cx.opts.memory)) flat_vals = [] - trap_if(ptr != align_to(ptr, alignment(tuple_type, cx.opts.memory.ptr_type()))) - trap_if(ptr + elem_size(tuple_type, cx.opts.memory.ptr_type()) > len(cx.opts.memory)) store(cx, tuple_value, tuple_type, ptr) else: flat_vals = []