mirror of
https://github.com/bellard/quickjs.git
synced 2025-11-15 10:12:14 +03:00
faster and safer dbuf functions (#443)
This commit is contained in:
52
cutils.c
52
cutils.c
@@ -100,15 +100,20 @@ void dbuf_init(DynBuf *s)
|
|||||||
dbuf_init2(s, NULL, NULL);
|
dbuf_init2(s, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return < 0 if error */
|
/* Try to allocate 'len' more bytes. return < 0 if error */
|
||||||
int dbuf_realloc(DynBuf *s, size_t new_size)
|
int dbuf_claim(DynBuf *s, size_t len)
|
||||||
{
|
{
|
||||||
size_t size;
|
size_t new_size, size;
|
||||||
uint8_t *new_buf;
|
uint8_t *new_buf;
|
||||||
|
new_size = s->size + len;
|
||||||
|
if (new_size < len)
|
||||||
|
return -1; /* overflow case */
|
||||||
if (new_size > s->allocated_size) {
|
if (new_size > s->allocated_size) {
|
||||||
if (s->error)
|
if (s->error)
|
||||||
return -1;
|
return -1;
|
||||||
size = s->allocated_size * 3 / 2;
|
size = s->allocated_size + (s->allocated_size / 2);
|
||||||
|
if (size < s->allocated_size)
|
||||||
|
return -1; /* overflow case */
|
||||||
if (size > new_size)
|
if (size > new_size)
|
||||||
new_size = size;
|
new_size = size;
|
||||||
new_buf = s->realloc_func(s->opaque, s->buf, new_size);
|
new_buf = s->realloc_func(s->opaque, s->buf, new_size);
|
||||||
@@ -122,22 +127,10 @@ int dbuf_realloc(DynBuf *s, size_t new_size)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dbuf_write(DynBuf *s, size_t offset, const uint8_t *data, size_t len)
|
|
||||||
{
|
|
||||||
size_t end;
|
|
||||||
end = offset + len;
|
|
||||||
if (dbuf_realloc(s, end))
|
|
||||||
return -1;
|
|
||||||
memcpy(s->buf + offset, data, len);
|
|
||||||
if (end > s->size)
|
|
||||||
s->size = end;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int dbuf_put(DynBuf *s, const uint8_t *data, size_t len)
|
int dbuf_put(DynBuf *s, const uint8_t *data, size_t len)
|
||||||
{
|
{
|
||||||
if (unlikely((s->size + len) > s->allocated_size)) {
|
if (unlikely((s->allocated_size - s->size) < len)) {
|
||||||
if (dbuf_realloc(s, s->size + len))
|
if (dbuf_claim(s, len))
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
memcpy_no_ub(s->buf + s->size, data, len);
|
memcpy_no_ub(s->buf + s->size, data, len);
|
||||||
@@ -147,8 +140,8 @@ int dbuf_put(DynBuf *s, const uint8_t *data, size_t len)
|
|||||||
|
|
||||||
int dbuf_put_self(DynBuf *s, size_t offset, size_t len)
|
int dbuf_put_self(DynBuf *s, size_t offset, size_t len)
|
||||||
{
|
{
|
||||||
if (unlikely((s->size + len) > s->allocated_size)) {
|
if (unlikely((s->allocated_size - s->size) < len)) {
|
||||||
if (dbuf_realloc(s, s->size + len))
|
if (dbuf_claim(s, len))
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
memcpy(s->buf + s->size, s->buf + offset, len);
|
memcpy(s->buf + s->size, s->buf + offset, len);
|
||||||
@@ -156,11 +149,26 @@ int dbuf_put_self(DynBuf *s, size_t offset, size_t len)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dbuf_putc(DynBuf *s, uint8_t c)
|
int __dbuf_putc(DynBuf *s, uint8_t c)
|
||||||
{
|
{
|
||||||
return dbuf_put(s, &c, 1);
|
return dbuf_put(s, &c, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int __dbuf_put_u16(DynBuf *s, uint16_t val)
|
||||||
|
{
|
||||||
|
return dbuf_put(s, (uint8_t *)&val, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
int __dbuf_put_u32(DynBuf *s, uint32_t val)
|
||||||
|
{
|
||||||
|
return dbuf_put(s, (uint8_t *)&val, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
int __dbuf_put_u64(DynBuf *s, uint64_t val)
|
||||||
|
{
|
||||||
|
return dbuf_put(s, (uint8_t *)&val, 8);
|
||||||
|
}
|
||||||
|
|
||||||
int dbuf_putstr(DynBuf *s, const char *str)
|
int dbuf_putstr(DynBuf *s, const char *str)
|
||||||
{
|
{
|
||||||
return dbuf_put(s, (const uint8_t *)str, strlen(str));
|
return dbuf_put(s, (const uint8_t *)str, strlen(str));
|
||||||
@@ -182,7 +190,7 @@ int __attribute__((format(printf, 2, 3))) dbuf_printf(DynBuf *s,
|
|||||||
/* fast case */
|
/* fast case */
|
||||||
return dbuf_put(s, (uint8_t *)buf, len);
|
return dbuf_put(s, (uint8_t *)buf, len);
|
||||||
} else {
|
} else {
|
||||||
if (dbuf_realloc(s, s->size + len + 1))
|
if (dbuf_claim(s, len + 1))
|
||||||
return -1;
|
return -1;
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
vsnprintf((char *)(s->buf + s->size), s->allocated_size - s->size,
|
vsnprintf((char *)(s->buf + s->size), s->allocated_size - s->size,
|
||||||
|
|||||||
46
cutils.h
46
cutils.h
@@ -264,24 +264,58 @@ typedef struct DynBuf {
|
|||||||
|
|
||||||
void dbuf_init(DynBuf *s);
|
void dbuf_init(DynBuf *s);
|
||||||
void dbuf_init2(DynBuf *s, void *opaque, DynBufReallocFunc *realloc_func);
|
void dbuf_init2(DynBuf *s, void *opaque, DynBufReallocFunc *realloc_func);
|
||||||
int dbuf_realloc(DynBuf *s, size_t new_size);
|
int dbuf_claim(DynBuf *s, size_t len);
|
||||||
int dbuf_write(DynBuf *s, size_t offset, const uint8_t *data, size_t len);
|
|
||||||
int dbuf_put(DynBuf *s, const uint8_t *data, size_t len);
|
int dbuf_put(DynBuf *s, const uint8_t *data, size_t len);
|
||||||
int dbuf_put_self(DynBuf *s, size_t offset, size_t len);
|
int dbuf_put_self(DynBuf *s, size_t offset, size_t len);
|
||||||
int dbuf_putc(DynBuf *s, uint8_t c);
|
|
||||||
int dbuf_putstr(DynBuf *s, const char *str);
|
int dbuf_putstr(DynBuf *s, const char *str);
|
||||||
|
int __dbuf_putc(DynBuf *s, uint8_t c);
|
||||||
|
int __dbuf_put_u16(DynBuf *s, uint16_t val);
|
||||||
|
int __dbuf_put_u32(DynBuf *s, uint32_t val);
|
||||||
|
int __dbuf_put_u64(DynBuf *s, uint64_t val);
|
||||||
|
|
||||||
|
static inline int dbuf_putc(DynBuf *s, uint8_t val)
|
||||||
|
{
|
||||||
|
if (unlikely((s->allocated_size - s->size) < 1)) {
|
||||||
|
return __dbuf_putc(s, val);
|
||||||
|
} else {
|
||||||
|
s->buf[s->size++] = val;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static inline int dbuf_put_u16(DynBuf *s, uint16_t val)
|
static inline int dbuf_put_u16(DynBuf *s, uint16_t val)
|
||||||
{
|
{
|
||||||
return dbuf_put(s, (uint8_t *)&val, 2);
|
if (unlikely((s->allocated_size - s->size) < 2)) {
|
||||||
|
return __dbuf_put_u16(s, val);
|
||||||
|
} else {
|
||||||
|
put_u16(s->buf + s->size, val);
|
||||||
|
s->size += 2;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int dbuf_put_u32(DynBuf *s, uint32_t val)
|
static inline int dbuf_put_u32(DynBuf *s, uint32_t val)
|
||||||
{
|
{
|
||||||
return dbuf_put(s, (uint8_t *)&val, 4);
|
if (unlikely((s->allocated_size - s->size) < 4)) {
|
||||||
|
return __dbuf_put_u32(s, val);
|
||||||
|
} else {
|
||||||
|
put_u32(s->buf + s->size, val);
|
||||||
|
s->size += 4;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int dbuf_put_u64(DynBuf *s, uint64_t val)
|
static inline int dbuf_put_u64(DynBuf *s, uint64_t val)
|
||||||
{
|
{
|
||||||
return dbuf_put(s, (uint8_t *)&val, 8);
|
if (unlikely((s->allocated_size - s->size) < 8)) {
|
||||||
|
return __dbuf_put_u64(s, val);
|
||||||
|
} else {
|
||||||
|
put_u64(s->buf + s->size, val);
|
||||||
|
s->size += 8;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int __attribute__((format(printf, 2, 3))) dbuf_printf(DynBuf *s,
|
int __attribute__((format(printf, 2, 3))) dbuf_printf(DynBuf *s,
|
||||||
const char *fmt, ...);
|
const char *fmt, ...);
|
||||||
void dbuf_free(DynBuf *s);
|
void dbuf_free(DynBuf *s);
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ static inline int is_digit(int c) {
|
|||||||
/* insert 'len' bytes at position 'pos'. Return < 0 if error. */
|
/* insert 'len' bytes at position 'pos'. Return < 0 if error. */
|
||||||
static int dbuf_insert(DynBuf *s, int pos, int len)
|
static int dbuf_insert(DynBuf *s, int pos, int len)
|
||||||
{
|
{
|
||||||
if (dbuf_realloc(s, s->size + len))
|
if (dbuf_claim(s, len))
|
||||||
return -1;
|
return -1;
|
||||||
memmove(s->buf + pos + len, s->buf + pos, s->size - pos);
|
memmove(s->buf + pos + len, s->buf + pos, s->size - pos);
|
||||||
s->size += len;
|
s->size += len;
|
||||||
@@ -2340,7 +2340,7 @@ static int re_parse_alternative(REParseState *s, BOOL is_backward_dir)
|
|||||||
speed is not really critical here) */
|
speed is not really critical here) */
|
||||||
end = s->byte_code.size;
|
end = s->byte_code.size;
|
||||||
term_size = end - term_start;
|
term_size = end - term_start;
|
||||||
if (dbuf_realloc(&s->byte_code, end + term_size))
|
if (dbuf_claim(&s->byte_code, term_size))
|
||||||
return -1;
|
return -1;
|
||||||
memmove(s->byte_code.buf + start + term_size,
|
memmove(s->byte_code.buf + start + term_size,
|
||||||
s->byte_code.buf + start,
|
s->byte_code.buf + start,
|
||||||
|
|||||||
@@ -1179,7 +1179,7 @@ int unicode_normalize(uint32_t **pdst, const uint32_t *src, int src_len,
|
|||||||
is_compat = n_type >> 1;
|
is_compat = n_type >> 1;
|
||||||
|
|
||||||
dbuf_init2(dbuf, opaque, realloc_func);
|
dbuf_init2(dbuf, opaque, realloc_func);
|
||||||
if (dbuf_realloc(dbuf, sizeof(int) * src_len))
|
if (dbuf_claim(dbuf, sizeof(int) * src_len))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
/* common case: latin1 is unaffected by NFC */
|
/* common case: latin1 is unaffected by NFC */
|
||||||
|
|||||||
@@ -22835,7 +22835,7 @@ static void emit_op(JSParseState *s, uint8_t val)
|
|||||||
static void emit_atom(JSParseState *s, JSAtom name)
|
static void emit_atom(JSParseState *s, JSAtom name)
|
||||||
{
|
{
|
||||||
DynBuf *bc = &s->cur_func->byte_code;
|
DynBuf *bc = &s->cur_func->byte_code;
|
||||||
if (dbuf_realloc(bc, bc->size + 4))
|
if (dbuf_claim(bc, 4))
|
||||||
return; /* not enough memory : don't duplicate the atom */
|
return; /* not enough memory : don't duplicate the atom */
|
||||||
put_u32(bc->buf + bc->size, JS_DupAtom(s->ctx, name));
|
put_u32(bc->buf + bc->size, JS_DupAtom(s->ctx, name));
|
||||||
bc->size += 4;
|
bc->size += 4;
|
||||||
@@ -27751,7 +27751,7 @@ static __exception int js_parse_for_in_of(JSParseState *s, int label_name,
|
|||||||
int chunk_size = pos_expr - pos_next;
|
int chunk_size = pos_expr - pos_next;
|
||||||
int offset = bc->size - pos_next;
|
int offset = bc->size - pos_next;
|
||||||
int i;
|
int i;
|
||||||
dbuf_realloc(bc, bc->size + chunk_size);
|
dbuf_claim(bc, chunk_size);
|
||||||
dbuf_put(bc, bc->buf + pos_next, chunk_size);
|
dbuf_put(bc, bc->buf + pos_next, chunk_size);
|
||||||
memset(bc->buf + pos_next, OP_nop, chunk_size);
|
memset(bc->buf + pos_next, OP_nop, chunk_size);
|
||||||
/* `next` part ends with a goto */
|
/* `next` part ends with a goto */
|
||||||
@@ -28157,7 +28157,7 @@ static __exception int js_parse_statement_or_decl(JSParseState *s,
|
|||||||
int chunk_size = pos_body - pos_cont;
|
int chunk_size = pos_body - pos_cont;
|
||||||
int offset = bc->size - pos_cont;
|
int offset = bc->size - pos_cont;
|
||||||
int i;
|
int i;
|
||||||
dbuf_realloc(bc, bc->size + chunk_size);
|
dbuf_claim(bc, chunk_size);
|
||||||
dbuf_put(bc, bc->buf + pos_cont, chunk_size);
|
dbuf_put(bc, bc->buf + pos_cont, chunk_size);
|
||||||
memset(bc->buf + pos_cont, OP_nop, chunk_size);
|
memset(bc->buf + pos_cont, OP_nop, chunk_size);
|
||||||
/* increment part ends with a goto */
|
/* increment part ends with a goto */
|
||||||
@@ -37097,7 +37097,7 @@ static int JS_WriteObjectAtoms(BCWriterState *s)
|
|||||||
/* XXX: could just append dbuf1 data, but it uses more memory if
|
/* XXX: could just append dbuf1 data, but it uses more memory if
|
||||||
dbuf1 is larger than dbuf */
|
dbuf1 is larger than dbuf */
|
||||||
atoms_size = s->dbuf.size;
|
atoms_size = s->dbuf.size;
|
||||||
if (dbuf_realloc(&dbuf1, dbuf1.size + atoms_size))
|
if (dbuf_claim(&dbuf1, atoms_size))
|
||||||
goto fail;
|
goto fail;
|
||||||
memmove(dbuf1.buf + atoms_size, dbuf1.buf, dbuf1.size);
|
memmove(dbuf1.buf + atoms_size, dbuf1.buf, dbuf1.size);
|
||||||
memcpy(dbuf1.buf, s->dbuf.buf, atoms_size);
|
memcpy(dbuf1.buf, s->dbuf.buf, atoms_size);
|
||||||
|
|||||||
Reference in New Issue
Block a user