• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

tarantool / luajit / 11139910794

02 Oct 2024 07:45AM UTC coverage: 92.891% (+0.006%) from 92.885%
11139910794

push

github

Buristan
Fix bit op coercion in DUALNUM builds.

Thanks to Sergey Kaplun.

(cherry picked from commit f5fd22203)

The `lj_carith_check64()` function coerces the given number value to the
32-bit wide value. In this case, the 64-bit-wide operands will lose
upper bits.

This patch removes the excess coercion for the DUALNUM mode and drops
the corresponding skipcond introduced for the test in the previous
commit.

Sergey Kaplun:
* added the description and the test for the problem

Part of tarantool/tarantool#10199

5684 of 6026 branches covered (94.32%)

Branch coverage included in aggregate %.

1 of 1 new or added line in 1 file covered. (100.0%)

2 existing lines in 1 file now uncovered.

21679 of 23431 relevant lines covered (92.52%)

2951479.61 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

13.79
/src/lj_utils_leb128.c
1
/*
2
** Working with LEB128/ULEB128 encoding.
3
**
4
** Major portions taken verbatim or adapted from the LuaVela.
5
** Copyright (C) 2015-2019 IPONWEB Ltd.
6
*/
7

8
#define lj_utils_leb128_c
9
#define LUA_CORE
10

11
#include "lj_utils.h"
12
#include "lj_obj.h"
13

14
#define LINK_BIT          (0x80)
15
#define MIN_TWOBYTE_VALUE (0x80)
16
#define PAYLOAD_MASK      (0x7f)
17
#define SHIFT_STEP        (7)
18
#define LEB_SIGN_BIT      (0x40)
19

20
/* ------------------------- Reading LEB128/ULEB128 ------------------------- */
21

22
/*
23
** XXX: For each LEB128 type (signed/unsigned) we have two versions of read
24
** functions: The one consuming unlimited number of input octets and the one
25
** consuming not more than given number of input octets. Currently reading
26
** is not used in performance critical places, so these two functions are
27
** implemented via single low-level function + run-time mode check. Feel free
28
** to change if this becomes a bottleneck.
29
*/
30

31
static LJ_AINLINE size_t _read_leb128(int64_t *out, const uint8_t *buffer,
×
32
                                      size_t n)
33
{
34
  size_t i = 0;
×
35
  uint64_t shift = 0;
×
36
  int64_t value = 0;
×
37
  uint8_t octet;
×
38

39
  for(;;) {
×
40
    if (n != 0 && i + 1 > n)
×
41
      return 0;
42
    octet = buffer[i++];
×
43
    value |= ((int64_t)(octet & PAYLOAD_MASK)) << shift;
×
44
    shift += SHIFT_STEP;
×
45
    if (!(octet & LINK_BIT))
×
46
      break;
47
  }
48

49
  if (octet & LEB_SIGN_BIT && shift < sizeof(int64_t) * 8)
×
50
    value |= -(1 << shift);
×
51

52
  *out = value;
×
53
  return i;
×
54
}
55

56
size_t LJ_FASTCALL lj_utils_read_leb128(int64_t *out, const uint8_t *buffer)
×
57
{
58
  return _read_leb128(out, buffer, 0);
×
59
}
60

61
size_t LJ_FASTCALL lj_utils_read_leb128_n(int64_t *out, const uint8_t *buffer,
×
62
                                          size_t n)
63
{
64
  return _read_leb128(out, buffer, n);
×
65
}
66

67

68
static LJ_AINLINE size_t _read_uleb128(uint64_t *out, const uint8_t *buffer,
×
69
                                       size_t n)
70
{
71
  size_t i = 0;
×
72
  uint64_t value = 0;
×
73
  uint64_t shift = 0;
×
74
  uint8_t octet;
×
75

76
  for(;;) {
×
77
    if (n != 0 && i + 1 > n)
×
78
      return 0;
79
    octet = buffer[i++];
×
80
    value |= ((uint64_t)(octet & PAYLOAD_MASK)) << shift;
×
81
    shift += SHIFT_STEP;
×
82
    if (!(octet & LINK_BIT))
×
83
      break;
84
  }
85

86
  *out = value;
×
87
  return i;
×
88
}
89

90
size_t LJ_FASTCALL lj_utils_read_uleb128(uint64_t *out, const uint8_t *buffer)
×
91
{
92
  return _read_uleb128(out, buffer, 0);
×
93
}
94

95
size_t LJ_FASTCALL lj_utils_read_uleb128_n(uint64_t *out, const uint8_t *buffer,
×
96
                                           size_t n)
97
{
98
  return _read_uleb128(out, buffer, n);
×
99
}
100

101
/* ------------------------- Writing LEB128/ULEB128 ------------------------- */
102

103
size_t LJ_FASTCALL lj_utils_write_leb128(uint8_t *buffer, int64_t value)
×
104
{
105
  size_t i = 0;
×
106

107
  /* LEB_SIGN_BIT propagation to check the remaining value. */
108
  while ((uint64_t)(value + LEB_SIGN_BIT) >= MIN_TWOBYTE_VALUE) {
×
109
    buffer[i++] = (uint8_t)((value & PAYLOAD_MASK) | LINK_BIT);
×
110
    value >>= SHIFT_STEP;
×
111
  }
112

113
  /* Omit LINK_BIT in case of overflow. */
114
  buffer[i++] = (uint8_t)(value & PAYLOAD_MASK);
×
115

116
  lj_assertX(i <= LEB128_U64_MAXSIZE, "bad leb128 size");
×
117

118
  return i;
×
119
}
120

121
size_t LJ_FASTCALL lj_utils_write_uleb128(uint8_t *buffer, uint64_t value)
1,077,502✔
122
{
123
  size_t i = 0;
1,077,502✔
124

125
  for (; value >= MIN_TWOBYTE_VALUE; value >>= SHIFT_STEP)
4,311,397✔
126
    buffer[i++] = (uint8_t)((value & PAYLOAD_MASK) | LINK_BIT);
3,233,895✔
127

128
  buffer[i++] = (uint8_t)value;
1,077,502✔
129

130
  lj_assertX(i <= LEB128_U64_MAXSIZE, "bad uleb128 size");
1,077,502✔
131

132
  return i;
1,077,502✔
133
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc