Migrate to quickjs-ng

This commit is contained in:
2025-01-19 22:05:33 +08:00
parent 9c99ac258a
commit 67496e2158
32 changed files with 23780 additions and 15972 deletions

View File

@@ -10,6 +10,8 @@
#include <future> #include <future>
#include <string.h> #include <string.h>
#define JS_BOOL bool
extern "C" extern "C"
{ {
@@ -99,8 +101,8 @@ extern "C"
DLLEXPORT uint32_t jsNewClass(JSContext *ctx, const char *name) DLLEXPORT uint32_t jsNewClass(JSContext *ctx, const char *name)
{ {
JSClassID QJSClassId = 0; JSClassID QJSClassId = 0;
JS_NewClassID(&QJSClassId);
JSRuntime *rt = JS_GetRuntime(ctx); JSRuntime *rt = JS_GetRuntime(ctx);
JS_NewClassID(rt, &QJSClassId);
if (!JS_IsRegisteredClass(rt, QJSClassId)) if (!JS_IsRegisteredClass(rt, QJSClassId))
{ {
JSClassDef def{ JSClassDef def{
@@ -312,7 +314,7 @@ extern "C"
DLLEXPORT int32_t jsIsPromise(JSContext *ctx, JSValueConst *val) DLLEXPORT int32_t jsIsPromise(JSContext *ctx, JSValueConst *val)
{ {
return JS_IsPromise(ctx, *val); return JS_IsPromise(*val);
} }
DLLEXPORT int32_t jsIsArray(JSContext *ctx, JSValueConst *val) DLLEXPORT int32_t jsIsArray(JSContext *ctx, JSValueConst *val)
@@ -322,7 +324,7 @@ extern "C"
DLLEXPORT int32_t jsIsMap(JSContext *ctx, JSValueConst *val) DLLEXPORT int32_t jsIsMap(JSContext *ctx, JSValueConst *val)
{ {
return JS_IsMap(ctx, *val); return JS_IsMap(*val);
} }
DLLEXPORT int32_t jsIsError(JSContext *ctx, JSValueConst *val) DLLEXPORT int32_t jsIsError(JSContext *ctx, JSValueConst *val)

View File

@@ -1,4 +1,4 @@
#include "quickjs/quickjs.h" #include "quickjs-ng/quickjs.h"
#ifdef _MSC_VER #ifdef _MSC_VER
#define DLLEXPORT __declspec(dllexport) #define DLLEXPORT __declspec(dllexport)

1
cxx/quickjs-ng/VERSION Normal file
View File

@@ -0,0 +1 @@
2024-02-14

1416
cxx/quickjs-ng/cutils.c Normal file

File diff suppressed because it is too large Load Diff

600
cxx/quickjs-ng/cutils.h Normal file
View File

@@ -0,0 +1,600 @@
/*
* C utilities
*
* Copyright (c) 2017 Fabrice Bellard
* Copyright (c) 2018 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.
*/
#ifndef CUTILS_H
#define CUTILS_H
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include <math.h>
#ifdef __cplusplus
extern "C" {
#endif
#if defined(_MSC_VER)
#include <winsock2.h>
#include <malloc.h>
#define alloca _alloca
#define ssize_t ptrdiff_t
#endif
#if defined(__APPLE__)
#include <malloc/malloc.h>
#elif defined(__linux__) || defined(__ANDROID__) || defined(__CYGWIN__)
#include <malloc.h>
#elif defined(__FreeBSD__)
#include <malloc_np.h>
#elif defined(_WIN32)
#include <windows.h>
#endif
#if !defined(_WIN32) && !defined(EMSCRIPTEN) && !defined(__wasi__)
#include <errno.h>
#include <pthread.h>
#endif
#if defined(_MSC_VER) && !defined(__clang__)
# define likely(x) (x)
# define unlikely(x) (x)
# define force_inline __forceinline
# define no_inline __declspec(noinline)
# define __maybe_unused
# define __attribute__(x)
# define __attribute(x)
#else
# define likely(x) __builtin_expect(!!(x), 1)
# define unlikely(x) __builtin_expect(!!(x), 0)
# define force_inline inline __attribute__((always_inline))
# define no_inline __attribute__((noinline))
# define __maybe_unused __attribute__((unused))
#endif
#if defined(_MSC_VER) && !defined(__clang__)
#include <math.h>
#define INF INFINITY
#define NEG_INF -INFINITY
#else
#define INF (1.0/0.0)
#define NEG_INF (-1.0/0.0)
#endif
#ifndef offsetof
#define offsetof(type, field) ((size_t) &((type *)0)->field)
#endif
#ifndef countof
#define countof(x) (sizeof(x) / sizeof((x)[0]))
#ifndef endof
#define endof(x) ((x) + countof(x))
#endif
#endif
#ifndef container_of
/* return the pointer of type 'type *' containing 'ptr' as field 'member' */
#define container_of(ptr, type, member) ((type *)((uint8_t *)(ptr) - offsetof(type, member)))
#endif
#if defined(_MSC_VER)
#define minimum_length(n) n
#else
#define minimum_length(n) static n
#endif
/* Borrowed from Folly */
#ifndef JS_PRINTF_FORMAT
#ifdef _MSC_VER
#include <sal.h>
#define JS_PRINTF_FORMAT _Printf_format_string_
#define JS_PRINTF_FORMAT_ATTR(format_param, dots_param)
#else
#define JS_PRINTF_FORMAT
#if !defined(__clang__) && defined(__GNUC__)
#define JS_PRINTF_FORMAT_ATTR(format_param, dots_param) \
__attribute__((format(gnu_printf, format_param, dots_param)))
#else
#define JS_PRINTF_FORMAT_ATTR(format_param, dots_param) \
__attribute__((format(printf, format_param, dots_param)))
#endif
#endif
#endif
void js__pstrcpy(char *buf, int buf_size, const char *str);
char *js__pstrcat(char *buf, int buf_size, const char *s);
int js__strstart(const char *str, const char *val, const char **ptr);
int js__has_suffix(const char *str, const char *suffix);
static inline uint8_t is_be(void) {
union {
uint16_t a;
uint8_t b;
} u = { 0x100 };
return u.b;
}
static inline int max_int(int a, int b)
{
if (a > b)
return a;
else
return b;
}
static inline int min_int(int a, int b)
{
if (a < b)
return a;
else
return b;
}
static inline uint32_t max_uint32(uint32_t a, uint32_t b)
{
if (a > b)
return a;
else
return b;
}
static inline uint32_t min_uint32(uint32_t a, uint32_t b)
{
if (a < b)
return a;
else
return b;
}
static inline int64_t max_int64(int64_t a, int64_t b)
{
if (a > b)
return a;
else
return b;
}
static inline int64_t min_int64(int64_t a, int64_t b)
{
if (a < b)
return a;
else
return b;
}
/* WARNING: undefined if a = 0 */
static inline int clz32(unsigned int a)
{
#if defined(_MSC_VER) && !defined(__clang__)
unsigned long index;
_BitScanReverse(&index, a);
return 31 - index;
#else
return __builtin_clz(a);
#endif
}
/* WARNING: undefined if a = 0 */
static inline int clz64(uint64_t a)
{
#if defined(_MSC_VER) && !defined(__clang__)
#if INTPTR_MAX == INT64_MAX
unsigned long index;
_BitScanReverse64(&index, a);
return 63 - index;
#else
if (a >> 32)
return clz32((unsigned)(a >> 32));
else
return clz32((unsigned)a) + 32;
#endif
#else
return __builtin_clzll(a);
#endif
}
/* WARNING: undefined if a = 0 */
static inline int ctz32(unsigned int a)
{
#if defined(_MSC_VER) && !defined(__clang__)
unsigned long index;
_BitScanForward(&index, a);
return index;
#else
return __builtin_ctz(a);
#endif
}
/* WARNING: undefined if a = 0 */
static inline int ctz64(uint64_t a)
{
#if defined(_MSC_VER) && !defined(__clang__)
unsigned long index;
_BitScanForward64(&index, a);
return index;
#else
return __builtin_ctzll(a);
#endif
}
static inline uint64_t get_u64(const uint8_t *tab)
{
uint64_t v;
memcpy(&v, tab, sizeof(v));
return v;
}
static inline int64_t get_i64(const uint8_t *tab)
{
int64_t v;
memcpy(&v, tab, sizeof(v));
return v;
}
static inline void put_u64(uint8_t *tab, uint64_t val)
{
memcpy(tab, &val, sizeof(val));
}
static inline uint32_t get_u32(const uint8_t *tab)
{
uint32_t v;
memcpy(&v, tab, sizeof(v));
return v;
}
static inline int32_t get_i32(const uint8_t *tab)
{
int32_t v;
memcpy(&v, tab, sizeof(v));
return v;
}
static inline void put_u32(uint8_t *tab, uint32_t val)
{
memcpy(tab, &val, sizeof(val));
}
static inline uint32_t get_u16(const uint8_t *tab)
{
uint16_t v;
memcpy(&v, tab, sizeof(v));
return v;
}
static inline int32_t get_i16(const uint8_t *tab)
{
int16_t v;
memcpy(&v, tab, sizeof(v));
return v;
}
static inline void put_u16(uint8_t *tab, uint16_t val)
{
memcpy(tab, &val, sizeof(val));
}
static inline uint32_t get_u8(const uint8_t *tab)
{
return *tab;
}
static inline int32_t get_i8(const uint8_t *tab)
{
return (int8_t)*tab;
}
static inline void put_u8(uint8_t *tab, uint8_t val)
{
*tab = val;
}
#ifndef bswap16
static inline uint16_t bswap16(uint16_t x)
{
return (x >> 8) | (x << 8);
}
#endif
#ifndef bswap32
static inline uint32_t bswap32(uint32_t v)
{
return ((v & 0xff000000) >> 24) | ((v & 0x00ff0000) >> 8) |
((v & 0x0000ff00) << 8) | ((v & 0x000000ff) << 24);
}
#endif
#ifndef bswap64
static inline uint64_t bswap64(uint64_t v)
{
return ((v & ((uint64_t)0xff << (7 * 8))) >> (7 * 8)) |
((v & ((uint64_t)0xff << (6 * 8))) >> (5 * 8)) |
((v & ((uint64_t)0xff << (5 * 8))) >> (3 * 8)) |
((v & ((uint64_t)0xff << (4 * 8))) >> (1 * 8)) |
((v & ((uint64_t)0xff << (3 * 8))) << (1 * 8)) |
((v & ((uint64_t)0xff << (2 * 8))) << (3 * 8)) |
((v & ((uint64_t)0xff << (1 * 8))) << (5 * 8)) |
((v & ((uint64_t)0xff << (0 * 8))) << (7 * 8));
}
#endif
static inline void inplace_bswap16(uint8_t *tab) {
put_u16(tab, bswap16(get_u16(tab)));
}
static inline void inplace_bswap32(uint8_t *tab) {
put_u32(tab, bswap32(get_u32(tab)));
}
static inline double fromfp16(uint16_t v) {
double d, s;
int e;
if ((v & 0x7C00) == 0x7C00) {
d = (v & 0x3FF) ? NAN : INFINITY;
} else {
d = (v & 0x3FF) / 1024.;
e = (v & 0x7C00) >> 10;
if (e == 0) {
e = -14;
} else {
d += 1;
e -= 15;
}
d = scalbn(d, e);
}
s = (v & 0x8000) ? -1.0 : 1.0;
return d * s;
}
static inline uint16_t tofp16(double d) {
uint16_t f, s;
double t;
int e;
s = 0;
if (copysign(1, d) < 0) { // preserve sign when |d| is negative zero
d = -d;
s = 0x8000;
}
if (isinf(d))
return s | 0x7C00;
if (isnan(d))
return s | 0x7C01;
if (d == 0)
return s | 0;
d = 2 * frexp(d, &e);
e--;
if (e > 15)
return s | 0x7C00; // out of range, return +/-infinity
if (e < -25) {
d = 0;
e = 0;
} else if (e < -14) {
d = scalbn(d, e + 14);
e = 0;
} else {
d -= 1;
e += 15;
}
d *= 1024.;
f = (uint16_t)d;
t = d - f;
if (t < 0.5)
goto done;
if (t == 0.5)
if ((f & 1) == 0)
goto done;
// adjust for rounding
if (++f == 1024) {
f = 0;
if (++e == 31)
return s | 0x7C00; // out of range, return +/-infinity
}
done:
return s | (e << 10) | f;
}
static inline int isfp16nan(uint16_t v) {
return (v & 0x7FFF) > 0x7C00;
}
static inline int isfp16zero(uint16_t v) {
return (v & 0x7FFF) == 0;
}
/* XXX: should take an extra argument to pass slack information to the caller */
typedef void *DynBufReallocFunc(void *opaque, void *ptr, size_t size);
typedef struct DynBuf {
uint8_t *buf;
size_t size;
size_t allocated_size;
bool error; /* true if a memory allocation error occurred */
DynBufReallocFunc *realloc_func;
void *opaque; /* for realloc_func */
} DynBuf;
void dbuf_init(DynBuf *s);
void dbuf_init2(DynBuf *s, void *opaque, DynBufReallocFunc *realloc_func);
int dbuf_realloc(DynBuf *s, size_t new_size);
int dbuf_write(DynBuf *s, size_t offset, const void *data, size_t len);
int dbuf_put(DynBuf *s, const void *data, 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);
static inline int dbuf_put_u16(DynBuf *s, uint16_t val)
{
return dbuf_put(s, (uint8_t *)&val, 2);
}
static inline int dbuf_put_u32(DynBuf *s, uint32_t val)
{
return dbuf_put(s, (uint8_t *)&val, 4);
}
static inline int dbuf_put_u64(DynBuf *s, uint64_t val)
{
return dbuf_put(s, (uint8_t *)&val, 8);
}
int JS_PRINTF_FORMAT_ATTR(2, 3) dbuf_printf(DynBuf *s, JS_PRINTF_FORMAT const char *fmt, ...);
void dbuf_free(DynBuf *s);
static inline bool dbuf_error(DynBuf *s) {
return s->error;
}
static inline void dbuf_set_error(DynBuf *s)
{
s->error = true;
}
/*---- UTF-8 and UTF-16 handling ----*/
#define UTF8_CHAR_LEN_MAX 4
enum {
UTF8_PLAIN_ASCII = 0, // 7-bit ASCII plain text
UTF8_NON_ASCII = 1, // has non ASCII code points (8-bit or more)
UTF8_HAS_16BIT = 2, // has 16-bit code points
UTF8_HAS_NON_BMP1 = 4, // has non-BMP1 code points, needs UTF-16 surrogate pairs
UTF8_HAS_ERRORS = 8, // has encoding errors
};
int utf8_scan(const char *buf, size_t len, size_t *plen);
size_t utf8_encode_len(uint32_t c);
size_t utf8_encode(uint8_t buf[minimum_length(UTF8_CHAR_LEN_MAX)], uint32_t c);
uint32_t utf8_decode_len(const uint8_t *p, size_t max_len, const uint8_t **pp);
uint32_t utf8_decode(const uint8_t *p, const uint8_t **pp);
size_t utf8_decode_buf8(uint8_t *dest, size_t dest_len, const char *src, size_t src_len);
size_t utf8_decode_buf16(uint16_t *dest, size_t dest_len, const char *src, size_t src_len);
size_t utf8_encode_buf8(char *dest, size_t dest_len, const uint8_t *src, size_t src_len);
size_t utf8_encode_buf16(char *dest, size_t dest_len, const uint16_t *src, size_t src_len);
static inline bool is_surrogate(uint32_t c)
{
return (c >> 11) == (0xD800 >> 11); // 0xD800-0xDFFF
}
static inline bool is_hi_surrogate(uint32_t c)
{
return (c >> 10) == (0xD800 >> 10); // 0xD800-0xDBFF
}
static inline bool is_lo_surrogate(uint32_t c)
{
return (c >> 10) == (0xDC00 >> 10); // 0xDC00-0xDFFF
}
static inline uint32_t get_hi_surrogate(uint32_t c)
{
return (c >> 10) - (0x10000 >> 10) + 0xD800;
}
static inline uint32_t get_lo_surrogate(uint32_t c)
{
return (c & 0x3FF) | 0xDC00;
}
static inline uint32_t from_surrogate(uint32_t hi, uint32_t lo)
{
return 65536 + 1024 * (hi & 1023) + (lo & 1023);
}
static inline int from_hex(int c)
{
if (c >= '0' && c <= '9')
return c - '0';
else if (c >= 'A' && c <= 'F')
return c - 'A' + 10;
else if (c >= 'a' && c <= 'f')
return c - 'a' + 10;
else
return -1;
}
static inline uint8_t is_upper_ascii(uint8_t c) {
return c >= 'A' && c <= 'Z';
}
static inline uint8_t to_upper_ascii(uint8_t c) {
return c >= 'a' && c <= 'z' ? c - 'a' + 'A' : c;
}
extern char const digits36[36];
size_t u32toa(char buf[minimum_length(11)], uint32_t n);
size_t i32toa(char buf[minimum_length(12)], int32_t n);
size_t u64toa(char buf[minimum_length(21)], uint64_t n);
size_t i64toa(char buf[minimum_length(22)], int64_t n);
size_t u32toa_radix(char buf[minimum_length(33)], uint32_t n, unsigned int base);
size_t i32toa_radix(char buf[minimum_length(34)], int32_t n, unsigned base);
size_t u64toa_radix(char buf[minimum_length(65)], uint64_t n, unsigned int base);
size_t i64toa_radix(char buf[minimum_length(66)], int64_t n, unsigned int base);
void rqsort(void *base, size_t nmemb, size_t size,
int (*cmp)(const void *, const void *, void *),
void *arg);
int64_t js__gettimeofday_us(void);
uint64_t js__hrtime_ns(void);
static inline size_t js__malloc_usable_size(const void *ptr)
{
#if defined(__APPLE__)
return malloc_size(ptr);
#elif defined(_WIN32)
return _msize((void *)ptr);
#elif defined(__linux__) || defined(__ANDROID__) || defined(__CYGWIN__) || defined(__FreeBSD__)
return malloc_usable_size((void *)ptr);
#else
return 0;
#endif
}
/* Cross-platform threading APIs. */
#if !defined(EMSCRIPTEN) && !defined(__wasi__)
#if defined(_WIN32)
#define JS_ONCE_INIT INIT_ONCE_STATIC_INIT
typedef INIT_ONCE js_once_t;
typedef CRITICAL_SECTION js_mutex_t;
typedef CONDITION_VARIABLE js_cond_t;
#else
#define JS_ONCE_INIT PTHREAD_ONCE_INIT
typedef pthread_once_t js_once_t;
typedef pthread_mutex_t js_mutex_t;
typedef pthread_cond_t js_cond_t;
#endif
void js_once(js_once_t *guard, void (*callback)(void));
void js_mutex_init(js_mutex_t *mutex);
void js_mutex_destroy(js_mutex_t *mutex);
void js_mutex_lock(js_mutex_t *mutex);
void js_mutex_unlock(js_mutex_t *mutex);
void js_cond_init(js_cond_t *cond);
void js_cond_destroy(js_cond_t *cond);
void js_cond_signal(js_cond_t *cond);
void js_cond_broadcast(js_cond_t *cond);
void js_cond_wait(js_cond_t *cond, js_mutex_t *mutex);
int js_cond_timedwait(js_cond_t *cond, js_mutex_t *mutex, uint64_t timeout);
#endif /* !defined(EMSCRIPTEN) && !defined(__wasi__) */
#ifdef __cplusplus
} /* extern "C" { */
#endif
#endif /* CUTILS_H */

File diff suppressed because it is too large Load Diff

23
cxx/quickjs-ng/fuzz.c Normal file
View File

@@ -0,0 +1,23 @@
// clang -g -O1 -fsanitize=fuzzer -o fuzz fuzz.c
#include "quickjs.h"
#include "quickjs.c"
#include "cutils.c"
#include "libbf.c"
#include "libregexp.c"
#include "libunicode.c"
#include <stdlib.h>
int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len)
{
JSRuntime *rt = JS_NewRuntime();
if (!rt)
exit(1);
JSContext *ctx = JS_NewContext(rt);
if (!ctx)
exit(1);
JSValueConst val = JS_ReadObject(ctx, buf, len, /*flags*/0);
JS_FreeValue(ctx, val);
JS_FreeContext(ctx);
JS_FreeRuntime(rt);
return 0;
}

View File

@@ -0,0 +1,653 @@
#ifndef __GETOPT_H__
/**
* DISCLAIMER
* This file is part of the mingw-w64 runtime package.
*
* The mingw-w64 runtime package and its code is distributed in the hope that it
* will be useful but WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESSED OR
* IMPLIED ARE HEREBY DISCLAIMED. This includes but is not limited to
* warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
/*
* Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Sponsored in part by the Defense Advanced Research Projects
* Agency (DARPA) and Air Force Research Laboratory, Air Force
* Materiel Command, USAF, under agreement number F39502-99-1-0512.
*/
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Dieter Baron and Thomas Klausner.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#pragma warning(disable:4996)
#define __GETOPT_H__
/* All the headers include this file. */
#include <crtdefs.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include <windows.h>
#ifdef __cplusplus
extern "C" {
#endif
#define REPLACE_GETOPT /* use this getopt as the system getopt(3) */
#ifdef REPLACE_GETOPT
int opterr = 1; /* if error message should be printed */
int optind = 1; /* index into parent argv vector */
int optopt = '?'; /* character checked for validity */
#undef optreset /* see getopt.h */
#define optreset __mingw_optreset
int optreset; /* reset getopt */
char *optarg; /* argument associated with option */
#endif
//extern int optind; /* index of first non-option in argv */
//extern int optopt; /* single option character, as parsed */
//extern int opterr; /* flag to enable built-in diagnostics... */
// /* (user may set to zero, to suppress) */
//
//extern char *optarg; /* pointer to argument of current option */
#define PRINT_ERROR ((opterr) && (*options != ':'))
#define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */
#define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */
#define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */
/* return values */
#define BADCH (int)'?'
#define BADARG ((*options == ':') ? (int)':' : (int)'?')
#define INORDER (int)1
#ifndef __CYGWIN__
#define __progname __argv[0]
#else
extern char __declspec(dllimport) *__progname;
#endif
#ifdef __CYGWIN__
static char EMSG[] = "";
#else
#define EMSG ""
#endif
struct option /* specification for a long form option... */
{
const char *name; /* option name, without leading hyphens */
int has_arg; /* does it take an argument? */
int *flag; /* where to save its status, or NULL */
int val; /* its associated status value */
};
static int getopt_internal(int, char * const *, const char *,
const struct option *, int *, int);
static int parse_long_options(char * const *, const char *,
const struct option *, int *, int);
static int gcd(int, int);
static void permute_args(int, int, int, char * const *);
static char *place = EMSG; /* option letter processing */
/* XXX: set optreset to 1 rather than these two */
static int nonopt_start = -1; /* first non option argument (for permute) */
static int nonopt_end = -1; /* first option after non options (for permute) */
/* Error messages */
static const char recargchar[] = "option requires an argument -- %c";
static const char recargstring[] = "option requires an argument -- %s";
static const char ambig[] = "ambiguous option -- %.*s";
static const char noarg[] = "option doesn't take an argument -- %.*s";
static const char illoptchar[] = "unknown option -- %c";
static const char illoptstring[] = "unknown option -- %s";
static void
_vwarnx(const char *fmt,va_list ap)
{
(void)fprintf(stderr,"%s: ",__progname);
if (fmt != NULL)
(void)vfprintf(stderr,fmt,ap);
(void)fprintf(stderr,"\n");
}
static void
warnx(const char *fmt,...)
{
va_list ap;
va_start(ap,fmt);
_vwarnx(fmt,ap);
va_end(ap);
}
/*
* Compute the greatest common divisor of a and b.
*/
static int
gcd(int a, int b)
{
int c;
c = a % b;
while (c != 0) {
a = b;
b = c;
c = a % b;
}
return (b);
}
/*
* Exchange the block from nonopt_start to nonopt_end with the block
* from nonopt_end to opt_end (keeping the same order of arguments
* in each block).
*/
static void
permute_args(int panonopt_start, int panonopt_end, int opt_end,
char * const *nargv)
{
int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos;
char *swap;
/*
* compute lengths of blocks and number and size of cycles
*/
nnonopts = panonopt_end - panonopt_start;
nopts = opt_end - panonopt_end;
ncycle = gcd(nnonopts, nopts);
cyclelen = (opt_end - panonopt_start) / ncycle;
for (i = 0; i < ncycle; i++) {
cstart = panonopt_end+i;
pos = cstart;
for (j = 0; j < cyclelen; j++) {
if (pos >= panonopt_end)
pos -= nnonopts;
else
pos += nopts;
swap = nargv[pos];
/* LINTED const cast */
((char **) nargv)[pos] = nargv[cstart];
/* LINTED const cast */
((char **)nargv)[cstart] = swap;
}
}
}
#ifdef REPLACE_GETOPT
/*
* getopt --
* Parse argc/argv argument vector.
*
* [eventually this will replace the BSD getopt]
*/
int
getopt(int nargc, char * const *nargv, const char *options)
{
/*
* We don't pass FLAG_PERMUTE to getopt_internal() since
* the BSD getopt(3) (unlike GNU) has never done this.
*
* Furthermore, since many privileged programs call getopt()
* before dropping privileges it makes sense to keep things
* as simple (and bug-free) as possible.
*/
return (getopt_internal(nargc, nargv, options, NULL, NULL, 0));
}
#endif /* REPLACE_GETOPT */
//extern int getopt(int nargc, char * const *nargv, const char *options);
#ifdef _BSD_SOURCE
/*
* BSD adds the non-standard `optreset' feature, for reinitialisation
* of `getopt' parsing. We support this feature, for applications which
* proclaim their BSD heritage, before including this header; however,
* to maintain portability, developers are advised to avoid it.
*/
# define optreset __mingw_optreset
extern int optreset;
#endif
#ifdef __cplusplus
}
#endif
/*
* POSIX requires the `getopt' API to be specified in `unistd.h';
* thus, `unistd.h' includes this header. However, we do not want
* to expose the `getopt_long' or `getopt_long_only' APIs, when
* included in this manner. Thus, close the standard __GETOPT_H__
* declarations block, and open an additional __GETOPT_LONG_H__
* specific block, only when *not* __UNISTD_H_SOURCED__, in which
* to declare the extended API.
*/
#endif /* !defined(__GETOPT_H__) */
#if !defined(__UNISTD_H_SOURCED__) && !defined(__GETOPT_LONG_H__)
#define __GETOPT_LONG_H__
#ifdef __cplusplus
extern "C" {
#endif
enum /* permitted values for its `has_arg' field... */
{
no_argument = 0, /* option never takes an argument */
required_argument, /* option always requires an argument */
optional_argument /* option may take an argument */
};
/*
* parse_long_options --
* Parse long options in argc/argv argument vector.
* Returns -1 if short_too is set and the option does not match long_options.
*/
static int
parse_long_options(char * const *nargv, const char *options,
const struct option *long_options, int *idx, int short_too)
{
char *current_argv, *has_equal;
size_t current_argv_len;
int i, ambiguous, match;
#define IDENTICAL_INTERPRETATION(_x, _y) \
(long_options[(_x)].has_arg == long_options[(_y)].has_arg && \
long_options[(_x)].flag == long_options[(_y)].flag && \
long_options[(_x)].val == long_options[(_y)].val)
current_argv = place;
match = -1;
ambiguous = 0;
optind++;
if ((has_equal = strchr(current_argv, '=')) != NULL) {
/* argument found (--option=arg) */
current_argv_len = has_equal - current_argv;
has_equal++;
} else
current_argv_len = strlen(current_argv);
for (i = 0; long_options[i].name; i++) {
/* find matching long option */
if (strncmp(current_argv, long_options[i].name,
current_argv_len))
continue;
if (strlen(long_options[i].name) == current_argv_len) {
/* exact match */
match = i;
ambiguous = 0;
break;
}
/*
* If this is a known short option, don't allow
* a partial match of a single character.
*/
if (short_too && current_argv_len == 1)
continue;
if (match == -1) /* partial match */
match = i;
else if (!IDENTICAL_INTERPRETATION(i, match))
ambiguous = 1;
}
if (ambiguous) {
/* ambiguous abbreviation */
if (PRINT_ERROR)
warnx(ambig, (int)current_argv_len,
current_argv);
optopt = 0;
return (BADCH);
}
if (match != -1) { /* option found */
if (long_options[match].has_arg == no_argument
&& has_equal) {
if (PRINT_ERROR)
warnx(noarg, (int)current_argv_len,
current_argv);
/*
* XXX: GNU sets optopt to val regardless of flag
*/
if (long_options[match].flag == NULL)
optopt = long_options[match].val;
else
optopt = 0;
return (BADARG);
}
if (long_options[match].has_arg == required_argument ||
long_options[match].has_arg == optional_argument) {
if (has_equal)
optarg = has_equal;
else if (long_options[match].has_arg ==
required_argument) {
/*
* optional argument doesn't use next nargv
*/
optarg = nargv[optind++];
}
}
if ((long_options[match].has_arg == required_argument)
&& (optarg == NULL)) {
/*
* Missing argument; leading ':' indicates no error
* should be generated.
*/
if (PRINT_ERROR)
warnx(recargstring,
current_argv);
/*
* XXX: GNU sets optopt to val regardless of flag
*/
if (long_options[match].flag == NULL)
optopt = long_options[match].val;
else
optopt = 0;
--optind;
return (BADARG);
}
} else { /* unknown option */
if (short_too) {
--optind;
return (-1);
}
if (PRINT_ERROR)
warnx(illoptstring, current_argv);
optopt = 0;
return (BADCH);
}
if (idx)
*idx = match;
if (long_options[match].flag) {
*long_options[match].flag = long_options[match].val;
return (0);
} else
return (long_options[match].val);
#undef IDENTICAL_INTERPRETATION
}
/*
* getopt_internal --
* Parse argc/argv argument vector. Called by user level routines.
*/
static int
getopt_internal(int nargc, char * const *nargv, const char *options,
const struct option *long_options, int *idx, int flags)
{
char *oli; /* option letter list index */
int optchar, short_too;
static int posixly_correct = -1;
if (options == NULL)
return (-1);
/*
* XXX Some GNU programs (like cvs) set optind to 0 instead of
* XXX using optreset. Work around this braindamage.
*/
if (optind == 0)
optind = optreset = 1;
/*
* Disable GNU extensions if POSIXLY_CORRECT is set or options
* string begins with a '+'.
*
* CV, 2009-12-14: Check POSIXLY_CORRECT anew if optind == 0 or
* optreset != 0 for GNU compatibility.
*/
if (posixly_correct == -1 || optreset != 0)
posixly_correct = (getenv("POSIXLY_CORRECT") != NULL);
if (*options == '-')
flags |= FLAG_ALLARGS;
else if (posixly_correct || *options == '+')
flags &= ~FLAG_PERMUTE;
if (*options == '+' || *options == '-')
options++;
optarg = NULL;
if (optreset)
nonopt_start = nonopt_end = -1;
start:
if (optreset || !*place) { /* update scanning pointer */
optreset = 0;
if (optind >= nargc) { /* end of argument vector */
place = EMSG;
if (nonopt_end != -1) {
/* do permutation, if we have to */
permute_args(nonopt_start, nonopt_end,
optind, nargv);
optind -= nonopt_end - nonopt_start;
}
else if (nonopt_start != -1) {
/*
* If we skipped non-options, set optind
* to the first of them.
*/
optind = nonopt_start;
}
nonopt_start = nonopt_end = -1;
return (-1);
}
if (*(place = nargv[optind]) != '-' ||
(place[1] == '\0' && strchr(options, '-') == NULL)) {
place = EMSG; /* found non-option */
if (flags & FLAG_ALLARGS) {
/*
* GNU extension:
* return non-option as argument to option 1
*/
optarg = nargv[optind++];
return (INORDER);
}
if (!(flags & FLAG_PERMUTE)) {
/*
* If no permutation wanted, stop parsing
* at first non-option.
*/
return (-1);
}
/* do permutation */
if (nonopt_start == -1)
nonopt_start = optind;
else if (nonopt_end != -1) {
permute_args(nonopt_start, nonopt_end,
optind, nargv);
nonopt_start = optind -
(nonopt_end - nonopt_start);
nonopt_end = -1;
}
optind++;
/* process next argument */
goto start;
}
if (nonopt_start != -1 && nonopt_end == -1)
nonopt_end = optind;
/*
* If we have "-" do nothing, if "--" we are done.
*/
if (place[1] != '\0' && *++place == '-' && place[1] == '\0') {
optind++;
place = EMSG;
/*
* We found an option (--), so if we skipped
* non-options, we have to permute.
*/
if (nonopt_end != -1) {
permute_args(nonopt_start, nonopt_end,
optind, nargv);
optind -= nonopt_end - nonopt_start;
}
nonopt_start = nonopt_end = -1;
return (-1);
}
}
/*
* Check long options if:
* 1) we were passed some
* 2) the arg is not just "-"
* 3) either the arg starts with -- we are getopt_long_only()
*/
if (long_options != NULL && place != nargv[optind] &&
(*place == '-' || (flags & FLAG_LONGONLY))) {
short_too = 0;
if (*place == '-')
place++; /* --foo long option */
else if (*place != ':' && strchr(options, *place) != NULL)
short_too = 1; /* could be short option too */
optchar = parse_long_options(nargv, options, long_options,
idx, short_too);
if (optchar != -1) {
place = EMSG;
return (optchar);
}
}
if ((optchar = (int)*place++) == (int)':' ||
(optchar == (int)'-' && *place != '\0') ||
(oli = (char*)strchr(options, optchar)) == NULL) {
/*
* If the user specified "-" and '-' isn't listed in
* options, return -1 (non-option) as per POSIX.
* Otherwise, it is an unknown option character (or ':').
*/
if (optchar == (int)'-' && *place == '\0')
return (-1);
if (!*place)
++optind;
if (PRINT_ERROR)
warnx(illoptchar, optchar);
optopt = optchar;
return (BADCH);
}
if (long_options != NULL && optchar == 'W' && oli[1] == ';') {
/* -W long-option */
if (*place) /* no space */
/* NOTHING */;
else if (++optind >= nargc) { /* no arg */
place = EMSG;
if (PRINT_ERROR)
warnx(recargchar, optchar);
optopt = optchar;
return (BADARG);
} else /* white space */
place = nargv[optind];
optchar = parse_long_options(nargv, options, long_options,
idx, 0);
place = EMSG;
return (optchar);
}
if (*++oli != ':') { /* doesn't take argument */
if (!*place)
++optind;
} else { /* takes (optional) argument */
optarg = NULL;
if (*place) /* no white space */
optarg = place;
else if (oli[1] != ':') { /* arg not optional */
if (++optind >= nargc) { /* no arg */
place = EMSG;
if (PRINT_ERROR)
warnx(recargchar, optchar);
optopt = optchar;
return (BADARG);
} else
optarg = nargv[optind];
}
place = EMSG;
++optind;
}
/* dump back option letter */
return (optchar);
}
/*
* getopt_long --
* Parse argc/argv argument vector.
*/
int
getopt_long(int nargc, char * const *nargv, const char *options,
const struct option *long_options, int *idx)
{
return (getopt_internal(nargc, nargv, options, long_options, idx,
FLAG_PERMUTE));
}
/*
* getopt_long_only --
* Parse argc/argv argument vector.
*/
int
getopt_long_only(int nargc, char * const *nargv, const char *options,
const struct option *long_options, int *idx)
{
return (getopt_internal(nargc, nargv, options, long_options, idx,
FLAG_PERMUTE|FLAG_LONGONLY));
}
//extern int getopt_long(int nargc, char * const *nargv, const char *options,
// const struct option *long_options, int *idx);
//extern int getopt_long_only(int nargc, char * const *nargv, const char *options,
// const struct option *long_options, int *idx);
/*
* Previous MinGW implementation had...
*/
#ifndef HAVE_DECL_GETOPT
/*
* ...for the long form API only; keep this for compatibility.
*/
# define HAVE_DECL_GETOPT 1
#endif
#ifdef __cplusplus
}
#endif
#endif /* !defined(__UNISTD_H_SOURCED__) && !defined(__GETOPT_LONG_H__) */

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
/* /*
* Tiny arbitrary precision floating point library * Tiny arbitrary precision floating point library
* *
* Copyright (c) 2017-2021 Fabrice Bellard * Copyright (c) 2017-2021 Fabrice Bellard
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy * Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -27,7 +27,11 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#if defined(__SIZEOF_INT128__) && (INTPTR_MAX >= INT64_MAX) #ifdef __cplusplus
extern "C" {
#endif
#if INTPTR_MAX >= INT64_MAX && !defined(_WIN32) && !defined(__TINYC__)
#define LIMB_LOG2_BITS 6 #define LIMB_LOG2_BITS 6
#else #else
#define LIMB_LOG2_BITS 5 #define LIMB_LOG2_BITS 5
@@ -36,8 +40,10 @@
#define LIMB_BITS (1 << LIMB_LOG2_BITS) #define LIMB_BITS (1 << LIMB_LOG2_BITS)
#if LIMB_BITS == 64 #if LIMB_BITS == 64
typedef __int128 int128_t; #ifndef INT128_MAX
typedef unsigned __int128 uint128_t; __extension__ typedef __int128 int128_t;
__extension__ typedef unsigned __int128 uint128_t;
#endif
typedef int64_t slimb_t; typedef int64_t slimb_t;
typedef uint64_t limb_t; typedef uint64_t limb_t;
typedef uint128_t dlimb_t; typedef uint128_t dlimb_t;
@@ -171,7 +177,7 @@ static inline bf_flags_t bf_set_exp_bits(int n)
#define BF_ST_UNDERFLOW (1 << 3) #define BF_ST_UNDERFLOW (1 << 3)
#define BF_ST_INEXACT (1 << 4) #define BF_ST_INEXACT (1 << 4)
/* indicate that a memory allocation error occured. NaN is returned */ /* indicate that a memory allocation error occured. NaN is returned */
#define BF_ST_MEM_ERROR (1 << 5) #define BF_ST_MEM_ERROR (1 << 5)
#define BF_RADIX_MAX 36 /* maximum radix for bf_atof() and bf_ftoa() */ #define BF_RADIX_MAX 36 /* maximum radix for bf_atof() and bf_ftoa() */
@@ -284,7 +290,7 @@ int bf_sub(bf_t *r, const bf_t *a, const bf_t *b, limb_t prec, bf_flags_t flags)
int bf_add_si(bf_t *r, const bf_t *a, int64_t b1, limb_t prec, bf_flags_t flags); int bf_add_si(bf_t *r, const bf_t *a, int64_t b1, limb_t prec, bf_flags_t flags);
int bf_mul(bf_t *r, const bf_t *a, const bf_t *b, limb_t prec, bf_flags_t flags); int bf_mul(bf_t *r, const bf_t *a, const bf_t *b, limb_t prec, bf_flags_t flags);
int bf_mul_ui(bf_t *r, const bf_t *a, uint64_t b1, limb_t prec, bf_flags_t flags); int bf_mul_ui(bf_t *r, const bf_t *a, uint64_t b1, limb_t prec, bf_flags_t flags);
int bf_mul_si(bf_t *r, const bf_t *a, int64_t b1, limb_t prec, int bf_mul_si(bf_t *r, const bf_t *a, int64_t b1, limb_t prec,
bf_flags_t flags); bf_flags_t flags);
int bf_mul_2exp(bf_t *r, slimb_t e, limb_t prec, bf_flags_t flags); int bf_mul_2exp(bf_t *r, slimb_t e, limb_t prec, bf_flags_t flags);
int bf_div(bf_t *r, const bf_t *a, const bf_t *b, limb_t prec, bf_flags_t flags); int bf_div(bf_t *r, const bf_t *a, const bf_t *b, limb_t prec, bf_flags_t flags);
@@ -341,12 +347,12 @@ int bf_mul_pow_radix(bf_t *r, const bf_t *T, limb_t radix,
/* fractional format: prec digits after the decimal point rounded with /* fractional format: prec digits after the decimal point rounded with
(flags & BF_RND_MASK) */ (flags & BF_RND_MASK) */
#define BF_FTOA_FORMAT_FRAC (1 << 16) #define BF_FTOA_FORMAT_FRAC (1 << 16)
/* free format: /* free format:
For binary radices with bf_ftoa() and for bfdec_ftoa(): use the minimum For binary radices with bf_ftoa() and for bfdec_ftoa(): use the minimum
number of digits to represent 'a'. The precision and the rounding number of digits to represent 'a'. The precision and the rounding
mode are ignored. mode are ignored.
For the non binary radices with bf_ftoa(): use as many digits as For the non binary radices with bf_ftoa(): use as many digits as
necessary so that bf_atof() return the same number when using necessary so that bf_atof() return the same number when using
precision 'prec', rounding to nearest and the subnormal precision 'prec', rounding to nearest and the subnormal
@@ -373,7 +379,7 @@ char *bf_ftoa(size_t *plen, const bf_t *a, int radix, limb_t prec,
bf_flags_t flags); bf_flags_t flags);
/* modulo 2^n instead of saturation. NaN and infinity return 0 */ /* modulo 2^n instead of saturation. NaN and infinity return 0 */
#define BF_GET_INT_MOD (1 << 0) #define BF_GET_INT_MOD (1 << 0)
int bf_get_int32(int *pres, const bf_t *a, int flags); int bf_get_int32(int *pres, const bf_t *a, int flags);
int bf_get_int64(int64_t *pres, const bf_t *a, int flags); int bf_get_int64(int64_t *pres, const bf_t *a, int flags);
int bf_get_uint64(uint64_t *pres, const bf_t *a); int bf_get_uint64(uint64_t *pres, const bf_t *a);
@@ -387,10 +393,10 @@ int bf_normalize_and_round(bf_t *r, limb_t prec1, bf_flags_t flags);
int bf_can_round(const bf_t *a, slimb_t prec, bf_rnd_t rnd_mode, slimb_t k); int bf_can_round(const bf_t *a, slimb_t prec, bf_rnd_t rnd_mode, slimb_t k);
slimb_t bf_mul_log2_radix(slimb_t a1, unsigned int radix, int is_inv, slimb_t bf_mul_log2_radix(slimb_t a1, unsigned int radix, int is_inv,
int is_ceil1); int is_ceil1);
int mp_mul(bf_context_t *s, limb_t *result, int mp_mul(bf_context_t *s, limb_t *result,
const limb_t *op1, limb_t op1_size, const limb_t *op1, limb_t op1_size,
const limb_t *op2, limb_t op2_size); const limb_t *op2, limb_t op2_size);
limb_t mp_add(limb_t *res, const limb_t *op1, const limb_t *op2, limb_t mp_add(limb_t *res, const limb_t *op1, const limb_t *op2,
limb_t n, limb_t carry); limb_t n, limb_t carry);
limb_t mp_add_ui(limb_t *tab, limb_t b, size_t n); limb_t mp_add_ui(limb_t *tab, limb_t b, size_t n);
int mp_sqrtrem(bf_context_t *s, limb_t *tabs, limb_t *taba, limb_t n); int mp_sqrtrem(bf_context_t *s, limb_t *tabs, limb_t *taba, limb_t n);
@@ -532,4 +538,8 @@ static inline int bfdec_resize(bfdec_t *r, limb_t len)
} }
int bfdec_normalize_and_round(bfdec_t *r, limb_t prec1, bf_flags_t flags); int bfdec_normalize_and_round(bfdec_t *r, limb_t prec1, bf_flags_t flags);
#ifdef __cplusplus
} /* extern "C" { */
#endif
#endif /* LIBBF_H */ #endif /* LIBBF_H */

View File

@@ -25,7 +25,8 @@
#ifdef DEF #ifdef DEF
DEF(invalid, 1) /* never used */ DEF(invalid, 1) /* never used */
DEF(char, 3) DEF(char8, 2) /* 7 bits in fact */
DEF(char16, 3)
DEF(char32, 5) DEF(char32, 5)
DEF(dot, 1) DEF(dot, 1)
DEF(any, 1) /* same as dot but match any character including line terminator */ DEF(any, 1) /* same as dot but match any character including line terminator */

View File

@@ -60,15 +60,17 @@ typedef enum {
#define TMP_BUF_SIZE 128 #define TMP_BUF_SIZE 128
// invariant: is_unicode ^ unicode_sets (or neither, but not both)
typedef struct { typedef struct {
DynBuf byte_code; DynBuf byte_code;
const uint8_t *buf_ptr; const uint8_t *buf_ptr;
const uint8_t *buf_end; const uint8_t *buf_end;
const uint8_t *buf_start; const uint8_t *buf_start;
int re_flags; int re_flags;
BOOL is_unicode; bool is_unicode;
BOOL ignore_case; bool unicode_sets;
BOOL dotall; bool ignore_case;
bool dotall;
int capture_count; int capture_count;
int total_capture_count; /* -1 = not computed yet */ int total_capture_count; /* -1 = not computed yet */
int has_named_captures; /* -1 = don't know, 0 = no, 1 = yes */ int has_named_captures; /* -1 = don't know, 0 = no, 1 = yes */
@@ -98,13 +100,13 @@ static const REOpCode reopcode_info[REOP_COUNT] = {
}; };
#define RE_HEADER_FLAGS 0 #define RE_HEADER_FLAGS 0
#define RE_HEADER_CAPTURE_COUNT 1 #define RE_HEADER_CAPTURE_COUNT 2
#define RE_HEADER_STACK_SIZE 2 #define RE_HEADER_STACK_SIZE 3
#define RE_HEADER_BYTECODE_LEN 3 #define RE_HEADER_BYTECODE_LEN 4
#define RE_HEADER_LEN 7 #define RE_HEADER_LEN 8
static inline int is_digit(int c) { static inline int lre_is_digit(int c) {
return c >= '0' && c <= '9'; return c >= '0' && c <= '9';
} }
@@ -141,19 +143,19 @@ static const uint16_t char_range_s[] = {
0xFEFF, 0xFEFF + 1, 0xFEFF, 0xFEFF + 1,
}; };
BOOL lre_is_space(int c) bool lre_is_space(int c)
{ {
int i, n, low, high; int i, n, low, high;
n = (countof(char_range_s) - 1) / 2; n = (countof(char_range_s) - 1) / 2;
for(i = 0; i < n; i++) { for(i = 0; i < n; i++) {
low = char_range_s[2 * i + 1]; low = char_range_s[2 * i + 1];
if (c < low) if (c < low)
return FALSE; return false;
high = char_range_s[2 * i + 2]; high = char_range_s[2 * i + 2];
if (c < high) if (c < high)
return TRUE; return true;
} }
return FALSE; return false;
} }
uint32_t const lre_id_start_table_ascii[4] = { uint32_t const lre_id_start_table_ascii[4] = {
@@ -194,7 +196,7 @@ static const uint16_t *char_range_table[] = {
static int cr_init_char_range(REParseState *s, CharRange *cr, uint32_t c) static int cr_init_char_range(REParseState *s, CharRange *cr, uint32_t c)
{ {
BOOL invert; bool invert;
const uint16_t *c_pt; const uint16_t *c_pt;
int len, i; int len, i;
@@ -261,15 +263,15 @@ static __maybe_unused void lre_dump_bytecode(const uint8_t *buf,
} }
printf("%s", reopcode_info[opcode].name); printf("%s", reopcode_info[opcode].name);
switch(opcode) { switch(opcode) {
case REOP_char: case REOP_char8:
val = get_u8(buf + pos + 1);
goto printchar;
case REOP_char16:
val = get_u16(buf + pos + 1); val = get_u16(buf + pos + 1);
if (val >= ' ' && val <= 126) goto printchar;
printf(" '%c'", val);
else
printf(" 0x%04x", val);
break;
case REOP_char32: case REOP_char32:
val = get_u32(buf + pos + 1); val = get_u32(buf + pos + 1);
printchar:
if (val >= ' ' && val <= 126) if (val >= ' ' && val <= 126)
printf(" '%c'", val); printf(" '%c'", val);
else else
@@ -372,7 +374,7 @@ static void re_emit_op_u16(REParseState *s, int op, uint32_t val)
dbuf_put_u16(&s->byte_code, val); dbuf_put_u16(&s->byte_code, val);
} }
static int __attribute__((format(printf, 2, 3))) re_parse_error(REParseState *s, const char *fmt, ...) static int JS_PRINTF_FORMAT_ATTR(2, 3) re_parse_error(REParseState *s, const char *fmt, ...)
{ {
va_list ap; va_list ap;
va_start(ap, fmt); va_start(ap, fmt);
@@ -388,7 +390,7 @@ static int re_parse_out_of_memory(REParseState *s)
/* If allow_overflow is false, return -1 in case of /* If allow_overflow is false, return -1 in case of
overflow. Otherwise return INT32_MAX. */ overflow. Otherwise return INT32_MAX. */
static int parse_digits(const uint8_t **pp, BOOL allow_overflow) static int parse_digits(const uint8_t **pp, bool allow_overflow)
{ {
const uint8_t *p; const uint8_t *p;
uint64_t v; uint64_t v;
@@ -519,7 +521,7 @@ int lre_parse_escape(const uint8_t **pp, int allow_utf16)
c -= '0'; c -= '0';
if (allow_utf16 == 2) { if (allow_utf16 == 2) {
/* only accept \0 not followed by digit */ /* only accept \0 not followed by digit */
if (c != 0 || is_digit(*p)) if (c != 0 || lre_is_digit(*p))
return -1; return -1;
} else { } else {
/* parse a legacy octal sequence */ /* parse a legacy octal sequence */
@@ -545,9 +547,8 @@ int lre_parse_escape(const uint8_t **pp, int allow_utf16)
return c; return c;
} }
#ifdef CONFIG_ALL_UNICODE
/* XXX: we use the same chars for name and value */ /* XXX: we use the same chars for name and value */
static BOOL is_unicode_char(int c) static bool is_unicode_char(int c)
{ {
return ((c >= '0' && c <= '9') || return ((c >= '0' && c <= '9') ||
(c >= 'A' && c <= 'Z') || (c >= 'A' && c <= 'Z') ||
@@ -556,12 +557,12 @@ static BOOL is_unicode_char(int c)
} }
static int parse_unicode_property(REParseState *s, CharRange *cr, static int parse_unicode_property(REParseState *s, CharRange *cr,
const uint8_t **pp, BOOL is_inv) const uint8_t **pp, bool is_inv)
{ {
const uint8_t *p; const uint8_t *p;
char name[64], value[64]; char name[64], value[64];
char *q; char *q;
BOOL script_ext; bool script_ext;
int ret; int ret;
p = *pp; p = *pp;
@@ -591,10 +592,10 @@ static int parse_unicode_property(REParseState *s, CharRange *cr,
// printf("name=%s value=%s\n", name, value); // printf("name=%s value=%s\n", name, value);
if (!strcmp(name, "Script") || !strcmp(name, "sc")) { if (!strcmp(name, "Script") || !strcmp(name, "sc")) {
script_ext = FALSE; script_ext = false;
goto do_script; goto do_script;
} else if (!strcmp(name, "Script_Extensions") || !strcmp(name, "scx")) { } else if (!strcmp(name, "Script_Extensions") || !strcmp(name, "scx")) {
script_ext = TRUE; script_ext = true;
do_script: do_script:
cr_init(cr, s->opaque, lre_realloc); cr_init(cr, s->opaque, lre_realloc);
ret = unicode_script(cr, value, script_ext); ret = unicode_script(cr, value, script_ext);
@@ -648,15 +649,14 @@ static int parse_unicode_property(REParseState *s, CharRange *cr,
out_of_memory: out_of_memory:
return re_parse_out_of_memory(s); return re_parse_out_of_memory(s);
} }
#endif /* CONFIG_ALL_UNICODE */
/* return -1 if error otherwise the character or a class range /* return -1 if error otherwise the character or a class range
(CLASS_RANGE_BASE). In case of class range, 'cr' is (CLASS_RANGE_BASE). In case of class range, 'cr' is
initialized. Otherwise, it is ignored. */ initialized. Otherwise, it is ignored. */
static int get_class_atom(REParseState *s, CharRange *cr, static int get_class_atom(REParseState *s, CharRange *cr,
const uint8_t **pp, BOOL inclass) const uint8_t **pp, bool inclass)
{ {
const uint8_t *p; const uint8_t *p, *p_next;
uint32_t c; uint32_t c;
int ret; int ret;
@@ -708,7 +708,6 @@ static int get_class_atom(REParseState *s, CharRange *cr,
c = '\\'; c = '\\';
} }
break; break;
#ifdef CONFIG_ALL_UNICODE
case 'p': case 'p':
case 'P': case 'P':
if (s->is_unicode) { if (s->is_unicode) {
@@ -718,7 +717,6 @@ static int get_class_atom(REParseState *s, CharRange *cr,
break; break;
} }
/* fall thru */ /* fall thru */
#endif
default: default:
p--; p--;
ret = lre_parse_escape(&p, s->is_unicode * 2); ret = lre_parse_escape(&p, s->is_unicode * 2);
@@ -729,6 +727,9 @@ static int get_class_atom(REParseState *s, CharRange *cr,
/* always valid to escape these characters */ /* always valid to escape these characters */
goto normal_char; goto normal_char;
} else if (s->is_unicode) { } else if (s->is_unicode) {
// special case: allowed inside [] but not outside
if (ret == -2 && *p == '-' && inclass)
goto normal_char;
invalid_escape: invalid_escape:
return re_parse_error(s, "invalid escape sequence in regular expression"); return re_parse_error(s, "invalid escape sequence in regular expression");
} else { } else {
@@ -747,15 +748,18 @@ static int get_class_atom(REParseState *s, CharRange *cr,
/* fall thru */ /* fall thru */
default: default:
normal_char: normal_char:
/* normal char */ p++;
if (c >= 128) { if (c >= 0x80) {
c = unicode_from_utf8(p, UTF8_CHAR_LEN_MAX, &p); c = utf8_decode(p - 1, &p_next);
if ((unsigned)c > 0xffff && !s->is_unicode) { if (p_next == p)
/* XXX: should handle non BMP-1 code points */ return re_parse_error(s, "invalid UTF-8 sequence");
p = p_next;
if (c > 0xFFFF && !s->is_unicode) {
// TODO(chqrlie): should handle non BMP-1 code points in
// the calling function and no require the source string
// to be CESU-8 encoded if not s->is_unicode
return re_parse_error(s, "malformed unicode char"); return re_parse_error(s, "malformed unicode char");
} }
} else {
p++;
} }
break; break;
} }
@@ -801,30 +805,56 @@ static int re_emit_range(REParseState *s, const CharRange *cr)
return 0; return 0;
} }
// s->unicode turns patterns like []] into syntax errors
// s->unicode_sets turns more patterns into errors, like [a-] or [[]
static int re_parse_char_class(REParseState *s, const uint8_t **pp) static int re_parse_char_class(REParseState *s, const uint8_t **pp)
{ {
const uint8_t *p; const uint8_t *p;
uint32_t c1, c2; uint32_t c1, c2;
CharRange cr_s, *cr = &cr_s; CharRange cr_s, *cr = &cr_s;
CharRange cr1_s, *cr1 = &cr1_s; CharRange cr1_s, *cr1 = &cr1_s;
BOOL invert; bool invert;
cr_init(cr, s->opaque, lre_realloc); cr_init(cr, s->opaque, lre_realloc);
p = *pp; p = *pp;
p++; /* skip '[' */ p++; /* skip '[' */
invert = FALSE; if (s->unicode_sets) {
static const char verboten[] =
"()[{}/-|" "\0"
"&&!!##$$%%**++,,..::;;<<==>>??@@``~~" "\0"
"^^^_^^";
const char *s = verboten;
int n = 1;
do {
if (!memcmp(s, p, n))
if (p[n] == ']')
goto invalid_class_range;
s += n;
if (!*s) {
s++;
n++;
}
} while (n < 4);
}
invert = false;
if (*p == '^') { if (*p == '^') {
p++; p++;
invert = TRUE; invert = true;
} }
for(;;) { for(;;) {
if (*p == ']') if (*p == ']')
break; break;
c1 = get_class_atom(s, cr1, &p, TRUE); c1 = get_class_atom(s, cr1, &p, true);
if ((int)c1 < 0) if ((int)c1 < 0)
goto fail; goto fail;
if (*p == '-' && p[1] == ']' && s->unicode_sets) {
if (c1 >= CLASS_RANGE_BASE)
cr_free(cr1);
goto invalid_class_range;
}
if (*p == '-' && p[1] != ']') { if (*p == '-' && p[1] != ']') {
const uint8_t *p0 = p + 1; const uint8_t *p0 = p + 1;
if (c1 >= CLASS_RANGE_BASE) { if (c1 >= CLASS_RANGE_BASE) {
@@ -835,7 +865,7 @@ static int re_parse_char_class(REParseState *s, const uint8_t **pp)
/* Annex B: match '-' character */ /* Annex B: match '-' character */
goto class_atom; goto class_atom;
} }
c2 = get_class_atom(s, cr1, &p0, TRUE); c2 = get_class_atom(s, cr1, &p0, true);
if ((int)c2 < 0) if ((int)c2 < 0)
goto fail; goto fail;
if (c2 >= CLASS_RANGE_BASE) { if (c2 >= CLASS_RANGE_BASE) {
@@ -893,14 +923,15 @@ static int re_parse_char_class(REParseState *s, const uint8_t **pp)
- true if the opcodes may not advance the char pointer - true if the opcodes may not advance the char pointer
- false if the opcodes always advance the char pointer - false if the opcodes always advance the char pointer
*/ */
static BOOL re_need_check_advance(const uint8_t *bc_buf, int bc_buf_len) static bool re_need_check_advance(const uint8_t *bc_buf, int bc_buf_len)
{ {
int pos, opcode, len; int pos, opcode, len;
uint32_t val; uint32_t val;
BOOL ret; bool ret;
ret = TRUE; ret = true;
pos = 0; pos = 0;
while (pos < bc_buf_len) { while (pos < bc_buf_len) {
opcode = bc_buf[pos]; opcode = bc_buf[pos];
len = reopcode_info[opcode].size; len = reopcode_info[opcode].size;
@@ -913,12 +944,13 @@ static BOOL re_need_check_advance(const uint8_t *bc_buf, int bc_buf_len)
val = get_u16(bc_buf + pos + 1); val = get_u16(bc_buf + pos + 1);
len += val * 8; len += val * 8;
goto simple_char; goto simple_char;
case REOP_char:
case REOP_char32: case REOP_char32:
case REOP_char16:
case REOP_char8:
case REOP_dot: case REOP_dot:
case REOP_any: case REOP_any:
simple_char: simple_char:
ret = FALSE; ret = false;
break; break;
case REOP_line_start: case REOP_line_start:
case REOP_line_end: case REOP_line_end:
@@ -937,8 +969,8 @@ static BOOL re_need_check_advance(const uint8_t *bc_buf, int bc_buf_len)
case REOP_backward_back_reference: case REOP_backward_back_reference:
break; break;
default: default:
/* safe behavior: we cannot predict the outcome */ /* safe behvior: we cannot predict the outcome */
return TRUE; return true;
} }
pos += len; pos += len;
} }
@@ -966,8 +998,9 @@ static int re_is_simple_quantifier(const uint8_t *bc_buf, int bc_buf_len)
val = get_u16(bc_buf + pos + 1); val = get_u16(bc_buf + pos + 1);
len += val * 8; len += val * 8;
goto simple_char; goto simple_char;
case REOP_char:
case REOP_char32: case REOP_char32:
case REOP_char16:
case REOP_char8:
case REOP_dot: case REOP_dot:
case REOP_any: case REOP_any:
simple_char: simple_char:
@@ -989,35 +1022,35 @@ static int re_is_simple_quantifier(const uint8_t *bc_buf, int bc_buf_len)
/* '*pp' is the first char after '<' */ /* '*pp' is the first char after '<' */
static int re_parse_group_name(char *buf, int buf_size, const uint8_t **pp) static int re_parse_group_name(char *buf, int buf_size, const uint8_t **pp)
{ {
const uint8_t *p, *p1; const uint8_t *p, *p_next;
uint32_t c, d; uint32_t c, d;
char *q; char *q;
p = *pp; p = *pp;
q = buf; q = buf;
for(;;) { for(;;) {
c = *p; c = *p++;
if (c == '\\') { if (c == '\\') {
p++;
if (*p != 'u') if (*p != 'u')
return -1; return -1;
c = lre_parse_escape(&p, 2); // accept surrogate pairs c = lre_parse_escape(&p, 2); // accept surrogate pairs
if ((int)c < 0)
return -1;
} else if (c == '>') { } else if (c == '>') {
break; break;
} else if (c >= 128) { } else if (c >= 0x80) {
c = unicode_from_utf8(p, UTF8_CHAR_LEN_MAX, &p); c = utf8_decode(p - 1, &p_next);
if (p_next == p)
return -1;
p = p_next;
if (is_hi_surrogate(c)) { if (is_hi_surrogate(c)) {
d = unicode_from_utf8(p, UTF8_CHAR_LEN_MAX, &p1); d = utf8_decode(p, &p_next);
if (is_lo_surrogate(d)) { if (is_lo_surrogate(d)) {
c = from_surrogate(c, d); c = from_surrogate(c, d);
p = p1; p = p_next;
} }
} }
} else {
p++;
} }
if (c > 0x10FFFF)
return -1;
if (q == buf) { if (q == buf) {
if (!lre_js_is_ident_first(c)) if (!lre_js_is_ident_first(c))
return -1; return -1;
@@ -1027,16 +1060,15 @@ static int re_parse_group_name(char *buf, int buf_size, const uint8_t **pp)
} }
if ((q - buf + UTF8_CHAR_LEN_MAX + 1) > buf_size) if ((q - buf + UTF8_CHAR_LEN_MAX + 1) > buf_size)
return -1; return -1;
if (c < 128) { if (c < 0x80) {
*q++ = c; *q++ = c;
} else { } else {
q += unicode_to_utf8((uint8_t*)q, c); q += utf8_encode((uint8_t*)q, c);
} }
} }
if (q == buf) if (q == buf)
return -1; return -1;
*q = '\0'; *q = '\0';
p++;
*pp = p; *pp = p;
return 0; return 0;
} }
@@ -1104,7 +1136,7 @@ static int re_count_captures(REParseState *s)
return s->total_capture_count; return s->total_capture_count;
} }
static BOOL re_has_named_captures(REParseState *s) static bool re_has_named_captures(REParseState *s)
{ {
if (s->has_named_captures < 0) if (s->has_named_captures < 0)
re_count_captures(s); re_count_captures(s);
@@ -1132,13 +1164,13 @@ static int find_group_name(REParseState *s, const char *name)
return -1; return -1;
} }
static int re_parse_disjunction(REParseState *s, BOOL is_backward_dir); static int re_parse_disjunction(REParseState *s, bool is_backward_dir);
static int re_parse_term(REParseState *s, BOOL is_backward_dir) static int re_parse_term(REParseState *s, bool is_backward_dir)
{ {
const uint8_t *p; const uint8_t *p;
int c, last_atom_start, quant_min, quant_max, last_capture_count; int c, last_atom_start, quant_min, quant_max, last_capture_count;
BOOL greedy, add_zero_advance_check, is_neg, is_backward_lookahead; bool greedy, add_zero_advance_check, is_neg, is_backward_lookahead;
CharRange cr_s, *cr = &cr_s; CharRange cr_s, *cr = &cr_s;
last_atom_start = -1; last_atom_start = -1;
@@ -1167,18 +1199,18 @@ static int re_parse_term(REParseState *s, BOOL is_backward_dir)
case '{': case '{':
if (s->is_unicode) { if (s->is_unicode) {
return re_parse_error(s, "syntax error"); return re_parse_error(s, "syntax error");
} else if (!is_digit(p[1])) { } else if (!lre_is_digit(p[1])) {
/* Annex B: we accept '{' not followed by digits as a /* Annex B: we accept '{' not followed by digits as a
normal atom */ normal atom */
goto parse_class_atom; goto parse_class_atom;
} else { } else {
const uint8_t *p1 = p + 1; const uint8_t *p1 = p + 1;
/* Annex B: error if it is like a repetition count */ /* Annex B: error if it is like a repetition count */
parse_digits(&p1, TRUE); parse_digits(&p1, true);
if (*p1 == ',') { if (*p1 == ',') {
p1++; p1++;
if (is_digit(*p1)) { if (lre_is_digit(*p1)) {
parse_digits(&p1, TRUE); parse_digits(&p1, true);
} }
} }
if (*p1 != '}') { if (*p1 != '}') {
@@ -1204,14 +1236,14 @@ static int re_parse_term(REParseState *s, BOOL is_backward_dir)
return -1; return -1;
} else if ((p[2] == '=' || p[2] == '!')) { } else if ((p[2] == '=' || p[2] == '!')) {
is_neg = (p[2] == '!'); is_neg = (p[2] == '!');
is_backward_lookahead = FALSE; is_backward_lookahead = false;
p += 3; p += 3;
goto lookahead; goto lookahead;
} else if (p[2] == '<' && } else if (p[2] == '<' &&
(p[3] == '=' || p[3] == '!')) { (p[3] == '=' || p[3] == '!')) {
int pos; int pos;
is_neg = (p[3] == '!'); is_neg = (p[3] == '!');
is_backward_lookahead = TRUE; is_backward_lookahead = true;
p += 4; p += 4;
/* lookahead */ /* lookahead */
lookahead: lookahead:
@@ -1325,7 +1357,7 @@ static int re_parse_term(REParseState *s, BOOL is_backward_dir)
p += 2; p += 2;
c = 0; c = 0;
if (s->is_unicode) { if (s->is_unicode) {
if (is_digit(*p)) { if (lre_is_digit(*p)) {
return re_parse_error(s, "invalid decimal escape in regular expression"); return re_parse_error(s, "invalid decimal escape in regular expression");
} }
} else { } else {
@@ -1344,7 +1376,7 @@ static int re_parse_term(REParseState *s, BOOL is_backward_dir)
{ {
const uint8_t *q = ++p; const uint8_t *q = ++p;
c = parse_digits(&p, FALSE); c = parse_digits(&p, false);
if (c < 0 || (c >= s->capture_count && c >= re_count_captures(s))) { if (c < 0 || (c >= s->capture_count && c >= re_count_captures(s))) {
if (!s->is_unicode) { if (!s->is_unicode) {
/* Annex B.1.4: accept legacy octal */ /* Annex B.1.4: accept legacy octal */
@@ -1393,7 +1425,7 @@ static int re_parse_term(REParseState *s, BOOL is_backward_dir)
goto parse_class_atom; goto parse_class_atom;
default: default:
parse_class_atom: parse_class_atom:
c = get_class_atom(s, cr, &p, FALSE); c = get_class_atom(s, cr, &p, false);
if ((int)c < 0) if ((int)c < 0)
return -1; return -1;
normal_char: normal_char:
@@ -1411,8 +1443,10 @@ static int re_parse_term(REParseState *s, BOOL is_backward_dir)
} else { } else {
if (s->ignore_case) if (s->ignore_case)
c = lre_canonicalize(c, s->is_unicode); c = lre_canonicalize(c, s->is_unicode);
if (c <= 0xffff) if (c <= 0x7f)
re_emit_op_u16(s, REOP_char, c); re_emit_op_u8(s, REOP_char8, c);
else if (c <= 0xffff)
re_emit_op_u16(s, REOP_char16, c);
else else
re_emit_op_u32(s, REOP_char32, c); re_emit_op_u32(s, REOP_char32, c);
} }
@@ -1445,18 +1479,18 @@ static int re_parse_term(REParseState *s, BOOL is_backward_dir)
const uint8_t *p1 = p; const uint8_t *p1 = p;
/* As an extension (see ES6 annex B), we accept '{' not /* As an extension (see ES6 annex B), we accept '{' not
followed by digits as a normal atom */ followed by digits as a normal atom */
if (!is_digit(p[1])) { if (!lre_is_digit(p[1])) {
if (s->is_unicode) if (s->is_unicode)
goto invalid_quant_count; goto invalid_quant_count;
break; break;
} }
p++; p++;
quant_min = parse_digits(&p, TRUE); quant_min = parse_digits(&p, true);
quant_max = quant_min; quant_max = quant_min;
if (*p == ',') { if (*p == ',') {
p++; p++;
if (is_digit(*p)) { if (lre_is_digit(*p)) {
quant_max = parse_digits(&p, TRUE); quant_max = parse_digits(&p, true);
if (quant_max < quant_min) { if (quant_max < quant_min) {
invalid_quant_count: invalid_quant_count:
return re_parse_error(s, "invalid repetition count"); return re_parse_error(s, "invalid repetition count");
@@ -1474,10 +1508,10 @@ static int re_parse_term(REParseState *s, BOOL is_backward_dir)
return -1; return -1;
} }
quantifier: quantifier:
greedy = TRUE; greedy = true;
if (*p == '?') { if (*p == '?') {
p++; p++;
greedy = FALSE; greedy = false;
} }
if (last_atom_start < 0) { if (last_atom_start < 0) {
return re_parse_error(s, "nothing to repeat"); return re_parse_error(s, "nothing to repeat");
@@ -1513,15 +1547,13 @@ static int re_parse_term(REParseState *s, BOOL is_backward_dir)
if (dbuf_error(&s->byte_code)) if (dbuf_error(&s->byte_code))
goto out_of_memory; goto out_of_memory;
/* the spec tells that if there is no advance when
running the atom after the first quant_min times,
then there is no match. We remove this test when we
are sure the atom always advances the position. */
add_zero_advance_check = re_need_check_advance(s->byte_code.buf + last_atom_start,
s->byte_code.size - last_atom_start);
} else {
add_zero_advance_check = FALSE;
} }
/* the spec tells that if there is no advance when
running the atom after the first quant_min times,
then there is no match. We remove this test when we
are sure the atom always advances the position. */
add_zero_advance_check = re_need_check_advance(s->byte_code.buf + last_atom_start,
s->byte_code.size - last_atom_start);
{ {
int len, pos; int len, pos;
@@ -1539,7 +1571,7 @@ static int re_parse_term(REParseState *s, BOOL is_backward_dir)
if (quant_max == 0) { if (quant_max == 0) {
s->byte_code.size = last_atom_start; s->byte_code.size = last_atom_start;
} else if (quant_max == 1 || quant_max == INT32_MAX) { } else if (quant_max == 1 || quant_max == INT32_MAX) {
BOOL has_goto = (quant_max == INT32_MAX); bool has_goto = (quant_max == INT32_MAX);
if (dbuf_insert(&s->byte_code, last_atom_start, 5 + add_zero_advance_check)) if (dbuf_insert(&s->byte_code, last_atom_start, 5 + add_zero_advance_check))
goto out_of_memory; goto out_of_memory;
s->byte_code.buf[last_atom_start] = REOP_split_goto_first + s->byte_code.buf[last_atom_start] = REOP_split_goto_first +
@@ -1626,7 +1658,7 @@ static int re_parse_term(REParseState *s, BOOL is_backward_dir)
return re_parse_out_of_memory(s); return re_parse_out_of_memory(s);
} }
static int re_parse_alternative(REParseState *s, BOOL is_backward_dir) static int re_parse_alternative(REParseState *s, bool is_backward_dir)
{ {
const uint8_t *p; const uint8_t *p;
int ret; int ret;
@@ -1660,7 +1692,7 @@ static int re_parse_alternative(REParseState *s, BOOL is_backward_dir)
return 0; return 0;
} }
static int re_parse_disjunction(REParseState *s, BOOL is_backward_dir) static int re_parse_disjunction(REParseState *s, bool is_backward_dir)
{ {
int start, len, pos; int start, len, pos;
@@ -1695,7 +1727,7 @@ static int re_parse_disjunction(REParseState *s, BOOL is_backward_dir)
} }
/* the control flow is recursive so the analysis can be linear */ /* the control flow is recursive so the analysis can be linear */
static int compute_stack_size(const uint8_t *bc_buf, int bc_buf_len) static int lre_compute_stack_size(const uint8_t *bc_buf, int bc_buf_len)
{ {
int stack_size, stack_size_max, pos, opcode, len; int stack_size, stack_size_max, pos, opcode, len;
uint32_t val; uint32_t val;
@@ -1749,7 +1781,7 @@ uint8_t *lre_compile(int *plen, char *error_msg, int error_msg_size,
{ {
REParseState s_s, *s = &s_s; REParseState s_s, *s = &s_s;
int stack_size; int stack_size;
BOOL is_sticky; bool is_sticky;
memset(s, 0, sizeof(*s)); memset(s, 0, sizeof(*s));
s->opaque = opaque; s->opaque = opaque;
@@ -1761,6 +1793,7 @@ uint8_t *lre_compile(int *plen, char *error_msg, int error_msg_size,
is_sticky = ((re_flags & LRE_FLAG_STICKY) != 0); is_sticky = ((re_flags & LRE_FLAG_STICKY) != 0);
s->ignore_case = ((re_flags & LRE_FLAG_IGNORECASE) != 0); s->ignore_case = ((re_flags & LRE_FLAG_IGNORECASE) != 0);
s->dotall = ((re_flags & LRE_FLAG_DOTALL) != 0); s->dotall = ((re_flags & LRE_FLAG_DOTALL) != 0);
s->unicode_sets = ((re_flags & LRE_FLAG_UNICODE_SETS) != 0);
s->capture_count = 1; s->capture_count = 1;
s->total_capture_count = -1; s->total_capture_count = -1;
s->has_named_captures = -1; s->has_named_captures = -1;
@@ -1768,7 +1801,7 @@ uint8_t *lre_compile(int *plen, char *error_msg, int error_msg_size,
dbuf_init2(&s->byte_code, opaque, lre_realloc); dbuf_init2(&s->byte_code, opaque, lre_realloc);
dbuf_init2(&s->group_names, opaque, lre_realloc); dbuf_init2(&s->group_names, opaque, lre_realloc);
dbuf_putc(&s->byte_code, re_flags); /* first element is the flags */ dbuf_put_u16(&s->byte_code, re_flags); /* first element is the flags */
dbuf_putc(&s->byte_code, 0); /* second element is the number of captures */ dbuf_putc(&s->byte_code, 0); /* second element is the number of captures */
dbuf_putc(&s->byte_code, 0); /* stack size */ dbuf_putc(&s->byte_code, 0); /* stack size */
dbuf_put_u32(&s->byte_code, 0); /* bytecode length */ dbuf_put_u32(&s->byte_code, 0); /* bytecode length */
@@ -1784,11 +1817,11 @@ uint8_t *lre_compile(int *plen, char *error_msg, int error_msg_size,
} }
re_emit_op_u8(s, REOP_save_start, 0); re_emit_op_u8(s, REOP_save_start, 0);
if (re_parse_disjunction(s, FALSE)) { if (re_parse_disjunction(s, false)) {
error: error:
dbuf_free(&s->byte_code); dbuf_free(&s->byte_code);
dbuf_free(&s->group_names); dbuf_free(&s->group_names);
pstrcpy(error_msg, error_msg_size, s->u.error_msg); js__pstrcpy(error_msg, error_msg_size, s->u.error_msg);
*plen = 0; *plen = 0;
return NULL; return NULL;
} }
@@ -1807,7 +1840,7 @@ uint8_t *lre_compile(int *plen, char *error_msg, int error_msg_size,
goto error; goto error;
} }
stack_size = compute_stack_size(s->byte_code.buf, s->byte_code.size); stack_size = lre_compute_stack_size(s->byte_code.buf, s->byte_code.size);
if (stack_size < 0) { if (stack_size < 0) {
re_parse_error(s, "too many imbricated quantifiers"); re_parse_error(s, "too many imbricated quantifiers");
goto error; goto error;
@@ -1821,7 +1854,8 @@ uint8_t *lre_compile(int *plen, char *error_msg, int error_msg_size,
/* add the named groups if needed */ /* add the named groups if needed */
if (s->group_names.size > (s->capture_count - 1)) { if (s->group_names.size > (s->capture_count - 1)) {
dbuf_put(&s->byte_code, s->group_names.buf, s->group_names.size); dbuf_put(&s->byte_code, s->group_names.buf, s->group_names.size);
s->byte_code.buf[RE_HEADER_FLAGS] |= LRE_FLAG_NAMED_GROUPS; put_u16(s->byte_code.buf + RE_HEADER_FLAGS,
LRE_FLAG_NAMED_GROUPS | lre_get_flags(s->byte_code.buf));
} }
dbuf_free(&s->group_names); dbuf_free(&s->group_names);
@@ -1834,12 +1868,12 @@ uint8_t *lre_compile(int *plen, char *error_msg, int error_msg_size,
return s->byte_code.buf; return s->byte_code.buf;
} }
static BOOL is_line_terminator(uint32_t c) static bool is_line_terminator(uint32_t c)
{ {
return (c == '\n' || c == '\r' || c == CP_LS || c == CP_PS); return (c == '\n' || c == '\r' || c == CP_LS || c == CP_PS);
} }
static BOOL is_word_char(uint32_t c) static bool is_word_char(uint32_t c)
{ {
return ((c >= '0' && c <= '9') || return ((c >= '0' && c <= '9') ||
(c >= 'a' && c <= 'z') || (c >= 'a' && c <= 'z') ||
@@ -1855,11 +1889,11 @@ static BOOL is_word_char(uint32_t c)
const uint16_t *_p = (const uint16_t *)cptr; \ const uint16_t *_p = (const uint16_t *)cptr; \
const uint16_t *_end = (const uint16_t *)cbuf_end; \ const uint16_t *_end = (const uint16_t *)cbuf_end; \
c = *_p++; \ c = *_p++; \
if (is_hi_surrogate(c) && cbuf_type == 2) { \ if (is_hi_surrogate(c)) \
if (_p < _end && is_lo_surrogate(*_p)) { \ if (cbuf_type == 2) \
c = from_surrogate(c, *_p++); \ if (_p < _end) \
} \ if (is_lo_surrogate(*_p)) \
} \ c = from_surrogate(c, *_p++); \
cptr = (const void *)_p; \ cptr = (const void *)_p; \
} \ } \
} while (0) } while (0)
@@ -1872,11 +1906,11 @@ static BOOL is_word_char(uint32_t c)
const uint16_t *_p = (const uint16_t *)cptr; \ const uint16_t *_p = (const uint16_t *)cptr; \
const uint16_t *_end = (const uint16_t *)cbuf_end; \ const uint16_t *_end = (const uint16_t *)cbuf_end; \
c = *_p++; \ c = *_p++; \
if (is_hi_surrogate(c) && cbuf_type == 2) { \ if (is_hi_surrogate(c)) \
if (_p < _end && is_lo_surrogate(*_p)) { \ if (cbuf_type == 2) \
c = from_surrogate(c, *_p); \ if (_p < _end) \
} \ if (is_lo_surrogate(*_p)) \
} \ c = from_surrogate(c, *_p); \
} \ } \
} while (0) } while (0)
@@ -1888,11 +1922,11 @@ static BOOL is_word_char(uint32_t c)
const uint16_t *_p = (const uint16_t *)cptr - 1; \ const uint16_t *_p = (const uint16_t *)cptr - 1; \
const uint16_t *_start = (const uint16_t *)cbuf_start; \ const uint16_t *_start = (const uint16_t *)cbuf_start; \
c = *_p; \ c = *_p; \
if (is_lo_surrogate(c) && cbuf_type == 2) { \ if (is_lo_surrogate(c)) \
if (_p > _start && is_hi_surrogate(_p[-1])) { \ if (cbuf_type == 2) \
c = from_surrogate(*--_p, c); \ if (_p > _start) \
} \ if (is_hi_surrogate(_p[-1])) \
} \ c = from_surrogate(*--_p, c); \
} \ } \
} while (0) } while (0)
@@ -1905,11 +1939,11 @@ static BOOL is_word_char(uint32_t c)
const uint16_t *_p = (const uint16_t *)cptr - 1; \ const uint16_t *_p = (const uint16_t *)cptr - 1; \
const uint16_t *_start = (const uint16_t *)cbuf_start; \ const uint16_t *_start = (const uint16_t *)cbuf_start; \
c = *_p; \ c = *_p; \
if (is_lo_surrogate(c) && cbuf_type == 2) { \ if (is_lo_surrogate(c)) \
if (_p > _start && is_hi_surrogate(_p[-1])) { \ if (cbuf_type == 2) \
c = from_surrogate(*--_p, c); \ if (_p > _start) \
} \ if (is_hi_surrogate(_p[-1])) \
} \ c = from_surrogate(*--_p, c); \
cptr = (const void *)_p; \ cptr = (const void *)_p; \
} \ } \
} while (0) } while (0)
@@ -1921,11 +1955,11 @@ static BOOL is_word_char(uint32_t c)
} else { \ } else { \
const uint16_t *_p = (const uint16_t *)cptr - 1; \ const uint16_t *_p = (const uint16_t *)cptr - 1; \
const uint16_t *_start = (const uint16_t *)cbuf_start; \ const uint16_t *_start = (const uint16_t *)cbuf_start; \
if (is_lo_surrogate(*_p) && cbuf_type == 2) { \ if (is_lo_surrogate(*_p)) \
if (_p > _start && is_hi_surrogate(_p[-1])) { \ if (cbuf_type == 2) \
--_p; \ if (_p > _start) \
} \ if (is_hi_surrogate(_p[-1])) \
} \ _p--; \
cptr = (const void *)_p; \ cptr = (const void *)_p; \
} \ } \
} while (0) } while (0)
@@ -1945,7 +1979,7 @@ typedef struct REExecState {
size_t count; /* only used for RE_EXEC_STATE_GREEDY_QUANT */ size_t count; /* only used for RE_EXEC_STATE_GREEDY_QUANT */
const uint8_t *cptr; const uint8_t *cptr;
const uint8_t *pc; const uint8_t *pc;
void *buf[0]; void *buf[];
} REExecState; } REExecState;
typedef struct { typedef struct {
@@ -1955,9 +1989,9 @@ typedef struct {
int cbuf_type; int cbuf_type;
int capture_count; int capture_count;
int stack_size_max; int stack_size_max;
BOOL multi_line; bool multi_line;
BOOL ignore_case; bool ignore_case;
BOOL is_unicode; bool is_unicode;
void *opaque; /* used for stack overflow check */ void *opaque; /* used for stack overflow check */
size_t state_size; size_t state_size;
@@ -2008,7 +2042,7 @@ static int push_state(REExecContext *s,
static intptr_t lre_exec_backtrack(REExecContext *s, uint8_t **capture, static intptr_t lre_exec_backtrack(REExecContext *s, uint8_t **capture,
StackInt *stack, int stack_len, StackInt *stack, int stack_len,
const uint8_t *pc, const uint8_t *cptr, const uint8_t *pc, const uint8_t *cptr,
BOOL no_recurse) bool no_recurse)
{ {
int opcode, ret; int opcode, ret;
int cbuf_type; int cbuf_type;
@@ -2095,9 +2129,13 @@ static intptr_t lre_exec_backtrack(REExecContext *s, uint8_t **capture,
val = get_u32(pc); val = get_u32(pc);
pc += 4; pc += 4;
goto test_char; goto test_char;
case REOP_char: case REOP_char16:
val = get_u16(pc); val = get_u16(pc);
pc += 2; pc += 2;
goto test_char;
case REOP_char8:
val = get_u8(pc);
pc += 1;
test_char: test_char:
if (cptr >= cbuf_end) if (cptr >= cbuf_end)
goto no_match; goto no_match;
@@ -2218,17 +2256,17 @@ static intptr_t lre_exec_backtrack(REExecContext *s, uint8_t **capture,
case REOP_word_boundary: case REOP_word_boundary:
case REOP_not_word_boundary: case REOP_not_word_boundary:
{ {
BOOL v1, v2; bool v1, v2;
/* char before */ /* char before */
if (cptr == s->cbuf) { if (cptr == s->cbuf) {
v1 = FALSE; v1 = false;
} else { } else {
PEEK_PREV_CHAR(c, cptr, s->cbuf, cbuf_type); PEEK_PREV_CHAR(c, cptr, s->cbuf, cbuf_type);
v1 = is_word_char(c); v1 = is_word_char(c);
} }
/* current char */ /* current char */
if (cptr >= cbuf_end) { if (cptr >= cbuf_end) {
v2 = FALSE; v2 = false;
} else { } else {
PEEK_CHAR(c, cptr, cbuf_end, cbuf_type); PEEK_CHAR(c, cptr, cbuf_end, cbuf_type);
v2 = is_word_char(c); v2 = is_word_char(c);
@@ -2381,7 +2419,7 @@ static intptr_t lre_exec_backtrack(REExecContext *s, uint8_t **capture,
q = 0; q = 0;
for(;;) { for(;;) {
res = lre_exec_backtrack(s, capture, stack, stack_len, res = lre_exec_backtrack(s, capture, stack, stack_len,
pc1, cptr, TRUE); pc1, cptr, true);
if (res == -1) if (res == -1)
return res; return res;
if (!res) if (!res)
@@ -2446,7 +2484,7 @@ int lre_exec(uint8_t **capture,
alloca_size = s->stack_size_max * sizeof(stack_buf[0]); alloca_size = s->stack_size_max * sizeof(stack_buf[0]);
stack_buf = alloca(alloca_size); stack_buf = alloca(alloca_size);
ret = lre_exec_backtrack(s, capture, stack_buf, 0, bc_buf + RE_HEADER_LEN, ret = lre_exec_backtrack(s, capture, stack_buf, 0, bc_buf + RE_HEADER_LEN,
cbuf + (cindex << cbuf_type), FALSE); cbuf + (cindex << cbuf_type), false);
lre_realloc(s->opaque, s->state_stack, 0); lre_realloc(s->opaque, s->state_stack, 0);
return ret; return ret;
} }
@@ -2458,7 +2496,7 @@ int lre_get_capture_count(const uint8_t *bc_buf)
int lre_get_flags(const uint8_t *bc_buf) int lre_get_flags(const uint8_t *bc_buf)
{ {
return bc_buf[RE_HEADER_FLAGS]; return get_u16(bc_buf + RE_HEADER_FLAGS);
} }
/* Return NULL if no group names. Otherwise, return a pointer to /* Return NULL if no group names. Otherwise, return a pointer to
@@ -2472,11 +2510,85 @@ const char *lre_get_groupnames(const uint8_t *bc_buf)
return (const char *)(bc_buf + RE_HEADER_LEN + re_bytecode_len); return (const char *)(bc_buf + RE_HEADER_LEN + re_bytecode_len);
} }
void lre_byte_swap(uint8_t *buf, size_t len, bool is_byte_swapped)
{
uint8_t *p, *pe;
uint32_t n, r, nw;
p = buf;
if (len < RE_HEADER_LEN)
abort();
// format is:
// <header>
// <bytecode>
// <capture group name 1>
// <capture group name 2>
// etc.
inplace_bswap16(&p[RE_HEADER_FLAGS]);
n = get_u32(&p[RE_HEADER_BYTECODE_LEN]);
inplace_bswap32(&p[RE_HEADER_BYTECODE_LEN]);
if (is_byte_swapped)
n = bswap32(n);
if (n > len - RE_HEADER_LEN)
abort();
p = &buf[RE_HEADER_LEN];
pe = &p[n];
while (p < pe) {
n = reopcode_info[*p].size;
switch (n) {
case 1:
case 2:
break;
case 3:
switch (*p) {
case REOP_save_reset: // has two 8 bit arguments
break;
case REOP_range32: // variable length
nw = get_u16(&p[1]); // number of pairs of uint32_t
if (is_byte_swapped)
n = bswap16(n);
for (r = 3 + 8 * nw; n < r; n += 4)
inplace_bswap32(&p[n]);
goto doswap16;
case REOP_range: // variable length
nw = get_u16(&p[1]); // number of pairs of uint16_t
if (is_byte_swapped)
n = bswap16(n);
for (r = 3 + 4 * nw; n < r; n += 2)
inplace_bswap16(&p[n]);
goto doswap16;
default:
doswap16:
inplace_bswap16(&p[1]);
break;
}
break;
case 5:
inplace_bswap32(&p[1]);
break;
case 17:
assert(*p == REOP_simple_greedy_quant);
inplace_bswap32(&p[1]);
inplace_bswap32(&p[5]);
inplace_bswap32(&p[9]);
inplace_bswap32(&p[13]);
break;
default:
abort();
}
p = &p[n];
}
}
#ifdef TEST #ifdef TEST
BOOL lre_check_stack_overflow(void *opaque, size_t alloca_size) bool lre_check_stack_overflow(void *opaque, size_t alloca_size)
{ {
return FALSE; return false;
} }
void *lre_realloc(void *opaque, void *ptr, size_t size) void *lre_realloc(void *opaque, void *ptr, size_t size)
@@ -2495,7 +2607,7 @@ int main(int argc, char **argv)
if (argc < 4) { if (argc < 4) {
printf("usage: %s regexp flags input\n", argv[0]); printf("usage: %s regexp flags input\n", argv[0]);
return 1; exit(1);
} }
flags = atoi(argv[2]); flags = atoi(argv[2]);
bc = lre_compile(&len, error_msg, sizeof(error_msg), argv[1], bc = lre_compile(&len, error_msg, sizeof(error_msg), argv[1],

View File

@@ -24,11 +24,14 @@
#ifndef LIBREGEXP_H #ifndef LIBREGEXP_H
#define LIBREGEXP_H #define LIBREGEXP_H
#include <stdbool.h>
#include <stddef.h> #include <stddef.h>
#include "libunicode.h" #include "libunicode.h"
#define LRE_BOOL int /* for documentation purposes */ #ifdef __cplusplus
extern "C" {
#endif
#define LRE_FLAG_GLOBAL (1 << 0) #define LRE_FLAG_GLOBAL (1 << 0)
#define LRE_FLAG_IGNORECASE (1 << 1) #define LRE_FLAG_IGNORECASE (1 << 1)
@@ -38,6 +41,7 @@
#define LRE_FLAG_STICKY (1 << 5) #define LRE_FLAG_STICKY (1 << 5)
#define LRE_FLAG_INDICES (1 << 6) /* Unused by libregexp, just recorded. */ #define LRE_FLAG_INDICES (1 << 6) /* Unused by libregexp, just recorded. */
#define LRE_FLAG_NAMED_GROUPS (1 << 7) /* named groups are present in the regexp */ #define LRE_FLAG_NAMED_GROUPS (1 << 7) /* named groups are present in the regexp */
#define LRE_FLAG_UNICODE_SETS (1 << 8)
uint8_t *lre_compile(int *plen, char *error_msg, int error_msg_size, uint8_t *lre_compile(int *plen, char *error_msg, int error_msg_size,
const char *buf, size_t buf_len, int re_flags, const char *buf, size_t buf_len, int re_flags,
@@ -50,10 +54,12 @@ int lre_exec(uint8_t **capture,
int cbuf_type, void *opaque); int cbuf_type, void *opaque);
int lre_parse_escape(const uint8_t **pp, int allow_utf16); int lre_parse_escape(const uint8_t **pp, int allow_utf16);
LRE_BOOL lre_is_space(int c); bool lre_is_space(int c);
void lre_byte_swap(uint8_t *buf, size_t len, bool is_byte_swapped);
/* must be provided by the user */ /* must be provided by the user */
LRE_BOOL lre_check_stack_overflow(void *opaque, size_t alloca_size); bool lre_check_stack_overflow(void *opaque, size_t alloca_size);
void *lre_realloc(void *opaque, void *ptr, size_t size); void *lre_realloc(void *opaque, void *ptr, size_t size);
/* JS identifier test */ /* JS identifier test */
@@ -65,11 +71,7 @@ static inline int lre_js_is_ident_first(int c)
if ((uint32_t)c < 128) { if ((uint32_t)c < 128) {
return (lre_id_start_table_ascii[c >> 5] >> (c & 31)) & 1; return (lre_id_start_table_ascii[c >> 5] >> (c & 31)) & 1;
} else { } else {
#ifdef CONFIG_ALL_UNICODE
return lre_is_id_start(c); return lre_is_id_start(c);
#else
return !lre_is_space(c);
#endif
} }
} }
@@ -79,14 +81,12 @@ static inline int lre_js_is_ident_next(int c)
return (lre_id_continue_table_ascii[c >> 5] >> (c & 31)) & 1; return (lre_id_continue_table_ascii[c >> 5] >> (c & 31)) & 1;
} else { } else {
/* ZWNJ and ZWJ are accepted in identifiers */ /* ZWNJ and ZWJ are accepted in identifiers */
#ifdef CONFIG_ALL_UNICODE
return lre_is_id_continue(c) || c == 0x200C || c == 0x200D; return lre_is_id_continue(c) || c == 0x200C || c == 0x200D;
#else
return !lre_is_space(c) || c == 0x200C || c == 0x200D;
#endif
} }
} }
#undef LRE_BOOL #ifdef __cplusplus
} /* extern "C" { */
#endif
#endif /* LIBREGEXP_H */ #endif /* LIBREGEXP_H */

View File

@@ -31,6 +31,7 @@
#include "libunicode.h" #include "libunicode.h"
#include "libunicode-table.h" #include "libunicode-table.h"
// note: stored as 4 bit tag, not much room left
enum { enum {
RUN_TYPE_U, RUN_TYPE_U,
RUN_TYPE_L, RUN_TYPE_L,
@@ -189,7 +190,7 @@ int lre_case_conv(uint32_t *res, uint32_t c, int conv_type)
return 1; return 1;
} }
static int lre_case_folding_entry(uint32_t c, uint32_t idx, uint32_t v, BOOL is_unicode) static int lre_case_folding_entry(uint32_t c, uint32_t idx, uint32_t v, bool is_unicode)
{ {
uint32_t res[LRE_CC_RES_LEN_MAX]; uint32_t res[LRE_CC_RES_LEN_MAX];
int len; int len;
@@ -215,7 +216,7 @@ static int lre_case_folding_entry(uint32_t c, uint32_t idx, uint32_t v, BOOL is_
c = c - 'a' + 'A'; c = c - 'a' + 'A';
} else { } else {
/* legacy regexp: to upper case if single char >= 128 */ /* legacy regexp: to upper case if single char >= 128 */
len = lre_case_conv_entry(res, c, FALSE, idx, v); len = lre_case_conv_entry(res, c, false, idx, v);
if (len == 1 && res[0] >= 128) if (len == 1 && res[0] >= 128)
c = res[0]; c = res[0];
} }
@@ -224,7 +225,7 @@ static int lre_case_folding_entry(uint32_t c, uint32_t idx, uint32_t v, BOOL is_
} }
/* JS regexp specific rules for case folding */ /* JS regexp specific rules for case folding */
int lre_canonicalize(uint32_t c, BOOL is_unicode) int lre_canonicalize(uint32_t c, bool is_unicode)
{ {
if (c < 128) { if (c < 128) {
/* fast case */ /* fast case */
@@ -262,11 +263,7 @@ int lre_canonicalize(uint32_t c, BOOL is_unicode)
static uint32_t get_le24(const uint8_t *ptr) static uint32_t get_le24(const uint8_t *ptr)
{ {
#if defined(__x86__) || defined(__x86_64__)
return *(uint16_t *)ptr | (ptr[2] << 16);
#else
return ptr[0] | (ptr[1] << 8) | (ptr[2] << 16); return ptr[0] | (ptr[1] << 8) | (ptr[2] << 16);
#endif
} }
#define UNICODE_INDEX_BLOCK_LEN 32 #define UNICODE_INDEX_BLOCK_LEN 32
@@ -305,7 +302,7 @@ static int get_index_pos(uint32_t *pcode, uint32_t c,
return (idx_min + 1) * UNICODE_INDEX_BLOCK_LEN + (v >> 21); return (idx_min + 1) * UNICODE_INDEX_BLOCK_LEN + (v >> 21);
} }
static BOOL lre_is_in_table(uint32_t c, const uint8_t *table, static bool lre_is_in_table(uint32_t c, const uint8_t *table,
const uint8_t *index_table, int index_table_len) const uint8_t *index_table, int index_table_len)
{ {
uint32_t code, b, bit; uint32_t code, b, bit;
@@ -314,7 +311,7 @@ static BOOL lre_is_in_table(uint32_t c, const uint8_t *table,
pos = get_index_pos(&code, c, index_table, index_table_len); pos = get_index_pos(&code, c, index_table, index_table_len);
if (pos < 0) if (pos < 0)
return FALSE; /* outside the table */ return false; /* outside the table */
p = table + pos; p = table + pos;
bit = 0; bit = 0;
for(;;) { for(;;) {
@@ -340,7 +337,7 @@ static BOOL lre_is_in_table(uint32_t c, const uint8_t *table,
} }
} }
BOOL lre_is_cased(uint32_t c) bool lre_is_cased(uint32_t c)
{ {
uint32_t v, code, len; uint32_t v, code, len;
int idx, idx_min, idx_max; int idx, idx_min, idx_max;
@@ -357,7 +354,7 @@ BOOL lre_is_cased(uint32_t c)
} else if (c >= code + len) { } else if (c >= code + len) {
idx_min = idx + 1; idx_min = idx + 1;
} else { } else {
return TRUE; return true;
} }
} }
return lre_is_in_table(c, unicode_prop_Cased1_table, return lre_is_in_table(c, unicode_prop_Cased1_table,
@@ -365,7 +362,7 @@ BOOL lre_is_cased(uint32_t c)
sizeof(unicode_prop_Cased1_index) / 3); sizeof(unicode_prop_Cased1_index) / 3);
} }
BOOL lre_is_case_ignorable(uint32_t c) bool lre_is_case_ignorable(uint32_t c)
{ {
return lre_is_in_table(c, unicode_prop_Case_Ignorable_table, return lre_is_in_table(c, unicode_prop_Case_Ignorable_table,
unicode_prop_Case_Ignorable_index, unicode_prop_Case_Ignorable_index,
@@ -533,16 +530,14 @@ int cr_invert(CharRange *cr)
return 0; return 0;
} }
#ifdef CONFIG_ALL_UNICODE bool lre_is_id_start(uint32_t c)
BOOL lre_is_id_start(uint32_t c)
{ {
return lre_is_in_table(c, unicode_prop_ID_Start_table, return lre_is_in_table(c, unicode_prop_ID_Start_table,
unicode_prop_ID_Start_index, unicode_prop_ID_Start_index,
sizeof(unicode_prop_ID_Start_index) / 3); sizeof(unicode_prop_ID_Start_index) / 3);
} }
BOOL lre_is_id_continue(uint32_t c) bool lre_is_id_continue(uint32_t c)
{ {
return lre_is_id_start(c) || return lre_is_id_start(c) ||
lre_is_in_table(c, unicode_prop_ID_Continue1_table, lre_is_in_table(c, unicode_prop_ID_Continue1_table,
@@ -550,6 +545,13 @@ BOOL lre_is_id_continue(uint32_t c)
sizeof(unicode_prop_ID_Continue1_index) / 3); sizeof(unicode_prop_ID_Continue1_index) / 3);
} }
bool lre_is_white_space(uint32_t c)
{
return lre_is_in_table(c, unicode_prop_White_Space_table,
unicode_prop_White_Space_index,
sizeof(unicode_prop_White_Space_index) / 3);
}
#define UNICODE_DECOMP_LEN_MAX 18 #define UNICODE_DECOMP_LEN_MAX 18
typedef enum { typedef enum {
@@ -757,7 +759,7 @@ static int unicode_decomp_entry(uint32_t *res, uint32_t c,
/* return the length of the decomposition (length <= /* return the length of the decomposition (length <=
UNICODE_DECOMP_LEN_MAX) or 0 if no decomposition */ UNICODE_DECOMP_LEN_MAX) or 0 if no decomposition */
static int unicode_decomp_char(uint32_t *res, uint32_t c, BOOL is_compat1) static int unicode_decomp_char(uint32_t *res, uint32_t c, bool is_compat1)
{ {
uint32_t v, type, is_compat, code, len; uint32_t v, type, is_compat, code, len;
int idx_min, idx_max, idx; int idx_min, idx_max, idx;
@@ -897,13 +899,6 @@ static void sort_cc(int *buf, int len)
buf[k + 1] = ch1; buf[k + 1] = ch1;
j++; j++;
} }
#if 0
printf("cc:");
for(k = start; k < j; k++) {
printf(" %3d", unicode_get_cc(buf[k]));
}
printf("\n");
#endif
i = j; i = j;
} }
} }
@@ -958,7 +953,7 @@ int unicode_normalize(uint32_t **pdst, const uint32_t *src, int src_len,
void *opaque, DynBufReallocFunc *realloc_func) void *opaque, DynBufReallocFunc *realloc_func)
{ {
int *buf, buf_len, i, p, starter_pos, cc, last_cc, out_len; int *buf, buf_len, i, p, starter_pos, cc, last_cc, out_len;
BOOL is_compat; bool is_compat;
DynBuf dbuf_s, *dbuf = &dbuf_s; DynBuf dbuf_s, *dbuf = &dbuf_s;
is_compat = n_type >> 1; is_compat = n_type >> 1;
@@ -1058,14 +1053,14 @@ static int unicode_find_name(const char *name_table, const char *name)
/* 'cr' must be initialized and empty. Return 0 if OK, -1 if error, -2 /* 'cr' must be initialized and empty. Return 0 if OK, -1 if error, -2
if not found */ if not found */
int unicode_script(CharRange *cr, int unicode_script(CharRange *cr,
const char *script_name, BOOL is_ext) const char *script_name, bool is_ext)
{ {
int script_idx; int script_idx;
const uint8_t *p, *p_end; const uint8_t *p, *p_end;
uint32_t c, c1, b, n, v, v_len, i, type; uint32_t c, c1, b, n, v, v_len, i, type;
CharRange cr1_s, *cr1; CharRange cr1_s = { 0 }, *cr1 = NULL;
CharRange cr2_s, *cr2 = &cr2_s; CharRange cr2_s = { 0 }, *cr2 = &cr2_s;
BOOL is_common; bool is_common;
script_idx = unicode_find_name(unicode_script_name_table, script_name); script_idx = unicode_find_name(unicode_script_name_table, script_name);
if (script_idx < 0) if (script_idx < 0)
@@ -1385,7 +1380,7 @@ static void cr_sort_and_remove_overlap(CharRange *cr)
/* canonicalize a character set using the JS regex case folding rules /* canonicalize a character set using the JS regex case folding rules
(see lre_canonicalize()) */ (see lre_canonicalize()) */
int cr_regexp_canonicalize(CharRange *cr, BOOL is_unicode) int cr_regexp_canonicalize(CharRange *cr, bool is_unicode)
{ {
CharRange cr_inter, cr_mask, cr_result, cr_sub; CharRange cr_inter, cr_mask, cr_result, cr_sub;
uint32_t v, code, len, i, idx, start, end, c, d_start, d_end, d; uint32_t v, code, len, i, idx, start, end, c, d_start, d_end, d;
@@ -1547,11 +1542,13 @@ static int unicode_prop_ops(CharRange *cr, ...)
} }
} }
done: done:
va_end(ap);
assert(stack_len == 1); assert(stack_len == 1);
ret = cr_copy(cr, &stack[0]); ret = cr_copy(cr, &stack[0]);
cr_free(&stack[0]); cr_free(&stack[0]);
return ret; return ret;
fail: fail:
va_end(ap);
for(i = 0; i < stack_len; i++) for(i = 0; i < stack_len; i++)
cr_free(&stack[i]); cr_free(&stack[i]);
return -1; return -1;
@@ -1731,42 +1728,6 @@ int unicode_prop(CharRange *cr, const char *prop_name)
POP_XOR, POP_XOR,
POP_END); POP_END);
break; break;
#if 0
case UNICODE_PROP_ID_Start:
ret = unicode_prop_ops(cr,
POP_GC, M(Lu) | M(Ll) | M(Lt) | M(Lm) | M(Lo) | M(Nl),
POP_PROP, UNICODE_PROP_Other_ID_Start,
POP_UNION,
POP_PROP, UNICODE_PROP_Pattern_Syntax,
POP_PROP, UNICODE_PROP_Pattern_White_Space,
POP_UNION,
POP_INVERT,
POP_INTER,
POP_END);
break;
case UNICODE_PROP_ID_Continue:
ret = unicode_prop_ops(cr,
POP_GC, M(Lu) | M(Ll) | M(Lt) | M(Lm) | M(Lo) | M(Nl) |
M(Mn) | M(Mc) | M(Nd) | M(Pc),
POP_PROP, UNICODE_PROP_Other_ID_Start,
POP_UNION,
POP_PROP, UNICODE_PROP_Other_ID_Continue,
POP_UNION,
POP_PROP, UNICODE_PROP_Pattern_Syntax,
POP_PROP, UNICODE_PROP_Pattern_White_Space,
POP_UNION,
POP_INVERT,
POP_INTER,
POP_END);
break;
case UNICODE_PROP_Case_Ignorable:
ret = unicode_prop_ops(cr,
POP_GC, M(Mn) | M(Cf) | M(Lm) | M(Sk),
POP_PROP, UNICODE_PROP_Case_Ignorable1,
POP_XOR,
POP_END);
break;
#else
/* we use the existing tables */ /* we use the existing tables */
case UNICODE_PROP_ID_Continue: case UNICODE_PROP_ID_Continue:
ret = unicode_prop_ops(cr, ret = unicode_prop_ops(cr,
@@ -1775,7 +1736,6 @@ int unicode_prop(CharRange *cr, const char *prop_name)
POP_XOR, POP_XOR,
POP_END); POP_END);
break; break;
#endif
default: default:
if (prop_idx >= countof(unicode_prop_table)) if (prop_idx >= countof(unicode_prop_table))
return -2; return -2;
@@ -1784,5 +1744,3 @@ int unicode_prop(CharRange *cr, const char *prop_name)
} }
return ret; return ret;
} }
#endif /* CONFIG_ALL_UNICODE */

View File

@@ -24,12 +24,13 @@
#ifndef LIBUNICODE_H #ifndef LIBUNICODE_H
#define LIBUNICODE_H #define LIBUNICODE_H
#include <stdbool.h>
#include <stddef.h>
#include <inttypes.h> #include <inttypes.h>
#define LRE_BOOL int /* for documentation purposes */ #ifdef __cplusplus
extern "C" {
/* define it to include all the unicode tables (40KB larger) */ #endif
#define CONFIG_ALL_UNICODE
#define LRE_CC_RES_LEN_MAX 3 #define LRE_CC_RES_LEN_MAX 3
@@ -41,9 +42,9 @@ typedef enum {
} UnicodeNormalizationEnum; } UnicodeNormalizationEnum;
int lre_case_conv(uint32_t *res, uint32_t c, int conv_type); int lre_case_conv(uint32_t *res, uint32_t c, int conv_type);
int lre_canonicalize(uint32_t c, LRE_BOOL is_unicode); int lre_canonicalize(uint32_t c, bool is_unicode);
LRE_BOOL lre_is_cased(uint32_t c); bool lre_is_cased(uint32_t c);
LRE_BOOL lre_is_case_ignorable(uint32_t c); bool lre_is_case_ignorable(uint32_t c);
/* char ranges */ /* char ranges */
@@ -101,13 +102,11 @@ int cr_op(CharRange *cr, const uint32_t *a_pt, int a_len,
const uint32_t *b_pt, int b_len, int op); const uint32_t *b_pt, int b_len, int op);
int cr_invert(CharRange *cr); int cr_invert(CharRange *cr);
int cr_regexp_canonicalize(CharRange *cr, bool is_unicode);
int cr_regexp_canonicalize(CharRange *cr, LRE_BOOL is_unicode); bool lre_is_id_start(uint32_t c);
bool lre_is_id_continue(uint32_t c);
#ifdef CONFIG_ALL_UNICODE bool lre_is_white_space(uint32_t c);
LRE_BOOL lre_is_id_start(uint32_t c);
LRE_BOOL lre_is_id_continue(uint32_t c);
int unicode_normalize(uint32_t **pdst, const uint32_t *src, int src_len, int unicode_normalize(uint32_t **pdst, const uint32_t *src, int src_len,
UnicodeNormalizationEnum n_type, UnicodeNormalizationEnum n_type,
@@ -116,12 +115,12 @@ int unicode_normalize(uint32_t **pdst, const uint32_t *src, int src_len,
/* Unicode character range functions */ /* Unicode character range functions */
int unicode_script(CharRange *cr, int unicode_script(CharRange *cr,
const char *script_name, LRE_BOOL is_ext); const char *script_name, bool is_ext);
int unicode_general_category(CharRange *cr, const char *gc_name); int unicode_general_category(CharRange *cr, const char *gc_name);
int unicode_prop(CharRange *cr, const char *prop_name); int unicode_prop(CharRange *cr, const char *prop_name);
#endif /* CONFIG_ALL_UNICODE */ #ifdef __cplusplus
} /* extern "C" { */
#undef LRE_BOOL #endif
#endif /* LIBUNICODE_H */ #endif /* LIBUNICODE_H */

View File

@@ -28,6 +28,10 @@
#include <stddef.h> #include <stddef.h>
#endif #endif
#ifdef __cplusplus
extern "C" {
#endif
struct list_head { struct list_head {
struct list_head *prev; struct list_head *prev;
struct list_head *next; struct list_head *next;
@@ -96,4 +100,8 @@ static inline int list_empty(struct list_head *el)
for(el = (head)->prev, el1 = el->prev; el != (head); \ for(el = (head)->prev, el1 = el->prev; el != (head); \
el = el1, el1 = el->prev) el = el1, el1 = el->prev)
#ifdef __cplusplus
} /* extern "C" { */
#endif
#endif /* LIST_H */ #endif /* LIST_H */

View File

@@ -78,9 +78,9 @@ DEF(await, "await")
/* empty string */ /* empty string */
DEF(empty_string, "") DEF(empty_string, "")
/* identifiers */ /* identifiers */
DEF(keys, "keys")
DEF(size, "size")
DEF(length, "length") DEF(length, "length")
DEF(fileName, "fileName")
DEF(lineNumber, "lineNumber")
DEF(message, "message") DEF(message, "message")
DEF(cause, "cause") DEF(cause, "cause")
DEF(errors, "errors") DEF(errors, "errors")
@@ -172,19 +172,11 @@ DEF(status, "status")
DEF(reason, "reason") DEF(reason, "reason")
DEF(globalThis, "globalThis") DEF(globalThis, "globalThis")
DEF(bigint, "bigint") DEF(bigint, "bigint")
#ifdef CONFIG_BIGNUM
DEF(bigfloat, "bigfloat")
DEF(bigdecimal, "bigdecimal")
DEF(roundingMode, "roundingMode")
DEF(maximumSignificantDigits, "maximumSignificantDigits")
DEF(maximumFractionDigits, "maximumFractionDigits")
#endif
/* the following 3 atoms are only used with CONFIG_ATOMICS */
DEF(not_equal, "not-equal") DEF(not_equal, "not-equal")
DEF(timed_out, "timed-out") DEF(timed_out, "timed-out")
DEF(ok, "ok") DEF(ok, "ok")
/* */
DEF(toJSON, "toJSON") DEF(toJSON, "toJSON")
DEF(maxByteLength, "maxByteLength")
/* class names */ /* class names */
DEF(Object, "Object") DEF(Object, "Object")
DEF(Array, "Array") DEF(Array, "Array")
@@ -213,21 +205,20 @@ DEF(Int32Array, "Int32Array")
DEF(Uint32Array, "Uint32Array") DEF(Uint32Array, "Uint32Array")
DEF(BigInt64Array, "BigInt64Array") DEF(BigInt64Array, "BigInt64Array")
DEF(BigUint64Array, "BigUint64Array") DEF(BigUint64Array, "BigUint64Array")
DEF(Float16Array, "Float16Array")
DEF(Float32Array, "Float32Array") DEF(Float32Array, "Float32Array")
DEF(Float64Array, "Float64Array") DEF(Float64Array, "Float64Array")
DEF(DataView, "DataView") DEF(DataView, "DataView")
DEF(BigInt, "BigInt") DEF(BigInt, "BigInt")
#ifdef CONFIG_BIGNUM DEF(WeakRef, "WeakRef")
DEF(BigFloat, "BigFloat") DEF(FinalizationRegistry, "FinalizationRegistry")
DEF(BigFloatEnv, "BigFloatEnv")
DEF(BigDecimal, "BigDecimal")
DEF(OperatorSet, "OperatorSet")
DEF(Operators, "Operators")
#endif
DEF(Map, "Map") DEF(Map, "Map")
DEF(Set, "Set") /* Map + 1 */ DEF(Set, "Set") /* Map + 1 */
DEF(WeakMap, "WeakMap") /* Map + 2 */ DEF(WeakMap, "WeakMap") /* Map + 2 */
DEF(WeakSet, "WeakSet") /* Map + 3 */ DEF(WeakSet, "WeakSet") /* Map + 3 */
DEF(Iterator, "Iterator")
DEF(IteratorHelper, "Iterator Helper")
DEF(IteratorWrap, "Iterator Wrap")
DEF(Map_Iterator, "Map Iterator") DEF(Map_Iterator, "Map Iterator")
DEF(Set_Iterator, "Set Iterator") DEF(Set_Iterator, "Set Iterator")
DEF(Array_Iterator, "Array Iterator") DEF(Array_Iterator, "Array Iterator")
@@ -250,6 +241,7 @@ DEF(SyntaxError, "SyntaxError")
DEF(TypeError, "TypeError") DEF(TypeError, "TypeError")
DEF(URIError, "URIError") DEF(URIError, "URIError")
DEF(InternalError, "InternalError") DEF(InternalError, "InternalError")
DEF(CallSite, "CallSite")
/* private symbols */ /* private symbols */
DEF(Private_brand, "<brand>") DEF(Private_brand, "<brand>")
/* symbols */ /* symbols */
@@ -266,8 +258,5 @@ DEF(Symbol_hasInstance, "Symbol.hasInstance")
DEF(Symbol_species, "Symbol.species") DEF(Symbol_species, "Symbol.species")
DEF(Symbol_unscopables, "Symbol.unscopables") DEF(Symbol_unscopables, "Symbol.unscopables")
DEF(Symbol_asyncIterator, "Symbol.asyncIterator") DEF(Symbol_asyncIterator, "Symbol.asyncIterator")
#ifdef CONFIG_BIGNUM
DEF(Symbol_operatorSet, "Symbol.operatorSet")
#endif
#endif /* DEF */ #endif /* DEF */

View File

@@ -0,0 +1,54 @@
/*
* QuickJS C atomics definitions
*
* Copyright (c) 2023 Marcin Kolny
*
* 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.
*/
#if (defined(__GNUC__) || defined(__GNUG__)) && !defined(__clang__)
// Use GCC builtins for version < 4.9
# if((__GNUC__ << 16) + __GNUC_MINOR__ < ((4) << 16) + 9)
# define GCC_BUILTIN_ATOMICS
# endif
#endif
#ifdef GCC_BUILTIN_ATOMICS
#define atomic_fetch_add(obj, arg) \
__atomic_fetch_add(obj, arg, __ATOMIC_SEQ_CST)
#define atomic_compare_exchange_strong(obj, expected, desired) \
__atomic_compare_exchange_n(obj, expected, desired, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
#define atomic_exchange(obj, desired) \
__atomic_exchange_n (obj, desired, __ATOMIC_SEQ_CST)
#define atomic_load(obj) \
__atomic_load_n(obj, __ATOMIC_SEQ_CST)
#define atomic_store(obj, desired) \
__atomic_store_n(obj, desired, __ATOMIC_SEQ_CST)
#define atomic_fetch_or(obj, arg) \
__atomic_fetch_or(obj, arg, __ATOMIC_SEQ_CST)
#define atomic_fetch_xor(obj, arg) \
__atomic_fetch_xor(obj, arg, __ATOMIC_SEQ_CST)
#define atomic_fetch_and(obj, arg) \
__atomic_fetch_and(obj, arg, __ATOMIC_SEQ_CST)
#define atomic_fetch_sub(obj, arg) \
__atomic_fetch_sub(obj, arg, __ATOMIC_SEQ_CST)
#define _Atomic
#else
#include <stdatomic.h>
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,62 @@
/*
* QuickJS C library
*
* Copyright (c) 2017-2018 Fabrice Bellard
*
* 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.
*/
#ifndef QUICKJS_LIBC_H
#define QUICKJS_LIBC_H
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include "quickjs.h"
#ifdef __cplusplus
extern "C" {
#endif
JSModuleDef *js_init_module_std(JSContext *ctx, const char *module_name);
JSModuleDef *js_init_module_os(JSContext *ctx, const char *module_name);
JSModuleDef *js_init_module_bjson(JSContext *ctx, const char *module_name);
void js_std_add_helpers(JSContext *ctx, int argc, char **argv);
int js_std_loop(JSContext *ctx);
JSValue js_std_await(JSContext *ctx, JSValue obj);
void js_std_init_handlers(JSRuntime *rt);
void js_std_free_handlers(JSRuntime *rt);
void js_std_dump_error(JSContext *ctx);
uint8_t *js_load_file(JSContext *ctx, size_t *pbuf_len, const char *filename);
int js_module_set_import_meta(JSContext *ctx, JSValue func_val,
bool use_realpath, bool is_main);
JSModuleDef *js_module_loader(JSContext *ctx,
const char *module_name, void *opaque);
void js_std_eval_binary(JSContext *ctx, const uint8_t *buf, size_t buf_len,
int flags);
void js_std_promise_rejection_tracker(JSContext *ctx, JSValue promise,
JSValue reason,
bool is_handled, void *opaque);
void js_std_set_worker_new_context_func(JSContext *(*func)(JSRuntime *rt));
#ifdef __cplusplus
} /* extern "C" { */
#endif
#endif /* QUICKJS_LIBC_H */

View File

@@ -44,6 +44,7 @@ FMT(loc)
FMT(arg) FMT(arg)
FMT(var_ref) FMT(var_ref)
FMT(u32) FMT(u32)
FMT(u32x2)
FMT(i32) FMT(i32)
FMT(const) FMT(const)
FMT(label) FMT(label)
@@ -110,6 +111,7 @@ DEF( return, 1, 1, 0, none)
DEF( return_undef, 1, 0, 0, none) DEF( return_undef, 1, 0, 0, none)
DEF(check_ctor_return, 1, 1, 2, none) DEF(check_ctor_return, 1, 1, 2, none)
DEF( check_ctor, 1, 0, 0, none) DEF( check_ctor, 1, 0, 0, none)
DEF( init_ctor, 1, 0, 1, none)
DEF( check_brand, 1, 2, 2, none) /* this_obj func -> this_obj func */ DEF( check_brand, 1, 2, 2, none) /* this_obj func -> this_obj func */
DEF( add_brand, 1, 2, 0, none) /* this_obj home_obj -> */ DEF( add_brand, 1, 2, 0, none) /* this_obj home_obj -> */
DEF( return_async, 1, 1, 0, none) DEF( return_async, 1, 1, 0, none)
@@ -135,9 +137,12 @@ DEF( put_ref_value, 1, 3, 0, none)
DEF( define_var, 6, 0, 0, atom_u8) DEF( define_var, 6, 0, 0, atom_u8)
DEF(check_define_var, 6, 0, 0, atom_u8) DEF(check_define_var, 6, 0, 0, atom_u8)
DEF( define_func, 6, 1, 0, atom_u8) DEF( define_func, 6, 1, 0, atom_u8)
// order matters, see IC counterparts
DEF( get_field, 5, 1, 1, atom) DEF( get_field, 5, 1, 1, atom)
DEF( get_field2, 5, 1, 2, atom) DEF( get_field2, 5, 1, 2, atom)
DEF( put_field, 5, 2, 0, atom) DEF( put_field, 5, 2, 0, atom)
DEF( get_private_field, 1, 2, 1, none) /* obj prop -> value */ DEF( get_private_field, 1, 2, 1, none) /* obj prop -> value */
DEF( put_private_field, 1, 3, 0, none) /* obj value prop -> */ DEF( put_private_field, 1, 3, 0, none) /* obj value prop -> */
DEF(define_private_field, 1, 3, 1, none) /* obj prop value -> obj */ DEF(define_private_field, 1, 3, 1, none) /* obj prop value -> obj */
@@ -172,7 +177,6 @@ DEF(set_loc_uninitialized, 3, 0, 0, loc)
DEF( get_loc_check, 3, 0, 1, loc) DEF( get_loc_check, 3, 0, 1, loc)
DEF( put_loc_check, 3, 1, 0, loc) /* must come after get_loc_check */ DEF( put_loc_check, 3, 1, 0, loc) /* must come after get_loc_check */
DEF( put_loc_check_init, 3, 1, 0, loc) DEF( put_loc_check_init, 3, 1, 0, loc)
DEF(get_loc_checkthis, 3, 0, 1, loc)
DEF(get_var_ref_check, 3, 0, 1, var_ref) DEF(get_var_ref_check, 3, 0, 1, var_ref)
DEF(put_var_ref_check, 3, 1, 0, var_ref) /* must come after get_var_ref_check */ DEF(put_var_ref_check, 3, 1, 0, var_ref) /* must come after get_var_ref_check */
DEF(put_var_ref_check_init, 3, 1, 0, var_ref) DEF(put_var_ref_check_init, 3, 1, 0, var_ref)
@@ -234,15 +238,20 @@ DEF( typeof, 1, 1, 1, none)
DEF( delete, 1, 2, 1, none) DEF( delete, 1, 2, 1, none)
DEF( delete_var, 5, 0, 1, atom) DEF( delete_var, 5, 0, 1, atom)
/* warning: order matters (see js_parse_assign_expr) */
DEF( mul, 1, 2, 1, none) DEF( mul, 1, 2, 1, none)
DEF( div, 1, 2, 1, none) DEF( div, 1, 2, 1, none)
DEF( mod, 1, 2, 1, none) DEF( mod, 1, 2, 1, none)
DEF( add, 1, 2, 1, none) DEF( add, 1, 2, 1, none)
DEF( sub, 1, 2, 1, none) DEF( sub, 1, 2, 1, none)
DEF( pow, 1, 2, 1, none)
DEF( shl, 1, 2, 1, none) DEF( shl, 1, 2, 1, none)
DEF( sar, 1, 2, 1, none) DEF( sar, 1, 2, 1, none)
DEF( shr, 1, 2, 1, none) DEF( shr, 1, 2, 1, none)
DEF( and, 1, 2, 1, none)
DEF( xor, 1, 2, 1, none)
DEF( or, 1, 2, 1, none)
DEF( pow, 1, 2, 1, none)
DEF( lt, 1, 2, 1, none) DEF( lt, 1, 2, 1, none)
DEF( lte, 1, 2, 1, none) DEF( lte, 1, 2, 1, none)
DEF( gt, 1, 2, 1, none) DEF( gt, 1, 2, 1, none)
@@ -253,15 +262,8 @@ DEF( eq, 1, 2, 1, none)
DEF( neq, 1, 2, 1, none) DEF( neq, 1, 2, 1, none)
DEF( strict_eq, 1, 2, 1, none) DEF( strict_eq, 1, 2, 1, none)
DEF( strict_neq, 1, 2, 1, none) DEF( strict_neq, 1, 2, 1, none)
DEF( and, 1, 2, 1, none)
DEF( xor, 1, 2, 1, none)
DEF( or, 1, 2, 1, none)
DEF(is_undefined_or_null, 1, 1, 1, none) DEF(is_undefined_or_null, 1, 1, 1, none)
DEF( private_in, 1, 2, 1, none) DEF( private_in, 1, 2, 1, none)
#ifdef CONFIG_BIGNUM
DEF( mul_pow10, 1, 2, 1, none)
DEF( math_mod, 1, 2, 1, none)
#endif
/* must be the last non short and non temporary opcode */ /* must be the last non short and non temporary opcode */
DEF( nop, 1, 0, 0, none) DEF( nop, 1, 0, 0, none)
@@ -272,8 +274,6 @@ def( leave_scope, 3, 0, 0, u16) /* emitted in phase 1, removed in phase 2 */
def( label, 5, 0, 0, label) /* emitted in phase 1, removed in phase 3 */ def( label, 5, 0, 0, label) /* emitted in phase 1, removed in phase 3 */
/* the following opcodes must be in the same order as the 'with_x' and
get_var_undef, get_var and put_var opcodes */
def(scope_get_var_undef, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase 2 */ def(scope_get_var_undef, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase 2 */
def( scope_get_var, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase 2 */ def( scope_get_var, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase 2 */
def( scope_put_var, 7, 1, 0, atom_u16) /* emitted in phase 1, removed in phase 2 */ def( scope_put_var, 7, 1, 0, atom_u16) /* emitted in phase 1, removed in phase 2 */
@@ -281,7 +281,6 @@ def(scope_delete_var, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase
def( scope_make_ref, 11, 0, 2, atom_label_u16) /* emitted in phase 1, removed in phase 2 */ def( scope_make_ref, 11, 0, 2, atom_label_u16) /* emitted in phase 1, removed in phase 2 */
def( scope_get_ref, 7, 0, 2, atom_u16) /* emitted in phase 1, removed in phase 2 */ def( scope_get_ref, 7, 0, 2, atom_u16) /* emitted in phase 1, removed in phase 2 */
def(scope_put_var_init, 7, 0, 2, atom_u16) /* emitted in phase 1, removed in phase 2 */ def(scope_put_var_init, 7, 0, 2, atom_u16) /* emitted in phase 1, removed in phase 2 */
def(scope_get_var_checkthis, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase 2, only used to return 'this' in derived class constructors */
def(scope_get_private_field, 7, 1, 1, atom_u16) /* obj -> value, emitted in phase 1, removed in phase 2 */ def(scope_get_private_field, 7, 1, 1, atom_u16) /* obj -> value, emitted in phase 1, removed in phase 2 */
def(scope_get_private_field2, 7, 1, 2, atom_u16) /* obj -> obj value, emitted in phase 1, removed in phase 2 */ def(scope_get_private_field2, 7, 1, 2, atom_u16) /* obj -> obj value, emitted in phase 1, removed in phase 2 */
def(scope_put_private_field, 7, 2, 0, atom_u16) /* obj value ->, emitted in phase 1, removed in phase 2 */ def(scope_put_private_field, 7, 2, 0, atom_u16) /* obj value ->, emitted in phase 1, removed in phase 2 */
@@ -290,9 +289,8 @@ def(get_field_opt_chain, 5, 1, 1, atom) /* emitted in phase 1, removed in phase
def(get_array_el_opt_chain, 1, 2, 1, none) /* emitted in phase 1, removed in phase 2 */ def(get_array_el_opt_chain, 1, 2, 1, none) /* emitted in phase 1, removed in phase 2 */
def( set_class_name, 5, 1, 1, u32) /* emitted in phase 1, removed in phase 2 */ def( set_class_name, 5, 1, 1, u32) /* emitted in phase 1, removed in phase 2 */
def( line_num, 5, 0, 0, u32) /* emitted in phase 1, removed in phase 3 */ def( source_loc, 9, 0, 0, u32x2) /* emitted in phase 1, removed in phase 3 */
#if SHORT_OPCODES
DEF( push_minus1, 1, 0, 1, none_int) DEF( push_minus1, 1, 0, 1, none_int)
DEF( push_0, 1, 0, 1, none_int) DEF( push_0, 1, 0, 1, none_int)
DEF( push_1, 1, 0, 1, none_int) DEF( push_1, 1, 0, 1, none_int)
@@ -312,6 +310,7 @@ DEF( get_loc8, 2, 0, 1, loc8)
DEF( put_loc8, 2, 1, 0, loc8) DEF( put_loc8, 2, 1, 0, loc8)
DEF( set_loc8, 2, 1, 1, loc8) DEF( set_loc8, 2, 1, 1, loc8)
DEF( get_loc0_loc1, 1, 0, 2, none_loc)
DEF( get_loc0, 1, 0, 1, none_loc) DEF( get_loc0, 1, 0, 1, none_loc)
DEF( get_loc1, 1, 0, 1, none_loc) DEF( get_loc1, 1, 0, 1, none_loc)
DEF( get_loc2, 1, 0, 1, none_loc) DEF( get_loc2, 1, 0, 1, none_loc)
@@ -365,7 +364,11 @@ DEF( is_undefined, 1, 1, 1, none)
DEF( is_null, 1, 1, 1, none) DEF( is_null, 1, 1, 1, none)
DEF(typeof_is_undefined, 1, 1, 1, none) DEF(typeof_is_undefined, 1, 1, 1, none)
DEF( typeof_is_function, 1, 1, 1, none) DEF( typeof_is_function, 1, 1, 1, none)
#endif
// order matters, see non-IC counterparts
DEF( get_field_ic, 5, 1, 1, none)
DEF( get_field2_ic, 5, 1, 2, none)
DEF( put_field_ic, 5, 2, 0, none)
#undef DEF #undef DEF
#undef def #undef def

File diff suppressed because it is too large Load Diff

1100
cxx/quickjs-ng/quickjs.h Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +1,11 @@
cmake_minimum_required(VERSION 3.10) cmake_minimum_required(VERSION 3.10)
set(CXX_LIB_DIR ${CMAKE_CURRENT_LIST_DIR}) set(CXX_LIB_DIR ${CMAKE_CURRENT_LIST_DIR})
set(CMAKE_CXX_STANDARD 17) set(CMAKE_C_STANDARD 11)
project(quickjs LANGUAGES C)
# quickjs # quickjs
set(QUICK_JS_LIB_DIR ${CXX_LIB_DIR}/quickjs) set(QUICK_JS_LIB_DIR ${CXX_LIB_DIR}/quickjs-ng)
file (STRINGS "${QUICK_JS_LIB_DIR}/VERSION" QUICKJS_VERSION) file (STRINGS "${QUICK_JS_LIB_DIR}/VERSION" QUICKJS_VERSION)
add_library(quickjs STATIC add_library(quickjs STATIC
${QUICK_JS_LIB_DIR}/cutils.c ${QUICK_JS_LIB_DIR}/cutils.c
@@ -13,7 +15,6 @@ add_library(quickjs STATIC
${QUICK_JS_LIB_DIR}/libbf.c ${QUICK_JS_LIB_DIR}/libbf.c
) )
project(quickjs LANGUAGES C)
target_compile_options(quickjs PRIVATE "-DCONFIG_VERSION=\"${QUICKJS_VERSION}\"") target_compile_options(quickjs PRIVATE "-DCONFIG_VERSION=\"${QUICKJS_VERSION}\"")
target_compile_options(quickjs PRIVATE "-DDUMP_LEAKS") target_compile_options(quickjs PRIVATE "-DDUMP_LEAKS")

View File

@@ -1 +0,0 @@
2024-02-14

View File

@@ -1,631 +0,0 @@
/*
* C utilities
*
* Copyright (c) 2017 Fabrice Bellard
* Copyright (c) 2018 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 <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include "cutils.h"
void pstrcpy(char *buf, int buf_size, const char *str)
{
int c;
char *q = buf;
if (buf_size <= 0)
return;
for(;;) {
c = *str++;
if (c == 0 || q >= buf + buf_size - 1)
break;
*q++ = c;
}
*q = '\0';
}
/* strcat and truncate. */
char *pstrcat(char *buf, int buf_size, const char *s)
{
int len;
len = strlen(buf);
if (len < buf_size)
pstrcpy(buf + len, buf_size - len, s);
return buf;
}
int strstart(const char *str, const char *val, const char **ptr)
{
const char *p, *q;
p = str;
q = val;
while (*q != '\0') {
if (*p != *q)
return 0;
p++;
q++;
}
if (ptr)
*ptr = p;
return 1;
}
int has_suffix(const char *str, const char *suffix)
{
size_t len = strlen(str);
size_t slen = strlen(suffix);
return (len >= slen && !memcmp(str + len - slen, suffix, slen));
}
/* Dynamic buffer package */
static void *dbuf_default_realloc(void *opaque, void *ptr, size_t size)
{
return realloc(ptr, size);
}
void dbuf_init2(DynBuf *s, void *opaque, DynBufReallocFunc *realloc_func)
{
memset(s, 0, sizeof(*s));
if (!realloc_func)
realloc_func = dbuf_default_realloc;
s->opaque = opaque;
s->realloc_func = realloc_func;
}
void dbuf_init(DynBuf *s)
{
dbuf_init2(s, NULL, NULL);
}
/* return < 0 if error */
int dbuf_realloc(DynBuf *s, size_t new_size)
{
size_t size;
uint8_t *new_buf;
if (new_size > s->allocated_size) {
if (s->error)
return -1;
size = s->allocated_size * 3 / 2;
if (size > new_size)
new_size = size;
new_buf = s->realloc_func(s->opaque, s->buf, new_size);
if (!new_buf) {
s->error = TRUE;
return -1;
}
s->buf = new_buf;
s->allocated_size = new_size;
}
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)
{
if (unlikely((s->size + len) > s->allocated_size)) {
if (dbuf_realloc(s, s->size + len))
return -1;
}
memcpy_no_ub(s->buf + s->size, data, len);
s->size += len;
return 0;
}
int dbuf_put_self(DynBuf *s, size_t offset, size_t len)
{
if (unlikely((s->size + len) > s->allocated_size)) {
if (dbuf_realloc(s, s->size + len))
return -1;
}
memcpy(s->buf + s->size, s->buf + offset, len);
s->size += len;
return 0;
}
int dbuf_putc(DynBuf *s, uint8_t c)
{
return dbuf_put(s, &c, 1);
}
int dbuf_putstr(DynBuf *s, const char *str)
{
return dbuf_put(s, (const uint8_t *)str, strlen(str));
}
int __attribute__((format(printf, 2, 3))) dbuf_printf(DynBuf *s,
const char *fmt, ...)
{
va_list ap;
char buf[128];
int len;
va_start(ap, fmt);
len = vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
if (len < sizeof(buf)) {
/* fast case */
return dbuf_put(s, (uint8_t *)buf, len);
} else {
if (dbuf_realloc(s, s->size + len + 1))
return -1;
va_start(ap, fmt);
vsnprintf((char *)(s->buf + s->size), s->allocated_size - s->size,
fmt, ap);
va_end(ap);
s->size += len;
}
return 0;
}
void dbuf_free(DynBuf *s)
{
/* we test s->buf as a fail safe to avoid crashing if dbuf_free()
is called twice */
if (s->buf) {
s->realloc_func(s->opaque, s->buf, 0);
}
memset(s, 0, sizeof(*s));
}
/* Note: at most 31 bits are encoded. At most UTF8_CHAR_LEN_MAX bytes
are output. */
int unicode_to_utf8(uint8_t *buf, unsigned int c)
{
uint8_t *q = buf;
if (c < 0x80) {
*q++ = c;
} else {
if (c < 0x800) {
*q++ = (c >> 6) | 0xc0;
} else {
if (c < 0x10000) {
*q++ = (c >> 12) | 0xe0;
} else {
if (c < 0x00200000) {
*q++ = (c >> 18) | 0xf0;
} else {
if (c < 0x04000000) {
*q++ = (c >> 24) | 0xf8;
} else if (c < 0x80000000) {
*q++ = (c >> 30) | 0xfc;
*q++ = ((c >> 24) & 0x3f) | 0x80;
} else {
return 0;
}
*q++ = ((c >> 18) & 0x3f) | 0x80;
}
*q++ = ((c >> 12) & 0x3f) | 0x80;
}
*q++ = ((c >> 6) & 0x3f) | 0x80;
}
*q++ = (c & 0x3f) | 0x80;
}
return q - buf;
}
static const unsigned int utf8_min_code[5] = {
0x80, 0x800, 0x10000, 0x00200000, 0x04000000,
};
static const unsigned char utf8_first_code_mask[5] = {
0x1f, 0xf, 0x7, 0x3, 0x1,
};
/* return -1 if error. *pp is not updated in this case. max_len must
be >= 1. The maximum length for a UTF8 byte sequence is 6 bytes. */
int unicode_from_utf8(const uint8_t *p, int max_len, const uint8_t **pp)
{
int l, c, b, i;
c = *p++;
if (c < 0x80) {
*pp = p;
return c;
}
switch(c) {
case 0xc0: case 0xc1: case 0xc2: case 0xc3:
case 0xc4: case 0xc5: case 0xc6: case 0xc7:
case 0xc8: case 0xc9: case 0xca: case 0xcb:
case 0xcc: case 0xcd: case 0xce: case 0xcf:
case 0xd0: case 0xd1: case 0xd2: case 0xd3:
case 0xd4: case 0xd5: case 0xd6: case 0xd7:
case 0xd8: case 0xd9: case 0xda: case 0xdb:
case 0xdc: case 0xdd: case 0xde: case 0xdf:
l = 1;
break;
case 0xe0: case 0xe1: case 0xe2: case 0xe3:
case 0xe4: case 0xe5: case 0xe6: case 0xe7:
case 0xe8: case 0xe9: case 0xea: case 0xeb:
case 0xec: case 0xed: case 0xee: case 0xef:
l = 2;
break;
case 0xf0: case 0xf1: case 0xf2: case 0xf3:
case 0xf4: case 0xf5: case 0xf6: case 0xf7:
l = 3;
break;
case 0xf8: case 0xf9: case 0xfa: case 0xfb:
l = 4;
break;
case 0xfc: case 0xfd:
l = 5;
break;
default:
return -1;
}
/* check that we have enough characters */
if (l > (max_len - 1))
return -1;
c &= utf8_first_code_mask[l - 1];
for(i = 0; i < l; i++) {
b = *p++;
if (b < 0x80 || b >= 0xc0)
return -1;
c = (c << 6) | (b & 0x3f);
}
if (c < utf8_min_code[l - 1])
return -1;
*pp = p;
return c;
}
#if 0
#if defined(EMSCRIPTEN) || defined(__ANDROID__)
static void *rqsort_arg;
static int (*rqsort_cmp)(const void *, const void *, void *);
static int rqsort_cmp2(const void *p1, const void *p2)
{
return rqsort_cmp(p1, p2, rqsort_arg);
}
/* not reentrant, but not needed with emscripten */
void rqsort(void *base, size_t nmemb, size_t size,
int (*cmp)(const void *, const void *, void *),
void *arg)
{
rqsort_arg = arg;
rqsort_cmp = cmp;
qsort(base, nmemb, size, rqsort_cmp2);
}
#endif
#else
typedef void (*exchange_f)(void *a, void *b, size_t size);
typedef int (*cmp_f)(const void *, const void *, void *opaque);
static void exchange_bytes(void *a, void *b, size_t size) {
uint8_t *ap = (uint8_t *)a;
uint8_t *bp = (uint8_t *)b;
while (size-- != 0) {
uint8_t t = *ap;
*ap++ = *bp;
*bp++ = t;
}
}
static void exchange_one_byte(void *a, void *b, size_t size) {
uint8_t *ap = (uint8_t *)a;
uint8_t *bp = (uint8_t *)b;
uint8_t t = *ap;
*ap = *bp;
*bp = t;
}
static void exchange_int16s(void *a, void *b, size_t size) {
uint16_t *ap = (uint16_t *)a;
uint16_t *bp = (uint16_t *)b;
for (size /= sizeof(uint16_t); size-- != 0;) {
uint16_t t = *ap;
*ap++ = *bp;
*bp++ = t;
}
}
static void exchange_one_int16(void *a, void *b, size_t size) {
uint16_t *ap = (uint16_t *)a;
uint16_t *bp = (uint16_t *)b;
uint16_t t = *ap;
*ap = *bp;
*bp = t;
}
static void exchange_int32s(void *a, void *b, size_t size) {
uint32_t *ap = (uint32_t *)a;
uint32_t *bp = (uint32_t *)b;
for (size /= sizeof(uint32_t); size-- != 0;) {
uint32_t t = *ap;
*ap++ = *bp;
*bp++ = t;
}
}
static void exchange_one_int32(void *a, void *b, size_t size) {
uint32_t *ap = (uint32_t *)a;
uint32_t *bp = (uint32_t *)b;
uint32_t t = *ap;
*ap = *bp;
*bp = t;
}
static void exchange_int64s(void *a, void *b, size_t size) {
uint64_t *ap = (uint64_t *)a;
uint64_t *bp = (uint64_t *)b;
for (size /= sizeof(uint64_t); size-- != 0;) {
uint64_t t = *ap;
*ap++ = *bp;
*bp++ = t;
}
}
static void exchange_one_int64(void *a, void *b, size_t size) {
uint64_t *ap = (uint64_t *)a;
uint64_t *bp = (uint64_t *)b;
uint64_t t = *ap;
*ap = *bp;
*bp = t;
}
static void exchange_int128s(void *a, void *b, size_t size) {
uint64_t *ap = (uint64_t *)a;
uint64_t *bp = (uint64_t *)b;
for (size /= sizeof(uint64_t) * 2; size-- != 0; ap += 2, bp += 2) {
uint64_t t = ap[0];
uint64_t u = ap[1];
ap[0] = bp[0];
ap[1] = bp[1];
bp[0] = t;
bp[1] = u;
}
}
static void exchange_one_int128(void *a, void *b, size_t size) {
uint64_t *ap = (uint64_t *)a;
uint64_t *bp = (uint64_t *)b;
uint64_t t = ap[0];
uint64_t u = ap[1];
ap[0] = bp[0];
ap[1] = bp[1];
bp[0] = t;
bp[1] = u;
}
static inline exchange_f exchange_func(const void *base, size_t size) {
switch (((uintptr_t)base | (uintptr_t)size) & 15) {
case 0:
if (size == sizeof(uint64_t) * 2)
return exchange_one_int128;
else
return exchange_int128s;
case 8:
if (size == sizeof(uint64_t))
return exchange_one_int64;
else
return exchange_int64s;
case 4:
case 12:
if (size == sizeof(uint32_t))
return exchange_one_int32;
else
return exchange_int32s;
case 2:
case 6:
case 10:
case 14:
if (size == sizeof(uint16_t))
return exchange_one_int16;
else
return exchange_int16s;
default:
if (size == 1)
return exchange_one_byte;
else
return exchange_bytes;
}
}
static void heapsortx(void *base, size_t nmemb, size_t size, cmp_f cmp, void *opaque)
{
uint8_t *basep = (uint8_t *)base;
size_t i, n, c, r;
exchange_f swap = exchange_func(base, size);
if (nmemb > 1) {
i = (nmemb / 2) * size;
n = nmemb * size;
while (i > 0) {
i -= size;
for (r = i; (c = r * 2 + size) < n; r = c) {
if (c < n - size && cmp(basep + c, basep + c + size, opaque) <= 0)
c += size;
if (cmp(basep + r, basep + c, opaque) > 0)
break;
swap(basep + r, basep + c, size);
}
}
for (i = n - size; i > 0; i -= size) {
swap(basep, basep + i, size);
for (r = 0; (c = r * 2 + size) < i; r = c) {
if (c < i - size && cmp(basep + c, basep + c + size, opaque) <= 0)
c += size;
if (cmp(basep + r, basep + c, opaque) > 0)
break;
swap(basep + r, basep + c, size);
}
}
}
}
static inline void *med3(void *a, void *b, void *c, cmp_f cmp, void *opaque)
{
return cmp(a, b, opaque) < 0 ?
(cmp(b, c, opaque) < 0 ? b : (cmp(a, c, opaque) < 0 ? c : a )) :
(cmp(b, c, opaque) > 0 ? b : (cmp(a, c, opaque) < 0 ? a : c ));
}
/* pointer based version with local stack and insertion sort threshhold */
void rqsort(void *base, size_t nmemb, size_t size, cmp_f cmp, void *opaque)
{
struct { uint8_t *base; size_t count; int depth; } stack[50], *sp = stack;
uint8_t *ptr, *pi, *pj, *plt, *pgt, *top, *m;
size_t m4, i, lt, gt, span, span2;
int c, depth;
exchange_f swap = exchange_func(base, size);
exchange_f swap_block = exchange_func(base, size | 128);
if (nmemb < 2 || size <= 0)
return;
sp->base = (uint8_t *)base;
sp->count = nmemb;
sp->depth = 0;
sp++;
while (sp > stack) {
sp--;
ptr = sp->base;
nmemb = sp->count;
depth = sp->depth;
while (nmemb > 6) {
if (++depth > 50) {
/* depth check to ensure worst case logarithmic time */
heapsortx(ptr, nmemb, size, cmp, opaque);
nmemb = 0;
break;
}
/* select median of 3 from 1/4, 1/2, 3/4 positions */
/* should use median of 5 or 9? */
m4 = (nmemb >> 2) * size;
m = med3(ptr + m4, ptr + 2 * m4, ptr + 3 * m4, cmp, opaque);
swap(ptr, m, size); /* move the pivot to the start or the array */
i = lt = 1;
pi = plt = ptr + size;
gt = nmemb;
pj = pgt = top = ptr + nmemb * size;
for (;;) {
while (pi < pj && (c = cmp(ptr, pi, opaque)) >= 0) {
if (c == 0) {
swap(plt, pi, size);
lt++;
plt += size;
}
i++;
pi += size;
}
while (pi < (pj -= size) && (c = cmp(ptr, pj, opaque)) <= 0) {
if (c == 0) {
gt--;
pgt -= size;
swap(pgt, pj, size);
}
}
if (pi >= pj)
break;
swap(pi, pj, size);
i++;
pi += size;
}
/* array has 4 parts:
* from 0 to lt excluded: elements identical to pivot
* from lt to pi excluded: elements smaller than pivot
* from pi to gt excluded: elements greater than pivot
* from gt to n excluded: elements identical to pivot
*/
/* move elements identical to pivot in the middle of the array: */
/* swap values in ranges [0..lt[ and [i-lt..i[
swapping the smallest span between lt and i-lt is sufficient
*/
span = plt - ptr;
span2 = pi - plt;
lt = i - lt;
if (span > span2)
span = span2;
swap_block(ptr, pi - span, span);
/* swap values in ranges [gt..top[ and [i..top-(top-gt)[
swapping the smallest span between top-gt and gt-i is sufficient
*/
span = top - pgt;
span2 = pgt - pi;
pgt = top - span2;
gt = nmemb - (gt - i);
if (span > span2)
span = span2;
swap_block(pi, top - span, span);
/* now array has 3 parts:
* from 0 to lt excluded: elements smaller than pivot
* from lt to gt excluded: elements identical to pivot
* from gt to n excluded: elements greater than pivot
*/
/* stack the larger segment and keep processing the smaller one
to minimize stack use for pathological distributions */
if (lt > nmemb - gt) {
sp->base = ptr;
sp->count = lt;
sp->depth = depth;
sp++;
ptr = pgt;
nmemb -= gt;
} else {
sp->base = pgt;
sp->count = nmemb - gt;
sp->depth = depth;
sp++;
nmemb = lt;
}
}
/* Use insertion sort for small fragments */
for (pi = ptr + size, top = ptr + nmemb * size; pi < top; pi += size) {
for (pj = pi; pj > ptr && cmp(pj - size, pj, opaque) > 0; pj -= size)
swap(pj, pj - size, size);
}
}
}
#endif

View File

@@ -1,398 +0,0 @@
/*
* C utilities
*
* Copyright (c) 2017 Fabrice Bellard
* Copyright (c) 2018 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.
*/
#ifndef CUTILS_H
#define CUTILS_H
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#ifdef _MSC_VER
#include <intrin.h>
#endif
#ifdef _MSC_VER
#define likely(x) (x)
#define unlikely(x) (x)
#define force_inline __forceinline
#define no_inline __declspec(noinline)
#define __maybe_unused
#define __attribute__(...)
#else
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
#define force_inline inline __attribute__((always_inline))
#define no_inline __attribute__((noinline))
#define __maybe_unused __attribute__((unused))
#endif
#define xglue(x, y) x ## y
#define glue(x, y) xglue(x, y)
#define stringify(s) tostring(s)
#define tostring(s) #s
#ifndef offsetof
#define offsetof(type, field) ((size_t) &((type *)0)->field)
#endif
#ifndef countof
#define countof(x) (sizeof(x) / sizeof((x)[0]))
#endif
#ifndef container_of
/* return the pointer of type 'type *' containing 'ptr' as field 'member' */
#define container_of(ptr, type, member) ((type *)((uint8_t *)(ptr) - offsetof(type, member)))
#endif
#if !defined(_MSC_VER) && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
#define minimum_length(n) static n
#else
#define minimum_length(n) n
#endif
typedef int BOOL;
#ifndef FALSE
enum {
FALSE = 0,
TRUE = 1,
};
#endif
void pstrcpy(char *buf, int buf_size, const char *str);
char *pstrcat(char *buf, int buf_size, const char *s);
int strstart(const char *str, const char *val, const char **ptr);
int has_suffix(const char *str, const char *suffix);
/* Prevent UB when n == 0 and (src == NULL or dest == NULL) */
static inline void memcpy_no_ub(void *dest, const void *src, size_t n) {
if (n)
memcpy(dest, src, n);
}
static inline int max_int(int a, int b)
{
if (a > b)
return a;
else
return b;
}
static inline int min_int(int a, int b)
{
if (a < b)
return a;
else
return b;
}
static inline uint32_t max_uint32(uint32_t a, uint32_t b)
{
if (a > b)
return a;
else
return b;
}
static inline uint32_t min_uint32(uint32_t a, uint32_t b)
{
if (a < b)
return a;
else
return b;
}
static inline int64_t max_int64(int64_t a, int64_t b)
{
if (a > b)
return a;
else
return b;
}
static inline int64_t min_int64(int64_t a, int64_t b)
{
if (a < b)
return a;
else
return b;
}
/* WARNING: undefined if a = 0 */
static inline int clz32(unsigned int a)
{
#ifdef _MSC_VER
unsigned long idx;
_BitScanReverse(&idx, a);
return 31 ^ idx;
#else
return __builtin_clz(a);
#endif
}
/* WARNING: undefined if a = 0 */
static inline int clz64(uint64_t a)
{
#ifdef _MSC_VER
unsigned long idx;
_BitScanReverse64(&idx, a);
return 63 ^ idx;
#else
return __builtin_clzll(a);
#endif
}
/* WARNING: undefined if a = 0 */
static inline int ctz32(unsigned int a)
{
#ifdef _MSC_VER
unsigned long idx;
_BitScanForward(&idx, a);
return 31 ^ idx;
#else
return __builtin_ctz(a);
#endif
}
/* WARNING: undefined if a = 0 */
static inline int ctz64(uint64_t a)
{
#ifdef _MSC_VER
unsigned long idx;
_BitScanForward64(&idx, a);
return 63 ^ idx;
#else
return __builtin_ctzll(a);
#endif
}
#ifdef _MSC_VER
#pragma pack(push, 1)
struct packed_u64 {
uint64_t v;
};
struct packed_u32 {
uint32_t v;
};
struct packed_u16 {
uint16_t v;
};
#pragma pack(pop)
#else
struct __attribute__((packed)) packed_u64 {
uint64_t v;
};
struct __attribute__((packed)) packed_u32 {
uint32_t v;
};
struct __attribute__((packed)) packed_u16 {
uint16_t v;
};
#endif
static inline uint64_t get_u64(const uint8_t *tab)
{
return ((const struct packed_u64 *)tab)->v;
}
static inline int64_t get_i64(const uint8_t *tab)
{
return (int64_t)((const struct packed_u64 *)tab)->v;
}
static inline void put_u64(uint8_t *tab, uint64_t val)
{
((struct packed_u64 *)tab)->v = val;
}
static inline uint32_t get_u32(const uint8_t *tab)
{
return ((const struct packed_u32 *)tab)->v;
}
static inline int32_t get_i32(const uint8_t *tab)
{
return (int32_t)((const struct packed_u32 *)tab)->v;
}
static inline void put_u32(uint8_t *tab, uint32_t val)
{
((struct packed_u32 *)tab)->v = val;
}
static inline uint32_t get_u16(const uint8_t *tab)
{
return ((const struct packed_u16 *)tab)->v;
}
static inline int32_t get_i16(const uint8_t *tab)
{
return (int16_t)((const struct packed_u16 *)tab)->v;
}
static inline void put_u16(uint8_t *tab, uint16_t val)
{
((struct packed_u16 *)tab)->v = val;
}
static inline uint32_t get_u8(const uint8_t *tab)
{
return *tab;
}
static inline int32_t get_i8(const uint8_t *tab)
{
return (int8_t)*tab;
}
static inline void put_u8(uint8_t *tab, uint8_t val)
{
*tab = val;
}
#ifndef bswap16
static inline uint16_t bswap16(uint16_t x)
{
return (x >> 8) | (x << 8);
}
#endif
#ifndef bswap32
static inline uint32_t bswap32(uint32_t v)
{
return ((v & 0xff000000) >> 24) | ((v & 0x00ff0000) >> 8) |
((v & 0x0000ff00) << 8) | ((v & 0x000000ff) << 24);
}
#endif
#ifndef bswap64
static inline uint64_t bswap64(uint64_t v)
{
return ((v & ((uint64_t)0xff << (7 * 8))) >> (7 * 8)) |
((v & ((uint64_t)0xff << (6 * 8))) >> (5 * 8)) |
((v & ((uint64_t)0xff << (5 * 8))) >> (3 * 8)) |
((v & ((uint64_t)0xff << (4 * 8))) >> (1 * 8)) |
((v & ((uint64_t)0xff << (3 * 8))) << (1 * 8)) |
((v & ((uint64_t)0xff << (2 * 8))) << (3 * 8)) |
((v & ((uint64_t)0xff << (1 * 8))) << (5 * 8)) |
((v & ((uint64_t)0xff << (0 * 8))) << (7 * 8));
}
#endif
/* XXX: should take an extra argument to pass slack information to the caller */
typedef void *DynBufReallocFunc(void *opaque, void *ptr, size_t size);
typedef struct DynBuf {
uint8_t *buf;
size_t size;
size_t allocated_size;
BOOL error; /* true if a memory allocation error occurred */
DynBufReallocFunc *realloc_func;
void *opaque; /* for realloc_func */
} DynBuf;
void dbuf_init(DynBuf *s);
void dbuf_init2(DynBuf *s, void *opaque, DynBufReallocFunc *realloc_func);
int dbuf_realloc(DynBuf *s, size_t new_size);
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_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);
static inline int dbuf_put_u16(DynBuf *s, uint16_t val)
{
return dbuf_put(s, (uint8_t *)&val, 2);
}
static inline int dbuf_put_u32(DynBuf *s, uint32_t val)
{
return dbuf_put(s, (uint8_t *)&val, 4);
}
static inline int dbuf_put_u64(DynBuf *s, uint64_t val)
{
return dbuf_put(s, (uint8_t *)&val, 8);
}
int __attribute__((format(printf, 2, 3))) dbuf_printf(DynBuf *s,
const char *fmt, ...);
void dbuf_free(DynBuf *s);
static inline BOOL dbuf_error(DynBuf *s) {
return s->error;
}
static inline void dbuf_set_error(DynBuf *s)
{
s->error = TRUE;
}
#define UTF8_CHAR_LEN_MAX 6
int unicode_to_utf8(uint8_t *buf, unsigned int c);
int unicode_from_utf8(const uint8_t *p, int max_len, const uint8_t **pp);
static inline BOOL is_surrogate(uint32_t c)
{
return (c >> 11) == (0xD800 >> 11); // 0xD800-0xDFFF
}
static inline BOOL is_hi_surrogate(uint32_t c)
{
return (c >> 10) == (0xD800 >> 10); // 0xD800-0xDBFF
}
static inline BOOL is_lo_surrogate(uint32_t c)
{
return (c >> 10) == (0xDC00 >> 10); // 0xDC00-0xDFFF
}
static inline uint32_t get_hi_surrogate(uint32_t c)
{
return (c >> 10) - (0x10000 >> 10) + 0xD800;
}
static inline uint32_t get_lo_surrogate(uint32_t c)
{
return (c & 0x3FF) | 0xDC00;
}
static inline uint32_t from_surrogate(uint32_t hi, uint32_t lo)
{
return 0x10000 + 0x400 * (hi - 0xD800) + (lo - 0xDC00);
}
static inline int from_hex(int c)
{
if (c >= '0' && c <= '9')
return c - '0';
else if (c >= 'A' && c <= 'F')
return c - 'A' + 10;
else if (c >= 'a' && c <= 'f')
return c - 'a' + 10;
else
return -1;
}
void rqsort(void *base, size_t nmemb, size_t size,
int (*cmp)(const void *, const void *, void *),
void *arg);
#endif /* CUTILS_H */

File diff suppressed because it is too large Load Diff

View File

@@ -37,10 +37,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: collection name: collection
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.18.0" version: "1.19.0"
fake_async: fake_async:
dependency: transitive dependency: transitive
description: description:
@@ -94,18 +94,18 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: leak_tracker name: leak_tracker
sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "10.0.5" version: "10.0.7"
leak_tracker_flutter_testing: leak_tracker_flutter_testing:
dependency: transitive dependency: transitive
description: description:
name: leak_tracker_flutter_testing name: leak_tracker_flutter_testing
sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.5" version: "3.0.8"
leak_tracker_testing: leak_tracker_testing:
dependency: transitive dependency: transitive
description: description:
@@ -150,7 +150,7 @@ packages:
dependency: transitive dependency: transitive
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.99" version: "0.0.0"
source_span: source_span:
dependency: transitive dependency: transitive
description: description:
@@ -163,10 +163,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: stack_trace name: stack_trace
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.11.1" version: "1.12.0"
stream_channel: stream_channel:
dependency: transitive dependency: transitive
description: description:
@@ -179,10 +179,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: string_scanner name: string_scanner
sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.2.0" version: "1.3.0"
term_glyph: term_glyph:
dependency: transitive dependency: transitive
description: description:
@@ -195,10 +195,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: test_api name: test_api
sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.7.2" version: "0.7.3"
vector_math: vector_math:
dependency: transitive dependency: transitive
description: description:
@@ -211,10 +211,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: vm_service name: vm_service
sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "14.2.5" version: "14.3.0"
sdks: sdks:
dart: ">=3.5.0 <4.0.0" dart: ">=3.5.0 <4.0.0"
flutter: ">=3.24.0" flutter: ">=3.24.0"

View File

@@ -5,23 +5,23 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: _fe_analyzer_shared name: _fe_analyzer_shared
sha256: f256b0c0ba6c7577c15e2e4e114755640a875e885099367bf6e012b19314c834 sha256: f6dbf021f4b214d85c79822912c5fcd142a2c4869f01222ad371bc51f9f1c356
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "72.0.0" version: "74.0.0"
_macros: _macros:
dependency: transitive dependency: transitive
description: dart description: dart
source: sdk source: sdk
version: "0.3.2" version: "0.3.3"
analyzer: analyzer:
dependency: transitive dependency: transitive
description: description:
name: analyzer name: analyzer
sha256: b652861553cd3990d8ed361f7979dc6d7053a9ac8843fa73820ab68ce5410139 sha256: f7e8caf82f2d3190881d81012606effdf8a38e6c1ab9e30947149733065f817c
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.7.0" version: "6.9.0"
archive: archive:
dependency: transitive dependency: transitive
description: description:
@@ -58,10 +58,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: browser_launcher name: browser_launcher
sha256: "6ee4c6b1f68a42e769ef6e663c4f56708522f7bce9d2ab6e308a37b612ffa4ec" sha256: "54a2da4d152c34760b87cbd4a9fe8a563379487e57bfcd1b387be394dfa91734"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.1.1" version: "1.1.2"
built_collection: built_collection:
dependency: transitive dependency: transitive
description: description:
@@ -106,10 +106,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: collection name: collection
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a sha256: a1ace0a119f20aabc852d165077c036cd864315bd99b7eaa10a60100341941bf
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.18.0" version: "1.19.0"
completion: completion:
dependency: transitive dependency: transitive
description: description:
@@ -130,18 +130,18 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: coverage name: coverage
sha256: "3945034e86ea203af7a056d98e98e42a5518fff200d6e8e6647e1886b07e936e" sha256: c1fb2dce3c0085f39dc72668e85f8e0210ec7de05345821ff58530567df345a5
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.8.0" version: "1.9.2"
crypto: crypto:
dependency: transitive dependency: transitive
description: description:
name: crypto name: crypto
sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab sha256: ec30d999af904f33454ba22ed9a86162b35e52b44ac4807d1d93c288041d7d27
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.3" version: "3.0.5"
csslib: csslib:
dependency: transitive dependency: transitive
description: description:
@@ -162,10 +162,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: dds name: dds
sha256: f3bca60b6b7d2b005268a1a579c82e38bec3d85cc85c332a872fe623c7ba94d7 sha256: c90723eb1f1402429c57f717550ce5af80288d74a27c45ccbe754a0e3e038f95
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.2.4+2" version: "4.2.7"
dds_service_extensions: dds_service_extensions:
dependency: transitive dependency: transitive
description: description:
@@ -178,34 +178,34 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: devtools_shared name: devtools_shared
sha256: a6e66165629ec004cabd84e6971f502aeac07f1a5f6ffd9b3244cd05b1a06fb0 sha256: "72369878105eccd563547afbad97407a2431b96bd4c04a1d6da75cb068437f50"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "10.0.1" version: "10.0.2"
dtd: dtd:
dependency: transitive dependency: transitive
description: description:
name: dtd name: dtd
sha256: "58ac5c2d628e575dbcdfda44a698cd4c1212663e27fe5f8ced37aea85faa0d30" sha256: "6e4e508c0d03e12e2c96f21faa0e5acc191f9431ecd02adb8daee64dbfae6b86"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.2.0" version: "2.3.0"
dwds: dwds:
dependency: transitive dependency: transitive
description: description:
name: dwds name: dwds
sha256: "61ebaabb04d779d040b47d3b4d0b3963449ced0920fb8efd81ca6d5e51ccfc1a" sha256: d0cf9d18511df6b397c40527f3fd8ddb47b7efcc501e703dd94f13cabaf82ffc
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "24.0.0" version: "24.1.0"
extension_discovery: extension_discovery:
dependency: transitive dependency: transitive
description: description:
name: extension_discovery name: extension_discovery
sha256: "20735622d0763865f9d94c3ecdce4441174530870760253e9d364fb4f3da8688" sha256: de1fce715ab013cdfb00befc3bdf0914bea5e409c3a567b7f8f144bc061611a7
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.0" version: "2.1.0"
fake_async: fake_async:
dependency: transitive dependency: transitive
description: description:
@@ -218,10 +218,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: ffi name: ffi
sha256: "493f37e7df1804778ff3a53bd691d8692ddf69702cf4c1c1096a2e41b4779e21" sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.2" version: "2.1.3"
file: file:
dependency: transitive dependency: transitive
description: description:
@@ -243,6 +243,14 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
flutter_lints:
dependency: "direct dev"
description:
name: flutter_lints
sha256: "5398f14efa795ffb7a33e9b6a08798b26a180edac4ad7db3f231e40f82ce11e1"
url: "https://pub.dev"
source: hosted
version: "5.0.0"
flutter_template_images: flutter_template_images:
dependency: transitive dependency: transitive
description: description:
@@ -281,10 +289,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: graphs name: graphs
sha256: aedc5a15e78fc65a6e23bcd927f24c64dd995062bcd1ca6eda65a3cff92a4d19 sha256: "741bbf84165310a68ff28fe9e727332eef1407342fca52759cb21ad8177bb8d0"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.3.1" version: "2.3.2"
html: html:
dependency: transitive dependency: transitive
description: description:
@@ -297,10 +305,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: http name: http
sha256: "5895291c13fa8a3bd82e76d5627f69e0d85ca6a30dcac95c4ea19a5d555879c2" sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.13.6" version: "1.2.2"
http_multi_server: http_multi_server:
dependency: transitive dependency: transitive
description: description:
@@ -313,10 +321,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: http_parser name: http_parser
sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" sha256: "40f592dd352890c3b60fec1b68e786cefb9603e05ff303dbc4dda49b304ecdf4"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.0.2" version: "4.1.0"
intl: intl:
dependency: transitive dependency: transitive
description: description:
@@ -333,6 +341,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.4" version: "1.0.4"
js:
dependency: transitive
description:
name: js
sha256: c1b2e9b5ea78c45e1a0788d29606ba27dc5f71f019f32ca5140f61ef071838cf
url: "https://pub.dev"
source: hosted
version: "0.7.1"
json_rpc_2: json_rpc_2:
dependency: transitive dependency: transitive
description: description:
@@ -345,18 +361,18 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: leak_tracker name: leak_tracker
sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" sha256: "7bb2830ebd849694d1ec25bf1f44582d6ac531a57a365a803a6034ff751d2d06"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "10.0.5" version: "10.0.7"
leak_tracker_flutter_testing: leak_tracker_flutter_testing:
dependency: transitive dependency: transitive
description: description:
name: leak_tracker_flutter_testing name: leak_tracker_flutter_testing
sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" sha256: "9491a714cca3667b60b5c420da8217e6de0d1ba7a5ec322fab01758f6998f379"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.5" version: "3.0.8"
leak_tracker_testing: leak_tracker_testing:
dependency: transitive dependency: transitive
description: description:
@@ -365,6 +381,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.1" version: "3.0.1"
lints:
dependency: transitive
description:
name: lints
sha256: c35bb79562d980e9a453fc715854e1ed39e24e7d0297a880ef54e17f9874a9d7
url: "https://pub.dev"
source: hosted
version: "5.1.1"
logging: logging:
dependency: transitive dependency: transitive
description: description:
@@ -377,10 +401,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: macros name: macros
sha256: "0acaed5d6b7eab89f63350bccd82119e6c602df0f391260d0e32b5e23db79536" sha256: "1d9e801cd66f7ea3663c45fc708450db1fa57f988142c64289142c9b7ee80656"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.1.2-main.4" version: "0.1.3-main.0"
matcher: matcher:
dependency: transitive dependency: transitive
description: description:
@@ -409,10 +433,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: mime name: mime
sha256: "2e123074287cc9fd6c09de8336dae606d1ddb88d9ac47358826db698c176a1f2" sha256: "801fd0b26f14a4a58ccb09d5892c3fbdeff209594300a542492cf13fba9d247a"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.5" version: "1.0.6"
multicast_dns: multicast_dns:
dependency: transitive dependency: transitive
description: description:
@@ -433,26 +457,34 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: native_assets_builder name: native_assets_builder
sha256: e6612ad01cbc3c4d1b00a1a42aa25aa567950ab10ae1f95721574923540f3bd8 sha256: ad76e66cc1ca7aa922d682651aee2663cd80e6ba483a346d13a8c40f604ebfd9
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.7.0" version: "0.8.3"
native_assets_cli: native_assets_cli:
dependency: transitive dependency: transitive
description: description:
name: native_assets_cli name: native_assets_cli
sha256: f54ddc4a3f8cff1d8d63723b4938902da7586a5a47fe3c1bfa226eb80223f32e sha256: db902509468ec2a6c6d11fa9ce02805ede280e8dbfb5f0014ef3de8483cadfce
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.6.0" version: "0.8.0"
native_stack_traces: native_stack_traces:
dependency: transitive dependency: transitive
description: description:
name: native_stack_traces name: native_stack_traces
sha256: "64d2f4bcf3b69326fb9bc91b4dd3a06f94bb5bbc3a65e25ae6467ace0b34bfd3" sha256: "8ba566c10ea781491c203876b04b9bdcf19dfbe17b9e486869f20eaae0ee470f"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.5.7" version: "0.6.0"
node_preamble:
dependency: transitive
description:
name: node_preamble
sha256: "6e7eac89047ab8a8d26cf16127b5ed26de65209847630400f9aefd7cd5c730db"
url: "https://pub.dev"
source: hosted
version: "2.0.2"
package_config: package_config:
dependency: transitive dependency: transitive
description: description:
@@ -513,10 +545,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: shelf name: shelf
sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4 sha256: e7dd780a7ffb623c57850b33f43309312fc863fb6aa3d276a754bb299839ef12
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.4.1" version: "1.4.2"
shelf_packages_handler: shelf_packages_handler:
dependency: transitive dependency: transitive
description: description:
@@ -537,31 +569,31 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: shelf_static name: shelf_static
sha256: a41d3f53c4adf0f57480578c1d61d90342cd617de7fc8077b1304643c2d85c1e sha256: c87c3875f91262785dade62d135760c2c69cb217ac759485334c5857ad89f6e3
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.1.2" version: "1.1.3"
shelf_web_socket: shelf_web_socket:
dependency: transitive dependency: transitive
description: description:
name: shelf_web_socket name: shelf_web_socket
sha256: "9ca081be41c60190ebcb4766b2486a7d50261db7bd0f5d9615f2d653637a84c1" sha256: "073c147238594ecd0d193f3456a5fe91c4b0abbcc68bf5cd95b36c4e194ac611"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.4" version: "2.0.0"
sky_engine: sky_engine:
dependency: transitive dependency: transitive
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.99" version: "0.0.0"
source_map_stack_trace: source_map_stack_trace:
dependency: transitive dependency: transitive
description: description:
name: source_map_stack_trace name: source_map_stack_trace
sha256: "84cf769ad83aa6bb61e0aa5a18e53aea683395f196a6f39c4c881fb90ed4f7ae" sha256: c0713a43e323c3302c2abe2a1cc89aa057a387101ebd280371d6a6c9fa68516b
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.1" version: "2.1.2"
source_maps: source_maps:
dependency: transitive dependency: transitive
description: description:
@@ -578,22 +610,30 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.10.0" version: "1.10.0"
sprintf:
dependency: transitive
description:
name: sprintf
sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23"
url: "https://pub.dev"
source: hosted
version: "7.0.0"
sse: sse:
dependency: transitive dependency: transitive
description: description:
name: sse name: sse
sha256: fdce3a4ac3ae1c01083d05ded0bcdb7e02857ca2323823548e9e76d2f61638f0 sha256: "111a05843ea9035042975744fe61d5e8b95bc4d38656dbafc5532da77a0bb89a"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.1.5" version: "4.1.6"
stack_trace: stack_trace:
dependency: transitive dependency: transitive
description: description:
name: stack_trace name: stack_trace
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.11.1" version: "1.12.0"
standard_message_codec: standard_message_codec:
dependency: transitive dependency: transitive
description: description:
@@ -614,10 +654,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: string_scanner name: string_scanner
sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.2.0" version: "1.3.0"
sync_http: sync_http:
dependency: transitive dependency: transitive
description: description:
@@ -634,22 +674,30 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.2.1" version: "1.2.1"
test:
dependency: transitive
description:
name: test
sha256: "713a8789d62f3233c46b4a90b174737b2c04cb6ae4500f2aa8b1be8f03f5e67f"
url: "https://pub.dev"
source: hosted
version: "1.25.8"
test_api: test_api:
dependency: transitive dependency: transitive
description: description:
name: test_api name: test_api
sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.7.2" version: "0.7.3"
test_core: test_core:
dependency: transitive dependency: transitive
description: description:
name: test_core name: test_core
sha256: "55ea5a652e38a1dfb32943a7973f3681a60f872f8c3a05a14664ad54ef9c6696" sha256: "12391302411737c176b0b5d6491f466b0dd56d4763e347b6714efbaa74d7953d"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.6.4" version: "0.6.5"
typed_data: typed_data:
dependency: transitive dependency: transitive
description: description:
@@ -662,10 +710,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: unified_analytics name: unified_analytics
sha256: "916215af2dc2f54a204c6bfbc645ec401b6a150048764814379f42e09b557d2d" sha256: "9f3c68cb30faa6d05b920498d2af79eace00fef0bae9beba9f3cda84fdbe46df"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.1.2" version: "6.1.4"
usage: usage:
dependency: transitive dependency: transitive
description: description:
@@ -678,10 +726,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: uuid name: uuid
sha256: "648e103079f7c64a36dc7d39369cabb358d377078a051d6ae2ad3aa539519313" sha256: a5be9ef6618a7ac1e964353ef476418026db906c4facdedaa299b7a2e71690ff
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.7" version: "4.5.1"
vector_math: vector_math:
dependency: transitive dependency: transitive
description: description:
@@ -694,10 +742,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: vm_service name: vm_service
sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" sha256: f6be3ed8bd01289b34d679c2b62226f63c0e69f9fd2e50a6b3c1c729a961041b
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "14.2.5" version: "14.3.0"
vm_service_interface: vm_service_interface:
dependency: transitive dependency: transitive
description: description:
@@ -726,26 +774,34 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: web name: web
sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27" sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.5.1" version: "1.1.0"
web_socket:
dependency: transitive
description:
name: web_socket
sha256: "3c12d96c0c9a4eec095246debcea7b86c0324f22df69893d538fcc6f1b8cce83"
url: "https://pub.dev"
source: hosted
version: "0.1.6"
web_socket_channel: web_socket_channel:
dependency: transitive dependency: transitive
description: description:
name: web_socket_channel name: web_socket_channel
sha256: "58c6666b342a38816b2e7e50ed0f1e261959630becd4c879c4f26bfa14aa5a42" sha256: "9f187088ed104edd8662ca07af4b124465893caf063ba29758f97af57e61da8f"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.4.5" version: "3.0.1"
webdriver: webdriver:
dependency: transitive dependency: transitive
description: description:
name: webdriver name: webdriver
sha256: "003d7da9519e1e5f329422b36c4dcdf18d7d2978d1ba099ea4e45ba490ed845e" sha256: "3d773670966f02a646319410766d3b5e1037efb7f07cc68f844d5e06cd4d61c8"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.3" version: "3.0.4"
webkit_inspection_protocol: webkit_inspection_protocol:
dependency: transitive dependency: transitive
description: description:
@@ -779,5 +835,5 @@ packages:
source: hosted source: hosted
version: "2.2.1" version: "2.2.1"
sdks: sdks:
dart: ">=3.5.0 <4.0.0" dart: ">=3.6.0 <4.0.0"
flutter: ">=3.24.0" flutter: ">=3.24.0"

View File

@@ -17,6 +17,7 @@ dev_dependencies:
sdk: flutter sdk: flutter
flutter_tools: flutter_tools:
sdk: flutter sdk: flutter
flutter_lints:
# For information on the generic Dart part of this file, see the # For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec # following page: https://dart.dev/tools/pub/pubspec