aboutsummaryrefslogtreecommitdiff
path: root/src/lib_buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib_buffer.c')
-rw-r--r--src/lib_buffer.c60
1 files changed, 42 insertions, 18 deletions
diff --git a/src/lib_buffer.c b/src/lib_buffer.c
index 78c4eeb9..f13320c4 100644
--- a/src/lib_buffer.c
+++ b/src/lib_buffer.c
@@ -29,9 +29,7 @@
29#include "lj_serialize.h" 29#include "lj_serialize.h"
30#include "lj_lib.h" 30#include "lj_lib.h"
31 31
32/* ------------------------------------------------------------------------ */ 32/* -- Helper functions ---------------------------------------------------- */
33
34#define LJLIB_MODULE_buffer_method
35 33
36/* Check that the first argument is a string buffer. */ 34/* Check that the first argument is a string buffer. */
37static SBufExt *buffer_tobuf(lua_State *L) 35static SBufExt *buffer_tobuf(lua_State *L)
@@ -49,11 +47,16 @@ static LJ_AINLINE SBufExt *buffer_tobufw(lua_State *L)
49 return sbx; 47 return sbx;
50} 48}
51 49
50#define buffer_toudata(sbx) ((GCudata *)(sbx)-1)
51
52/* -- Buffer methods ------------------------------------------------------ */
53
54#define LJLIB_MODULE_buffer_method
55
52LJLIB_CF(buffer_method_free) 56LJLIB_CF(buffer_method_free)
53{ 57{
54 SBufExt *sbx = buffer_tobuf(L); 58 SBufExt *sbx = buffer_tobuf(L);
55 lj_bufx_free(G(L), sbx); 59 lj_bufx_free(L, sbx);
56 lj_bufx_init(L, sbx);
57 L->top = L->base+1; /* Chain buffer object. */ 60 L->top = L->base+1; /* Chain buffer object. */
58 return 1; 61 return 1;
59} 62}
@@ -83,6 +86,7 @@ LJLIB_CF(buffer_method_skip)
83LJLIB_CF(buffer_method_set) 86LJLIB_CF(buffer_method_set)
84{ 87{
85 SBufExt *sbx = buffer_tobuf(L); 88 SBufExt *sbx = buffer_tobuf(L);
89 GCobj *ref;
86 const char *p; 90 const char *p;
87 MSize len; 91 MSize len;
88#if LJ_HASFFI 92#if LJ_HASFFI
@@ -98,9 +102,11 @@ LJLIB_CF(buffer_method_set)
98 p = strdata(str); 102 p = strdata(str);
99 len = str->len; 103 len = str->len;
100 } 104 }
101 lj_bufx_free(G(L), sbx); 105 lj_bufx_free(L, sbx);
102 lj_bufx_init_cow(L, sbx, p, len); 106 lj_bufx_set_cow(L, sbx, p, len);
103 setgcref(sbx->cowref, gcV(L->base+1)); 107 ref = gcV(L->base+1);
108 setgcref(sbx->cowref, ref);
109 lj_gc_objbarrier(L, buffer_toudata(sbx), ref);
104 L->top = L->base+1; /* Chain buffer object. */ 110 L->top = L->base+1; /* Chain buffer object. */
105 return 1; 111 return 1;
106} 112}
@@ -249,8 +255,7 @@ LJLIB_CF(buffer_method_decode)
249LJLIB_CF(buffer_method___gc) 255LJLIB_CF(buffer_method___gc)
250{ 256{
251 SBufExt *sbx = buffer_tobuf(L); 257 SBufExt *sbx = buffer_tobuf(L);
252 lj_bufx_free(G(L), sbx); 258 lj_bufx_free(L, sbx);
253 lj_bufx_init(L, sbx);
254 return 0; 259 return 0;
255} 260}
256 261
@@ -272,7 +277,7 @@ LJLIB_CF(buffer_method___len)
272LJLIB_PUSH("buffer") LJLIB_SET(__metatable) 277LJLIB_PUSH("buffer") LJLIB_SET(__metatable)
273LJLIB_PUSH(top-1) LJLIB_SET(__index) 278LJLIB_PUSH(top-1) LJLIB_SET(__index)
274 279
275/* ------------------------------------------------------------------------ */ 280/* -- Buffer library functions -------------------------------------------- */
276 281
277#define LJLIB_MODULE_buffer 282#define LJLIB_MODULE_buffer
278 283
@@ -280,16 +285,33 @@ LJLIB_PUSH(top-2) LJLIB_SET(!) /* Set environment. */
280 285
281LJLIB_CF(buffer_new) 286LJLIB_CF(buffer_new)
282{ 287{
283 MSize sz = L->base == L->top ? 0u : 288 MSize sz = 0;
284 (MSize)lj_lib_checkintrange(L, 1, 0, LJ_MAX_BUF); 289 int targ = 1;
285 GCtab *env = tabref(curr_func(L)->c.env); 290 GCtab *env, *dict = NULL;
286 GCudata *ud = lj_udata_new(L, sizeof(SBufExt), env); 291 GCudata *ud;
287 SBufExt *sbx = (SBufExt *)uddata(ud); 292 SBufExt *sbx;
293 if (L->base < L->top && !tvistab(L->base)) {
294 targ = 2;
295 if (!tvisnil(L->base))
296 sz = (MSize)lj_lib_checkintrange(L, 1, 0, LJ_MAX_BUF);
297 }
298 if (L->base+targ-1 < L->top) {
299 GCtab *options = lj_lib_checktab(L, targ);
300 cTValue *opt_dict = lj_tab_getstr(options, lj_str_newlit(L, "dict"));
301 if (opt_dict && tvistab(opt_dict)) {
302 dict = tabV(opt_dict);
303 lj_serialize_dict_prep(L, dict);
304 }
305 }
306 env = tabref(curr_func(L)->c.env);
307 ud = lj_udata_new(L, sizeof(SBufExt), env);
288 ud->udtype = UDTYPE_BUFFER; 308 ud->udtype = UDTYPE_BUFFER;
289 /* NOBARRIER: The GCudata is new (marked white). */ 309 /* NOBARRIER: The GCudata is new (marked white). */
290 setgcref(ud->metatable, obj2gco(env)); 310 setgcref(ud->metatable, obj2gco(env));
291 setudataV(L, L->top++, ud); 311 setudataV(L, L->top++, ud);
312 sbx = (SBufExt *)uddata(ud);
292 lj_bufx_init(L, sbx); 313 lj_bufx_init(L, sbx);
314 setgcref(sbx->dict, obj2gco(dict));
293 if (sz > 0) lj_buf_need2((SBuf *)sbx, sz); 315 if (sz > 0) lj_buf_need2((SBuf *)sbx, sz);
294 return 1; 316 return 1;
295} 317}
@@ -298,7 +320,8 @@ LJLIB_CF(buffer_encode)
298{ 320{
299 cTValue *o = lj_lib_checkany(L, 1); 321 cTValue *o = lj_lib_checkany(L, 1);
300 SBufExt sbx; 322 SBufExt sbx;
301 lj_bufx_init_borrow(L, &sbx, &G(L)->tmpbuf); 323 memset(&sbx, 0, sizeof(SBufExt));
324 lj_bufx_set_borrow(L, &sbx, &G(L)->tmpbuf);
302 lj_serialize_put(&sbx, o); 325 lj_serialize_put(&sbx, o);
303 setstrV(L, L->top++, lj_buf_str(L, (SBuf *)&sbx)); 326 setstrV(L, L->top++, lj_buf_str(L, (SBuf *)&sbx));
304 lj_gc_check(L); 327 lj_gc_check(L);
@@ -309,7 +332,8 @@ LJLIB_CF(buffer_decode)
309{ 332{
310 GCstr *str = lj_lib_checkstrx(L, 1); 333 GCstr *str = lj_lib_checkstrx(L, 1);
311 SBufExt sbx; 334 SBufExt sbx;
312 lj_bufx_init_cow(L, &sbx, strdata(str), str->len); 335 memset(&sbx, 0, sizeof(SBufExt));
336 lj_bufx_set_cow(L, &sbx, strdata(str), str->len);
313 /* No need to set sbx.cowref here. */ 337 /* No need to set sbx.cowref here. */
314 setnilV(L->top++); 338 setnilV(L->top++);
315 lj_serialize_get(&sbx, L->top-1); 339 lj_serialize_get(&sbx, L->top-1);