json 2.7.2 → 2.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,101 +1,103 @@
1
-
2
1
  #ifndef _FBUFFER_H_
3
2
  #define _FBUFFER_H_
4
3
 
5
4
  #include "ruby.h"
5
+ #include "ruby/encoding.h"
6
6
 
7
- #ifndef RHASH_SIZE
8
- #define RHASH_SIZE(hsh) (RHASH(hsh)->tbl->num_entries)
7
+ /* shims */
8
+ /* This is the fallback definition from Ruby 3.4 */
9
+
10
+ #ifndef RBIMPL_STDBOOL_H
11
+ #if defined(__cplusplus)
12
+ # if defined(HAVE_STDBOOL_H) && (__cplusplus >= 201103L)
13
+ # include <cstdbool>
14
+ # endif
15
+ #elif defined(HAVE_STDBOOL_H)
16
+ # include <stdbool.h>
17
+ #elif !defined(HAVE__BOOL)
18
+ typedef unsigned char _Bool;
19
+ # define bool _Bool
20
+ # define true ((_Bool)+1)
21
+ # define false ((_Bool)+0)
22
+ # define __bool_true_false_are_defined
9
23
  #endif
10
-
11
- #ifndef RFLOAT_VALUE
12
- #define RFLOAT_VALUE(val) (RFLOAT(val)->value)
13
24
  #endif
14
25
 
15
- #ifndef RARRAY_LEN
16
- #define RARRAY_LEN(ARRAY) RARRAY(ARRAY)->len
17
- #endif
18
- #ifndef RSTRING_PTR
19
- #define RSTRING_PTR(string) RSTRING(string)->ptr
20
- #endif
21
- #ifndef RSTRING_LEN
22
- #define RSTRING_LEN(string) RSTRING(string)->len
26
+ #ifndef RB_UNLIKELY
27
+ #define RB_UNLIKELY(expr) expr
23
28
  #endif
24
29
 
25
- #ifdef PRIsVALUE
26
- # define RB_OBJ_CLASSNAME(obj) rb_obj_class(obj)
27
- # define RB_OBJ_STRING(obj) (obj)
28
- #else
29
- # define PRIsVALUE "s"
30
- # define RB_OBJ_CLASSNAME(obj) rb_obj_classname(obj)
31
- # define RB_OBJ_STRING(obj) StringValueCStr(obj)
30
+ #ifndef RB_LIKELY
31
+ #define RB_LIKELY(expr) expr
32
32
  #endif
33
33
 
34
- #ifdef HAVE_RUBY_ENCODING_H
35
- #include "ruby/encoding.h"
36
- #define FORCE_UTF8(obj) rb_enc_associate((obj), rb_utf8_encoding())
37
- #else
38
- #define FORCE_UTF8(obj)
34
+ #ifndef MAYBE_UNUSED
35
+ # define MAYBE_UNUSED(x) x
39
36
  #endif
40
37
 
41
- /* We don't need to guard objects for rbx, so let's do nothing at all. */
42
- #ifndef RB_GC_GUARD
43
- #define RB_GC_GUARD(object)
44
- #endif
38
+ enum fbuffer_type {
39
+ FBUFFER_HEAP_ALLOCATED = 0,
40
+ FBUFFER_STACK_ALLOCATED = 1,
41
+ };
45
42
 
46
43
  typedef struct FBufferStruct {
44
+ enum fbuffer_type type;
47
45
  unsigned long initial_length;
48
- char *ptr;
49
46
  unsigned long len;
50
47
  unsigned long capa;
48
+ char *ptr;
51
49
  } FBuffer;
52
50
 
51
+ #define FBUFFER_STACK_SIZE 512
53
52
  #define FBUFFER_INITIAL_LENGTH_DEFAULT 1024
54
53
 
55
- #define FBUFFER_PTR(fb) (fb->ptr)
56
- #define FBUFFER_LEN(fb) (fb->len)
57
- #define FBUFFER_CAPA(fb) (fb->capa)
54
+ #define FBUFFER_PTR(fb) ((fb)->ptr)
55
+ #define FBUFFER_LEN(fb) ((fb)->len)
56
+ #define FBUFFER_CAPA(fb) ((fb)->capa)
58
57
  #define FBUFFER_PAIR(fb) FBUFFER_PTR(fb), FBUFFER_LEN(fb)
59
58
 
60
- static FBuffer *fbuffer_alloc(unsigned long initial_length);
61
59
  static void fbuffer_free(FBuffer *fb);
60
+ #ifndef JSON_GENERATOR
62
61
  static void fbuffer_clear(FBuffer *fb);
62
+ #endif
63
63
  static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned long len);
64
64
  #ifdef JSON_GENERATOR
65
65
  static void fbuffer_append_long(FBuffer *fb, long number);
66
66
  #endif
67
- static void fbuffer_append_char(FBuffer *fb, char newchr);
67
+ static inline void fbuffer_append_char(FBuffer *fb, char newchr);
68
68
  #ifdef JSON_GENERATOR
69
- static FBuffer *fbuffer_dup(FBuffer *fb);
70
69
  static VALUE fbuffer_to_s(FBuffer *fb);
71
70
  #endif
72
71
 
73
- static FBuffer *fbuffer_alloc(unsigned long initial_length)
72
+ static void fbuffer_stack_init(FBuffer *fb, unsigned long initial_length, char *stack_buffer, long stack_buffer_size)
74
73
  {
75
- FBuffer *fb;
76
- if (initial_length <= 0) initial_length = FBUFFER_INITIAL_LENGTH_DEFAULT;
77
- fb = ALLOC(FBuffer);
78
- memset((void *) fb, 0, sizeof(FBuffer));
79
- fb->initial_length = initial_length;
80
- return fb;
74
+ fb->initial_length = (initial_length > 0) ? initial_length : FBUFFER_INITIAL_LENGTH_DEFAULT;
75
+ if (stack_buffer) {
76
+ fb->type = FBUFFER_STACK_ALLOCATED;
77
+ fb->ptr = stack_buffer;
78
+ fb->capa = stack_buffer_size;
79
+ }
81
80
  }
82
81
 
83
82
  static void fbuffer_free(FBuffer *fb)
84
83
  {
85
- if (fb->ptr) ruby_xfree(fb->ptr);
86
- ruby_xfree(fb);
84
+ if (fb->ptr && fb->type == FBUFFER_HEAP_ALLOCATED) {
85
+ ruby_xfree(fb->ptr);
86
+ }
87
87
  }
88
88
 
89
+ #ifndef JSON_GENERATOR
89
90
  static void fbuffer_clear(FBuffer *fb)
90
91
  {
91
92
  fb->len = 0;
92
93
  }
94
+ #endif
93
95
 
94
- static void fbuffer_inc_capa(FBuffer *fb, unsigned long requested)
96
+ static void fbuffer_do_inc_capa(FBuffer *fb, unsigned long requested)
95
97
  {
96
98
  unsigned long required;
97
99
 
98
- if (!fb->ptr) {
100
+ if (RB_UNLIKELY(!fb->ptr)) {
99
101
  fb->ptr = ALLOC_N(char, fb->initial_length);
100
102
  fb->capa = fb->initial_length;
101
103
  }
@@ -103,11 +105,25 @@ static void fbuffer_inc_capa(FBuffer *fb, unsigned long requested)
103
105
  for (required = fb->capa; requested > required - fb->len; required <<= 1);
104
106
 
105
107
  if (required > fb->capa) {
106
- REALLOC_N(fb->ptr, char, required);
108
+ if (fb->type == FBUFFER_STACK_ALLOCATED) {
109
+ const char *old_buffer = fb->ptr;
110
+ fb->ptr = ALLOC_N(char, required);
111
+ fb->type = FBUFFER_HEAP_ALLOCATED;
112
+ MEMCPY(fb->ptr, old_buffer, char, fb->len);
113
+ } else {
114
+ REALLOC_N(fb->ptr, char, required);
115
+ }
107
116
  fb->capa = required;
108
117
  }
109
118
  }
110
119
 
120
+ static inline void fbuffer_inc_capa(FBuffer *fb, unsigned long requested)
121
+ {
122
+ if (RB_UNLIKELY(requested > fb->capa - fb->len)) {
123
+ fbuffer_do_inc_capa(fb, requested);
124
+ }
125
+ }
126
+
111
127
  static void fbuffer_append(FBuffer *fb, const char *newstr, unsigned long len)
112
128
  {
113
129
  if (len > 0) {
@@ -129,7 +145,7 @@ static void fbuffer_append_str(FBuffer *fb, VALUE str)
129
145
  }
130
146
  #endif
131
147
 
132
- static void fbuffer_append_char(FBuffer *fb, char newchr)
148
+ static inline void fbuffer_append_char(FBuffer *fb, char newchr)
133
149
  {
134
150
  fbuffer_inc_capa(fb, 1);
135
151
  *(fb->ptr + fb->len) = newchr;
@@ -137,50 +153,31 @@ static void fbuffer_append_char(FBuffer *fb, char newchr)
137
153
  }
138
154
 
139
155
  #ifdef JSON_GENERATOR
140
- static void freverse(char *start, char *end)
141
- {
142
- char c;
143
-
144
- while (end > start) {
145
- c = *end, *end-- = *start, *start++ = c;
146
- }
147
- }
148
-
149
156
  static long fltoa(long number, char *buf)
150
157
  {
151
- static char digits[] = "0123456789";
158
+ static const char digits[] = "0123456789";
152
159
  long sign = number;
153
160
  char* tmp = buf;
154
161
 
155
162
  if (sign < 0) number = -number;
156
- do *tmp++ = digits[number % 10]; while (number /= 10);
157
- if (sign < 0) *tmp++ = '-';
158
- freverse(buf, tmp - 1);
159
- return tmp - buf;
163
+ do *tmp-- = digits[number % 10]; while (number /= 10);
164
+ if (sign < 0) *tmp-- = '-';
165
+ return buf - tmp;
160
166
  }
161
167
 
168
+ #define LONG_BUFFER_SIZE 20
162
169
  static void fbuffer_append_long(FBuffer *fb, long number)
163
170
  {
164
- char buf[20];
165
- unsigned long len = fltoa(number, buf);
166
- fbuffer_append(fb, buf, len);
167
- }
168
-
169
- static FBuffer *fbuffer_dup(FBuffer *fb)
170
- {
171
- unsigned long len = fb->len;
172
- FBuffer *result;
173
-
174
- result = fbuffer_alloc(len);
175
- fbuffer_append(result, FBUFFER_PAIR(fb));
176
- return result;
171
+ char buf[LONG_BUFFER_SIZE];
172
+ char *buffer_end = buf + LONG_BUFFER_SIZE;
173
+ long len = fltoa(number, buffer_end - 1);
174
+ fbuffer_append(fb, buffer_end - len, len);
177
175
  }
178
176
 
179
177
  static VALUE fbuffer_to_s(FBuffer *fb)
180
178
  {
181
- VALUE result = rb_str_new(FBUFFER_PTR(fb), FBUFFER_LEN(fb));
179
+ VALUE result = rb_utf8_str_new(FBUFFER_PTR(fb), FBUFFER_LEN(fb));
182
180
  fbuffer_free(fb);
183
- FORCE_UTF8(result);
184
181
  return result;
185
182
  }
186
183
  #endif
@@ -1,4 +1,10 @@
1
1
  require 'mkmf'
2
2
 
3
- $defs << "-DJSON_GENERATOR"
4
- create_makefile 'json/ext/generator'
3
+ if RUBY_ENGINE == 'truffleruby'
4
+ # The pure-Ruby generator is faster on TruffleRuby, so skip compiling the generator extension
5
+ File.write('Makefile', dummy_makefile("").join)
6
+ else
7
+ append_cflags("-std=c99")
8
+ $defs << "-DJSON_GENERATOR"
9
+ create_makefile 'json/ext/generator'
10
+ end