mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-05-23 13:52:28 +00:00
Reduce build latency and fix old cpu bugs
This commit is contained in:
parent
df8ab0aa0c
commit
533f3d1ef1
69 changed files with 43069 additions and 43683 deletions
331
third_party/quickjs/strbuf.c
vendored
Normal file
331
third_party/quickjs/strbuf.c
vendored
Normal file
|
@ -0,0 +1,331 @@
|
|||
/*
|
||||
* QuickJS Javascript Engine
|
||||
*
|
||||
* Copyright (c) 2017-2021 Fabrice Bellard
|
||||
* Copyright (c) 2017-2021 Charlie Gordon
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#include "third_party/quickjs/internal.h"
|
||||
#include "third_party/quickjs/libregexp.h"
|
||||
#include "third_party/quickjs/quickjs.h"
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
QuickJS (MIT License)\\n\
|
||||
Copyright (c) 2017-2021 Fabrice Bellard\\n\
|
||||
Copyright (c) 2017-2021 Charlie Gordon\"");
|
||||
asm(".include \"libc/disclaimer.inc\"");
|
||||
/* clang-format off */
|
||||
|
||||
/* It is valid to call string_buffer_end() and all string_buffer functions even
|
||||
if string_buffer_init() or another string_buffer function returns an error.
|
||||
If the error_status is set, string_buffer_end() returns JS_EXCEPTION.
|
||||
*/
|
||||
int string_buffer_init2(JSContext *ctx, StringBuffer *s, int size, int is_wide)
|
||||
{
|
||||
s->ctx = ctx;
|
||||
s->size = size;
|
||||
s->len = 0;
|
||||
s->is_wide_char = is_wide;
|
||||
s->error_status = 0;
|
||||
s->str = js_alloc_string(ctx, size, is_wide);
|
||||
if (UNLIKELY(!s->str)) {
|
||||
s->size = 0;
|
||||
return s->error_status = -1;
|
||||
}
|
||||
#ifdef DUMP_LEAKS
|
||||
/* the StringBuffer may reallocate the JSString, only link it at the end */
|
||||
list_del(&s->str->link);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int string_buffer_init(JSContext *ctx, StringBuffer *s, int size)
|
||||
{
|
||||
return string_buffer_init2(ctx, s, size, 0);
|
||||
}
|
||||
|
||||
void string_buffer_free(StringBuffer *s)
|
||||
{
|
||||
js_free(s->ctx, s->str);
|
||||
s->str = NULL;
|
||||
}
|
||||
|
||||
int string_buffer_set_error(StringBuffer *s)
|
||||
{
|
||||
js_free(s->ctx, s->str);
|
||||
s->str = NULL;
|
||||
s->size = 0;
|
||||
s->len = 0;
|
||||
return s->error_status = -1;
|
||||
}
|
||||
|
||||
int string_buffer_widen(StringBuffer *s, int size)
|
||||
{
|
||||
JSString *str;
|
||||
size_t slack;
|
||||
int i;
|
||||
if (s->error_status)
|
||||
return -1;
|
||||
str = js_realloc2(s->ctx, s->str, sizeof(JSString) + (size << 1), &slack);
|
||||
if (!str)
|
||||
return string_buffer_set_error(s);
|
||||
size += slack >> 1;
|
||||
for(i = s->len; i-- > 0;) {
|
||||
str->u.str16[i] = str->u.str8[i];
|
||||
}
|
||||
s->is_wide_char = 1;
|
||||
s->size = size;
|
||||
s->str = str;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int string_buffer_realloc(StringBuffer *s, int new_len, int c)
|
||||
{
|
||||
JSString *new_str;
|
||||
int new_size;
|
||||
size_t new_size_bytes, slack;
|
||||
if (s->error_status)
|
||||
return -1;
|
||||
if (new_len > JS_STRING_LEN_MAX) {
|
||||
JS_ThrowInternalError(s->ctx, "string too long");
|
||||
return string_buffer_set_error(s);
|
||||
}
|
||||
new_size = min_int(max_int(new_len, s->size * 3 / 2), JS_STRING_LEN_MAX);
|
||||
if (!s->is_wide_char && c >= 0x100) {
|
||||
return string_buffer_widen(s, new_size);
|
||||
}
|
||||
new_size_bytes = sizeof(JSString) + (new_size << s->is_wide_char) + 1 - s->is_wide_char;
|
||||
new_str = js_realloc2(s->ctx, s->str, new_size_bytes, &slack);
|
||||
if (!new_str)
|
||||
return string_buffer_set_error(s);
|
||||
new_size = min_int(new_size + (slack >> s->is_wide_char), JS_STRING_LEN_MAX);
|
||||
s->size = new_size;
|
||||
s->str = new_str;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int string_buffer_putc_slow(StringBuffer *s, uint32_t c)
|
||||
{
|
||||
if (UNLIKELY(s->len >= s->size)) {
|
||||
if (string_buffer_realloc(s, s->len + 1, c))
|
||||
return -1;
|
||||
}
|
||||
if (s->is_wide_char) {
|
||||
s->str->u.str16[s->len++] = c;
|
||||
} else if (c < 0x100) {
|
||||
s->str->u.str8[s->len++] = c;
|
||||
} else {
|
||||
if (string_buffer_widen(s, s->size))
|
||||
return -1;
|
||||
s->str->u.str16[s->len++] = c;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 0 <= c <= 0xff */
|
||||
int string_buffer_putc8(StringBuffer *s, uint32_t c)
|
||||
{
|
||||
if (UNLIKELY(s->len >= s->size)) {
|
||||
if (string_buffer_realloc(s, s->len + 1, c))
|
||||
return -1;
|
||||
}
|
||||
if (s->is_wide_char) {
|
||||
s->str->u.str16[s->len++] = c;
|
||||
} else {
|
||||
s->str->u.str8[s->len++] = c;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 0 <= c <= 0xffff */
|
||||
int string_buffer_putc16(StringBuffer *s, uint32_t c)
|
||||
{
|
||||
if (LIKELY(s->len < s->size)) {
|
||||
if (s->is_wide_char) {
|
||||
s->str->u.str16[s->len++] = c;
|
||||
return 0;
|
||||
} else if (c < 0x100) {
|
||||
s->str->u.str8[s->len++] = c;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return string_buffer_putc_slow(s, c);
|
||||
}
|
||||
|
||||
/* 0 <= c <= 0x10ffff */
|
||||
int string_buffer_putc(StringBuffer *s, uint32_t c)
|
||||
{
|
||||
if (UNLIKELY(c >= 0x10000)) {
|
||||
/* surrogate pair */
|
||||
c -= 0x10000;
|
||||
if (string_buffer_putc16(s, (c >> 10) + 0xd800))
|
||||
return -1;
|
||||
c = (c & 0x3ff) + 0xdc00;
|
||||
}
|
||||
return string_buffer_putc16(s, c);
|
||||
}
|
||||
|
||||
int string_buffer_write8(StringBuffer *s, const uint8_t *p, int len)
|
||||
{
|
||||
int i;
|
||||
if (s->len + len > s->size) {
|
||||
if (string_buffer_realloc(s, s->len + len, 0))
|
||||
return -1;
|
||||
}
|
||||
if (s->is_wide_char) {
|
||||
for (i = 0; i < len; i++) {
|
||||
s->str->u.str16[s->len + i] = p[i];
|
||||
}
|
||||
s->len += len;
|
||||
} else {
|
||||
memcpy(&s->str->u.str8[s->len], p, len);
|
||||
s->len += len;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int string_buffer_write16(StringBuffer *s, const uint16_t *p, int len)
|
||||
{
|
||||
int c = 0, i;
|
||||
for (i = 0; i < len; i++) {
|
||||
c |= p[i];
|
||||
}
|
||||
if (s->len + len > s->size) {
|
||||
if (string_buffer_realloc(s, s->len + len, c))
|
||||
return -1;
|
||||
} else if (!s->is_wide_char && c >= 0x100) {
|
||||
if (string_buffer_widen(s, s->size))
|
||||
return -1;
|
||||
}
|
||||
if (s->is_wide_char) {
|
||||
memcpy(&s->str->u.str16[s->len], p, len << 1);
|
||||
s->len += len;
|
||||
} else {
|
||||
for (i = 0; i < len; i++) {
|
||||
s->str->u.str8[s->len + i] = p[i];
|
||||
}
|
||||
s->len += len;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* appending an ASCII string */
|
||||
int string_buffer_puts8(StringBuffer *s, const char *str)
|
||||
{
|
||||
return string_buffer_write8(s, (const uint8_t *)str, strlen(str));
|
||||
}
|
||||
|
||||
int string_buffer_concat(StringBuffer *s, const JSString *p, uint32_t from, uint32_t to)
|
||||
{
|
||||
if (to <= from)
|
||||
return 0;
|
||||
if (p->is_wide_char)
|
||||
return string_buffer_write16(s, p->u.str16 + from, to - from);
|
||||
else
|
||||
return string_buffer_write8(s, p->u.str8 + from, to - from);
|
||||
}
|
||||
|
||||
int string_buffer_concat_value(StringBuffer *s, JSValueConst v)
|
||||
{
|
||||
JSString *p;
|
||||
JSValue v1;
|
||||
int res;
|
||||
if (s->error_status) {
|
||||
/* prevent exception overload */
|
||||
return -1;
|
||||
}
|
||||
if (UNLIKELY(JS_VALUE_GET_TAG(v) != JS_TAG_STRING)) {
|
||||
v1 = JS_ToString(s->ctx, v);
|
||||
if (JS_IsException(v1))
|
||||
return string_buffer_set_error(s);
|
||||
p = JS_VALUE_GET_STRING(v1);
|
||||
res = string_buffer_concat(s, p, 0, p->len);
|
||||
JS_FreeValue(s->ctx, v1);
|
||||
return res;
|
||||
}
|
||||
p = JS_VALUE_GET_STRING(v);
|
||||
return string_buffer_concat(s, p, 0, p->len);
|
||||
}
|
||||
|
||||
int string_buffer_concat_value_free(StringBuffer *s, JSValue v)
|
||||
{
|
||||
JSString *p;
|
||||
int res;
|
||||
if (s->error_status) {
|
||||
/* prevent exception overload */
|
||||
JS_FreeValue(s->ctx, v);
|
||||
return -1;
|
||||
}
|
||||
if (UNLIKELY(JS_VALUE_GET_TAG(v) != JS_TAG_STRING)) {
|
||||
v = JS_ToStringFree(s->ctx, v);
|
||||
if (JS_IsException(v))
|
||||
return string_buffer_set_error(s);
|
||||
}
|
||||
p = JS_VALUE_GET_STRING(v);
|
||||
res = string_buffer_concat(s, p, 0, p->len);
|
||||
JS_FreeValue(s->ctx, v);
|
||||
return res;
|
||||
}
|
||||
|
||||
int string_buffer_fill(StringBuffer *s, int c, int count)
|
||||
{
|
||||
/* XXX: optimize */
|
||||
if (s->len + count > s->size) {
|
||||
if (string_buffer_realloc(s, s->len + count, c))
|
||||
return -1;
|
||||
}
|
||||
while (count-- > 0) {
|
||||
if (string_buffer_putc16(s, c))
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
JSValue string_buffer_end(StringBuffer *s)
|
||||
{
|
||||
JSString *str;
|
||||
str = s->str;
|
||||
if (s->error_status)
|
||||
return JS_EXCEPTION;
|
||||
if (s->len == 0) {
|
||||
js_free(s->ctx, str);
|
||||
s->str = NULL;
|
||||
return JS_AtomToString(s->ctx, JS_ATOM_empty_string);
|
||||
}
|
||||
if (s->len < s->size) {
|
||||
/* smaller size so js_realloc should not fail, but OK if it does */
|
||||
/* XXX: should add some slack to avoid unnecessary calls */
|
||||
/* XXX: might need to use malloc+free to ensure smaller size */
|
||||
str = js_realloc_rt(s->ctx->rt, str, sizeof(JSString) +
|
||||
(s->len << s->is_wide_char) + 1 - s->is_wide_char);
|
||||
if (str == NULL)
|
||||
str = s->str;
|
||||
s->str = str;
|
||||
}
|
||||
if (!s->is_wide_char)
|
||||
str->u.str8[s->len] = 0;
|
||||
#ifdef DUMP_LEAKS
|
||||
list_add_tail(&str->link, &s->ctx->rt->string_list);
|
||||
#endif
|
||||
str->is_wide_char = s->is_wide_char;
|
||||
str->len = s->len;
|
||||
s->str = NULL;
|
||||
return JS_MKPTR(JS_TAG_STRING, str);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue