@@ -1679,59 +1679,11 @@ let allocate_bytes_uninitialized = (wasm_mod, env, size) => {
16791679 );
16801680};
16811681
1682- let allocate_char = (wasm_mod, env, char) => {
1683- // Copy bytes into a fresh buffer so we can guarantee a copy of a full word
1684- let bytes = Bytes . make(4 , Char . chr(0 ));
1685- // OCaml String#length is byte length, not Unicode character length
1686- // Guaranteed not to be longer than 4 bytes by well-formedness
1687- Bytes . blit_string(char, 0 , bytes, 0 , String . length(char));
1688- let value = Bytes . get_int32_le(bytes, 0 );
1689-
1690- let get_swap = () => get_swap(wasm_mod, env, 0 );
1691- let tee_swap = tee_swap(wasm_mod, env, 0 );
1692- Expression . Block . make(
1693- wasm_mod,
1694- gensym_label("allocate_char" ),
1695- [
1696- store(
1697- ~offset= 0 ,
1698- wasm_mod,
1699- tee_swap(heap_allocate(wasm_mod, env, 2 )),
1700- Expression . Const . make(
1701- wasm_mod,
1702- const_int32(tag_val_of_heap_tag_type(CharType )),
1703- ),
1704- ),
1705- store(
1706- ~offset= 4 ,
1707- wasm_mod,
1708- get_swap() ,
1709- Expression . Const . make(wasm_mod, wrap_int32(value)),
1710- ),
1711- get_swap() ,
1712- ] ,
1713- );
1714- };
1715-
1716- let allocate_char_uninitialized = (wasm_mod, env) => {
1717- let get_swap = () => get_swap(wasm_mod, env, 0 );
1718- let tee_swap = tee_swap(wasm_mod, env, 0 );
1719- Expression . Block . make(
1720- wasm_mod,
1721- gensym_label("allocate_char_uninitialized" ),
1722- [
1723- store(
1724- ~offset= 0 ,
1725- wasm_mod,
1726- tee_swap(heap_allocate(wasm_mod, env, 2 )),
1727- Expression . Const . make(
1728- wasm_mod,
1729- const_int32(tag_val_of_heap_tag_type(CharType )),
1730- ),
1731- ),
1732- get_swap() ,
1733- ] ,
1734- );
1682+ let create_char = (wasm_mod, env, char) => {
1683+ let uchar = List . hd @@ Utf8 . decodeUtf8String(char);
1684+ let uchar_int : int = Utf8__Uchar . toInt(uchar);
1685+ let grain_char = uchar_int lsl 3 lor 0b 010 ;
1686+ Expression . Const . make(wasm_mod, const_int32(grain_char));
17351687};
17361688
17371689let allocate_closure =
@@ -2261,7 +2213,6 @@ let allocate_rational = (wasm_mod, env, n, d) => {
22612213
22622214let compile_prim0 = (wasm_mod, env, p0): Expression . t => {
22632215 switch (p0) {
2264- | AllocateChar => allocate_char_uninitialized(wasm_mod, env)
22652216 | AllocateInt32 => allocate_number_uninitialized(wasm_mod, env, BoxedInt32 )
22662217 | AllocateInt64 => allocate_number_uninitialized(wasm_mod, env, BoxedInt64 )
22672218 | AllocateFloat32 =>
@@ -2307,6 +2258,25 @@ let compile_prim1 = (wasm_mod, env, p1, arg, loc): Expression.t => {
23072258 compiled_arg,
23082259 Expression . Const . make(wasm_mod, const_int32(0x 1 )),
23092260 )
2261+ | TagChar =>
2262+ Expression . Binary . make(
2263+ wasm_mod,
2264+ Op . xor_int32,
2265+ Expression . Binary . make(
2266+ wasm_mod,
2267+ Op . shl_int32,
2268+ compiled_arg,
2269+ Expression . Const . make(wasm_mod, const_int32(0x 3 )),
2270+ ),
2271+ Expression . Const . make(wasm_mod, const_int32(0b 10 )),
2272+ )
2273+ | UntagChar =>
2274+ Expression . Binary . make(
2275+ wasm_mod,
2276+ Op . shr_s_int32,
2277+ compiled_arg,
2278+ Expression . Const . make(wasm_mod, const_int32(0x 3 )),
2279+ )
23102280 | Not =>
23112281 /* Flip the first bit */
23122282 Expression . Binary . make(
@@ -2691,7 +2661,7 @@ let compile_allocation = (wasm_mod, env, alloc_type) =>
26912661 | MRecord (ttag , elts ) => allocate_record(wasm_mod, env, ttag, elts)
26922662 | MBytes (bytes ) => allocate_bytes(wasm_mod, env, bytes)
26932663 | MString (str ) => allocate_string(wasm_mod, env, str)
2694- | MChar (char ) => allocate_char (wasm_mod, env, char)
2664+ | MChar (char ) => create_char (wasm_mod, env, char)
26952665 | MADT (ttag , vtag , elts ) => allocate_adt(wasm_mod, env, ttag, vtag, elts)
26962666 | MInt32 (i ) =>
26972667 allocate_int32(
0 commit comments