diff --git a/docs/Manual.html b/docs/Manual.html
index 4e248b22dbf..aa9e53a00f8 100644
--- a/docs/Manual.html
+++ b/docs/Manual.html
@@ -639,6 +639,7 @@
Appendix A: CHANGES
+1.02 (dev)
1.01
1.0
@@ -4096,6 +4097,25 @@ Appendix A: CHANGES
+
+
+
@@ -4119,7 +4139,7 @@
1.01
-Bug fixes and enhancment
+Bug fixes and enhancement
-
diff --git a/jscomp/runtime/caml_string.ml b/jscomp/runtime/caml_string.ml
index e60e982b42f..64a90afca3d 100644
--- a/jscomp/runtime/caml_string.ml
+++ b/jscomp/runtime/caml_string.ml
@@ -87,25 +87,45 @@ let caml_blit_string s1 i1 s2 i2 (len : int ) =
done
end
+(** Same as {!Array.prototype.copyWithin} *)
+let copyWithin s1 i1 i2 len =
+ if i1 < i2 then (* nop for i1 = i2 *)
+ let range_a = length s1 - i2 - 1 in
+ let range_b = len - 1 in
+ let range = if range_a > range_b then range_b else range_a in
+ for j = range downto 0 do
+ unsafe_set s1 (i2 + j) (unsafe_get s1 (i1 + j))
+ done
+ else if i1 > i2 then
+ let range_a = length s1 - i1 - 1 in
+ let range_b = len - 1 in
+ let range = if range_a > range_b then range_b else range_a in
+ for k = 0 to range do
+ unsafe_set s1 (i2 + k) (unsafe_get s1 (i1 + k))
+ done
+
(* TODO: when the compiler could optimize small function calls,
use high order functions instead
*)
let caml_blit_bytes s1 i1 s2 i2 len =
if len > 0 then
- let off1 = length s1 - i1 in
- if len <= off1 then
- for i = 0 to len - 1 do
- unsafe_set s2 (i2 + i) (unsafe_get s1 (i1 + i))
- done
- else
- begin
- for i = 0 to off1 - 1 do
+ if s1 == s2 then
+ copyWithin s1 i1 i2 len
+ else
+ let off1 = length s1 - i1 in
+ if len <= off1 then
+ for i = 0 to len - 1 do
unsafe_set s2 (i2 + i) (unsafe_get s1 (i1 + i))
- done;
- for i = off1 to len - 1 do
- unsafe_set s2 (i2 + i) '\000'
done
- end
+ else
+ begin
+ for i = 0 to off1 - 1 do
+ unsafe_set s2 (i2 + i) (unsafe_get s1 (i1 + i))
+ done;
+ for i = off1 to len - 1 do
+ unsafe_set s2 (i2 + i) '\000'
+ done
+ end
(** checkout [Bytes.empty] -- to be inlined? *)
let bytes_of_string s =
diff --git a/jscomp/test/.depend b/jscomp/test/.depend
index bb234d751c3..338e0365759 100644
--- a/jscomp/test/.depend
+++ b/jscomp/test/.depend
@@ -114,6 +114,8 @@ buffer_test.cmj : ../stdlib/string.cmi mt.cmi ../stdlib/bytes.cmi \
../stdlib/buffer.cmi
buffer_test.cmx : ../stdlib/string.cmx mt.cmx ../stdlib/bytes.cmx \
../stdlib/buffer.cmx
+bytes_split_gpr_743.cmj : mt.cmi ../runtime/js.cmj ../stdlib/bytes.cmi
+bytes_split_gpr_743.cmx : mt.cmx ../runtime/js.cmx ../stdlib/bytes.cmx
caml_compare_test.cmj : mt.cmi
caml_compare_test.cmx : mt.cmx
caml_format_test.cmj : ../stdlib/printf.cmi mt.cmi ../stdlib/int64.cmi \
@@ -926,6 +928,8 @@ buffer_test.cmo : ../stdlib/string.cmi mt.cmi ../stdlib/bytes.cmi \
../stdlib/buffer.cmi
buffer_test.cmj : ../stdlib/string.cmj mt.cmj ../stdlib/bytes.cmj \
../stdlib/buffer.cmj
+bytes_split_gpr_743.cmo : mt.cmi ../runtime/js.cmo ../stdlib/bytes.cmi
+bytes_split_gpr_743.cmj : mt.cmj ../runtime/js.cmj ../stdlib/bytes.cmj
caml_compare_test.cmo : mt.cmi
caml_compare_test.cmj : mt.cmj
caml_format_test.cmo : ../stdlib/printf.cmi mt.cmi ../stdlib/int64.cmi \
diff --git a/jscomp/test/Makefile b/jscomp/test/Makefile
index b9e05d6399d..0970e0395ab 100644
--- a/jscomp/test/Makefile
+++ b/jscomp/test/Makefile
@@ -65,7 +65,8 @@ OTHERS := literals a test_ari test_export2 test_internalOO test_obj_simple_ffi t
watch_test bs_node_string_buffer_test \
bs_ignore_test bs_ignore_effect \
ppx_this_obj_field single_module_alias \
- CCSexpM CCSexpM_test CCSexp js_json_test array_subtle_test
+ CCSexpM CCSexpM_test CCSexp js_json_test array_subtle_test bytes_split_gpr_743
+
diff --git a/jscomp/test/bytes_split_gpr_743.js b/jscomp/test/bytes_split_gpr_743.js
new file mode 100644
index 00000000000..5e181516578
--- /dev/null
+++ b/jscomp/test/bytes_split_gpr_743.js
@@ -0,0 +1,74 @@
+'use strict';
+
+var Bytes = require("../../lib/js/bytes");
+var Mt = require("./mt");
+var Block = require("../../lib/js/block");
+var Caml_string = require("../../lib/js/caml_string");
+
+var suites = [/* [] */0];
+
+var test_id = [0];
+
+function eq(loc, param) {
+ var y = param[1];
+ var x = param[0];
+ test_id[0] = test_id[0] + 1 | 0;
+ suites[0] = /* :: */[
+ /* tuple */[
+ loc + (" id " + test_id[0]),
+ function () {
+ return /* Eq */Block.__(0, [
+ x,
+ y
+ ]);
+ }
+ ],
+ suites[0]
+ ];
+ return /* () */0;
+}
+
+var b = new Array(3);
+
+b[0] = /* "a" */97;
+
+b[1] = /* "b" */98;
+
+b[2] = /* "c" */99;
+
+Bytes.blit(b, 0, b, 1, 2);
+
+var res = Caml_string.bytes_to_string(b);
+
+console.log(res);
+
+eq('File "bytes_split_gpr_743.ml", line 17, characters 5-12', /* tuple */[
+ "aab",
+ res
+ ]);
+
+var b$1 = new Array(3);
+
+b$1[0] = /* "a" */97;
+
+b$1[1] = /* "b" */98;
+
+b$1[2] = /* "c" */99;
+
+Bytes.blit(b$1, 1, b$1, 0, 2);
+
+var res2 = Caml_string.bytes_to_string(b$1);
+
+console.log(res2);
+
+eq('File "bytes_split_gpr_743.ml", line 32, characters 5-12', /* tuple */[
+ "bcc",
+ res2
+ ]);
+
+Mt.from_pair_suites("bytes_split_gpr_743.ml", suites[0]);
+
+exports.suites = suites;
+exports.test_id = test_id;
+exports.eq = eq;
+/* Not a pure module */
diff --git a/jscomp/test/bytes_split_gpr_743.ml b/jscomp/test/bytes_split_gpr_743.ml
new file mode 100644
index 00000000000..4b6a9ece077
--- /dev/null
+++ b/jscomp/test/bytes_split_gpr_743.ml
@@ -0,0 +1,35 @@
+let suites : Mt.pair_suites ref = ref []
+let test_id = ref 0
+let eq loc (x, y) =
+ incr test_id ;
+ suites :=
+ (loc ^" id " ^ (string_of_int !test_id), (fun _ -> Mt.Eq(x,y))) :: !suites
+
+
+let () =
+ let b = Bytes.create 3 in
+ Bytes.set b 0 'a';
+ Bytes.set b 1 'b';
+ Bytes.set b 2 'c';
+ Bytes.blit b 0 b 1 2;
+ let res = (Bytes.unsafe_to_string b) in
+ Js.log res; (* "aab"*)
+ eq __LOC__ ("aab", res)
+ (* assert('a' = Bytes.get b 0); *)
+ (* assert('a' = Bytes.get b 1); *)
+ (* assert('b' = Bytes.get b 2); *)
+ (* () *)
+
+
+let () =
+ let b = Bytes.create 3 in
+ Bytes.set b 0 'a';
+ Bytes.set b 1 'b';
+ Bytes.set b 2 'c';
+ Bytes.blit b 1 b 0 2;
+ let res2 = (Bytes.unsafe_to_string b) in
+ Js.log res2 (* "bcc"*);
+ eq __LOC__ ("bcc", res2)
+
+
+let () = Mt.from_pair_suites __FILE__ !suites
diff --git a/lib/js/caml_string.js b/lib/js/caml_string.js
index eb0978faca3..15026f4672b 100644
--- a/lib/js/caml_string.js
+++ b/lib/js/caml_string.js
@@ -80,21 +80,50 @@ function caml_blit_string(s1, i1, s2, i2, len) {
function caml_blit_bytes(s1, i1, s2, i2, len) {
if (len > 0) {
- var off1 = s1.length - i1 | 0;
- if (len <= off1) {
- for(var i = 0 ,i_finish = len - 1 | 0; i <= i_finish; ++i){
- s2[i2 + i | 0] = s1[i1 + i | 0];
+ if (s1 === s2) {
+ var s1$1 = s1;
+ var i1$1 = i1;
+ var i2$1 = i2;
+ var len$1 = len;
+ if (i1$1 < i2$1) {
+ var range_a = (s1$1.length - i2$1 | 0) - 1 | 0;
+ var range_b = len$1 - 1 | 0;
+ var range = range_a > range_b ? range_b : range_a;
+ for(var j = range; j >= 0; --j){
+ s1$1[i2$1 + j | 0] = s1$1[i1$1 + j | 0];
+ }
+ return /* () */0;
+ }
+ else if (i1$1 > i2$1) {
+ var range_a$1 = (s1$1.length - i1$1 | 0) - 1 | 0;
+ var range_b$1 = len$1 - 1 | 0;
+ var range$1 = range_a$1 > range_b$1 ? range_b$1 : range_a$1;
+ for(var k = 0; k <= range$1; ++k){
+ s1$1[i2$1 + k | 0] = s1$1[i1$1 + k | 0];
+ }
+ return /* () */0;
+ }
+ else {
+ return 0;
}
- return /* () */0;
}
else {
- for(var i$1 = 0 ,i_finish$1 = off1 - 1 | 0; i$1 <= i_finish$1; ++i$1){
- s2[i2 + i$1 | 0] = s1[i1 + i$1 | 0];
+ var off1 = s1.length - i1 | 0;
+ if (len <= off1) {
+ for(var i = 0 ,i_finish = len - 1 | 0; i <= i_finish; ++i){
+ s2[i2 + i | 0] = s1[i1 + i | 0];
+ }
+ return /* () */0;
}
- for(var i$2 = off1 ,i_finish$2 = len - 1 | 0; i$2 <= i_finish$2; ++i$2){
- s2[i2 + i$2 | 0] = /* "\000" */0;
+ else {
+ for(var i$1 = 0 ,i_finish$1 = off1 - 1 | 0; i$1 <= i_finish$1; ++i$1){
+ s2[i2 + i$1 | 0] = s1[i1 + i$1 | 0];
+ }
+ for(var i$2 = off1 ,i_finish$2 = len - 1 | 0; i$2 <= i_finish$2; ++i$2){
+ s2[i2 + i$2 | 0] = /* "\000" */0;
+ }
+ return /* () */0;
}
- return /* () */0;
}
}
else {
diff --git a/site/docsource/CHANGELOG.adoc b/site/docsource/CHANGELOG.adoc
index 9d62e273b91..2cb33a09e9a 100644
--- a/site/docsource/CHANGELOG.adoc
+++ b/site/docsource/CHANGELOG.adoc
@@ -3,6 +3,11 @@
## CHANGES
:issues: https://github.com/bloomberg/bucklescript/issues
+== 1.02 (dev)
+
+* Bug fixes and enhancement
+
+- Fix Bytes.blit when src==dst {issues}743[#743]
== 1.01
@@ -12,7 +17,7 @@
- Introduce phantom arguments (`bs.ignore`) for ad-hoc
polymorphism {issues}/686[#686]
-* Bug fixes and enhancment
+* Bug fixes and enhancement
- Enforce `#=` always return unit {issues}718[#718] for better error messages