Skip to content

Commit ae3fd98

Browse files
committed
feat: Add flags support
Signed-off-by: Gordon Smith <GordonJSmith@gmail.com>
1 parent aba5b04 commit ae3fd98

File tree

12 files changed

+389
-96
lines changed

12 files changed

+389
-96
lines changed

src/flags.hpp

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#ifndef CMCPP_FLAGS_HPP
2+
#define CMCPP_FLAGS_HPP
3+
4+
#include "context.hpp"
5+
#include "integer.hpp"
6+
#include "util.hpp"
7+
8+
namespace cmcpp
9+
{
10+
namespace flags
11+
{
12+
template <Flags T>
13+
int32_t pack_flags_into_int(const T &v)
14+
{
15+
uint32_t retVal = 0;
16+
uint32_t finger = 1;
17+
for (uint32_t i = 0; i < v.labelsSize; ++i)
18+
{
19+
retVal += v.flags.test(i) ? finger : 0;
20+
finger *= 2;
21+
}
22+
return retVal;
23+
}
24+
25+
template <Flags T>
26+
void store(CallContext &cx, const T &v, offset ptr)
27+
{
28+
auto i = pack_flags_into_int(v);
29+
std::memcpy(&cx.memory[ptr], i, ValTrait<T>::size);
30+
}
31+
32+
template <Flags T>
33+
WasmValVector lower_flat(CallContext &cx, const T &v)
34+
{
35+
return {pack_flags_into_int(v)};
36+
}
37+
38+
template <Flags T>
39+
T unpack_flags_from_int(const uint32_t &buff)
40+
{
41+
T retVal;
42+
uint32_t finger = 1;
43+
for (uint32_t i = 0; i < retVal.labelsSize; ++i)
44+
{
45+
retVal.flags.set(i, buff & finger);
46+
finger *= 2;
47+
}
48+
return retVal;
49+
}
50+
51+
template <Flags T>
52+
T load(const CallContext &cx, uint32_t ptr)
53+
{
54+
uint8_t buff[ValTrait<T>::size];
55+
std::memcpy(&buff, &cx.memory[ptr], ValTrait<T>::size);
56+
return unpack_flags_from_int<T>(buff);
57+
}
58+
59+
template <Flags T>
60+
T lift_flat(const CallContext &cx, const WasmValVectorIterator &vi)
61+
{
62+
auto i = vi.next<int32_t>();
63+
uint8_t buff[ValTrait<T>::size];
64+
std::memcpy(&buff, &i, ValTrait<T>::size);
65+
return unpack_flags_from_int<T>(i);
66+
}
67+
}
68+
}
69+
#endif

src/float.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@ namespace cmcpp
4747
}
4848

4949
template <Float T>
50-
T lower_flat(T f)
50+
WasmValVector lower_flat(T f)
5151
{
52-
return canonicalize_nan(f);
52+
return {canonicalize_nan(f)};
5353
}
5454

5555
template <typename T>

src/lift.hpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "float.hpp"
77
#include "string.hpp"
88
#include "list.hpp"
9+
#include "flags.hpp"
910
#include "record.hpp"
1011
#include "util.hpp"
1112

@@ -17,6 +18,12 @@ namespace cmcpp
1718
return convert_int_to_bool(vi.next<int32_t>());
1819
}
1920

21+
template <Char T>
22+
inline T lift_flat(const CallContext &cx, const WasmValVectorIterator &vi)
23+
{
24+
return convert_i32_to_char(cx, vi.next<int32_t>());
25+
}
26+
2027
template <UnsignedInteger T>
2128
inline T lift_flat(const CallContext &cx, const WasmValVectorIterator &vi)
2229
{
@@ -47,6 +54,12 @@ namespace cmcpp
4754
return list::lift_flat<typename ValTrait<T>::inner_type>(cx, vi);
4855
}
4956

57+
template <Flags T>
58+
inline T lift_flat(const CallContext &cx, const WasmValVectorIterator &vi)
59+
{
60+
return flags::lift_flat<T>(cx, vi);
61+
}
62+
5063
template <Record T>
5164
T lift_flat(const CallContext &cx, const WasmValVectorIterator &vi)
5265
{

src/load.hpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "integer.hpp"
66
#include "float.hpp"
77
#include "string.hpp"
8+
#include "flags.hpp"
89
#include "util.hpp"
910

1011
namespace cmcpp
@@ -15,14 +16,20 @@ namespace cmcpp
1516
return convert_int_to_bool(integer::load<uint8_t>(cx, ptr));
1617
}
1718

19+
template <Char T>
20+
inline T load(const CallContext &cx, uint32_t ptr)
21+
{
22+
return convert_i32_to_char(cx, integer::load<uint32_t>(cx, ptr));
23+
}
24+
1825
template <Integer T>
19-
inline uint8_t load(const CallContext &cx, uint32_t ptr)
26+
inline T load(const CallContext &cx, uint32_t ptr)
2027
{
2128
return integer::load<T>(cx, ptr);
2229
}
2330

2431
template <Float T>
25-
inline float32_t load(const CallContext &cx, uint32_t ptr)
32+
inline T load(const CallContext &cx, uint32_t ptr)
2633
{
2734
return float_::load<T>(cx, ptr);
2835
}
@@ -32,6 +39,12 @@ namespace cmcpp
3239
{
3340
return string::load<T>(cx, ptr);
3441
}
42+
43+
template <Flags T>
44+
inline T load(const CallContext &cx, uint32_t ptr)
45+
{
46+
return flags::load<T>(cx, ptr);
47+
}
3548
}
3649

3750
#endif

src/lower.hpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "float.hpp"
77
#include "string.hpp"
88
#include "list.hpp"
9+
#include "flags.hpp"
910
#include "record.hpp"
1011
#include "util.hpp"
1112

@@ -20,6 +21,12 @@ namespace cmcpp
2021
return {static_cast<ValTrait<T>::flat_type>(v)};
2122
}
2223

24+
template <Char T>
25+
inline WasmValVector lower_flat(CallContext &cx, const T &v)
26+
{
27+
return {static_cast<ValTrait<T>::flat_type>(char_to_i32(cx, v))};
28+
}
29+
2330
template <UnsignedInteger T>
2431
inline WasmValVector lower_flat(CallContext &cx, const T &v)
2532
{
@@ -53,6 +60,12 @@ namespace cmcpp
5360
return list::lower_flat(cx, v);
5461
}
5562

63+
template <Flags T>
64+
inline WasmValVector lower_flat(CallContext &cx, const T &v)
65+
{
66+
return flags::lower_flat(cx, v);
67+
}
68+
5669
template <Record T>
5770
inline WasmValVector lower_flat(CallContext &cx, const T &v)
5871
{

src/store.hpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "integer.hpp"
77
#include "string.hpp"
88
#include "list.hpp"
9+
#include "flags.hpp"
910
#include "util.hpp"
1011

1112
#include <tuple>
@@ -19,6 +20,12 @@ namespace cmcpp
1920
integer::store<T>(cx, v, ptr);
2021
}
2122

23+
template <Char T>
24+
inline void store(CallContext &cx, const T &v, uint32_t ptr)
25+
{
26+
integer::store<T>(cx, char_to_i32(cx, v), ptr);
27+
}
28+
2229
template <Integer T>
2330
inline void store(CallContext &cx, const T &v, uint32_t ptr)
2431
{
@@ -36,6 +43,12 @@ namespace cmcpp
3643
{
3744
string::store(cx, v, ptr);
3845
}
46+
47+
template <Flags T>
48+
inline void store(CallContext &cx, const T &v, uint32_t ptr)
49+
{
50+
flags::store(cx, v, ptr);
51+
}
3952
}
4053

4154
#endif

src/string.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@ namespace cmcpp
7878
auto encoded = cx.convert(&cx.memory[ptr], src_byte_length, src, src_code_units, Encoding::Utf16, Encoding::Utf16);
7979
const uint8_t *enc_src_ptr = &cx.memory[ptr];
8080
if (std::any_of(enc_src_ptr, enc_src_ptr + encoded.second,
81-
[](uint8_t c)
82-
{ return static_cast<unsigned char>(c) >= (1 << 8); }))
81+
[](unsigned c)
82+
{ return c >= (1 << 8); }))
8383
{
8484
uint32_t tagged_code_units = static_cast<uint32_t>(encoded.second / 2) | UTF16_TAG;
8585
return std::make_pair(ptr, tagged_code_units);

src/string.hpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ namespace cmcpp
4747
trap_if(cx, ptr + worst_case_size > cx.memory.size(), "Out of bounds access");
4848

4949
#ifdef SIMPLE_UTF16_CONVERSION
50-
// Convert entire string to UTF-16 in one go, ignoring the previously copued data ---
50+
// Convert entire string to UTF-16 in one go, ignoring the previously computed data ---
5151
auto encoded = cx.convert(&cx.memory[ptr], worst_case_size, src, src_code_units * ValTrait<T>::char_size, src_encoding, Encoding::Utf16);
5252
if (encoded.second < worst_case_size)
5353
{
@@ -75,7 +75,7 @@ namespace cmcpp
7575
// Add special tag to indicate the string is a UTF-16 string ---
7676
uint32_t tagged_code_units = static_cast<uint32_t>(dst_byte_length + encoded.second / 2) | UTF16_TAG;
7777
return std::make_pair(ptr, tagged_code_units);
78-
#endif // SIMPLE_UTF16_CONVERSION
78+
#endif
7979
}
8080
}
8181
if (dst_byte_length < src_code_units)
@@ -120,6 +120,8 @@ namespace cmcpp
120120
switch (cx.guest_encoding)
121121
{
122122
case Encoding::Latin1:
123+
cx.trap("Invalid guest encoding, must be UTF8, UTF16 or Latin1/UTF16");
124+
break;
123125
case Encoding::Utf8:
124126
switch (src_simple_encoding)
125127
{
@@ -215,7 +217,7 @@ namespace cmcpp
215217
retVal.encoding = encoding;
216218
}
217219
retVal.resize(host_byte_length);
218-
auto decoded = cx.convert(retVal.data(), host_byte_length, (void *)&cx.memory[ptr], byte_length, encoding, ValTrait<T>::encoding);
220+
auto decoded = cx.convert(retVal.data(), host_byte_length, (void *)&cx.memory[ptr], byte_length, encoding, ValTrait<T>::encoding == Encoding::Latin1_Utf16 ? encoding : ValTrait<T>::encoding);
219221
if ((decoded.second / char_size) < host_byte_length)
220222
{
221223
retVal.resize(decoded.second / char_size);

0 commit comments

Comments
 (0)