[m-rev.] diff: fix the failure of hard_coded/write_binary_it8 in the C# grade

Julien Fischer jfischer at opturion.com
Thu Oct 19 22:47:35 AEDT 2017


Fix the failure of hard_coded/write_binary_int8 in the C# grade.

library/io.m:
     Cast the argument of write_binary_int8 to a uint8 before writing
     it to the stream.  If this is not done, sign extension means that
     negative values will exceed the allowed range of the call to ToByte
     in the C# implementation of do_write_byte/5 and an exception will
     be thrown.

library/uint8.m:
     Add the function cast_from_int8/1 for use by the above.

Julien.

diff --git a/library/io.m b/library/io.m
index 44592ce..7c75f75 100644
--- a/library/io.m
+++ b/library/io.m
@@ -8389,7 +8389,8 @@ write_byte(binary_output_stream(Stream), Byte, !IO) :-
      throw_on_output_error(Error, !IO).

  write_binary_int8(binary_output_stream(Stream), Int8, !IO) :-
-    Int = int8.to_int(Int8),
+    UInt8 = uint8.cast_from_int8(Int8),
+    Int = uint8.to_int(UInt8),
      do_write_byte(Stream, Int, Error, !IO),
      throw_on_output_error(Error, !IO).

diff --git a/library/uint8.m b/library/uint8.m
index 5acdf68..00a3a5c 100644
--- a/library/uint8.m
+++ b/library/uint8.m
@@ -33,6 +33,8 @@

  :- func cast_from_int(int) = uint8.

+:- func cast_from_int8(int8) = uint8.
+
  :- func to_int(uint8) = int.

  %---------------------------------------------------------------------------%
@@ -240,6 +242,34 @@ cast_from_int(_) = _ :-
  %---------------------------------------------------------------------------%

  :- pragma foreign_proc("C",
+    cast_from_int8(I8::in) = (U8::out),
+    [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail,
+        does_not_affect_liveness],
+"
+    U8 = (uint8_t) I8;
+").
+
+:- pragma foreign_proc("C#",
+    cast_from_int8(I8::in) = (U8::out),
+    [will_not_call_mercury, promise_pure, thread_safe],
+"
+    U8 = (byte) I8;
+").
+
+:- pragma foreign_proc("Java",
+    cast_from_int8(I8::in) = (U8::out),
+    [will_not_call_mercury, promise_pure, thread_safe],
+"
+    U8 = I8;
+").
+
+:- pragma no_determinism_warning(cast_from_int8/1).
+cast_from_int8(_) = _ :-
+    sorry($module, "uint8.cast_from_int8/1 NYI for Erlang").
+
+%---------------------------------------------------------------------------%
+
+:- pragma foreign_proc("C",
      to_int(U8::in) = (I::out),
      [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail,
          does_not_affect_liveness],


More information about the reviews mailing list