diff --git a/main.ml b/main.ml index 595158a..976535a 100644 --- a/main.ml +++ b/main.ml @@ -2402,6 +2402,12 @@ let rec generate (letfuncs, strings, typedefs, exps) = appfmt buf "mov rax, %d" @@ tagged_int 0 ; appstr buf "ret" ; appstr buf "" ; + appstr buf "aqaml_string_create:" ; + appstr buf @@ untag_int "rax" ; + appstr buf "mov rdi, rax" ; + appstr buf "call aqaml_string_create_detail@PLT" ; + appstr buf "ret" ; + appstr buf "" ; appstr buf "aqaml_string_blit:" ; appstr buf @@ untag_int "rbx" ; appstr buf @@ untag_int "rsi" ; diff --git a/stdlib.ml b/stdlib.ml index 33ed351..726e751 100644 --- a/stdlib.ml +++ b/stdlib.ml @@ -19,6 +19,8 @@ module Bytes = struct external set : bytes -> int -> char -> unit = "aqaml_string_set" + external create : int -> bytes = "aqaml_string_create" + external blit : bytes -> int -> bytes -> int -> int -> unit = "aqaml_string_blit" @@ -39,6 +41,8 @@ module String = struct external set : string -> int -> char -> unit = "aqaml_string_set" + external create : int -> bytes = "aqaml_string_create" + external blit : string -> int -> bytes -> int -> int -> unit = "aqaml_string_blit" diff --git a/test.ml b/test.ml index f0ab783..c8924e3 100644 --- a/test.ml +++ b/test.ml @@ -1517,3 +1517,11 @@ let dst = Bytes.of_string "def " in String.blit src 1 dst 2 3 ; test src "abcd" ; test dst @@ Bytes.of_string "debcd" + +;; +let src = "abcd" in +let dst = Bytes.create 5 in +dst.[0] <- 'd' ; +dst.[1] <- 'e' ; +String.blit src 1 dst 2 3 ; +test dst @@ Bytes.of_string "debcd" diff --git a/utility.c b/utility.c index 063129b..6e03ffb 100644 --- a/utility.c +++ b/utility.c @@ -29,6 +29,7 @@ typedef struct AQamlValue { } AQamlValue; uint64_t aqaml_string_length_detail(uint64_t ptr); +uint64_t aqaml_string_create_detail(uint64_t len); void *aqaml_malloc_detail(uint32_t size) { @@ -103,17 +104,13 @@ uint64_t aqaml_concat_string_detail(uint64_t lhs_src, uint64_t rhs_src) AQamlValue lhs = get_value(lhs_src), rhs = get_value(rhs_src); // assert(lhs.kind == AQAML_STRING && rhs.kind == AQAML_STRING); - uint64_t ret_src = aqaml_alloc_block((lhs_len + rhs_len) / 8 + 1, 0, 252); + uint64_t ret_src = aqaml_string_create_detail(lhs_len + rhs_len); AQamlValue ret = get_value(ret_src); - uint64_t space = 7 - (lhs_len + rhs_len) % 8; for (uint64_t i = 0; i < lhs_len; i++) ret.string->str[i] = lhs.string->str[i]; for (uint64_t i = 0; i < rhs_len; i++) ret.string->str[i + lhs_len] = rhs.string->str[i]; - for (uint64_t i = 0; i < space; i++) - ret.string->str[i + lhs_len + rhs_len] = 0u; - ret.string->str[lhs_len + rhs_len + space] = space; return ret_src; } @@ -145,6 +142,16 @@ void aqaml_string_set_detail(uint64_t str_src, uint64_t index, uint64_t chr) val.string->str[index] = (uint8_t)chr; } +uint64_t aqaml_string_create_detail(uint64_t len) +{ + uint64_t ret_src = aqaml_alloc_block(len / 8 + 1, 0, 252); + uint64_t space = 7 - len % 8; + AQamlValue ret = get_value(ret_src); + for (uint64_t i = 0; i < space; i++) ret.string->str[len + i] = 0; + ret.string->str[len + space] = space; + return ret_src; +} + void aqaml_string_blit_detail(uint64_t src_src, uint64_t srcoff, uint64_t dst_src, uint64_t dstoff, uint64_t len) {