Skip to content
This repository was archived by the owner on Nov 5, 2024. It is now read-only.

Commit 9db89ed

Browse files
committed
fix custom decoder dispatching by taking and passing blobs to decode fn
1 parent 16d7321 commit 9db89ed

File tree

13 files changed

+131
-42
lines changed

13 files changed

+131
-42
lines changed

.github/workflows/test.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ jobs:
2222
TARGET: ${{ matrix.build.target }}
2323
CXX: ${{ matrix.build.cxx }}
2424
AR: ${{ matrix.build.ar }}
25+
RUST_BACKTRACE: "1"
2526
strategy:
2627
fail-fast: false
2728
matrix:

api.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ namespace lib_ruby_parser
55
{
66
BLOB(ParserResult);
77
BLOB(ParserOptions);
8-
BLOB(ByteList);
98

109
extern "C"
1110
{

bytes.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
namespace lib_ruby_parser
55
{
6-
BLOB(ByteList);
76
BLOB(Bytes);
87

98
extern "C"

bytes.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define LIB_RUBY_PARSER_BYTES_HPP
33

44
#include <cstddef>
5+
#include <cstdint>
56

67
namespace lib_ruby_parser
78
{
@@ -33,6 +34,14 @@ namespace lib_ruby_parser
3334
static ByteList Copied(const char *s, size_t len);
3435
};
3536

37+
extern "C"
38+
{
39+
struct ByteListBlob
40+
{
41+
uint8_t bytes[sizeof(ByteList)];
42+
};
43+
}
44+
3645
/// Rerpresentation of `Bytes` struct from lib-ruby-parser.
3746
class Bytes
3847
{

decoder.cpp

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,12 @@ namespace lib_ruby_parser
6666
std::memset(&other, 0, sizeof(Value));
6767
}
6868
DecoderResult::Value::~Value() {}
69+
DecoderResult::Value &DecoderResult::Value::operator=(DecoderResult::Value &&other)
70+
{
71+
std::memcpy(this, &other, sizeof(Value));
72+
std::memset(&other, 0, sizeof(Value));
73+
return *this;
74+
}
6975

7076
DecoderResult::DecoderResult(Tag tag_,
7177
Value as_) : tag(tag_),
@@ -89,6 +95,52 @@ namespace lib_ruby_parser
8995
}
9096

9197
// decoder
98+
String string_from_string_blob(StringBlob blob)
99+
{
100+
union U
101+
{
102+
String t;
103+
StringBlob b;
104+
105+
U() { std::memset(this, 0, sizeof(U)); }
106+
~U() {}
107+
};
108+
109+
U u;
110+
u.b = blob;
111+
return std::move(u.t);
112+
}
113+
ByteList byte_list_from_byte_list_blob(ByteListBlob blob)
114+
{
115+
union U
116+
{
117+
ByteList t;
118+
ByteListBlob b;
119+
120+
U() { std::memset(this, 0, sizeof(U)); }
121+
~U() {}
122+
};
123+
124+
U u;
125+
u.b = blob;
126+
return std::move(u.t);
127+
}
128+
DecoderResultBlob decoder_result_to_blob(DecoderResult decoder_result)
129+
{
130+
union U
131+
{
132+
DecoderResult t;
133+
DecoderResultBlob b;
134+
135+
U() { std::memset(this, 0, sizeof(U)); }
136+
~U() {}
137+
};
138+
139+
U u;
140+
u.t = std::move(decoder_result);
141+
return u.b;
142+
}
143+
92144
Decoder::Decoder(DecoderFunction f_, void *state_) : f(f_), state(state_) {}
93145

94146
// maybe decoder

decoder.hpp

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define LIB_RUBY_PARSER_DECODER_HPP
33

44
#include <cstdbool>
5+
#include <cstring>
56
#include "string.hpp"
67
#include "bytes.hpp"
78

@@ -41,9 +42,8 @@ namespace lib_ruby_parser
4142
static InputError DecodingError(String decoding_error);
4243
};
4344

44-
class DecoderResult
45+
struct DecoderResult
4546
{
46-
public:
4747
enum class Tag
4848
{
4949
OK,
@@ -57,6 +57,7 @@ namespace lib_ruby_parser
5757

5858
Value();
5959
Value(Value &&);
60+
Value &operator=(Value &&);
6061
~Value();
6162
};
6263

@@ -65,13 +66,29 @@ namespace lib_ruby_parser
6566

6667
DecoderResult(Tag tag, Value as);
6768
DecoderResult(DecoderResult &&) = default;
69+
DecoderResult &operator=(DecoderResult &&) = default;
6870
~DecoderResult();
6971

7072
static DecoderResult Ok(ByteList decoded);
7173
static DecoderResult Err(InputError err);
7274
};
7375

74-
typedef DecoderResult (*DecoderFunction)(String, ByteList, void *);
76+
extern "C"
77+
{
78+
struct DecoderResultBlob
79+
{
80+
uint8_t bytes[sizeof(DecoderResult)];
81+
};
82+
}
83+
84+
String string_from_string_blob(StringBlob blob);
85+
ByteList byte_list_from_byte_list_blob(ByteListBlob blob);
86+
DecoderResultBlob decoder_result_to_blob(DecoderResult decoder_result);
87+
88+
extern "C"
89+
{
90+
typedef DecoderResultBlob (*DecoderFunction)(void *, StringBlob, ByteListBlob);
91+
}
7592
class Decoder
7693
{
7794
public:

ruby-parser-cpp/src/decoder.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,9 @@ pub extern "C" fn LIB_RUBY_PARSER_drop_decoder_result(decoder_result: *mut Decod
5353
#[derive(Debug)]
5454
pub struct Decoder {
5555
pub f: extern "C" fn(
56+
state: *const std::ffi::c_void,
5657
encoding: StringBlob,
5758
input: ByteListBlob,
58-
state: *const std::ffi::c_void,
5959
) -> DecoderResultBlob,
6060
pub state: *const std::ffi::c_void,
6161
}
@@ -65,9 +65,9 @@ pub struct Decoder {
6565
pub extern "C" fn lib_ruby_parser__test__always_ok_decoder(output: *const u8) -> Decoder {
6666
#[no_mangle]
6767
pub extern "C" fn lib_ruby_parser__test__always_ok_decoder_fn(
68+
state: *const std::ffi::c_void,
6869
encoding: StringBlob,
6970
input: ByteListBlob,
70-
state: *const std::ffi::c_void,
7171
) -> DecoderResultBlob {
7272
// do cleanup
7373
drop(String::from(encoding));
@@ -89,9 +89,9 @@ pub extern "C" fn lib_ruby_parser__test__always_ok_decoder(output: *const u8) ->
8989
pub extern "C" fn lib_ruby_parser__test__always_err_decoder(output: *const u8) -> Decoder {
9090
#[no_mangle]
9191
pub extern "C" fn lib_ruby_parser__test__always_err_decoder_fn(
92+
state: *const std::ffi::c_void,
9293
encoding: StringBlob,
9394
input: ByteListBlob,
94-
state: *const std::ffi::c_void,
9595
) -> DecoderResultBlob {
9696
// do cleanup
9797
drop(String::from(encoding));

ruby-parser-cpp/src/parser_options.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ impl From<CParserOptions> for lib_ruby_parser::ParserOptions {
2121
} = options;
2222

2323
let decoder = decoder.map(|decoder| {
24-
let Decoder { f, state } = decoder;
2524
lib_ruby_parser::source::Decoder::new(Box::new(move |encoding, input| {
26-
f(encoding.into(), input.into(), state).into()
25+
let Decoder { f, state } = decoder;
26+
f(state, encoding.into(), input.into()).into()
2727
}))
2828
});
2929

string.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44

55
namespace lib_ruby_parser
66
{
7-
BLOB(String);
8-
97
extern "C"
108
{
119
StringBlob LIB_RUBY_PARSER_new_string_owned(char *s, size_t len);

string.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,14 @@ namespace lib_ruby_parser
3232
static String Copied(const char *s);
3333
};
3434

35+
extern "C"
36+
{
37+
struct StringBlob
38+
{
39+
uint8_t bytes[sizeof(String)];
40+
};
41+
}
42+
3543
/// Rerpresentation of Option<String>.
3644
/// Rust has a Option<non-null ptr> optimization that None is NULL on the byte level.
3745
/// Thus, it's not a tagged enum.

0 commit comments

Comments
 (0)