1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
/*
* upb - a minimalist implementation of protocol buffers.
*
* Copyright (c) 2013 Google Inc. See LICENSE for details.
* Author: Josh Haberman <jhaberman@gmail.com>
*/
#include "upb/shim/shim.h"
#include <stdlib.h>
// Fallback implementation if the shim is not specialized by the JIT.
#define SHIM_WRITER(type, ctype) \
bool upb_shim_set ## type (void *c, const void *hd, ctype val) { \
uint8_t *m = c; \
const upb_shim_data *d = hd; \
if (d->hasbit > 0) \
*(uint8_t*)&m[d->hasbit / 8] |= 1 << (d->hasbit % 8); \
*(ctype*)&m[d->offset] = val; \
return true; \
} \
SHIM_WRITER(double, double)
SHIM_WRITER(float, float)
SHIM_WRITER(int32, int32_t)
SHIM_WRITER(int64, int64_t)
SHIM_WRITER(uint32, uint32_t)
SHIM_WRITER(uint64, uint64_t)
SHIM_WRITER(bool, bool)
#undef SHIM_WRITER
bool upb_shim_set(upb_handlers *h, const upb_fielddef *f, size_t offset,
int32_t hasbit) {
upb_shim_data *d = malloc(sizeof(*d));
if (!d) return false;
d->offset = offset;
d->hasbit = hasbit;
upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER;
upb_handlerattr_sethandlerdata(&attr, d, free);
#define TYPE(u, l) \
case UPB_TYPE_##u: \
ok = upb_handlers_set##l(h, f, upb_shim_set##l, &attr); break;
bool ok = false;
switch (upb_fielddef_type(f)) {
TYPE(INT64, int64);
TYPE(INT32, int32);
TYPE(ENUM, int32);
TYPE(UINT64, uint64);
TYPE(UINT32, uint32);
TYPE(DOUBLE, double);
TYPE(FLOAT, float);
TYPE(BOOL, bool);
default: assert(false); break;
}
#undef TYPE
upb_handlerattr_uninit(&attr);
return ok;
}
const upb_shim_data *upb_shim_getdata(const upb_handlers *h, upb_selector_t s,
upb_fieldtype_t *type) {
upb_func *f = upb_handlers_gethandler(h, s);
if ((upb_int64_handlerfunc*)f == upb_shim_setint64) {
*type = UPB_TYPE_INT64;
} else if ((upb_int32_handlerfunc*)f == upb_shim_setint32) {
*type = UPB_TYPE_INT32;
} else if ((upb_uint64_handlerfunc*)f == upb_shim_setuint64) {
*type = UPB_TYPE_UINT64;
} else if ((upb_uint32_handlerfunc*)f == upb_shim_setuint32) {
*type = UPB_TYPE_UINT32;
} else if ((upb_double_handlerfunc*)f == upb_shim_setdouble) {
*type = UPB_TYPE_DOUBLE;
} else if ((upb_float_handlerfunc*)f == upb_shim_setfloat) {
*type = UPB_TYPE_FLOAT;
} else if ((upb_bool_handlerfunc*)f == upb_shim_setbool) {
*type = UPB_TYPE_BOOL;
} else {
return NULL;
}
return (const upb_shim_data*)upb_handlers_gethandlerdata(h, s);
}
|